Skip to content

Accept a card payment

A sale authorizes the card and captures the funds in a single request. Use it when you deliver at the moment of payment — a digital download, a subscription charge, a service that completes right away.

If you ship later, authorize now and capture when you ship instead.

Before you start

  • Your Api-Key and Client-Id — see Authentication
  • A processor integration configured for cards

Send the sale

POST /v1/transactions with type set to SALE.

The fields that decide whether this works:

FieldNotes
typeSALE. A card also accepts AUTH. It does not accept PAYOUT
amountInteger, smallest currency unit. 10000 is 100.00 USD. Minimum 50
payment_method.typeCard, spelled exactly that way. Mixed case, not CARD
payment_method.pan14 to 19 digits
payment_method.expiryAn object of two integers: month 1–12, year four digits
payment_method.cvv3 or 4 digits. Optional, but send it when the cardholder is present
payment_method.billing_addressDrives AVS. Optional, and worth sending
currencyUSD is the only accepted value, and the default

Two mistakes are easy to make here.

  • expiry is nested, and its parts are integers. "month": 1, not "expiry_month": "01".
  • The name fields are first_name and last_name, inside payment_method. There is no cardholder_name.

Read the response

Response

The approved sale. Because a SALE authorizes and captures in one step, batch_id is already assigned and the transaction settles at the next batch close. reference_transaction_id is null because this is an original transaction, not a capture, void, or refund of another one.

{ "id": "TRANSACTION-01KEW32V6YNV11T33XGDR7TGWC", "reference_transaction_id": null, "type": "SALE", "result": "APPROVED", "client_id": "CLIENT-01KFDKXMQ637EKEAY410MSQSXB", "client_dba": "Acme Jewelry", "integrations": [ "TSYS" ], "response_code": "00", "response_description": "Approved", "batch_id": "BATCH-01KEW32V6YNV11T33XGDR7TGWC", "is_settled": false, "time_created": "2026-07-15T14:22:05Z", "amount": 10000, "tip": 0, "currency": "USD", "payment_method": { "type": "CARD", "truncated_pan": "****-****-****-5439", "payment_token": "PAYMENT_TOKEN-01KFDKXMQ637EKEAY410MSQSXB", "expiry": { … }, "first_name": "John", "last_name": "Doe", "entry_method": "keyed", "auth_code": "123456", "retrieval_reference_number": "000000603076", "card_type": "UNKNOWN", "card_brand": "Visa", "cvv_result_code": "M", "avs_result_code": "Y", "avs_response": "Exact Match - Street address and postal code match" }, "initiator": "CUSTOMER", "network_transaction_id": "MCC1234567890", "metadata": { "order_id": "ORD-10432", "sales_channel": "web", "customer_reference": "cust-8891" } }

Check result first. APPROVED means the money is yours at the next batch close; DECLINED means the issuer said no; ERROR means the transaction could not be attempted. All three come back as 200.

A few fields deserve attention.

  • payment_method.payment_token is a token for this card, issued as a side effect of the transaction. Store it and you never need the number again. See Save and reuse a payment method.
  • payment_method.avs_result_code says how much of the billing address matched. Y is a full match, Z postal code only, N neither. See AVS and CVV.
  • payment_method.card_type is always UNKNOWN here. The processor does not report it on an authorization. Read the transaction back from GET /v1/transactions/{id} for the real value.
  • batch_id is the settlement batch. It is null until the transaction reaches one.

Next steps