Payment intents
A payment intent represents a single crypto payment you want to collect. You specify the amount in USD, the network, and the token. BchainPay assigns a fresh blockchain address, converts the USD amount to crypto at current market rates, and monitors the chain until the payment settles or the intent expires.
Payment flow
- Create —
POST /v1/payment-intentswithamount_cents,network, andtoken. The intent is created and immediately shows asrequires_actionin the API. - Generate address —
POST /v1/payment-intents/:id/generate-address. BchainPay assigns a blockchain address and calculates the crypto amount from USD at current market rates. - Confirm —
POST /v1/payment-intents/:id/confirm. Transitions the intent toprocessing. - On-chain settlement — BchainPay detects the transaction on-chain and transitions the intent to
completed. Apayment_intent.completedwebhook fires.
If expires_at passes without payment the intent moves to expired. Cancellation is not currently available via the API — uncollected intents expire automatically.
State machine
Valid transitions:
| From | To |
|---|---|
created | requires_action, cancelled, expired |
requires_action | processing, cancelled, expired |
processing | completed, failed, expired |
completed | — (terminal) |
failed | — (terminal) |
cancelled | — (terminal) |
expired | — (terminal) |
API statuses
The API exposes these statuses:
| Status | Description |
|---|---|
requires_action | Intent created, waiting for address generation or confirmation. |
processing | Payment detected, awaiting on-chain settlement. |
completed | Payment settled. Terminal. |
failed | Payment failed (e.g. insufficient funds received before expiry). Terminal. |
cancelled | Cancelled by the system. Terminal. |
expired | Expired before full payment received. Terminal. |
Crypto amount calculation
When you call generate-address, BchainPay converts your amount_cents (USD) into the equivalent crypto amount at current market rates. The converted amount is locked at that moment — subsequent price changes do not affect the expected payment.
The intent tracks two fields as payment arrives:
received_amount_cents— the USD-equivalent value of crypto received so far.remaining_amount_cents— how much is still outstanding.
One intent per order
- Every checkout, invoice, or recurring charge gets its own payment intent.
- Every intent gets a unique blockchain address. Never reuse addresses across orders — this is how BchainPay attributes payments unambiguously.
Expiration
Every intent has an expires_at timestamp. If the full amount has not been received by that time, the intent transitions to expired. Expiration is enforced regardless of the current state (created, requires_action, or processing).