Docs

Build your first app

A complete ATM integration walkthrough from app registration to fulfillment.

Closed beta@atmosphere-money/app-nodeSDK beta: 0.0.0-beta.3ATM API beta: 2026-0672 lexicons

Compatible with the closed-beta ATM app APIs and versioned ATM event headers. Check atm-api-version on every webhook or XRPC receiver event.

Before you start

ATM integrations should be server-led. Your client can show product pages, ticket pickers, and support buttons, but your server should create checkout envelopes, mint service-auth, verify events, and fulfill app orders.

You need

An app DID, an ATM app role, and a server that can call ATM XRPC methods.

Keep private

Webhook secrets, checkout envelopes, app order ids, customer details, and service-auth signing material.

Use test first

Configure the app test environment before requesting live payment access.

Fulfill later

Use ATM events or status, not browser redirects, as payment truth.

1. Create the app profile

Sign into ATM with the DID that represents your app, then register it as an app during the beta. The app still has a normal ATM profile for name, icon, and description; app-specific settings live in the app dashboard.

  1. 01

    Sign in

    Use the app account DID.

  2. 02

    Register app

    ATM adds the app role without deleting payer or creator roles.

  3. 03

    Choose payment setup

    Pick app-fee payouts only, direct payments, or both.

  4. 04

    Choose modules

    Enable payments, products, subscriptions, tickets, or future modules in test mode.

  5. 05

    Copy secrets

    Store test webhook secrets and service-auth config server-side.

2. Configure test mode

Test and live environments are separate. Start with test webhooks, test modules, and test fees. ATM queues events even before a webhook URL exists, so you can register early and add infrastructure later.

Webhook URLWhere ATM sends signed HTTP events for this environment.
XRPC receiverOptional AT Protocol-native event receiver for apps that already host XRPC.
ModulesThe app features enabled in this environment.
Fee shareThe app fee and optional ATM support share for app-originated checkouts.

3. Check recipient payability

Before showing a live payment button, ask ATM whether the recipient can receive payments. This avoids sending buyers into a checkout that cannot complete.

http
GET /xrpc/money.atmosphere.actor.getPayoutStatus?actor=did:plc:creator
Authorization: Bearer <app service-auth jwt>

4. Request creator approval

If the checkout is for a creator or organizer, ask them to approve this app before creating checkout. ATM checks the approved payment types, app fee cap, environment, and public-record policy at checkout time.

ts
const approval = await atm.requestRecipientApproval({
  recipientDid: "did:plc:creator",
  environment: "test",
  paymentTypes: ["shop"],
  feeShareBps: 300,
  requestReason: "Enable Example App checkout"
});

if (approval.status !== "approved") {
  return Response.redirect(approval.dashboardUrl);
}

5. Create checkout

Create the app order first, then create the ATM checkout envelope. The envelope can include an app order id and safe public strongRefs, but customer details and fulfillment fields stay private.

ts
const checkout = await atm.initiatePayment({
  environment: "test",
  recipient: "did:plc:creator",
  paymentType: "shop",
  amount: 2500,
  currency: "usd",
  listing: productStrongRef,
  metadata: { appOrderId: order.id },
  returnUrl: "https://app.example/orders/" + order.id,
  cancelUrl: "https://app.example/products/" + product.slug
});

return Response.redirect(checkout.url);

6. Handle return

The buyer may return before processor webhooks and app events finish moving. Show a processing state, poll ATM status, and update the app order when ATM confirms payment.

http
GET /xrpc/network.attested.payment.status?token=atm_checkout_...
Authorization: Bearer <app service-auth jwt>

7. Fulfill from events

Fulfillment should be event-driven. Verify signatures, deduplicate delivery ids, and make the final app-side mutation idempotent.

  1. 01

    payment.completed

    ATM has confirmed payment settlement.

  2. 02

    Verify

    Check webhook signature or XRPC service-auth.

  3. 03

    Deduplicate

    Store delivery id and payment id before side effects.

  4. 04

    Fulfill

    Mark the order paid, issue content, or notify the buyer.

8. Move to live

Live mode should use live webhook secrets, live payment rails, and a live app review. Keep test traffic isolated so beta and regression checks never mix into production reporting.

  • Test guest and signed-in buyer checkout.
  • Verify webhook signature handling with the raw body.
  • Redrive a failed delivery from the app dashboard.
  • Confirm refund and cancellation behavior.
  • Confirm support contact and privacy/terms links.
  • Switch app modules and webhooks to live intentionally.
Build your first app - Atmosphere Money Docs