Create the consumer handoff
Create, observe and safely replace a private-beta Paybytoken Pay session.
Create the PaymentIntent and ConsumerPaymentSession from your server. Both requests require a
merchant secret key and a retry-stable Idempotency-Key.
curl https://api-prod.paybytoken.io/api/v1/payment_intents \
-X POST \
-H "Authorization: Bearer $PAYBYTOKEN_SECRET_KEY" \
-H "Idempotency-Key: order-8342" \
-H "Content-Type: application/json" \
-d '{
"amount": "10.15",
"currency": "USDC",
"chain": "base",
"customer": "cus_example",
"payment_method_types": ["paybytoken_pay"]
}'The PaymentIntent returns requires_action. The merchant cannot confirm it. Create the handoff:
curl https://api-prod.paybytoken.io/api/v1/consumer_payment_sessions \
-X POST \
-H "Authorization: Bearer $PAYBYTOKEN_SECRET_KEY" \
-H "Idempotency-Key: handoff-order-8342" \
-H "Content-Type: application/json" \
-d '{
"payment_intent": "pay_example",
"return_url": "https://merchant.example/orders/8342/return",
"locale": "en"
}'Redirect the browser to the returned hosted_url. It contains a short-lived fragment capability;
do not log, persist, proxy or append it to another URL. The Paybytoken-hosted page removes the
fragment before making API requests.
Observe the result
Retrieve the PaymentIntent from your server. Its consumer_payment_handoff is a privacy-reduced
projection with lifecycle state, expiry, cancel/replace eligibility and a stable failure category.
Use the PaymentIntent ID when contacting support. Never ask the customer to send a token or hosted
URL.
If a pending handoff expires or becomes unusable, create a replacement with a new idempotency key. Core cancels the older pending session and keeps the PaymentIntent. An owner/admin Portal user or a merchant secret key may cancel a pending handoff; read-only team members cannot.
Possible retry guidance includes:
| Category | Meaning | Normal response |
|---|---|---|
funding | Finalized consumer funds are insufficient | Customer adds finalized funds and retries |
velocity_limit | A configured payment limit rejected the attempt | Wait or request an approved review |
availability | Platform, merchant, consumer or asset is not enabled | Do not retry automatically; contact the indicated owner |
unknown | The failure is not safe to classify publicly | Contact support with the PaymentIntent ID |
The browser return is not proof of payment. Verify a signed webhook and fetch the canonical PaymentIntent before fulfillment.
Did this page answer your question?
Your feedback helps us improve the integration path.