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.

Loading...

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
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
payment_method.entry_methodHow you took the card details. ECOMMERCE, the default, or MOTO. Both are Card Not Present
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. A SALE authorizes and captures in one step, so the transaction joins the open batch and settles at the next batch close. batch_id is null until then, because the gateway assigns it at settlement. reference_transaction_id is null because this is an original transaction, not a capture, void, or refund of another one. entry_method echoes the request value.

{ "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": null, "is_settled": false, "time_created": "2026-07-15T14:22:05Z", "amount": 10000, "tip": 0, "tax_amount": 500, "currency": "USD", "payment_method": { "type": "CARD", "truncated_pan": "****-****-****-5439", "payment_token": "CARD_TOKEN-01KFDKXMQ637EKEAY410MSQSXB", "expiry": { … }, "first_name": "John", "last_name": "Doe", "entry_method": "ECOMMERCE", "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" }, "recurring": false, "initiator": "CUSTOMER", "network_transaction_id": "000000004271001", "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 batch settles, so a null value on a new sale is normal.
  • payment_method.entry_method echoes the value you sent.

Take a payment by phone or mail

When an operator keys in card details that the cardholder gave over the phone or by mail, set payment_method.entry_method to MOTO. Everything else about the sale is the same.

Loading...

The CVV is optional on a MOTO sale. Leave it out of a mail order, where the cardholder should not write it down. Without it, cvv_result_code comes back null.

Next steps