app.ski is a checkout for iOS and Android apps. Your paywall opens it, the buyer pays by card, Apple Pay or USDC, and they're back in your app with the purchase unlocked. List your app in the app.ski Store and new customers can find it and subscribe there too.
Back in Powder.
One $100 sale, after everyone's fees. Your price, your customer, your payout schedule.
| Sold through | Fees | You keep |
|---|---|---|
| App Store or Google Play, standard | 30% commission | $70.00 |
| App Store or Google Play, small business program | 15% commission | $85.00 |
| app.ski, card or Apple Pay | 3% + Stripe (2.9% + 30¢) | $93.80 |
| app.ski, USDC | 3%; the buyer pays a few cents of gas | $97.00 |
Store programs and Stripe pricing vary by region and volume. Check the current rates for yours.
Most apps finish in an afternoon. Everything works in test mode first, with no Stripe account and no wallet.
import AppSki AppSki.configure(apiKey: "pk_live_…", appUserID: user.id, returnURL: "powder://purchased") let result = try await AppSki.shared.purchase("pro_yearly") if result.isActive("pro") { unlockPro() }
AppSki.configure(context, apiKey = "pk_live_…", appUserId = user.id, returnUrl = "powder://purchased") lifecycleScope.launch { val result = AppSki.purchase(activity, "pro_yearly") if (result.isActive("pro")) unlockPro() }
import AppSki from '@appski/react-native'; AppSki.configure({ apiKey: 'pk_live_…', appUserId: user.id, returnUrl: 'powder://purchased' }); const { entitlements } = await AppSki.purchase('pro_yearly'); if (entitlements.pro?.active) unlockPro();
# Is this user Pro? curl https://app.ski/v1/customers/u_42/entitlements \ -H "Authorization: Bearer sk_live_…" # Webhooks arrive signed: Appski-Signature: t=…,v1=HMAC-SHA256 # purchase.completed · subscription.renewed · purchase.refunded · pass.transferred
The app.ski Store is where people browse apps they can subscribe to on the web. List yours from the dashboard; it's free.
email:<address>, so they work in your app when people sign in with that email.Optional, per product. The subscription becomes a token on Base, and whoever holds it has access until it expires.
GET /v1/wallets/:address/entitlements tells you what a wallet unlocks.The parts of app billing you'd otherwise build yourself.
Court rulings and the EU's Digital Markets Act opened up link-outs. Rules differ by store and country and keep changing, so check each store's current guidelines.
| Store and region | Status | Notes |
|---|---|---|
| App Store, United States | Allowed | Since the April 2025 Epic v. Apple injunction; no Apple commission on web purchases. |
| Google Play, United States | Allowed | Under the Epic v. Google remedies. |
| Both stores, EU / EEA | Via programs | DMA link-out and alternative-billing programs, with the stores' own fees and disclosures. |
| Elsewhere | Varies | Reader apps and some markets allow it. Show the web option only where permitted. |
Yes. Many apps offer both. Entitlements are keyed to your user ID, so you can merge them with StoreKit or Play Billing.
You are, through your connected Stripe account. Turn on Stripe Tax for VAT and sales tax.
No. The SDK reads entitlements with your publishable key. If you have a server, use webhooks and the secret key.
No. USDC and NFT passes are optional. Card buyers never see a wallet.
Access moves to the new holder and the seller loses it. A wallet links to one account at a time.
Store buyers enter an email, so the purchase belongs to email:<address>. Use that as the user ID, or match it on your server.
Everything, simulated: checkout, renewals, refunds and passes. No card or wallet needed.