API Integration
Create and retrieve Checkout sessions from your backend.
Your backend creates a Checkout session for each order and retrieves it to verify the payment.
For Node.js, the @tapayadot/checkout SDK provides typed create() and get() methods for these endpoints. It reads TAPAYA_SECRET_KEY by default. The HTTP examples on this page pass TAPAYA_CHECKOUT_API_KEY explicitly.
Authentication
Every Checkout call is server-to-server and sends a key as a bearer token:
Authorization: Bearer <key>Choose the mode that matches who runs the backend. Keep either key on your server; see Checkout Security.
Merchant mode
One shop. A merchant checkout key selects its merchant, with no extra header.
Platform mode
Many merchants. The organization Secret key, plus a merchant token per request.
Merchant mode
Use this when the backend serves one shop. Create a merchant checkout key in Checkout settings: open the merchant and select Create merchant key. The key starts with tapaya_test_ in sandbox or tapaya_live_ in production and resolves to exactly that merchant.
Authorization: Bearer <merchant-checkout-key>X-Tapaya-Merchant-Token is optional in this mode. If you send it, it must name the same merchant.
The Platform shows the key once and stores only a hash. Create a replacement before revoking the old key to rotate it. Revoking a key does not affect other merchant keys, organization keys, or client secrets already issued to browsers.
Platform mode
Use this when one backend acts for many merchants, such as a marketplace or food delivery platform. Send the organization Secret key from the API Keys page and the merchant's token on every request:
Authorization: Bearer <secret-key>
X-Tapaya-Merchant-Token: <merchant-token>There is no default merchant. A request without the header returns HTTP 401. The merchant must belong to the key's organization. Copy merchant tokens from the merchants table in Checkout settings. The token identifies the merchant; it is not a secret.
The organization Secret key is the same credential called a Server Secret Token in the Platform API docs. Checkout requires the Bearer prefix. Other Platform API endpoints take the token directly. Merchant onboarding and organization management use the Platform API.
Request bodies do not accept a merchantId.
Environments
| Environment | API origin | Hosted Checkout origin | Credentials |
|---|---|---|---|
| Sandbox | https://api.sandbox.tapaya.com | https://checkout.sandbox.tapaya.com | Sandbox keys, with test cards |
| Production | https://api.tapaya.com | https://checkout.tapaya.com | Live keys, with real payment methods |
Set TAPAYA_CHECKOUT_API_URL to the API origin for your environment. Both hosted and embedded payments are available in production. Each merchant must complete onboarding, receive online processor approval, and have a payment gateway configured. Check merchant readiness in Checkout settings. Use the returned hosted session URL unchanged.
Checkout Sessions
Create a Checkout Session
Create a session when the customer clicks Checkout in your shop, then redirect them to the returned url.
Calculate the final total on your server and persist the order with a unique idempotency key first.
Endpoint: POST /merchant/checkout-sessions
curl -X 'POST' "$TAPAYA_CHECKOUT_API_URL/merchant/checkout-sessions" \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $TAPAYA_CHECKOUT_API_KEY" \
-H "X-Tapaya-Merchant-Token: $TAPAYA_MERCHANT_TOKEN" \
-H 'Idempotency-Key: order-1001-checkout-1' \
-d '{
"merchantOrderId": "order-1001",
"amount": 12100,
"currency": "EUR",
"tax": 2100,
"shipping": 605,
"taxRate": 21,
"successUrl": "https://shop.example/checkout/return",
"cancelUrl": "https://shop.example/checkout/cancel"
}'Headers:
| Header | Required | Description |
|---|---|---|
Authorization | ✓ | Bearer <key>: a merchant checkout key or the organization Secret key. |
X-Tapaya-Merchant-Token | Platform mode | Merchant token belonging to the key's organization. Optional with a merchant checkout key. |
Idempotency-Key | ✓ | Nonblank, at most 250 characters. See Idempotency and errors. |
Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
merchantOrderId | string | ✓ | Your order reference, 1 to 200 characters. See One payment per order. |
amount | integer | ✓ | Final charge total in currency minor units, including tax and shipping. 1 to 2,147,483,647. |
currency | string | ✓ | Three-letter ISO 4217 code supported by the backend, in uppercase, such as EUR. |
locale | string | Defaults to en. | |
successUrl | string | Overrides the default success URL for this session. Must match an allowed website of the calling credential. | |
cancelUrl | string | Overrides the default cancel URL for this session. Must match an allowed website of the calling credential. | |
tax | integer | VAT already included in amount, between zero and amount. Defaults to 0. | |
shipping | integer | Shipping already included in amount, between zero and amount. Defaults to 0. | |
taxRate | number | Order-wide VAT percentage, such as 21 or 5.5. Non-negative. | |
taxBreakdown | array | VAT grouped by rate. A nonempty array cannot accompany taxRate. | |
items | array | Display-only order items. Does not determine the charge total. | |
customer | object | Customer email, billing address, and shipping address. |
The session charges in the currency you set. Supported Currencies lists every
currency Tapaya supports, but a merchant is usually enabled for only some of them. Creating a session in a
currency the merchant or backend does not support is rejected, so no hosted page is created.
The API charges amount as supplied. It does not add shipping or tax, calculate VAT from a rate, or calculate a
total from items.
Responses:
| Code | Description |
|---|---|
200 | Session created, or the same session returned with its current status for a repeated key, body, and credential mode |
409 | Conflict: the key was reused with a changed body or credential mode (API-0025), or the order is already paid or has a payment in progress |
Response body:
{
"id": "cs_7Hq2x9LmR4",
"merchantOrderId": "order-1001",
"url": "https://checkout.sandbox.tapaya.com/c/cs_7Hq2x9LmR4",
"status": "open",
"paymentStatus": "unpaid",
"amount": 12100,
"currency": "EUR",
"tax": 2100,
"shipping": 605,
"taxRate": 21,
"taxBreakdown": [],
"items": [],
"expiresAt": "2026-07-15T12:30:00Z",
"createdAt": "2026-07-15T12:00:00Z"
}taxRate is included only when supplied. Store the id with your order, then send the browser to url with
HTTP 303. A session accepts new payments for 30 minutes after creation; a payment already submitted still
completes after that. Return URLs are selected and validated at creation, using either the request values or
the defaults of the calling credential: the organization's return destinations
for the organization Secret key with X-Tapaya-Merchant-Token, the merchant's for a merchant checkout key. The
two are never combined.
Retrieve a Session
When the customer returns to your success or cancel URL, or from a reconciliation job, retrieve the session and compare it with the stored order before fulfilling.
Endpoint: GET /merchant/checkout-sessions/{id}
curl "$TAPAYA_CHECKOUT_API_URL/merchant/checkout-sessions/cs_7Hq2x9LmR4" \
-H "Authorization: Bearer $TAPAYA_CHECKOUT_API_KEY" \
-H "X-Tapaya-Merchant-Token: $TAPAYA_MERCHANT_TOKEN"There is no /status suffix. The response carries the session identity, URL, totals, tax fields, states, and
timestamps, plus nullable paymentReference and completedAt. paymentReference identifies the latest
confirmation attempt and is null before an attempt exists. A non-null reference does not prove success.
Timestamps are ISO 8601 strings.
Session status:
status | Meaning |
|---|---|
open | Session is available for payment, or a submitted payment's outcome is still being confirmed. |
completed | Session has completed. Check paymentStatus for the payment result. |
expired | Session is no longer available for a new payment: it expired, or a newer session for the same order replaced it. |
Payment status:
paymentStatus | Meaning for the order |
|---|---|
unpaid | No confirmed successful payment. The outcome may still be being confirmed. |
successful | Payment succeeded. Reconcile order reference, amount, and currency before fulfillment. |
failed | Payment was declined. The customer can try another card or wallet while the session is open. |
cancelled | Payment was cancelled. |
action_needed | Further action is required. Do not fulfill as paid. |
A declined card leaves status as open and paymentStatus as failed. While Tapaya confirms an uncertain
outcome in the background, the session stays open and unpaid; retrieve it again later. Following the hosted
page's cancel link is navigation to cancelUrl; it does not itself prove a cancelled payment state.
Verify on your server
Fulfill only when the retrieved session matches your stored order's reference, amount, and currency and
paymentStatus is successful. A browser redirect alone never proves payment.
Order and payment ownership
| Your server owns | Tapaya owns |
|---|---|
| The order reference, prices, currency, and fulfillment state | The checkout session and the gateway payment result |
A checkout session ID identifies a hosted checkout. Its merchantOrderId links it to your order, while
paymentReference identifies the latest confirmation attempt. Store the session ID with the order so you can
retrieve the result even if the customer closes the browser.
The hosted page uses separate public endpoints to load and confirm the session. Its session ID is an access credential for those endpoints. A merchant integration verifies payment through the authenticated merchant endpoint.
One payment per order
Hosted and Embedded Checkout share one payment engine. A merchant can
have at most one successful payment per merchantOrderId. Order IDs are scoped to the merchant, so different
merchants, even under one organization, can use the same IDs.
- Creating a session for an unpaid order replaces the previous unpaid session. The old URL reports
expiredand can no longer take payment. - Creating a session for an order that is already paid, or has a payment in progress, returns HTTP 409.
- After a decline, the customer can try another card or wallet on the same session. Submitting the same card token again never charges twice.
- Tapaya sets the 3-D Secure policy and always attempts authentication.
Idempotency and errors
Creation requires a nonblank Idempotency-Key of at most 250 characters. For the same merchant:
| You send | Tapaya returns |
|---|---|
| The same key, body, and credential mode | The same session, with its current status and paymentStatus |
| The same key with a changed body | HTTP 409 with code API-0025 |
| The same key and body with the other credential mode | HTTP 409 with code API-0025, because each mode uses its own redirect settings |
| Invalid totals, an unsupported currency, invalid redirect destinations, missing gateway configuration, or a merchant not added to Checkout | A rejected creation |
A card decline is a payment outcome, not proof that an HTTP request failed.
Unknown outcome
A network error or timeout leaves the payment outcome unknown. There are no Checkout webhooks yet: reconcile by retrieving the session from your server, and retry creation only with the same key and body.