Skip to content

Native bindings missing: StoreKit 2 (iOS) + Google Play Billing Library (Android) #537

@proggeramlug

Description

@proggeramlug

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-ktxBillingClient, 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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions