Glossary
Common terms that appear across the CROSS Pay API, SDK, and Webhook documentation. Each entry follows the same shape: a one-line definition, an example, and where you'll encounter it.
Payment lifecycle
PaymentIntent
A server-side object representing the merchant's intent to start a single
payment. Created by POST /v1/payments.
- ID format:
pay_<22-char base62>(e.g.,pay_4xKqRtJp9aB2c7zNm0) - One PaymentIntent maps 1:1 to a single payment attempt
curl -X POST https://api.crosspay.io/v1/payments \
-H "Authorization: Bearer $CROSS_PAY_API_KEY" \
-d '{"currency":"USD","amount":"9.99","payer_uid":"user-123"}'
# → { "id": "pay_abc123", "status": "PENDING", "checkout_url": "..." }
Checkout
A session in which the buyer selects a payment method and interacts with
the PG. Maps 1:1 to a PaymentIntent. ID format: cs_<16-char base62>
(e.g., cs_a1b2c3d4e5f6g7h8).
The checkout_id itself acts as a capability token, so the browser can call
/v1/checkout/{checkout_id} directly — without an API key.
Quote
A fee, tax, and total estimate for a specific payment method. Frozen at SelectQuote time and unchanged until the payment terminates.
{
"fee_rate": "0.029",
"fee_amount": "1450",
"estimated_tax": "5000",
"total_amount": "56450"
}
Session (PG session)
An internal object that ties a merchant's PaymentIntent to a payment record
on an external PG (Worldpay / PayLetter / BinancePay / on-chain). Format:
sess_<base62>.
Merchants don't handle this directly, but for on-chain payments you fetch
contract call parameters via GET /v1/onchain/sessions/{session_id}.
Payment status (PaymentStatus)
For the full state machine and transition rules, see Webhooks Overview — Payment state machine.
PENDING
Immediately after PaymentIntent creation, before quote selection. The merchant cancel API is only allowed at this stage.
PROCESSING
The handover-to-external-PG window that begins right after
POST /checkout/{id}/quotes (SelectQuote) creates a PG session. The server
waits for the PG/chain terminal webhook (PAID / FAILED) or the expiry
worker (EXPIRED).
Merchant branching example:
switch (payment.status) {
case 'PENDING':
return showCheckout(payment.checkout_url)
case 'PROCESSING':
return showWaitingScreen('PG processing — awaiting result') // not confirmed yet
case 'PAID':
return fulfillOrder(payment)
case 'FAILED':
case 'EXPIRED':
case 'CANCELLED':
return showFailureScreen(payment)
}
Terminal states
PAID / FAILED / EXPIRED / CANCELLED / PARTIALLY_REFUNDED / REFUNDED.
These do not transition to other states (refunds are the exception, following
PAID → PARTIALLY_REFUNDED → REFUNDED).
Authentication and security
Merchant API Key
A server-side secret required for /v1/payments/** calls. Passed via the
Authorization: Bearer <key> header. Must not be exposed in the browser.
Production keys use the sk_live_ prefix. A separate sk_test_ prefix
for the public sandbox environment is coming soon.
Idempotency-Key
A client-issued key that ensures the same request is processed only once even if it arrives multiple times. Cached in Redis for 24 hours; subsequent calls with the same key replay the original response.
POST /v1/payments HTTP/1.1
Idempotency-Key: 0190a1b2-c3d4-7e5f-89ab-cdef01234567
Reusing the same key with a different body returns 409 IDEMPOTENCY_CONFLICT.
Callback Secret (webhook secret)
A per-merchant secret used to verify signatures on the merchant's webhook endpoint. Stored encrypted at rest on the CROSS Pay side and issued out-of-band (email or partner channels).
Verification algorithm: HMAC-SHA256 over ${webhook-id}.${webhook-timestamp}.${body}.
See Verifying Webhooks for details.
MAC2 (Worldpay HPP)
The HMAC-SHA256 signature Worldpay Hosted Payment Pages uses to detect tampering of buyer-redirect URLs. Computed over the query strings of successURL / failureURL / cancelURL.
Safeguards
FDS (Fraud Detection Service)
A fraud detection check run just before the /v1/checkout/** response. When
blocking, it returns HTTP 200 with only the
fds: { outcome: "DENY", code, message, ... } envelope.
{
"fds": {
"outcome": "DENY",
"code": "COUNTRY_BLOCKED",
"risk_level": "HIGH",
"risk_score": 92
}
}
Merchant SDKs must branch on fds.outcome, not on the HTTP status.
Stale webhook guard
If the merchant changes the payment method on the same checkout,
payment.provider is updated. If the previous PG sends a delayed callback,
the server detects a mismatch between payment.provider and the webhook's
PG and ignores it with ACK 200 + WARN. The stale terminal event never
reaches the merchant endpoint.
Delivery
event queue
The internal queue where payment domain events accumulate before they are delivered to the merchant. Events are captured in the same transaction as the PG callback, guaranteeing at-least-once delivery.
Standard Webhooks v1
The webhook envelope specification CROSS Pay follows (https://www.standardwebhooks.com).
Three headers (webhook-id, webhook-timestamp, webhook-signature) handle
identification, idempotency, and signature verification together.
at-least-once · dedup key
A webhook can arrive at least once — possibly more. Merchants must use
the webhook-id header value as a dedup key to handle duplicates.
const seen = await redis.set(`webhook:${webhookId}`, '1', 'NX', 'EX', 86400)
if (!seen) return res.status(200).end() // already processed
Currency and amounts
amount (decimal string)
amount is always a string (to avoid JS Number precision loss). Exceeding
the currency's ISO 4217 decimals returns 422 INVALID_AMOUNT.
| Currency | Valid example |
|---|---|
| USD | "9.99" (decimals=2) |
| JPY | "500" (decimals=0) |
| USDT @ BSC | "10.123456789012345678" (decimals=18) |
amount_smallest_unit
An integer string passed directly to the token contract call for on-chain
payments. Equivalent to amount × 10^decimals.
amount: "9.9", USDT @ Ethereum (decimals=6)
→ amount_smallest_unit: "9900000"
On-chain payments
PayGateway
The payment contract CROSS Pay deploys to each chain. The buyer's wallet
calls it directly. Fetch the ABI and address via GET /v1/chains/{slug}.
pay_uuid
The payment identifier corresponding 1:1 to the PayGateway.pay(bytes16 uuid, ...)
signature. Format: 0x + 32 hex characters (16 bytes). The wallet client
passes the getBytes(pay_uuid) result directly into the contract call.
finality
The point at which the blockchain is considered to no longer reorg a
transaction. CROSS Pay waits for finality before emitting the
payment.completed event, so paid_at reflects the finality confirmation
time, not the TX broadcast time.
Suggesting additional terms
If a term is missing from this glossary, please file an issue on GitHub Issues or email dev@to.nexus.