Checkout
How apps start ATM checkout, pass private session context, and reconcile payment state.
Compatible with the closed-beta ATM app APIs and versioned ATM event headers. Check atm-api-version on every webhook or XRPC receiver event.
Hosted checkout
Hosted ATM checkout is the standard ATM checkout path. It lets ATM own the payment form lifecycle, wallet eligibility, processor session, receipts, proof writes, return URLs, and fulfillment events.
Embedded ATM checkout is on the roadmap as an optional iframe or JS wrapper. Hosted checkout remains the fallback for wallet-domain rules, redirect methods, OAuth re-auth, browser quirks, and CSP failures.
Initiation contract
The public attested.network initiate route stays strict. ATM-specific fields are encoded in the opaque product envelope.
POST /xrpc/network.attested.payment.initiate
Authorization: Bearer <app service-auth jwt>
Content-Type: application/json
{
"product": "atm.checkout.v1:<private-envelope>"
}Checkout envelope
The ATM envelope can include public protocol refs and private checkout context. Apps should keep the raw envelope server-side.
- Public refs
- Product, price, entitlement, discount, and discount-code strongRefs.
- Private session fields
- Payer hint, return URL, cancel URL, app order id, selected options, buyer message flags, and buyer assertions.
{
"recipient": "did:plc:creator",
"paymentType": "shop",
"amount": 500,
"currency": "usd",
"listing": {
"$type": "com.atproto.repo.strongRef",
"uri": "at://did:plc:creator/money.atmosphere.product/abc",
"cid": "bafy..."
},
"payerDid": "did:plc:buyer",
"returnUrl": "https://app.example/checkout/return",
"cancelUrl": "https://app.example/product/abc",
"metadata": {
"appOrderId": "ord_123"
}
}Completion
After payment, ATM sends app events and updates status. Apps should use redirects for UI continuity, not fulfillment truth.
- Use
payment.completedfor fulfillment. - Use status polling when the buyer returns before the webhook arrives.
- Use idempotency keys around app order creation and fulfillment.
- Do not assume a browser return means a payment settled.