CROSS Pay API
Version 0.9.9
CROSS Pay v1 REST API. Merchant servers create a PaymentIntent and drive its lifecycle from a server-to-server context using the merchant API key.
Try it out on this site is proxied through the sandbox (/v1) with the sandbox API key injected server-side. Production keys are never exposed to the browser.
Download the spec
Import the full spec into Postman, an SDK generator, or your IDE. It covers exactly the merchant server endpoints documented on this page:
Authentication
All /payments/** endpoints and GET /catalog require a merchant API key (Authorization: Bearer <API_KEY>). The buyer-facing hosted checkout, on-chain session lookups for wallet clients, the public countries / chains lookups, and provider-side webhooks are consumed by the CROSS Pay hosted checkout, wallet SDKs, and the platform itself — they are not part of this merchant integration reference.
Environment
CROSS Pay currently exposes the Production environment (https://api.crosspay.io): a 53-country catalog, chain slugs ethereum / bsc / cross, crypto currencies USDT / CROSSD, and an API key prefix of sk_live_….
A public Sandbox environment (with self-serve test keys, test cards, and test tokens) is planned for an upcoming release.
See the Supported Countries & Payment Method Catalog for the full per-country mapping.
PaymentStatus overview
| Status | Meaning / entry path |
|---|---|
PENDING | Right after POST /payments. No quote selected yet. |
PROCESSING | After the buyer selects a payment method on the hosted checkout. The external PG-handoff window — waiting for the PG/chain terminating webhook (PAID/FAILED) or the expiry worker (EXPIRED). |
PAID / FAILED | A PG/chain webhook terminates PROCESSING. Terminal. |
EXPIRED | TTL expiry worker. Reachable from both PENDING and PROCESSING. Terminal. |
CANCELLED | Merchant cancel call or a buyer-cancel webhook. Reachable only from PENDING — a PROCESSING cancel is rejected with 409 INVALID_PAYMENT_STATE due to the PG race. Terminal. |
PARTIALLY_REFUNDED / REFUNDED | Refund results. Reached from PAID. Terminal. |
PENDING → PAID/FAILED direct transitions are no longer allowed. Every webhook-driven terminal transition passes through PROCESSING. For the full state machine and webhook mapping, see the Webhooks Overview.
Recent changes
- New PG: MyCard (v0.9.9, additive): the TW/HK/SEA fiat hosted-page PG
MyCardwas added to the PG registry. There is no buyer-facing wire-shape change — only the valuemycardwas added to theproviderenum onPayment, and payments handled by MyCard reportproviderasmycard. The MyCard ops callbacks are outside this merchant reference (webhook group). GET /catalognow requires authentication (v0.9.3, BREAKING): the formerly public (no-auth) catalog now requires a Merchant API Key. Calling it withoutAuthorization: Bearer <API_KEY>returns 401.Cache-Controlalso changed frompublictoprivateso shared caches (CDN/proxy) do not store it.ETag/If-None-Match304 revalidation is unchanged.GET /catalogper-merchant scoping (v0.9.5): the catalog is filtered per authenticated merchant — it exposes only the currencies payable through the merchant's provisioned payment methods (merchant_payment_method) and omits countries with nothing payable. The response wire shape is unchanged; only the returned set narrows. TheETagnow derives from per-merchant freshness.include_pegged_assetsnow defaults totrue(v0.7.55, BREAKING):POST /paymentsflips the opt-in flag introduced in v0.7.51 to opt-out. A fiat-currency payment created without the flag now also exposes stablecoins pegged to that fiat (USDT / USDC / …) as payment options on the hosted checkout. Merchants that must keep stablecoins hidden have to send an explicitinclude_pegged_assets: false. No other wire-shape or DB change. See the field description onCreatePaymentRequestfor before/after behaviour.- Added
GET /catalog(v0.7.55, additive): returns, per supported country, the currencies/assets payable through the calling merchant's provisioned payment methods, with the display decimals of each. Served from a cache withETag/If-None-Matchrevalidation. - Country-level crypto restrictions (v0.7.55): an admin-managed restriction list (types
CRYPTO/ONRAMP) now governs where crypto payment is offered. Checkout quotes hide crypto payment methods when the buyer's IP-resolved country (CloudFront-Viewer-Country — authoritative, not client-supplied) carries aCRYPTOrestriction, andGET /catalogexcludes crypto currencies for those countries. Response field structures are unchanged — only the returned sets narrow. The former on-rampcountry_blacklistconfig (defaultKR) migrated into this list asONRAMProws. - Added
PROCESSINGstatus (v0.7.34, additive):PROCESSINGwas added to thePaymentStatusenum. The PG webhook terminatesPROCESSING → PAID/FAILED. Existing clients keep working, but consumers that branch onstatuswithout a default / unknown path must explicitly handlePROCESSING(showing a "PG processing — awaiting result" state is recommended). - Re-opened
POST /payments/{payment_id}/cancel(v0.7.34): the cancel route removed in v0.7.27 is exposed again to merchants with the same wire format. Cancelling aPROCESSINGpayment returns409 INVALID_PAYMENT_STATE— done to avoid a race against the PG. Cancel only whilePENDING, or wait for a terminal result and use the refund API. POST /payments: the optionalcountryfield is only forwarded to the checkout URL as a?country=XXhint and is not persisted to the database.
Authentication
MerchantApiKey — http (bearer)
Merchant API Key
Contact
Cross Pay Team