Tringify sends a signed request to the charge endpoint selected for the payment session. The declaration revision, protocol version, and test or live mode must still match the connected account before initiation. If the connection changes, select it again for a new attempt. Create or retrieve the corresponding provider payment using session_id as the idempotency key and return one browser handoff.
Verify and deduplicate the request#
Verify the signature against the raw body before parsing. Treat session_id as the idempotency key. A repeated request with identical immutable fields returns the original provider session; reuse with a different store, order, amount, currency, or return URL is rejected.
{
"session_id": "session_…",
"protocol_version": "1",
"declaration_revision_id": "revision_…",
"store_id": "store_…",
"market_id": "market_…",
"store_name": "Acme Goods",
"order_id": "order_…",
"order_number": "1042",
"amount": "1499.00",
"currency_code": "USD",
"test": false,
"customer_email": "buyer@example.com",
"return_url": "https://shop.example/checkout/return",
"cancel_url": "https://shop.example/checkout/payment",
"expires_at": "2026-07-13T12:30:00Z"
}
Return the handoff#
Return launch_url for a provider-hosted HTTPS checkout. The response field browser_action also exists. The two forms are mutually exclusive, but browser_action is not available to third-party apps: it selects a browser adapter built into Tringify checkout, the set of adapters is fixed by Tringify, and an app cannot register a new one. Third-party payment apps return launch_url.
For completeness, Tringify checks every browser_action before checkout opens it: handler must name a built-in adapter, complete_url must be 1 to 2048 bytes with no control characters, payload must be a JSON object of at most 16384 bytes, and the amount and currency inside payload must equal the session's. A successful response with both handoffs, neither, or a browser_action that fails these checks fails the session.
{
"success": true,
"launch_url": "https://checkout.provider.example/session/provider_session_…",
"provider_session_id": "provider_session_…"
}
The handoff response does not settle the session. Verify the authoritative result with the provider, then resolve the session through the Store API. Browser navigation is not payment evidence.
Time limits and lost responses#
Tringify sends the charge request once and allows 30 seconds for it, from connecting to reading your full response. Answer with a 2xx status. Redirects are refused, and a status of 400 or above counts as no answer; Tringify reads the body of any other status as your response. Tringify itself waits up to 40 seconds for the outcome, longer than the request, so a response that arrives within 30 seconds is never discarded. Give your own calls to the payment provider a shorter deadline so that you always answer in time.
If Tringify does not get a valid response, because of a timeout, a transport failure, a refused redirect, a status of 400 or above, an unreadable body, an invalid handoff, or a response that rejects the request, it marks the session failed with a failure code naming the cause and releases the checkout's stock hold. This applies only while the session is still waiting for your response. If you have already resolved the session through the Store API, for example as pending while the provider confirms the payment, a lost response does not fail it: the session keeps the state you reported and checkout keeps its stock hold, so resolve it as paid or failed when the provider reaches a final result. Once a session has failed, the shopper can start a replacement attempt. It arrives as a new charge request with a new session_id; create a new provider payment for it. The provider payment for the first session may still be completed: keep reconciling it and resolve that first session_id as paid. Tringify accepts the late capture on the failed session. If the order is meanwhile paid by the replacement, or cancelled, Tringify records the extra capture and refunds it through your refund endpoint.