---
title: "Integrate a global checkout"
seoTitle: "Add a Stripe-style global checkout to your app with BlindPay"
description: "Add a hosted checkout to your existing app: checkout sessions, a payment page for Pix, SPEI, ACH, wire, RTP, Argentine bank transfer, and PSE, USD settlement in stablecoins, and webhooks. Works for one merchant or a platform of many."
date: "2026-10-30"
category: "integrations"
products: ["payins", "quotes", "compliance", "webhooks"]
---

Paste this prompt into your coding agent to add a Stripe Checkout-style flow to the app you already run. You price in USD, the shopper pays from their own bank in their own currency, and the money settles as stablecoins in your wallet.

## Prompt

```text
You are adding a global checkout to my application, in the style of Stripe Checkout, with BlindPay as the money layer: shoppers pay with local bank rails and the merchant is paid in USD stablecoins.

Mode: single merchant. (Change this line to "platform" if my app onboards many merchants, each paid separately, with a platform fee on every payment.)

Before writing code, read these sources and follow them over any prior knowledge:
- https://blindpay.com/docs/llms.txt (read the payins, payin quotes, managed wallets, partner fees, and webhooks pages)
- The OpenAPI spec: curl https://api.blindpay.com/doc

Build the flow:
1. Merchant setup. The merchant is a BlindPay business customer: terms of service acceptance (POST /v1/e/instances/{instance_id}/tos returns a URL; after Accept, the browser comes back to your redirect_url with ?tos_id=to_..., and each tos_id works for one customer only), then POST /v1/instances/{instance_id}/customers with type "business" (KYB), then a managed wallet (POST /v1/instances/{instance_id}/customers/{customer_id}/wallets) that receives every payment. Single merchant: do this once, in a setup script or admin screen, and store the customer and wallet ids in config. Platform: build merchant onboarding (sign-up, terms, KYB form, a verification status screen that waits for kyc_status approved) and store the ids per merchant.
2. Checkout sessions. A server-side model and endpoint that creates a session with a USD amount in cents (at least 1000, the payin quote minimum), optional line items, success_url, cancel_url, metadata, and an expiry, and returns a URL to the hosted payment page. Status: open, processing (payin created), complete, failed, expired. Accept an Idempotency-Key so a retried create returns the same session. Platform mode: per-merchant API keys, stored hashed.
3. Hosted payment page. The shopper picks a country and rail: Brazil (pix), Mexico (spei), Argentina (transfers), Colombia (pse), or the US (ach, wire, rtp). Collect only what the rail needs in payer_rules: a CPF or CNPJ for Pix (pix_allowed_tax_ids, check digits are validated), a CUIT or CUIL for Argentina (transfers_allowed_tax_id), and full payer details for PSE (pse_full_name, pse_document_type, pse_document_number, pse_email, pse_phone, pse_bank_code).
4. Price. Request a payin quote (POST /v1/instances/{instance_id}/payin-quotes) with wallet_id, currency_type "receiver", request_amount set to the session amount, cover_fees true, the payment_method, and the payer_rules. The merchant then receives exactly the price, and sender_amount is the local amount the shopper pays, fees included. Show it with a countdown: quotes expire after 5 minutes (expires_at, epoch milliseconds), so quote when the shopper picks a rail and quote again silently if it expires. Platform mode: pass partner_fee_id (create the pf_ once with POST /v1/instances/{instance_id}/partner-fees) and record partner_fee_amount as platform revenue.
5. Pay. Create the payin (POST /v1/instances/{instance_id}/payins/evm with payin_quote_id; one endpoint for every rail) with an Idempotency-Key tied to the session, so a double click never creates two payins. A payin cannot be canceled, so bind the session to it and lock the rail. Show the instructions for that rail only: pix_code as a QR code and copyable text; clabe for SPEI; tracking_transaction.transfers_instruction.account for Argentina; tracking_transaction.pse_instruction.payment_link for PSE; memo_code plus blindpay_bank_details for ACH, wire, and RTP, with the memo marked as required.
6. Settle. Register a webhook endpoint (POST /v1/instances/{instance_id}/webhook-endpoints) and handle payin.new, payin.update, and payin.complete with signature verification. Find the session by payin id (pi_) and read the payin's status: payin.complete moves it to complete, and a payin.update with status failed or refunded moves it to failed. on_hold means held for review, so the session stays processing. Then redirect the shopper to success_url with the session id, and notify the merchant: platform mode sends signed merchant webhooks (checkout.session.completed, checkout.session.payment_failed, checkout.session.expired) with retries; single-merchant mode fulfills the order in my own code.
7. Expire open sessions past their expiry. A processing session never expires.

Constraints:
- Amounts are integers in minor units. For MXN, ARS, and COP, sender_amount is always a whole currency unit (a multiple of 100). API keys stay server-side; the browser only talks to my backend.
- Session and payment status come only from the payin status, never from wallet balance changes.
- Develop against a development instance with USDB on base_sepolia: KYB approves itself, payins complete by themselves (most rails in under a minute, Pix in about 2), a $666.00 payment ends failed, and a $777.00 payment ends refunded. pix_code and memo_code are the literal "<development>" there, so show a test-mode note instead.
- Wire carries a higher flat fee than ACH, so present it for larger orders.

Deliverables: merchant setup (or onboarding in platform mode), the checkout session API, the hosted payment page, the payin webhook handler with signature verification, and integration tests on the development instance that pay one session per rail and assert the completed, failed ($666.00), and refunded ($777.00) outcomes.
```

## How to use

1. Create a development instance and API key at [app.blindpay.com](https://app.blindpay.com).
2. Set the **Mode** line: keep "single merchant" if you sell your own products, change it to "platform" if you host checkout for other businesses.
3. Tell the agent which countries you sell to so it trims the rail picker.
4. Pay one session per rail on the development instance before going live.

Starting from an empty folder instead? [Build a global checkout](/prompts/build-a-global-checkout) builds and tests the whole platform in one unattended run.

## Related docs

- [Payin quotes](https://blindpay.com/docs/payin-quotes)
- [Payins](https://blindpay.com/docs/payins)
- [Partner fees](https://blindpay.com/docs/learn/partner-fees)
- [Managed wallets](https://blindpay.com/docs/wallets)
- [Payment methods](https://blindpay.com/docs/kb/payment-methods)
