Skip to main content

Transactions

A transaction is an instance of an action that requires a payment. Every charge, authorization, refund, and card verification on Payments AI is a transaction.

A transaction has the following characteristics:

  • It includes an amount and a currency.
  • It has a result (such as approved, declined, canceled, abandoned, or unknown) and a status (see Transaction statuses).
  • It is related to a specific merchant website and a customer.
  • It links to a specific payment instrument, such as the card, bank account, or wallet being charged.
  • It can connect to another transaction. For example, a refund references the specific sale it reverses.

HTTP 201 does not mean logical success:

POST /transactions returns a 201 Created status code whenever the transaction record is successfully created on the Payments AI platform. This includes declined payments. A 201 status code indicates that the request was accepted, not that the customer was successfully charged.

Always check the result and status fields in the response body before treating a transaction as successful. A response containing result: "declined" or status: "not-sent" returns a 201 status code but represents a logical failure.

A transaction's financial state is immutable in the public API:

The financial state of a transaction — including its amount, result, and status — cannot be modified via the API once the record is created. Corrections to that state, such as marking an offsite payment as completed, must be handled directly within the Payments AI panel. See Updating transactions via the dashboard.

Transaction types

The type value you specify on POST /transactions determines the action taken:

TypeWhat it does
saleAuthorizes and captures funds in a single step. The customer is charged immediately.
authorizeReserves funds without capturing them. You can capture these funds later using a separate sale action. See Authorize and capture.

The response field Transaction.type can return any of the following values: 3ds-authentication, authorize, capture, credit, refund, sale, or void. See Transaction statuses for the definition of each type. System-generated types appear automatically when secondary actions occur. For example, the refund type appears when you call the refund endpoint.

Creating a transaction

curl -X POST \
"https://staging-api.payments.ai/v1/public-api/organizations/${ORGANIZATION_ID}/transactions" \
-H 'Content-Type: application/json' \
-H "Authorization: ApiKey ${API_KEY}" \
-d '{
"type": "sale",
"customerId": "Customer ID Here",
"currency": "USD",
"amount": 10,
"paymentInstruction": { "token": "Token value from tokenization step" },
"isMerchantInitiated": false,
"redirectUrl": "https://yoursite.com/{id}/{result}"
}'

paymentInstruction

The paymentInstruction object defines what asset to charge. Which of the two structures you send is decided by whether the customer is present:

Customer present: send a fresh token. No customer present: send the stored paymentInstrumentId.

  • { "token": "<token>" }: A fresh tokenization token. Use this for every customer-initiated charge, including returning customers. The token carries the CVV the customer typed, and that CVV covers exactly one charge, which is why a stored instrument works at most once in a customer-present context and declines after that. See Token lifecycle.
  • { "paymentInstrumentId": "<id>" }: A stored payment instrument. Use this only for merchant-initiated charges, and only on an instrument produced by an approved customer-initiated transaction.

For the full customer-initiated to merchant-initiated sequence, see Card on file.

Customer-initiated vs. merchant-initiated transactions

The isMerchantInitiated flag indicates whether the customer is present during the transaction sequence:

ValueDefinition
trueMerchant-initiated transaction (MIT): A recurring charge or renewal executed without the customer present, utilizing a stored credential-on-file.
falseCustomer-initiated transaction (CIT): The customer is actively present at the checkout interface.
null (default)Payments AI infers the classification from context. For example, a subscription renewal is automatically treated as merchant-initiated.

This flag manages credential-on-file handling, network token usage, and Strong Customer Authentication (SCA) / 3DS exemption logic. Merchant-initiated transactions are typically out of scope for SCA requirements.

Set the flag explicitly rather than relying on inference, and pair it with the matching paymentInstruction:

ChargepaymentInstructionisMerchantInitiated
Customer-initiated (checkout, including returning customers){ token }false
Merchant-initiated (upsell, retry, scheduled charge){ paymentInstrumentId }true

Required: charge an MIT only after an approved CIT

