The Billing API lets your app charge merchants through PlatformDTC. Every charge follows the same flow: your app creates it, the merchant approves it on a PlatformDTC page, and only then is anything billed. Approved charges appear on the merchant’s PlatformDTC bill, on the card they already pay their plan with. You never handle card details. Base URL: https://api.platformdtc.com/api/v1/app_billing

Authentication

Call the Billing API with your install’s offline access token (the sq_agt_* token from the OAuth exchange), as Authorization: Bearer sq_agt_…. Only an installed app’s token can bill; any other key gets 403 APP_TOKEN_REQUIRED. The install must be active: an uninstalled install, or an app suspended by trust & safety, gets 403 APP_INSTALL_INACTIVE. All amounts are integer cents in USD.

Charge lifecycle

Subscribe to the app_subscriptions/update webhook topic (declare it in your version’s webhook_topics) to be told about every status change. The payload is:

Recurring subscriptions

Redirect the merchant to confirmation_url. After they approve or decline, they come back to your return_url with ?charge_id=<subscription id> — fetch the subscription to see the outcome.
  • interval: every_30_days (default) or annual.
  • plan_handle: instead of explicit fields, bill one of your app’s published pricing plans. Any field you also send overrides the plan’s.
  • trial_days: the merchant is not charged until the trial ends (0–365).
  • One active subscription per install. Creating a new one while another is active is how you change plans: when the merchant approves, the new subscription replaces the old one immediately and the merchant is credited for unused time on the old plan (Stripe proration). A replacement does not start a new trial.
GET /subscriptions lists the install’s subscriptions, GET /subscriptions/{id} returns one, and POST /subscriptions/{id}/cancel ends it ({"prorate": true} credits the merchant for the unused part of the period; the credit comes out of your earnings).

Usage charges

Add capped_amount_cents and usage_terms to a subscription to bill usage on top of (or instead of) a recurring price. The merchant approves the cap and the terms up front.
Then record usage as it happens:
  • The cap applies to each 30-day billing cycle; balance_used_cents resets when a new cycle starts.
  • A record that would take the cycle past the cap is refused with 422 CAPPED_AMOUNT_EXCEEDED. Nothing is billed.
  • idempotency_key (required, ≤255 chars) makes retries safe: the same key returns the original record (200) and never bills twice.
  • Usage is billed with the subscription’s next invoice. Usage can only be recorded on an active subscription. Usage-based pricing requires the every_30_days interval.
GET /subscriptions/{id}/usage_records lists them.

One-time charges

Same approval flow. The merchant’s card is charged when they approve. GET /one_time_charges and GET /one_time_charges/{id} read them back.

Test charges

Send "test": true to create a charge that runs the whole flow (approval page, statuses, webhooks, usage caps) but is never billed and earns nothing. Every charge on a development store is a test charge, whatever you send.

Errors

Revenue share and payouts

  • PlatformDTC takes 0% of your app revenue. No revenue share, no threshold, and payment processing fees aren’t taken out of your earnings. You keep everything merchants pay for your app.
  • Earnings are what merchants actually paid for your app (after discounts, before tax). Refunds and lost chargebacks are deducted.
  • Payouts run on the 1st and 16th of every month (UTC) and cover earnings recorded before that date. The minimum payout is $25; a smaller balance carries over to the next run.
  • Payouts go to your Stripe account. Set it up at Partner Dashboard → Payouts → Set up payouts (Stripe-hosted onboarding). Until it’s connected, payouts are created but held, and they’re sent automatically once your account can receive transfers.
  • The Partner Dashboard shows your balance, every ledger entry (earning, refund, payout), payouts per app on each app’s Earnings tab, and your full payout history.

Refunds

You can refund a merchant’s payment for your app, in full or in part, from the app’s Earnings tab (Payments → Refund). Partner owners and admins can refund.
  • The money goes back to the merchant’s card. Any tax the merchant paid on that amount is refunded with it.
  • The refund is deducted from your earnings right away. If the payment was already paid out to you, the refund comes out of your next payout.
  • A payment is one paid bill: a subscription period together with its usage charges, or one one-time charge. You can refund a payment more than once, up to what is left of it.
The same thing through the API (partner user token):
reason is requested_by_customer, duplicate or fraudulent. idempotency_key (8–64 characters) is yours: send the same key again after a timeout and you get the same refund, never a second one. A refund above refundable_cents is refused with 422 VALIDATION_FAILED.

When charges end

  • Uninstall: the merchant uninstalling your app cancels its subscription. Usage already recorded is still billed. No proration credit is issued.
  • Failed payment: the subscription becomes frozen while the card is retried, and active again when a retry succeeds.
  • Suspension: if trust & safety suspends your app, its subscriptions are frozen and nothing is collected while suspended. After reinstatement, billing resumes for each merchant once they re-authorize your app.