Card Transactions


With Veem's Card Transactions API, partners can initiate card-funded payments on behalf of payers using network-tokenized card credentials, retrieve transaction details, and cancel transactions through void or reversal operations.

📘
Network tokens only

The cardDetails.cardNumber field must contain a network token (DPAN) issued by a certified tokenization service such as Visa Token Service (VTS) or Mastercard Digital Enablement Service (MDES). Raw Primary Account Numbers (PANs) are not accepted.

Create Card Transaction

This endpoint is used to initiate a card-funded payment. Two operation types are supported:

  • Auth — Authorizes and reserves funds on the card. The payment is placed in Drafted status and requires a subsequent explicit Capture call to settle.
  • Sale — Authorizes and immediately triggers capture in a single request. No separate Capture call is needed. The Debit transaction is settled asynchronously; poll the Get Card Transaction endpoint to track the final status.
POSThttps://sandbox-api.veem.com/veem/v1.2/card-transactions
📘
Required Headers
NameTypeRequiredDescription
AuthorizationstringYesBearer token (OAuth 2.0). This header holds the bearer token required to use Veem's public API and belongs to the partner account. Example: Bearer c047594b-082c-4da1-be89-08fe3770f4b3
See Get Access Token to generate your bearer token.
X-REQUEST-IDstringYesA unique string identifying the current API request. Must follow UUID format. Reusing the same value without changing it will return the original response for that request (idempotency). Using the same value for a different transaction results in a 409 Conflict. Example: 48855846-628d-4177-b071-80332a116f0a
Content-TypestringYesThe content type of the request. Must be application/json.

Request Payload

When creating a card transaction, follow the format shown in the examples below. To switch between Auth and Sale operations, change the value of paymentDetails.transactionOperation accordingly.

Auth operation

JSON
{
  "cardDetails": {
    "cardNumber": "4111111111111111",
    "expirationMonth": "12",
    "expirationYear": "2030",
    "cvv": "123",
    "firstName": "John",
    "lastName": "Doe",
    "network": "VISA",
    "cryptogram": "AAABCZIhcQAAAABZlyFxAAAAAAA=",
    "billingAddress": {
      "line1": "123 Main St",
      "city": "San Francisco",
      "state": "CA",
      "postalCode": "94105",
      "isoCountryCode": "US"
    }
  },
  "3DS": {
    "eci": "05",
    "version": "2.1.0",
    "ucaf": "AJkBCEVyFgAAAAAKhAAhdQAAAAA=",
    "dsTransactionId": "CE02669B5209391E5F4F7D56E3ACC2AABC4AB9CB71B8F42118D1338378C5A2AF"
  },
  "paymentDetails": {
    "payer": {
      "email": "[email protected]"
    },
    "payee": {
      "accountId": 943013
    },
    "amount": 100.00,
    "currencyCode": "USD",
    "transactionOperation": "Auth",
    "referenceId": "REF-001",
    "purposeOfPayment": "Services"
  }
}

Sale operation — replace "transactionOperation": "Auth" with "transactionOperation": "Sale". All other fields are identical.

JSON
{
  "cardDetails": {
    "cardNumber": "4111111111111111",
    "expirationMonth": "12",
    "expirationYear": "2030",
    "cvv": "123",
    "firstName": "John",
    "lastName": "Doe",
    "network": "VISA",
    "cryptogram": "AAABCZIhcQAAAABZlyFxAAAAAAA=",
    "billingAddress": {
      "line1": "123 Main St",
      "city": "San Francisco",
      "state": "CA",
      "postalCode": "94105",
      "isoCountryCode": "US"
    }
  },
  "3DS": {
    "eci": "05",
    "version": "2.1.0",
    "ucaf": "AJkBCEVyFgAAAAAKhAAhdQAAAAA=",
    "dsTransactionId": "CE02669B5209391E5F4F7D56E3ACC2AABC4AB9CB71B8F42118D1338378C5A2AF"
  },
  "paymentDetails": {
    "payer": {
      "email": "[email protected]"
    },
    "payee": {
      "accountId": 943013
    },
    "amount": 100.00,
    "currencyCode": "USD",
    "transactionOperation": "Sale",
    "referenceId": "REF-002",
    "purposeOfPayment": "Services"
  }
}

Request Parameters

The following table contains detailed information on the payload's parameters.