A merchant-initiated transaction runs only on a payment instrument whose customer-initiated transaction reached result: "approved". Resolve the CIT to its final result first, store the instrument only then, and charge only instruments that passed. This ordering is part of the flow, not an optional check. See Card on file.

API Reference

Request fields

FieldRequiredNotes
typeYesUse sale or authorize.
customerIdYesThe ID of the customer being charged. Maximum 50 characters.
currencyYesThe ISO currency code (for example, USD).
amountYesThe transaction amount.
paymentInstructionYesSend { token } whenever the customer is present, { paymentInstrumentId } for merchant-initiated charges. See paymentInstruction.
redirectUrlRecommendedWhere the customer is redirected after an offsite step such as a 3DS challenge. Not enforced: omitting it does not fail the request; the response falls back to a URL configured on the account or website, which may not be the one you want. Set it explicitly on any charge that may go offsite. Maximum 1024 characters. See 3DS2 guide.
idempotencyKeyRecommendedDeduplicates retried requests. Maximum 100 characters.
metadataOptionalA free-form key-value object for custom data tracking.
invoiceIdsOptionalArray of invoice IDs to associate with the transaction.
isMerchantInitiatedOptionalMIT/CIT flag tracking customer presence. Set it explicitly (false when the customer is present, true for MIT/upsell charges) rather than relying on inference.
billingAddressOptionalThe billing address for the transaction. Fields: firstName, lastName, country, address, address2, city, zip. Note: the street address field is address (unlike the customer endpoint, which uses address1).

Response fields

The response wraps a Transaction object inside a top-level data field. The object contains:

FieldMeaning
idThe unique transaction ID.
createdAtWhen the transaction record was created.
updatedAtWhen the transaction record was last updated.
deletedAtWhen the transaction record was deleted (null otherwise).
dateWhen the transaction was executed (distinct from createdAt).
amountThe original transaction amount.
refundAmountThe total amount already refunded (returns null if no refunds have occurred).
refundableAmountThe remaining balance available for refund actions.
currencyThe ISO currency code.
statusSee Transaction statuses.
resultOne of abandoned, approved, canceled, declined, unknown. See Transaction statuses.
combinedStatusA merged representation of status and result. The CombinedStatus enum supports 13 values: abandoned, canceled, declined, completed, refunded, voided, partially-refunded, waiting, timeout, not-sent, disputed, sending, offsite.
typeThe transaction type (sale, authorize, capture, refund, credit, void, 3ds-authentication).
paymentTypeReturns one-time-payment or subscription-payment.
paymentInstrumentA historical data snapshot of the payment instrument captured at the moment of processing.
customerA narrow inline snapshot of the customer at the time of the transaction: name, email, origin, language. Not the full Customer object.
invoicesArray of invoice references attached to the transaction. Each entry has date, amount, currency.
parentTransactionIdPopulated only on a capture, referencing the authorization it settles. null everywhere else. A refund does not create a new transaction; it moves the original to refunded.
subscriptionIdThe originating subscription ID. This field populates only if the transaction was generated automatically by a subscription engine.
gatewayNameThe gateway that processed the transaction.
paymentLinkA URL the customer can use to complete payment when the transaction was created in a state that requires customer action.
redirectUrlThe redirect target propagated from the request (≤1024 characters). Echoed back on the response.
data3ds3DS authentication data, when applicable.
avsResponseAddress Verification Service response from the gateway.
cvvResponseCVV verification response from the gateway.
arnAcquirer Reference Number from the gateway.
ipAddressThe IP address recorded at transaction time.
fingerprintDevice or session fingerprint.
binThe 6-digit Bank Identification Number of the card (for example, 424242).
isMerchantInitiatedEchoed back: true for MIT, false for CIT, null when inferred.
permissionsBundle.isRefundableReturns true if the transaction can currently accept a refund request.

paymentType: Subscription vs. one-off

