API reference
The Merchant API is used by your server to create and query payment orders. API keys must be stored server-side.
Base URL
https://api.tariapay.com/v1Authentication
Bearer token is recommended:
Authorization: Bearer tpk_...Also accepted for compatibility:
x-api-key: tpk_...If the API key is missing, invalid, or revoked, the API returns 401.
Core endpoints
| Method | Path | Purpose |
|---|---|---|
POST | /payment-intents | Create a new payment order |
GET | /payment-intents | List orders, or look up by orderId |
GET | /payment-intents/:paymentId | Retrieve a single payment order (with transferDepositAddress + transferInstructions once a deposit address exists) |
GET | /payment-intents/:paymentId/transfer-status | Direct-transfer status of your own order: amount received, short/over, wrong chain or token, late funding. ?scanAllChains=true also reads the other enabled chains. See Pay programmatically |
GET | /payment-intents/:paymentId/transfer-deposit | Strictly read-only deposit balances for your own order (never triggers detection) |
POST | /payment-intents/:paymentId/transfer-deposit/settle | Settle a funded deposit now instead of waiting for the sweeps |
POST | /payment-intents/:paymentId/expire | Expire an unpaid order with no deposit received |
GET | /payment-status?orderId= | On-chain payment status of your own order, by your orderId (replaces the public merchant + orderId lookup) |
POST | /payment-intents/:paymentId/refunds | Refund a confirmed payment in full to the original payer wallet |
GET | /refunds | List merchant refunds |
Public checkout endpoints
These endpoints are used by Hosted Checkout, the Checkout Button, and the Checkout Panel; ordinary merchants normally don't call them directly. The Button path only needs your server to return the checkoutUrl; only the Panel path requires passing the paymentId to the frontend.
| Method | Path | Purpose |
|---|---|---|
GET | /checkout/v1/payment-intents/:paymentId | Read public checkout data |
POST | /checkout/v1/payment-intents/:paymentId/attempts | Create the payment configuration after the buyer selects a network and currency |
POST | /checkout/v1/payment-intents/:paymentId/sync | Sync the on-chain receipt after the buyer submits a transaction |
POST | /checkout/v1/payment-intents/:paymentId/transfer-status | Transfer payments: check whether funds have arrived at the order's dedicated deposit address |
The public checkout data carries only what the buyer's page needs — amount, status, networks, displayReference, publicMetadata — not your orderId, return URLs or private metadata. GET /checkout/v1/payment-intents/:paymentId/return?outcome=success|cancel is where the checkout sends the buyer back to you. GET /public/payment-status answers by paymentId or txHash only, is rate limited, and a txHash lookup returns on-chain fields only.
The :paymentId on these public endpoints accepts both the bare UUID and the pi_<uuid> form. The legacy /prepare endpoint is kept for compatibility only — do not use it in new integrations.
Subscription endpoints
For merchants with their own customer system managing subscriptions — see Subscriptions (API).
| Method | Path | Purpose |
|---|---|---|
POST | /subscription-plans | Create a plan (price object) |
GET | /subscription-plans | List plans |
GET | /subscription-plans/:planId | Retrieve a single plan |
PATCH | /subscription-plans/:planId | Update a plan |
POST | /subscriptions | Open a subscription for a customer; returns the subscription, invoice, and payment link |
GET | /subscriptions | List subscriptions, filterable by customerId / planId |
GET | /subscriptions/:id | Retrieve a single subscription |
GET | /subscriptions/:id/invoices | List a subscription's billing-period invoices |
POST | /subscriptions/:id/cancel | Cancel a subscription |
Creating a payment order
curl -X POST "https://api.tariapay.com/v1/payment-intents" \
-H "Authorization: Bearer tpk_..." \
-H "Content-Type: application/json" \
-d '{
"orderId": "order_1001",
"amount": "12.50",
"currency": "USDC",
"successUrl": "https://merchant.example/success",
"cancelUrl": "https://merchant.example/cancel",
"customer": {
"email": "buyer@example.com"
},
"metadata": {
"cartId": "cart_12"
}
}'Request fields
| Field | Required | Description |
|---|---|---|
orderId | Required | Order ID from your business system |
amount | Required | Order amount; a string is recommended |
currency | Required | USDC, USDT, or EURC — the primary coin |
acceptedCurrencies | Optional | USDC / USDT / EURC array for the checkout coin picker. Omit to show only currency. |
customer | Optional | { email?, name? } (legacy customerEmail / customerName also work) |
successUrl | Recommended | URL to return the buyer to your site after payment; redirected server-side once the payment is processing or confirmed, never exposed to the checkout page |
cancelUrl | Recommended | URL to return the buyer to your site after canceling |
displayReference | Optional | Order reference shown to the buyer, up to 64 printable characters. orderId is never shown |
publicMetadata | Optional | Up to 10 buyer-visible key/value pairs (keys [A-Za-z0-9_.-]{1,40}, values up to 200 characters) |
metadata | Optional | Merchant-defined key-value pairs, private to you (webhooks, dashboard, API) |
paymentMethods | Optional | { wallet?, transfer?, transferDefaultOpen? } — controls which payment methods the checkout shows, see Create a payment |
deferTransferDeposit | Optional | REST API boolean, default false. Set true for hosted redirects to prepare the transfer address when checkout loads, instead of waiting during creation. The create response may omit transferDepositAddress. Fixed-customer address ownership checks always run during creation. |
metadata.fixed_transfer_customer_id | Optional | Your customer ID for a verified returning customer — reuses one fixed transfer deposit address across their orders (SDK: the fixedTransferCustomerId field). See Fixed deposit address |
expiresAt | Optional | ISO-8601 timestamp. No cap and no default (omit = never expires on its own); allow an hour or more for programmatic payers |
Optional header: Idempotency-Key (1–255 printable ASCII characters, per merchant). Same key + same body → the original order, HTTP 200, idempotentReplay: true; same key + different body → HTTP 409, code idempotency_key_reused; an unusable key → HTTP 400, code invalid_idempotency_key.
Response structure
{
"paymentIntent": {
"paymentId": "b1985d0b-2026-4f8c-bf75-59ea53fe5466",
"id": "b1985d0b-2026-4f8c-bf75-59ea53fe5466",
"status": "requires_payment",
"orderId": "order_1001",
"amount": "12.50",
"currency": "USDC",
"checkoutUrl": "https://checkout.tariapay.com/pi_b1985d0b-2026-4f8c-bf75-59ea53fe5466",
"successUrl": "https://merchant.example/success",
"cancelUrl": "https://merchant.example/cancel",
"customer": {
"email": "buyer@example.com",
"name": "Alice"
},
"metadata": {
"cartId": "cart_12"
},
"txHash": null,
"paidAt": null,
"expiresAt": null,
"createdAt": "2026-03-30T00:00:00.000Z",
"updatedAt": "2026-03-30T00:00:00.000Z"
}
}Beside paymentIntent, a create response also carries paymentConfig, availableChains, the payment-method flags and, once a direct-transfer deposit address is allocated (the default; not with deferTransferDeposit: true), transferDepositAddress and the structured transferInstructions (address, expiry, per-chain token contracts, decimals and exact minor-unit amounts, and the rules for the payer). The retrieve response carries the same two fields once the address exists.
Payment order IDs and checkout URLs
paymentIdis the bare UUID without a prefix. Use this value when calling the Merchant API (queries, refunds).checkoutUrlis the typed-prefix checkout address, of the formhttps://checkout.tariapay.com/pi_<uuid>(pl_for payment links,su_for subscription plans). Hand it to the buyer exactly as returned — never construct checkout URLs yourself. The path format may change between versions, and thecheckoutUrlreturned by the API is always the authoritative form.- Older checkout links you previously saved or shared (such as
/payment-intents/<uuid>or/paylink/<slug>) remain valid indefinitely — they will not break or redirect.
Issuing a refund
Refunds must be initiated from your server. The current API performs a full refund to the original payer: the chain, currency, amount, and destination wallet all come from the confirmed original payment — the caller cannot override the refund address.
const refund = await tariapay.paymentIntents.refund(
"b1985d0b-2026-4f8c-bf75-59ea53fe5466",
{ reason: "Customer canceled the order" },
);curl -X POST "https://api.tariapay.com/v1/payment-intents/b1985d0b-2026-4f8c-bf75-59ea53fe5466/refunds" \
-H "Authorization: Bearer tpk_..." \
-H "Content-Type: application/json" \
-d '{"reason":"Customer canceled the order"}'A refund first atomically reserves the funds from your available balance for the payment's chain and currency. If the balance is insufficient, the API returns 422; after the on-chain submission it returns processing or completed, and repeated requests never transfer funds twice.
Error structure
{
"error": {
"type": "invalid_request_error",
"code": "order_id_conflict",
"message": "orderId already exists for merchant",
"requestId": "req_123"
}
}Common errors
| Status code | Common causes |
|---|---|
400 | Missing or malformed request fields |
401 | API key missing, invalid, or revoked |
409 | orderId already exists; or code fixed_transfer_active_payment — the customer's fixed transfer address is still held by another open order (resume or cancel that order first) |
403 | Code address_sanctioned — the refund or withdrawal destination is on a sanctions list; do not retry. See Sanctions screening |
422 | Merchant's available balance is insufficient for the refund |
503 | Code screening_stale or screening_unavailable — refunds and withdrawals are paused until sanctions data refreshes; retry later |
500 | Server error — record the requestId and contact support |
Next steps
- Integration steps: Quickstart
- Payment button or Checkout Panel: Checkout Button and Checkout Panel
- Payment results: Receiving payment results