App Subscriptions
App Billing
App Subscriptions
Create, list, and cancel per-app billing subscriptions for an installed app.
POST
App Subscriptions
App subscriptions are the recurring (or one-time) charges a merchant pays for an installed app. They are distinct from the store-level platform subscription atDocumentation Index
Fetch the complete documentation index at: https://docs.launchmystore.io/llms.txt
Use this file to discover all available pages before exploring further.
/api/v1/billing/* — each one is scoped to an
AppInstallation row that links a single app to a single merchant.
A subscription is always created against an existing installation. If the
app is not installed yet, the API returns 404 — App is not installed.
Auth: merchant JWT (Authorization: Bearer <merchant-jwt>). All endpoints
below are gated by @Auth(MERCHANT) — they cannot be called with an OAuth
app token.
Charge approval flow
- App developer publishes pricing for their app:
POST /apps/billing/pricing/:appIdwith{ monthly, yearly, currency }. This provisions the Stripe Product + Price objects. - Merchant installs the app via the marketplace.
- App (or merchant UI) calls
POST /apps/billing/checkout-sessionto obtain a Stripe Checkout URL. The merchant is redirected, completes payment, and is returned tosuccessUrl. - Stripe fires
checkout.session.completed→POST /apps/billing/webhookverifies the signature and marks the installation assubscribedplus inserts anAppBillingTransactionsrow. - Subsequent renewals fire
invoice.paidwebhooks; one transaction row is created per cycle.
POST /apps/billing/usage — see
Usage Records.
Setup pricing
Application UUID. The app must be owned by the calling developer or admin.
Monthly recurring price in major currency units (e.g.
9.99 for $9.99).Yearly recurring price in major currency units.
ISO-4217 currency code (e.g.
USD, EUR, INR).{ status, type, message, data: { stripeProductId, stripePriceMonthly, stripePriceYearly } }.
Subscribe an installation
POST /apps/billing/subscribe creates a Stripe Subscription wired to the
merchant’s stored payment method. Use this when the merchant has already
saved a card on the platform; for first-time card collection, use
/checkout-session (below).
Application UUID. Must correspond to an existing
AppInstallation row for
the calling store; otherwise 404.Either
monthly or yearly. The Stripe Price for that interval must have
been provisioned via POST /pricing/:appId.Stripe Subscription id.
UUID of the
AppInstallation now linked to this subscription.Stripe status:
active, incomplete, incomplete_expired, past_due, canceled, trialing, unpaid.ISO timestamp of next renewal.
Hosted checkout session (charge approval URL)
POST /apps/billing/checkout-session returns a Stripe Checkout URL. This
is the canonical “charge approval URL” — redirect the merchant to it, they
pay, Stripe redirects them back to successUrl.
UUID of the installed app.
One of
monthly, yearly, one_time. one_time is used for non-recurring app charges.URL Stripe redirects to on payment success. Defaults to the app’s configured success URL.
URL Stripe redirects to if the merchant abandons checkout. Defaults to the app’s configured cancel URL.
Stripe-hosted checkout URL. Open in a new tab or redirect.
cs_… Stripe Checkout Session id.UUID of the linked installation.
Cancel a subscription
POST /apps/billing/cancel cancels the Stripe Subscription tied to an
installation. The installation row remains; only the recurring charge is
stopped. Cancellation takes effect at the end of the current billing
period — the merchant retains access until then.
UUID of the
AppInstallation. Get it from GET /apps/installations or
from the subscribe / checkout-session response.Stripe subscription status after cancellation — typically
canceled (if immediate) or active with cancelAtPeriodEnd: true.true when the merchant keeps access until currentPeriodEnd.ISO end date.
Active subscriptions for a merchant
There is currently no dedicated “list app subscriptions for this merchant” endpoint. Use one of:GET /apps/installations(merchant) → each row carriesbilling: { subscriptionId, status, currentPeriodEnd, planInterval }.GET /apps/billing/transactions(merchant) → groups paid invoices per installation. See Transactions.
A dedicated
GET /apps/billing/subscriptions endpoint that returns just
the active subscription rows for the merchant is planned but not yet
exposed publicly.Webhook
POST /apps/billing/webhook (public, no auth) is the Stripe webhook
endpoint. The handler verifies the Stripe-Signature header against
STRIPE_APP_BILLING_WEBHOOK_SECRET and processes:
| Event | Effect |
|---|---|
checkout.session.completed | Activates the installation, inserts a paid AppBillingTransactions row, fires the app/subscription/created outbound webhook to the app. |
invoice.paid | Inserts a paid transaction row for the renewal cycle. |
invoice.payment_failed | Marks the installation as past_due; fires app/subscription/past_due. |
customer.subscription.deleted | Marks the installation as cancelled; fires app/subscription/cancelled. |
Error codes
| Code | Description |
|---|---|
400 | Missing Stripe-Signature header or unverifiable signature (webhook only). |
400 | planInterval not one of monthly / yearly / one_time. |
401 | Missing or invalid merchant JWT. |
404 | App is not installed — call POST /apps/install/:appId first. |
500 | Stripe API error (logged with the underlying Stripe error code). |