The paymentType field indicates whether the transaction originated from an automated subscription or a standard one-off payment:

  • subscription-payment: Generated by an automated subscription renewal. The subscriptionId field populates with the matching reference ID.
  • one-time-payment: A distinct, one-off charge originating from a single POST /transactions call or a single order event.

Use paymentType to organize UI groupings ("recurring" vs. "one-off") and clean up reporting metrics. Use subscriptionId to link a transaction back to its parent subscription profile.

paymentInstrument is a historical snapshot

The paymentInstrument object nested within a transaction response is a static snapshot captured at the moment of transaction execution. It does not act as a live reference. While the card brand and the last four digits remain constant, fields like expireDate can drift if a customer updates their stored payment profile later on.

  • Use Transaction.paymentInstrument for receipts, invoices, and historical ledger displays to reflect what was actually charged.
  • Use GET /payment-instruments/{Transaction.paymentInstrument.id} to verify the live state of the instrument, including current expiration data and active status.

Filtering transactions

GET /transactions supports query parameters for complex searching and ledger filtering:

ParameterTypeExample
combinedStatusesarray?combinedStatuses=completed,refunded
paymentMethodsarray?paymentMethods=payment-card,paypal
paymentTypeenum?paymentType=subscription-payment
gatewaysarray?gateways=stripe,paypal
currenciesarray?currencies=USD,EUR
dateFrom / dateTodate-time?dateFrom=2026-01-01T00:00:00Z&dateTo=2026-01-31T23:59:59Z
amountMin / amountMaxnumber?amountMin=10&amountMax=100
customerIdstring?customerId=<id>
subscriptionIdstring?subscriptionId=<id>
searchstring?search=John
limit / offsetinteger?limit=20&offset=40
sortBy / sortDirectionstring?sortBy=createdAt&sortDirection=desc

Filter examples

All completed transactions in January 2026, sorted by descending creation date:

GET /transactions?combinedStatuses=completed&dateFrom=2026-01-01T00:00:00Z&dateTo=2026-01-31T23:59:59Z&sortBy=createdAt&sortDirection=desc

All transactions associated with a single customer ID:

GET /transactions?customerId=<customerId>&sortBy=createdAt&sortDirection=desc

All fully or partially refunded transactions with an amount over $50:

GET /transactions?combinedStatuses=refunded&amountMin=50

All recurring transactions tied to a specific subscription record:

GET /transactions?paymentType=subscription-payment&subscriptionId=<subscriptionId>

All Stripe transactions processed during May 2026:

GET /transactions?gateways=stripe&dateFrom=2026-05-01T00:00:00Z

Supported gateways

The gateways parameter accepts default, paypal, klarna, coinbase, nmi, and stripe. See Gateways.

Supported payment methods

The paymentMethods parameter accepts an enum covering cards, ACH transfers, digital wallets, local payment options, and cryptocurrencies. Common values include:

ValuePayment Method
payment-cardCredit and debit cards
achACH bank transfer (US)
paypalPayPal
Apple PayApple Pay
GooglePayGoogle Pay
KlarnaKlarna
bitcoin / cryptocurrencyCryptocurrency payments routed via the Coinbase gateway
bank-transferGeneric bank transfers

For the complete list of roughly 120 regional payment types (such as PIX, WeChat Pay, Trustly, or MuchBetter), see the full GET /transactions API reference documentation.

Updating transactions via the dashboard

The public API does not expose endpoints to modify a transaction's financial state. Account operators can update a transaction's result field via the administrative panel under specific conditions (such as logging an offline settlement). This capability is restricted to the user interface.

Webhooks

Payments AI issues two distinct webhook notifications for transaction lifecycles:

  • transaction-processed: Sent as soon as a gateway completes transaction execution. This represents the primary integration hook for successful payments.
  • transaction-declined: Sent if a gateway declines the transaction. For automated subscription collection, this notification triggers on every consecutive billing retry.

Pass these identifiers inside the eventTypes array when registering endpoints. See Subscription webhooks for details on payload shapes and Webhook setup to review the registration workflow.