Payment Sessions v2
Create and read the authoritative session contract.
POST /v2/payment-sessions
Require X-Api-Key, Idempotency-Key and JSON. Persist the exact request and key before sending. Retry an uncertain outcome with the same identity and unchanged body; never bypass a conflict with a new key. Do not send projectId, mode, wallet IDs, route choices or return overrides. Scope comes from the key and project settings.
curl https://api.bramapay.com/v2/payment-sessions \
--header "X-Api-Key: YOUR_PROJECT_SECRET_KEY" \
--header "Idempotency-Key: order-demo-1042-v1" \
--header "Content-Type: application/json" \
--data '{"amountUsd":"25.00","currency":"USD","externalId":"order-demo-1042"}'| Field | Contract |
|---|---|
amountUsd | Positive decimal USD string with at most 6 fractional digits, required for default MERCHANT pricing. 25.0000001 is rejected. |
currency | Required literal USD. |
externalId | Required string, 1–200 characters; merchant order identity. |
expiresInSeconds | Optional integer 1–86400; default 1800 seconds. Route selection never extends the fixed deadline. |
displayOrderNumber | Optional plain text, at most 100 Unicode code points. |
description | Optional immutable plain text, at most 1000 Unicode code points; never changes money calculations. |
feePayer, pricingVersion, baseAmountUsd | Explicit buyer pricing: BUYER, BUYER_FEE_V1, positive decimal business amount with at most 6 fractional digits; 25.0000001 is rejected; omit amountUsd. Default fee payer is MERCHANT. |
merchantCustomer | Optional private allowlisted deposit or order object; never checkout/payment evidence. |
merchantCustomer accepts exactly one shape: {customerId, depositId, email?} or {customerId, orderId, orderNumber, email?}. Deposit customerId is 1–100 ASCII letters/digits/underscore/hyphen; order customerId may also be null. depositId/orderId are UUIDs; orderNumber is nonblank, at most 100 code points without control characters. Email is optional/null or a valid address up to 254 characters. Extra properties are rejected. Never send arbitrary metadata or sensitive customer data.
GET /v2/payment-sessions/:id
Use the same project/mode secret key. id is a session UUID. Cross-project/context reads return not found. Both create and read serialize the following fields; optional pricing fields depend on the saved contract. Monetary values are strings.
| Field | Contract |
|---|---|
sessionId, projectId, externalId | Session, project and merchant-order identity. |
mode, paymentMode | TEST or LIVE; both carry the saved mode. |
status | OPEN, PAID, EXPIRED. Closure is exposed separately by closedAt; CONFIRMING/CLOSED are dashboard filters, not this status field. |
amountUsd, currency, pricingVersion, feePayer, pricing | Decimal amount and conditional pricing snapshot; compare under saved pricing contract. |
serverNow, expiresAt, createdAt, paidAt, closedAt | Server time, fixed deadline and lifecycle timestamps; nullable when not reached. |
monitoringComplete, pendingSettlement, isFinal | Independent monitoring/finality indicators; expiry alone is not final unpaid proof. |
settlementState | WAITING_SETTLEMENT, STOPPED_BY_POLICY, COMPLETE, MONITORING. |
ratePolicy, discoveryPolicy, discoveryStopped | Saved policies and discovery state; never a reason to ask for another transfer. |
successUrl, cancelUrl, checkoutUrl | Saved return URLs and secret-bearing checkout capability URL. |
winningAttemptId | Winning child invoice/attempt ID, or null. |
routes | Currently offered {asset, network, networkKey, available} objects; may be empty. |
attempts | Retained immutable instructions and monitoring details; see below. |
receipts | Observed receipt records; a receipt alone does not authorize fulfillment. |
Each attempt contains attemptId, invoiceId, asset, network, networkKey, address, amount, requestedAmount, status, expiresAt, txHash, quote, monitoringState, monitoringComplete. Each receipt contains receiptId, attemptId, invoiceId, paymentId, asset, network, amount, txHash, status, receivedAt. Display the returned exact token amount; never derive it from amountUsd. New hosted attempts accept USDT only; existing USDC attempts remain readable. Empty routes are an unavailable state.
For project buyer pricing, integration amountUsd remains the order basis and baseAmountUsd/payableAmountUsd distinguish the gross amount. Explicit BUYER_FEE_V1 has its own contract. See buyer pricing. Fulfill only after a verified payment_session.paid, authenticated PAID read, saved order/project/mode/currency/pricing match and durable event/order deduplication. A redirect, connection test or child invoice is not independent fulfillment authority.