Summary
Perry currently exposes no TypeScript bindings for StoreKit 2 on iOS or for the Google Play Billing Library on Android. Apps that want to do in-app purchases for subscriptions on those platforms have no way to drive the native flow today; they must either go through Stripe-card on iOS / Android (rejected by Apple's review process for digital subscriptions) or skip native IAP entirely.
This is a feature request, not a bug — there is nothing to reproduce because the surface doesn't exist.
What's needed (server-driveable shape)
A small TypeScript surface that wraps the platform calls. Sketch:
// perry/iap (proposed)
export type Product = {
productId: string;
title: string;
description: string;
priceMicros: number;
priceCurrencyCode: string;
};
export type PurchaseResult = {
productId: string;
transactionId: string; // StoreKit transactionIdentifier or Play purchaseToken
purchaseDate: string; // ISO 8601
receipt: string; // base64 — server validates against Apple/Google
};
// iOS StoreKit 2:
export function loadProducts(productIds: string[]): Promise<Product[]>;
export function purchase(productId: string): Promise<PurchaseResult>;
export function restorePurchases(): Promise<PurchaseResult[]>;
// Android Play Billing Library:
// (same surface — implementation differs)
Server-side receipt validation is plain HTTPS against Apple's verifyReceipt / Google's Play Developer API and doesn't need a native binding.
Reference implementations
- iOS:
StoreKit 2 (Swift) — Product.products(for:), Product.purchase(), Transaction.currentEntitlements
- Android:
androidx.billing:billing-ktx — BillingClient, queryProductDetailsAsync, launchBillingFlow
- Both have well-documented async APIs that map cleanly to Promise-returning TS functions.
Why we filed
Our app spec calls for a Free / Pro / Business plan tier with subscriptions. Stripe-card works on macOS / web and (via SFSafariViewController) on iOS for organizations, but Apple requires StoreKit for individual subscriptions. We can ship the macOS/web flow today; the iOS flow is blocked.
Workaround
We will gate iOS/Android subscription UI behind a feature flag and ship without IAP for v1. Server endpoints for receipt validation can land independently (plain HTTPS).
Environment
perry 0.5.503
- Targets:
ios, android (binding for both platforms)
Summary
Perry currently exposes no TypeScript bindings for StoreKit 2 on iOS or for the Google Play Billing Library on Android. Apps that want to do in-app purchases for subscriptions on those platforms have no way to drive the native flow today; they must either go through Stripe-card on iOS / Android (rejected by Apple's review process for digital subscriptions) or skip native IAP entirely.
This is a feature request, not a bug — there is nothing to reproduce because the surface doesn't exist.
What's needed (server-driveable shape)
A small TypeScript surface that wraps the platform calls. Sketch:
Server-side receipt validation is plain HTTPS against Apple's
verifyReceipt/ Google's Play Developer API and doesn't need a native binding.Reference implementations
StoreKit 2(Swift) —Product.products(for:),Product.purchase(),Transaction.currentEntitlementsandroidx.billing:billing-ktx—BillingClient,queryProductDetailsAsync,launchBillingFlowWhy we filed
Our app spec calls for a Free / Pro / Business plan tier with subscriptions. Stripe-card works on macOS / web and (via SFSafariViewController) on iOS for organizations, but Apple requires StoreKit for individual subscriptions. We can ship the macOS/web flow today; the iOS flow is blocked.
Workaround
We will gate iOS/Android subscription UI behind a feature flag and ship without IAP for v1. Server endpoints for receipt validation can land independently (plain HTTPS).
Environment
perry 0.5.503ios,android(binding for both platforms)