ParameterMandatory?Format / Values
cardDetailsYesObject. Network-tokenized card credentials and billing address.
cardDetails.cardNumberYesNetwork token (DPAN), 13–19 digits. Must be a token issued by VTS or Mastercard MDES — raw PANs are rejected.
cardDetails.cryptogramYesTAVV / UCAF cryptogram from the tokenization provider. Single-use, generated per transaction.
cardDetails.expirationMonthYesToken expiration month in MM format (e.g., 03, 12).
cardDetails.expirationYearYesToken expiration year in YYYY format (e.g., 2030).
cardDetails.cvvNoCard security code. 3 digits for Visa/Mastercard, 4 digits for Amex. Improves authorization rates when provided.
cardDetails.firstNameNoCardholder first name. Used to create the claimless payer account.
cardDetails.lastNameNoCardholder last name. Used to create the claimless payer account.
cardDetails.networkNoCard network. Accepted values: VISA, MASTERCARD.
cardDetails.billingAddressNoObject. Card billing address. When provided, the fields state, isoCountryCode, and postalCode are all required — omitting any of them returns a 400 error.
cardDetails.billingAddress.line1NoStreet address line 1.
cardDetails.billingAddress.cityNoCity.
cardDetails.billingAddress.stateConditionalState or province (two-letter abbreviation, e.g., CA, NY). Required when billingAddress is provided.
cardDetails.billingAddress.postalCodeConditionalPostal / ZIP code. Format is validated per country. Required when billingAddress is provided.
cardDetails.billingAddress.isoCountryCodeConditionalISO 3166-1 alpha-2 country code (e.g., US). Required when billingAddress is provided.
3DSNoObject. 3-D Secure authentication data from the 3DS provider. Strongly recommended for card-not-present transactions.
3DS.eciNoElectronic Commerce Indicator returned by the 3DS server (e.g., 05 = fully authenticated, 06 = attempted).
3DS.versionNo3DS protocol version used (e.g., 2.1.0, 2.2.0).
3DS.ucafNoUniversal Cardholder Authentication Field (UCAF) value. Base64-encoded string from the 3DS authentication response.
3DS.dsTransactionIdNoUnique transaction ID assigned by the Directory Server during 3DS authentication.
paymentDetailsYesObject. Payment amount, currency, operation type, and participant identifiers.
paymentDetails.payerYesObject. Payer identification.
paymentDetails.payer.emailYesPayer's email address. Used to create or retrieve the claimless payer account within the payee's account context.
paymentDetails.payeeYesObject. Payee identification.
paymentDetails.payee.accountIdYesVeem account ID of the merchant or recipient receiving the funds.
paymentDetails.amountYesTransaction amount. Must be between 0.01 and 999999.99, with at most 2 decimal places.
paymentDetails.currencyCodeYesISO 4217 currency code (e.g., USD).
paymentDetails.transactionOperationYesOperation type. Accepted values:
  • Auth — Authorize only; requires a separate Capture call.
  • Sale — Authorize and capture in one step.
paymentDetails.referenceIdNoPartner-defined external reference identifier, stored for reconciliation purposes.
paymentDetails.purposeOfPaymentNoPurpose of the payment (e.g., Goods, Services).
paymentDetails.softDescriptorNoSoft descriptor to appear on the cardholder's statement.
paymentDetails.sweepToWalletIdNoPartner aggregate wallet ID to which settled funds should be swept after capture.

Response Payload

Once a valid request has been sent, a response payload of this format should be expected. The transactionId returned here is the identifier used in all subsequent calls (Capture, Get, and Cancel).

Note: both Auth and Sale operations return the same response structure. The initial status value is Drafted in both cases — for Sale, the Debit settlement continues asynchronously after the response is returned.

JSON
{
  "status": "Drafted",
  "transactionId": 475173,
  "cardDetails": {
    "last4": "1111",
    "network": "VISA",
    "expirationMonth": "12",
    "expirationYear": "2030"
  },
  "cardTransactionDetails": {
    "processorTransactionId": "ARQsIW0VuSNJh5Ere2EHow",
    "approvalCode": "123536",
    "networkResponseCode": "00",
    "processorStatus": "AUTHORIZED",
    "transactionId": "ARQsIW0VuSNJh5Ere2EHow",
    "status": "Drafted"
  },
  "paymentDetails": {
    "paymentId": 475173,
    "amount": {
      "number": 100.00,
      "currency": "USD"
    },
    "transactionOperation": "Auth",
    "paymentStatus": "Drafted",
    "purposeOfPayment": "Services"
  }
}

The following table provides extra information on the key response parameters:

Response ParameterExplanation
transactionIdVeem's internal payment identifier. Use this value in the path for Capture, Get, and Cancel calls.
statusPayment status. Initial value is Drafted for both Auth and Sale operations.
cardDetails.last4Last four digits of the card number, as echoed by the processor.
cardTransactionDetails.processorTransactionIdProcessor (Tabapay) transaction identifier. Can be used for support inquiries.
cardTransactionDetails.processorStatusProcessor authorization status. Typical value for a successful authorization: AUTHORIZED.
cardTransactionDetails.approvalCodeCard network authorization approval code.
cardTransactionDetails.networkResponseCodeISO 8583 network response code. 00 = approved.
paymentDetails.paymentIdVeem payment ID — same value as the top-level transactionId.
paymentDetails.transactionOperationThe operation type as submitted: Auth or Sale.

Capture Card Transaction

This endpoint is used to settle a previously authorized card transaction. It applies exclusively to the Auth flow: only payments in Drafted status (created with transactionOperation: "Auth") can be captured. For Sale transactions, capture is triggered automatically during creation — calling this endpoint against a Sale payment returns an error.

PATCHhttps://sandbox-api.veem.com/veem/v1.2/card-transactions/{transactionId}
📘
Use the same headers as for the Create Card Transaction endpoint.

Path Parameters

ParameterMandatory?Format / Values
transactionIdYesThe transactionId returned by the Create Card Transaction response (Veem payment ID).

Request Payload

No request body is required for this endpoint.

Response Payload

Once a valid request has been sent, a response payload of this format should be expected:

JSON
{
  "status": "Sent",
  "transactionId": 475173,
  "cardDetails": null,
  "cardTransactionDetails": null,
  "paymentDetails": {
    "paymentId": 475173,
    "amount": {
      "number": 100.00,
      "currency": "USD"
    },
    "transactionOperation": "Capture",
    "paymentStatus": "Sent",
    "purposeOfPayment": null
  }
}

Get Card Transaction

This endpoint is used to retrieve the complete details of a card transaction, including card information, processor response data, Veem payment status, and the full chronological history of transaction events (captures, reversals).

For Sale transactions, use this endpoint to poll for the final settlement status before attempting a reversal.

GEThttps://sandbox-api.veem.com/veem/v1.2/card-transactions/{identifier}
📘
Use the same headers as for the Create Card Transaction endpoint.

Path Parameters

ParameterMandatory?Format / Values
identifierYesThe transactionId returned by the Create Card Transaction response. Must correspond to a card-gateway payment — passing the ID of a non-card payment returns a 400 error.
📘
Polling for Sale transactions

After creating a Sale transaction, the Debit settlement runs asynchronously. Poll this endpoint until paymentDetails.status reaches a terminal state before proceeding with cancellation or any downstream logic.

status: "Complete"→ Debit settled. Safe to issue a reversal (provide amount).
status: "Sent"→ In progress. Continue polling.
status: "Drafted"→ Still processing. Continue polling.
status: "Failed"→ Transaction failed. Do not reverse.
status: "Cancelled"→ Already cancelled.

Suggested polling interval: 5 seconds, with exponential back-off after the first 3 attempts.

Response Payload

Once a valid request has been sent, a response payload of this format should be expected:

JSON
{
  "cardDetails": {
    "firstName": "John",
    "lastName": "Doe",
    "last4": "1111",
    "expirationMonth": null,
    "expirationYear": null,
    "billingAddress": {
      "line1": "123 Main St",
      "line2": null,
      "city": "San Francisco",
      "state": "CA",
      "postalCode": "94105",
      "isoCountryCode": "US"
    },
    "isoCountryCode": "US",
    "network": null
  },
  "cardTransactionDetails": {
    "status": "CAPTURED",
    "amount": "100.00",
    "currencyCode": "USD",
    "transactionId": "idg_MCaFISUsgNl-8_zSVg",
    "SC": 200,
    "EC": "0",
    "network": "Visa",
    "networkRC": "00",
    "networkID": "2026022610055771692",
    "approvalCode": "100557"
  },
  "paymentDetails": {
    "paymentId": 475168,
    "referenceId": null,
    "sweepToWalletId": null,
    "softDescriptor": "Veem Payment",
    "payee": { "accountId": 943013 },
    "payer": { "accountId": 946778, "email": null },
    "status": "Complete"
  },
  "transactionHistory": [
    {
      "type": "CAPTURE",
      "amount": "100.00",
      "currencyCode": "USD",
      "status": "Completed",
      "date": "2026-02-26T02:06:17Z",
      "transactionId": 7460398
    },
    {
      "type": "REVERSAL",
      "amount": "30.00",
      "currencyCode": "USD",
      "status": "Completed",
      "date": "2026-02-26T02:11:38Z",
      "transactionId": 7460406
    }
  ]
}

