Start Capabilities Payments, subscriptions and billing Quote and confirm purchases, Paywalls, subscription changes, trials, refunds, invoices and native purchases.
API v1 Updated Oct 22, 2026
On this page
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.ts TypeScript Copy 1 import { createIndiana } from "@tinkerlandai/indiana-sdk" ;2 3 const indiana = createIndiana ({4 baseUrl: "https://api.tinker.cash" , 5 scope: { projectId: "<APP_UUID>" , environment: "sandbox" }, 6 }); 7 8 export async function buy (customerToken: string, requestId: string) {9 indiana.identify (customerToken); 10 const { quote } = await indiana.previewAttach ({ 11 requestId, // persisted before the first attempt 12 plans: [{ productVersionId: "<PRODUCT_VERSION_UUID>" }], 13 provider: "stripe" , 14 currency: "USD" , 15 }); 16 const { operation } = await indiana.attach ({ operationId: quote.operationId }); 17 if (operation.checkoutUrl) window.location.assign (operation.checkoutUrl); 18 return operation.operationId; 19 } 20 21 export async function afterReturn (operationId: string) {22 const { operation } = await indiana.readSubscriptionOperation ({ operationId }); 23 return operation.status; // "pending" | "complete" | "cancelled" | "failed" 24 } 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.
1 import { createPaywallSession, showPaywall } from "@tinkerlandai/indiana-sdk" ;2 3 const options = {4 baseUrl: "https://api.tinker.cash" , 5 scope: { projectId: "<APP_UUID>" , environment: "sandbox" as const }, 6 }; 7 8 export function openPaywall (container: HTMLElement , customerToken: string) {9 return showPaywall (container, { 10 start: () => 11 createPaywallSession (options, { 12 paywallId: "<PAYWALL_UUID>" , 13 customerToken, 14 commerce: { provider: "stripe" , currency: "USD" }, 15 locale: "en" , 16 }), 17 onCheckoutUrl: (url) => window.location.assign (url), 18 onAccessGranted: (check) => console.log ("access" , check.allowed), 19 }); 20 } Change subscriptions, trials and refunds app/change-plan.ts TypeScript Copy 1 import { createIndiana } from "@tinkerlandai/indiana-sdk" ;2 3 const indiana = createIndiana ({4 baseUrl: "https://api.tinker.cash" , 5 scope: { projectId: "<APP_UUID>" , environment: "sandbox" }, 6 }); 7 8 export async function changePlan (customerToken: string, requestId: string, productVersionId: string) {9 indiana.identify (customerToken); 10 const { holdings } = await indiana.readHoldings (); 11 const membership = holdings.memberships[0 ]; 12 if (!membership) throw new Error ("No membership to change" ); 13 14 // 1. Quote the change; nothing is charged yet. 15 const { quote } = await indiana.previewUpdate ({ 16 requestId, // persisted before the first attempt 17 membershipId: membership.id, 18 timing: "immediate" , 19 change: { type : "plan" , productVersionId }, 20 }); 21 22 // 2. After the user accepts the quote, confirm it. 23 const { operation } = await indiana.update ({ operationId: quote.operationId }); 24 return operation; 25 }
Common tasks Task Methods Notes Upgrade, downgrade or cancel previewUpdate → update → readSubscriptionUpdatetiming applies the change immediately, at renewal or in the store.Save a payment method setupPayment → readPaymentSetupNo charge. Start, extend or end a trial manageSubscriptionTrial, readSubscriptionTrialBackend only. Refund previewRefund → refund → readRefundFull or partial; optionally revokes access. List subscriptions and purchases listSubscriptions, listPurchases, verifySubscriptionsBackend only. Resolve subscription conflicts listSubscriptionConflicts, 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.ts TypeScript Copy 1 import { createIndiana } from "@tinkerlandai/indiana-sdk" ;2 3 const indiana = createIndiana ({4 baseUrl: "https://api.tinker.cash" , 5 scope: { projectId: "<APP_UUID>" , environment: "sandbox" }, 6 }); 7 8 type UUID = ReturnType <typeof crypto.randomUUID>;9 10 export async function prepareAutoTopup (customerToken: string, requestId: UUID ) {11 indiana.identify (customerToken); 12 const { prepared } = await indiana.prepareBillingAuthorization ({ 13 requestId, 14 kind: "auto_topup" , 15 productVersionId: "<CREDIT_PACK_VERSION_UUID>" , 16 internal_feature_id: "<CREDIT_FEATURE_UUID>" , 17 currency: "USD" , 18 threshold: "100" , 19 quantity: "1" , 20 }); 21 return prepared; // show prepared.terms to the Customer 22 } 23 24 // Call only after the Customer explicitly accepts the displayed terms. 25 export async function acceptAutoTopup (authorizationId: string) {26 return indiana.confirmBillingAuthorization ({ authorizationId, accepted: true }); 27 } Invoices and usage limits Common tasks Task Methods Caller Create and manage invoices previewInvoice, createInvoice, manageInvoice, readInvoiceOperationBackend Read invoices listInvoiceTemplates, listInvoices, getInvoiceBackend Set usage limits and alerts manageBillingLimitsBackend Let users view their invoices listBillingInvoices, readBillingInvoice, readBillingControlsBrowser Let users apply offers to a membership setBillingCouponsBrowser
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) restoreNativePurchaseRelated: Paths, credentials and scopes in All operations