Skip to content
Indiana
Dashboard
Docs
Browse docs / Payments, subscriptions and billing

Payments, subscriptions and billing

Quote and confirm purchases, Paywalls, subscription changes, trials, refunds, invoices and native purchases.

API v1Updated

Start a purchase

  • Call previewAttach to get a quote and an operationId; nothing is charged yet.
  • Call attach to confirm; when it returns a checkoutUrl, redirect to the Stripe payment page.
  • When the user returns, call readSubscriptionOperation; complete means paid and active.
purchase.tsTypeScript
import { createIndiana } from "@tinkerlandai/indiana-sdk"; const indiana = createIndiana({  baseUrl: "https://api.tinker.cash",  scope: { projectId: "<APP_UUID>", environment: "sandbox" },}); export async function buy(customerToken: string, requestId: string) {  indiana.identify(customerToken);  const { quote } = await indiana.previewAttach({    requestId, // persisted before the first attempt    plans: [{ productVersionId: "<PRODUCT_VERSION_UUID>" }],    provider: "stripe",    currency: "USD",  });  const { operation } = await indiana.attach({ operationId: quote.operationId });  if (operation.checkoutUrl) window.location.assign(operation.checkoutUrl);  return operation.operationId;} export async function afterReturn(operationId: string) {  const { operation } = await indiana.readSubscriptionOperation({ operationId });  return operation.status; // "pending" | "complete" | "cancelled" | "failed"}
  • First connect Stripe for the App and environment under Payment connections in Console; Sandbox uses Stripe test mode.
  • A browser buys only for the current user; a backend using a Server Key passes customerId.
  • Save the requestId and reuse it on retries; never infer payment from the redirect.

Show a Paywall

After publishing a Paywall in Console, show it by ID. When the user buys, the SDK completes the quote and confirmation.

paywall.tsTypeScript
import { createPaywallSession, showPaywall } from "@tinkerlandai/indiana-sdk"; const options = {  baseUrl: "https://api.tinker.cash",  scope: { projectId: "<APP_UUID>", environment: "sandbox" as const },}; export function openPaywall(container: HTMLElement, customerToken: string) {  return showPaywall(container, {    start: () =>      createPaywallSession(options, {        paywallId: "<PAYWALL_UUID>",        customerToken,        commerce: { provider: "stripe", currency: "USD" },        locale: "en",      }),    onCheckoutUrl: (url) => window.location.assign(url),    onAccessGranted: (check) => console.log("access", check.allowed),  });}

Change subscriptions, trials and refunds

app/change-plan.tsTypeScript
import { createIndiana } from "@tinkerlandai/indiana-sdk"; const indiana = createIndiana({  baseUrl: "https://api.tinker.cash",  scope: { projectId: "<APP_UUID>", environment: "sandbox" },}); export async function changePlan(customerToken: string, requestId: string, productVersionId: string) {  indiana.identify(customerToken);  const { holdings } = await indiana.readHoldings();  const membership = holdings.memberships[0];  if (!membership) throw new Error("No membership to change");   // 1. Quote the change; nothing is charged yet.  const { quote } = await indiana.previewUpdate({    requestId, // persisted before the first attempt    membershipId: membership.id,    timing: "immediate",    change: { type: "plan", productVersionId },  });   // 2. After the user accepts the quote, confirm it.  const { operation } = await indiana.update({ operationId: quote.operationId });  return operation;}
Common tasks
TaskMethodsNotes
Upgrade, downgrade or cancelpreviewUpdate → update → readSubscriptionUpdatetiming applies the change immediately, at renewal or in the store.
Save a payment methodsetupPayment → readPaymentSetupNo charge.
Start, extend or end a trialmanageSubscriptionTrial, readSubscriptionTrialBackend only.
RefundpreviewRefund → refund → readRefundFull or partial; optionally revokes access.
List subscriptions and purchaseslistSubscriptions, listPurchases, verifySubscriptionsBackend only.
Resolve subscription conflictslistSubscriptionConflicts, retrySubscriptionConflictBackend only.

Common tasks

  • Upgrade, downgrade or cancel

    Methods
    previewUpdate → update → readSubscriptionUpdate
    Notes
    timing applies the change immediately, at renewal or in the store.
  • Save a payment method

    Methods
    setupPayment → readPaymentSetup
    Notes
    No charge.
  • Start, extend or end a trial

    Methods
    manageSubscriptionTrial, readSubscriptionTrial
    Notes
    Backend only.
  • Refund

    Methods
    previewRefund → refund → readRefund
    Notes
    Full or partial; optionally revokes access.
  • List subscriptions and purchases

    Methods
    listSubscriptions, listPurchases, verifySubscriptions
    Notes
    Backend only.
  • Resolve subscription conflicts

    Methods
    listSubscriptionConflicts, retrySubscriptionConflict
    Notes
    Backend only.

Turn on auto top-up

When the balance falls below threshold, Indiana buys more with the user's saved payment method. Show prepared.terms to the user and confirm only after they accept.

auto-topup.tsTypeScript
import { createIndiana } from "@tinkerlandai/indiana-sdk"; const indiana = createIndiana({  baseUrl: "https://api.tinker.cash",  scope: { projectId: "<APP_UUID>", environment: "sandbox" },}); type UUID = ReturnType<typeof crypto.randomUUID>; export async function prepareAutoTopup(customerToken: string, requestId: UUID) {  indiana.identify(customerToken);  const { prepared } = await indiana.prepareBillingAuthorization({    requestId,    kind: "auto_topup",    productVersionId: "<CREDIT_PACK_VERSION_UUID>",    internal_feature_id: "<CREDIT_FEATURE_UUID>",    currency: "USD",    threshold: "100",    quantity: "1",  });  return prepared; // show prepared.terms to the Customer} // Call only after the Customer explicitly accepts the displayed terms.export async function acceptAutoTopup(authorizationId: string) {  return indiana.confirmBillingAuthorization({ authorizationId, accepted: true });}

Invoices and usage limits

Common tasks
TaskMethodsCaller
Create and manage invoicespreviewInvoice, createInvoice, manageInvoice, readInvoiceOperationBackend
Read invoiceslistInvoiceTemplates, listInvoices, getInvoiceBackend
Set usage limits and alertsmanageBillingLimitsBackend
Let users view their invoiceslistBillingInvoices, readBillingInvoice, readBillingControlsBrowser
Let users apply offers to a membershipsetBillingCouponsBrowser

Common tasks

  • Create and manage invoices

    Methods
    previewInvoice, createInvoice, manageInvoice, readInvoiceOperation
    Caller
    Backend
  • Read invoices

    Methods
    listInvoiceTemplates, listInvoices, getInvoice
    Caller
    Backend
  • Set usage limits and alerts

    Methods
    manageBillingLimits
    Caller
    Backend
  • Let users view their invoices

    Methods
    listBillingInvoices, readBillingInvoice, readBillingControls
    Caller
    Browser
  • Let users apply offers to a membership

    Methods
    setBillingCoupons
    Caller
    Browser

Native app purchases

  • Call previewAttach with provider set to apple or google to get a purchase intent.
  • Complete the App Store or Google Play payment in the app.
  • Send the Apple signedTransaction or Google purchaseToken to restoreNativePurchase; access is granted after verification.
  • To restore purchases, call its read branch.

Related: iOS and Android

Related operations

Subscriptions and payments (19)
setupPayment, readPaymentSetup, verifySubscriptions, previewAttach, attach, readSubscriptionOperation, previewUpdate, update, readSubscriptionUpdate, listSubscriptions, listPurchases, listSubscriptionConflicts, retrySubscriptionConflict, manageSubscriptionTrial, readSubscriptionTrial, previewSubscriptionBatch, confirmSubscriptionBatch, readSubscriptionBatch, abandonSubscriptionBatch
Invoices, refunds and billing (19)
listInvoiceTemplates, previewInvoice, createInvoice, manageInvoice, readInvoiceOperation, listInvoices, getInvoice, previewRefund, refund, readRefund, readBillingControls, prepareBillingAuthorization, confirmBillingAuthorization, setBillingCoupons, revokeBillingAuthorization, listBillingInvoices, manageBillingLimits, readBillingInvoice, confirmBillingAdjustment
Native purchases (1)
restoreNativePurchase

Related: Paths, credentials and scopes in All operations