Checkout
/v1/checkout/webhooks/paymentMerchant-facing payment status callback (mirrors the payment.completed/payment.failed webhook catalog entries). `side` is your side — the side whose items your checkout sells; the trader paying there is the other side's, receiving those items. A completed payment clears your side to ship them immediately, independent of the other checkout. If this is the first checkout paid, starts the counterparty hold (trade.counterparty_hold_started) rather than waiting on the other checkout at all. Rejected once the trade session has reached a terminal status (including CLOSED_UNRECIPROCATED) — a closed trade can never be paid into again.
curl -X POST https://api.tbbnetwork.com/v1/checkout/webhooks/payment \
-H "Authorization: Bearer sk_sandbox_..." \
-H "Idempotency-Key: 5f2f...b91" \
-H "Content-Type: application/json" \
-d '{
"tradeSessionId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"side": "A",
"status": "completed",
"merchantCheckoutSessionRef": "merchantCheckoutSessionRef",
"failedReason": "failedReason"
}'Parameters
Request body
| Field | Type | Required |
|---|---|---|
| tradeSessionId | string (uuid) | yes |
| side | A | B | yes |
| status | completed | failed | yes |
| merchantCheckoutSessionRef | string | — |
| failedReason | string | — |
Possible errors
Any other failure (validation, auth, rate limiting, a resource that doesn't exist) returns this same envelope with a non-2xx status — error.code is stable and safe to branch on; error.requestId is worth logging and including in a support request.
{
"error": {
"code": "VALIDATION_ERROR",
"message": "A human-readable description of what went wrong.",
"requestId": "req_01hxyz..."
}
}/v1/checkout/webhooks/fulfillmentMerchant-facing fulfillment status callback, per-side: `started` requires only that this same `side`'s own payment is COMPLETE, regardless of the other side. The whole trade session auto-completes once both sides report `completed` — no separate step needed. Rejected once the session has reached a terminal status.
curl -X POST https://api.tbbnetwork.com/v1/checkout/webhooks/fulfillment \
-H "Authorization: Bearer sk_sandbox_..." \
-H "Idempotency-Key: 5f2f...b91" \
-H "Content-Type: application/json" \
-d '{
"tradeSessionId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"side": "A",
"status": "started"
}'Parameters
Request body
| Field | Type | Required |
|---|---|---|
| tradeSessionId | string (uuid) | yes |
| side | A | B | yes |
| status | started | completed | yes |
Possible errors
Any other failure (validation, auth, rate limiting, a resource that doesn't exist) returns this same envelope with a non-2xx status — error.code is stable and safe to branch on; error.requestId is worth logging and including in a support request.
{
"error": {
"code": "VALIDATION_ERROR",
"message": "A human-readable description of what went wrong.",
"requestId": "req_01hxyz..."
}
}/v1/checkout/paymentsGet both sides' payment records for a trade session
curl -X GET https://api.tbbnetwork.com/v1/checkout/payments \
-H "Authorization: Bearer sk_sandbox_..." \Parameters
| tradeSessionId | query | required |
Response (200)
[
{
"id": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"tradeSessionId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"side": "A",
"status": "PENDING",
"merchantCheckoutSessionRef": null,
"amount": 1,
"breakdown": null,
"currency": "USD",
"completedAt": "2026-07-01T12:00:00Z",
"failedReason": null,
"fulfillmentStartedAt": "2026-07-01T12:00:00Z",
"fulfillmentCompletedAt": "2026-07-01T12:00:00Z",
"settlement": "TBBN_CHECKOUT",
"externalSettlementDueAt": "2026-07-01T12:00:00Z",
"externalSettlementExtendedAt": "2026-07-01T12:00:00Z",
"externalSettlementExtensionReason": null
}
]