The following table provides extra information on the key response parameters:

Response ParameterExplanation
cardDetailsCardholder and card information stored at transaction creation time.
cardTransactionDetails.statusProcessor-authoritative status. Key values: AUTHORIZED, CAPTURED, VOID, REVERSED, PARTIALLY_REVERSED.
cardTransactionDetails.SCProcessor HTTP status code.
cardTransactionDetails.ECProcessor error code. "0" = success.
cardTransactionDetails.networkRCISO 8583 network response code from the card network.
cardTransactionDetails.networkIDNetwork transaction identifier assigned by the card network.
paymentDetails.statusVeem payment lifecycle status. Key values: Drafted, Sent, Complete, Cancelled, Failed.
transactionHistoryChronological list of all processor-level events for this payment (CAPTURE, REVERSAL, etc.). Each entry represents one discrete operation. This array is empty for transactions not yet captured.
transactionHistory[].typeEvent type: CAPTURE or REVERSAL.
transactionHistory[].amountAmount for this specific event, as reported by the processor.
transactionHistory[].dateUTC ISO 8601 timestamp of the event.
transactionHistory[].transactionIdInternal Veem transaction record ID for this event.

Cancel Card Transaction

This endpoint is used to cancel a card transaction. The cancellation mode is determined automatically by whether an amount is included in the request body, and depends on whether the underlying Debit transaction has been created and completed.

  • Void — Reverses the authorization before the Debit transaction is created. Applicable to Auth transactions in Drafted status (before Capture) and to Sale transactions whose Debit has not yet been created. No funds are moved. To void, send the request without an amount field.
  • Reversal — Issues a refund after the Debit transaction has completed. Only valid once paymentDetails.status is Complete (verify using Get Card Transaction). Supports full and partial refunds. Generates a reversal on the card processor (Tabapay). To reverse, include amount and currencyCode in the request body. Note: only one active reversal may be in progress for a given transaction at a time.
⚠️
Sale transactions: poll before reversing

For Sale transactions, the Debit is processed asynchronously. Do not attempt a reversal (with amount) until you have confirmed paymentDetails.status == "Complete" via the Get Card Transaction endpoint.

PATCHhttps://sandbox-api.veem.com/veem/v1.2/card-transactions/{transactionId}/cancel
📘
Use the same headers as for the Create Card Transaction endpoint.

Path Parameters

ParameterMandatory?Format / Values
transactionIdYesThe transactionId returned by the Create Card Transaction response.

Request Payload

When sending a cancel request, follow the format shown in the examples below.

Void — Omit amount. The API automatically performs a void when no amount is supplied.

JSON
{}

Full reversal — Include amount equal to the original transaction amount (after Debit completion).

JSON
{
  "amount": 100.00,
  "currencyCode": "USD"
}

Partial reversal — Include amount less than the original transaction amount.

JSON
{
  "amount": 30.00,
  "currencyCode": "USD"
}

Request Parameters

ParameterMandatory?Format / Values
amountConditionalDecimal. The cancellation mode is derived from this field:
  • Omitted — The API performs a void. Reverses the authorization before the Debit is created.
  • Provided — The API performs a reversal. Issues a refund after the Debit has completed. Supports partial amounts (must be ≤ original transaction amount).
currencyCodeConditionalISO 4217 currency code (e.g., USD). Required when amount is provided.

Response Payload

Once a valid request has been sent, a response payload of this format should be expected:

JSON
{
  "cardDetails": {
    "firstName": "John",
    "lastName": "Doe",
    "last4": "1111",
    "expirationMonth": null,
    "expirationYear": null,
    "billingAddress": {
      "line1": "123 Main St",
      "city": "San Francisco",
      "state": "CA",
      "postalCode": "94105",
      "isoCountryCode": "US"
    },
    "isoCountryCode": "US"
  },
  "cardTransactionDetails": {
    "SC": null,
    "EC": null,
    "status": "REVERSAL_INITIATED",
    "reversal": null
  },
  "paymentDetails": {
    "paymentId": 475172,
    "referenceId": null,
    "sweepToWalletId": null,
    "softDescriptor": "Veem Payment",
    "payee": { "accountId": 943013 },
    "payer": {
      "accountId": 946782,
      "email": "[email protected]"
    },
    "status": "Authorized"
  }
}
Response ParameterExplanation
cardTransactionDetails.statusREVERSAL_INITIATED = void or reversal acknowledged by processor. REVERSED = fully reversed. PARTIALLY_REVERSED = partial reversal applied.
cardTransactionDetails.reversalReversal details object, including networkRC (network response code). May be null when the reversal is still being initiated.
paymentDetails.statusUpdated Veem payment status. Typical values: Authorized (void or partial refund acknowledged), Cancelled (fully voided).

