Payments
How hosted checkout works, where funds settle, reacting to webhooks, and recovering from errors.
Hosted checkout
Every payment includes a checkout_url at /c/{id}. The page loads the amount, allowed assets, and your branding; the customer connects a wallet (Freighter, xBull, and more), approves, and Payoes verifies the transaction on Horizon.
Integration pattern
- 1
Create the payment server-side
Call POST /api/v1/payments from your backend with the amount, description, and any metadata like a user_id.
- 2
Redirect to the checkout_url
Send the customer to the checkout_url from the response; the hosted page loads the amount, assets, and your branding.
- 3
Let Payoes verify
The customer connects a wallet and approves, and Payoes confirms the transaction on Horizon.
Asset choice at checkout
Configure allowed_assets and the customer picks what to pay with.
Trustline preflight
Checkout catches missing USDC trustlines before the transaction is signed.
Retry confirmation
If Horizon lags, the page can re-confirm with the submitted transaction hash.
Settlement wallet
The Stellar public key that receives payments, configured per environment and proven by connecting the wallet. Payoes snapshots the address into each payment, so changing it later never redirects pending payments.
XLM requirement
The account must exist and hold the minimum balance.
USDC requirement
An active trustline to the Circle USDC issuer for your network.
No custody
Payoes never holds private keys; use a dedicated wallet in production.
Webhooks
Register an HTTPS endpoint and Payoes delivers payment.created, payment.completed, payment.failed, and payment.expired events, each signed with HMAC-SHA256 over the timestamp and raw body using your whsec_ secret.
Signed headers
Payoes-Signature, Payoes-Event, Payoes-Timestamp, and Payoes-Delivery-ID on every delivery.
Automatic retries
Up to 5 attempts with exponential backoff, from 1 minute to 24 hours.
Delivery logs and tests
Inspect attempts, retry manually, and send webhook.test events from the dashboard.
Errors
Payments move through pending, completed, failed, and expired. API errors use conventional status codes (400 invalid request, 401 unauthorized, 404 not found), and the common Stellar failures all have clear fixes.
op_no_trust
Missing USDC trustline; add one to the correct issuer for your network.
op_underfunded
Balance too low for the amount plus fees; fund the wallet.
op_line_full
Destination trustline limit reached; raise the limit on the receiving account.
Verification mismatches
Wrong destination, amount, or asset is rejected; amounts normalize Stellar's 7 decimals.