Quickstart
A minimal server-side integration path for app developers in the ATM beta.
Compatible with the closed-beta ATM app APIs and versioned ATM event headers. Check atm-api-version on every webhook or XRPC receiver event.
1. Register your app
App registration creates a developer-facing ATM role for your DID. You can configure test and live environments separately. Webhook URLs are optional at first: ATM still creates a signing secret and queues events until you add an endpoint.
During closed beta, app registration is gated. Invited apps can register from the ATM dashboard or a direct registration link.
2. Configure your test environment
- Choose the ATM modules your app needs.
- Add a webhook URL or XRPC receiver when you have one.
- Copy the environment-specific signing secret.
- Send a test event from the app dashboard.
- Use the dashboard delivery log to inspect or redrive events.
3. Use the App Node SDK
ATM's closed-beta package is @atmosphere-money/app-node. It is a server package, not a Next.js-specific package. Use it from any trusted backend that can keep app secrets private, mint service-auth JWTs, create checkout envelopes, and verify ATM events.
import { createAtmAppClient } from "@atmosphere-money/app-node";
const client = createAtmAppClient({
getServiceAuthToken: async ({ lxm, aud }) => {
return mintMyAppServiceAuthJwt({ lxm, aud });
},
});
const checkout = await client.initiatePayment({
recipient: "did:plc:creator",
amount: 500,
currency: "usd",
paymentType: "shop",
environment: "test",
returnUrl: "https://app.example/checkout/return",
cancelUrl: "https://app.example/product/abc"
});
return checkout.url;4. Call payout status before checkout
Apps should never send buyers to checkout if the recipient is not ready to receive payments. Call payout status first and show a friendly disabled state when setup is incomplete.
GET /xrpc/money.atmosphere.actor.getPayoutStatus?actor=did:plc:creator
Authorization: Bearer <app service-auth jwt>5. Start checkout
ATM follows the strict attested.network initiate route. The request body contains only the broker-defined product value. For ATM, that value is an atm.checkout.v1: envelope.
{
"product": "atm.checkout.v1:<private-envelope>"
}6. Fulfill from ATM truth
Browser redirects can race with processor and proof writes. Treat webhooks, XRPC receiver events, and status polling as the source of truth for fulfillment.
- Receive
payment.completed. - Verify the event signature or service-auth envelope.
- Deduplicate by delivery id and ATM payment id.
- Fulfill the order in your app.
- Optionally poll status on browser return to update the UI.