Payments
If your app charges money. Even just once, even just a dollar. You need to do it the right way for the platform.
There are two ways apps take money on mobile, and picking the wrong one will get your app rejected by Apple. This page will get the right one for your situation in two minutes.
Which one do I need?
Answer one question: is the thing you're selling used inside the app, or outside it?
"Inside the app". Digital things people use in the app itself
A subscription that unlocks features. Coins or gems. A pack of credits. Premium themes. Anything where the user pays you, and the thing they get is on their phone, in your app.
→ Start with Apple In-App Purchase and Google Play Billing. Review each store's current rules, regional programs, and permitted exceptions for your product before release. RevenueCat wraps the native billing systems but does not replace store policy.
To make this easier, we use a service called RevenueCat that handles both platforms with one set of code.
"Outside the app". Physical goods, real-world services, web purchases
A pair of shoes. A cleaning booking. A B2B subscription to a SaaS product. Anything where what the user pays for happens off-phone.
→ Stripe is usually the relevant card-payments path. Review Stripe's current country, payment-method, verification, tax, and fee rules, plus the stores' current policies for your exact flow.
Both?
Some apps need both. A marketplace app might sell physical goods (Stripe) but also offer a premium membership inside the app (Apple/Google). That's allowed. You just have to keep them separate. The agent handles both.
Adding Stripe (for real-world goods and services)
"Let users upgrade to a Pro plan at $9.99/month or $99/year. Use Stripe Checkout, with cancel anytime. Remember on each user whether they're Pro so I can unlock features for them."
What the agent can generate:
- Adds a Pro/Free flag to your user records.
- Builds a "Subscribe" screen that opens Stripe's secure payment page.
- Generates checkout and webhook contracts so your deployed backend can reconcile payment state.
- Adds explicit handling paths for refunds, failed payments, and cancellations.
- Wires up the unlock logic so Pro users see Pro features.
What you do on Stripe's side
After the agent sets things up, you finish on Stripe:
- Create a free Stripe account at stripe.com.
- Open the Appsanic project build, select Connectors → Stripe, and enter matched keys from the same Stripe mode. Connector OAuth is not currently available. The connection applies only to this project.
- Decide who creates the catalogue. An
rk_connection is validation-only because Stripe has no safe Products-write probe. To opt into bounded product/price creation, connect a standardsk_key and turn on Account access; otherwise create them in Stripe yourself. Register the webhook manually at the exact deployed backend URL, choose only the events you need, and place its signing secret directly in that backend's environment.
If the agent needs Stripe mid-build and it isn't connected yet, it pauses and drops a connect card into the chat - connecting happens in a modal on the same page, and the build resumes on its own.
Testing without spending real money
Stripe has a test mode with fake credit card numbers (the famous one is 4242 4242 4242 4242). Run through the full purchase flow with test cards before flipping the switch to real money.
Adding Apple/Google in-app purchases (via RevenueCat)
This is required if you're selling things consumed inside the app.
"Let users subscribe to a Pro tier from inside the app using in-app purchases. Monthly and annual options. Use RevenueCat for cross-platform receipt handling."
What the agent does:
- Builds a clearly labelled, deterministic preview paywall that cannot purchase.
- Leaves commented native-SDK setup for an exported development build.
- Generates purchase, restore, and entitlement-check integration steps.
- Adds premium-gating UI without simulating a successful entitlement.
What you do on the platform side
This is the slightly tedious part. You only do it once:
- Create a free RevenueCat account at revenuecat.com.
- In App Store Connect (Apple's dashboard) and Google Play Console, create your subscription products. Both stores require this.
- Link those products to RevenueCat by their codes.
- In the Appsanic project build, select Connectors → RevenueCat. Use a
test_key only for RevenueCat Test Store development, or the platformappl_/goog_key for a real-store build. Connect other projects separately. - Export the app, install
react-native-purchases, configure a stable unguessable App User ID, and make a development build. RevenueCat's native SDK does not run in the browser preview or Expo Go.
Testing in-app purchases
You can test without spending real money:
- RevenueCat Test Store: use the connector's
test_field only in a development build configured for Test Store. - iPhone: before real-store release, switch to the
appl_key and use Apple's sandbox setup. - Android: before real-store release, switch to the
goog_key and use Play Console license testers.
Both are walked through in RevenueCat's onboarding.
A few things that catch people out
- Don't mix the two. Don't charge for in-app subscriptions via Stripe on iPhone. Apple will reject your app. Don't sell a physical product via Apple's in-app purchase. They don't do refunds for things the app didn't deliver. If you're not sure, ask the agent.
- Test keys vs release keys. Stripe test/live credentials must stay in matching modes. A RevenueCat
test_key works only with Test Store; an App Store or Play Store release still needs the appropriateappl_orgoog_key. - Tax. Stripe handles sales tax in most countries via "Stripe Tax." Apple and Google handle their own tax. They're the merchant of record, you receive the post-tax amount.
Refunds
- Stripe: you issue refunds in Stripe. Your separately deployed, signature-verifying webhook must process the event and update access idempotently.
- Apple/Google: they decide on refunds. RevenueCat can report entitlement changes after its native/dashboard/webhook setup is complete; your app must then refresh and enforce that state.
Your own Refund Policy still applies. Australian customers keep their Consumer Law rights either way.
Under the hood (for engineers)
Stripe and RevenueCat are project-scoped managed connectors with saved credential fields encrypted at rest. The agent scaffolds the client flow, but server payment keys and webhook secrets must be provisioned separately in the deployed backend.
Stripe:
- A webhook endpoint at
/api/stripe/webhookwith HMAC signature verification. - A
/api/billing/checkoutroute that creates a Stripe Checkout Session. - Handlers for
checkout.session.completed,customer.subscription.updated,customer.subscription.deleted,invoice.payment_succeeded,invoice.payment_failed,charge.refunded. - A
hasAccess(user, feature)helper for gating. - With Account access on and a standard
sk_connector key, an eligible build action can create products and prices. Anrk_connector remains validation-only. Webhook registration, signing-secret provisioning, refunds, and destructive account operations remain manual; the deployed backend always gets a separate restricted runtime key.
RevenueCat (for IAP):
- Preview: local sample paywall data, disabled purchase/restore actions, and explicit native-build messaging. Public SDK keys are not used for client subscriber REST calls.
- After export: install
react-native-purchases, configure the correct Test Store or platform key with a stable authenticated App User ID, and make a development build. - Dashboard: configure products, entitlements, a current Offering, and store credentials before expecting live offerings.
Webhook handlers must verify raw-body signatures and deduplicate on the provider event ID. Treat idempotency as a requirement to test, not an automatic guarantee.
Next
Read Push Notifications so you can let users know about purchases and other events.