Possible Errors

When using the Card Transactions API, one might encounter the following errors depending on the data provided and the state of the transaction.

400Card transaction processing failed

Returned by Create and Capture when the card processor rejects the authorization, the capture fails, or an unexpected internal error occurs during processing. The message field contains the specific reason.

JSON
{
  "code": 50009068,
  "message": "Card transaction processing failed: card declined",
  "logTag": "48855846-628d-4177-b071-80332a116f0a",
  "timestamp": "2026-02-26T12:00:00.000"
}
400Invalid payment status for capture

Returned by Capture when the payment is not in Drafted status. This occurs if the payment has already been captured, voided, or cancelled — or if the transactionId belongs to a Sale transaction.

JSON
{
  "code": 50009069,
  "message": "Payment must be in Drafted status to be captured. Current status: Complete",
  "logTag": "5fff5ff8-d9cb-4443-b0cb-46c511fa6857",
  "timestamp": "2026-02-26T12:35:01.800"
}
400Payer email is required

Returned by Create when paymentDetails.payer.email is missing or blank.

JSON
{
  "code": 50009070,
  "message": "Payer email is required",
  "logTag": "48855846-628d-4177-b071-80332a116f0a",
  "timestamp": "2026-02-26T12:00:00.000"
}
400Payee accountId is required

Returned by Create when paymentDetails.payee.accountId is missing or null.

JSON
{
  "code": 50009071,
  "message": "Payee accountId is required",
  "logTag": "48855846-628d-4177-b071-80332a116f0a",
  "timestamp": "2026-02-26T12:00:00.000"
}
400Incomplete billing address

Returned by Create when cardDetails.billingAddress is provided but one or more of the required sub-fields (state, isoCountryCode, postalCode) is missing or blank.

JSON
{
  "code": 50009073,
  "message": "Billing address must include state (stateProvince), country (isoCountryCode), and postal code (zipCode) when provided. Missing or blank: state",
  "logTag": "48855846-628d-4177-b071-80332a116f0a",
  "timestamp": "2026-02-26T12:00:00.000"
}
400Invalid billing address postal code format

Returned by Create when billingAddress.postalCode does not match the expected format for the given isoCountryCode (e.g., a five-digit ZIP code is required for US).

JSON
{
  "code": 50009074,
  "message": "Billing address postal code (zipCode) format is invalid for country US",
  "logTag": "48855846-628d-4177-b071-80332a116f0a",
  "timestamp": "2026-02-26T12:00:00.000"
}
400Required field is blank or null

Returned by any endpoint when a required field is sent as blank or null.

JSON
{
  "code": 50001002,
  "message": "The field transactionOperation should not be blank or null",
  "logTag": "48855846-628d-4177-b071-80332a116f0a",
  "timestamp": "2026-02-26T12:00:00.000"
}
400Transaction has already been fully reversed

Returned by Cancel when a reversal is requested for a transaction that has already been fully reversed. Partial reversals are allowed as long as the cumulative reversed amount is less than the original transaction amount.

JSON
{
  "code": 40300034,
  "message": "Transaction 98765 has already been fully reversed and cannot be reversed again",
  "logTag": "48855846-628d-4177-b071-80332a116f0a",
  "timestamp": "2026-02-26T12:00:00.000"
}
409Duplicate X-REQUEST-ID

Returned when the same X-REQUEST-ID value is used for a different transaction. To retry the exact same transaction, resubmitting the same X-REQUEST-ID will return the original response without re-processing.

JSON
{
  "code": 50001004,
  "message": "X-REQUEST-ID already has been used: 48855846-628d-4177-b071-80332a116f0a. Use a new one",
  "logTag": "48855846-628d-4177-b071-80332a116f0a",
  "timestamp": "2026-02-26T12:00:00.000"
}
📘
Retries

If you receive a network timeout or do not receive a response, you can safely retry by resubmitting the exact same payload with the same X-REQUEST-ID: if the transaction was already processed, the original response is returned; if it was not, the operation is executed normally. Always persist your X-REQUEST-ID before sending the request.


Veem Developer Documentation — Card Transactions — API v1.2 — For support, contact [email protected]