DEV Community

Cover image for How to Add Payment Processing to Your React Native App in 2026
Famitha M A
Famitha M A

Posted on • Originally published at fami-blog.hashnode.dev

How to Add Payment Processing to Your React Native App in 2026

How to Add Payment Processing to Your React Native App in 2026

Adding payments to a React Native app sounds simple until you realize there's no single "right way." If you sell physical goods, Stripe is the answer. If you sell digital content consumed inside your app, Apple and Google require their own billing APIs and they take up to 30%. Mix the two and you'll either pay double fees or get rejected during App Store review.

This is the practical guide I wish I'd had the first time. We'll cover the decision tree, set up @stripe/stripe-react-native, add Apple Pay and Google Pay, handle subscriptions with react-native-iap or RevenueCat, build a minimal backend, and test it all without spending a dollar.

The Decision Tree

You sell... Use this Fee
Physical goods Stripe / Braintree ~2.9% + $0.30
Real-world services (rides, etc.) Stripe / Braintree ~2.9% + $0.30
Digital subscriptions Apple IAP / Google Play Billing 15–30%
One-time digital unlocks Apple IAP / Google Play Billing 15–30%

Apple's Guideline 3.1.1 is the source of truth here. Don't skip it.

Step 1: Install the Stripe SDK

npm install @stripe/stripe-react-native
cd ios && pod install
Enter fullscreen mode Exit fullscreen mode

Expo SDK 50+ works via the config plugin. You need a development build — Expo Go can't run native payment modules.

Step 2: Wrap Your App in StripeProvider

import { StripeProvider } from '@stripe/stripe-react-native';

export default function App() {
  return (
    <StripeProvider
      publishableKey={process.env.EXPO_PUBLIC_STRIPE_PUBLISHABLE_KEY!}
      merchantIdentifier="merchant.com.yourapp"
      urlScheme="yourapp"
    >
      <RootNavigator />
    </StripeProvider>
  );
}
Enter fullscreen mode Exit fullscreen mode

Only the publishable key (pk_...) goes in the client. Your secret key never touches the bundle.

Step 3: Create a PaymentIntent on Your Backend

app.post('/payments/create-intent', async (req, res) => {
  const intent = await stripe.paymentIntents.create({
    amount: req.body.amount,
    currency: req.body.currency,
    automatic_payment_methods: { enabled: true },
  });
  res.json({ clientSecret: intent.client_secret });
});
Enter fullscreen mode Exit fullscreen mode

You can't create PaymentIntents from the client. Stripe blocks it because it would let an attacker manipulate the amount.

Step 4: Present PaymentSheet

const { initPaymentSheet, presentPaymentSheet } = useStripe();

async function checkout() {
  const { clientSecret } = await api.createIntent({ amount: 1999 });

  await initPaymentSheet({
    merchantDisplayName: 'Your Store',
    paymentIntentClientSecret: clientSecret,
    applePay: { merchantCountryCode: 'US' },
    googlePay: { merchantCountryCode: 'US', testEnv: true },
  });

  const { error } = await presentPaymentSheet();
  if (!error) showReceipt();
}
Enter fullscreen mode Exit fullscreen mode

PaymentSheet picks the right local methods automatically — cards in the US, iDEAL in the Netherlands, BLIK in Poland. You don't build any of that.

Apple Pay & Google Pay

Both flow through Stripe, they're not separate gateways. To enable Apple Pay:

  1. Create a Merchant ID in the Apple Developer portal.
  2. Generate the processing certificate from Stripe's dashboard.
  3. Add the Apple Pay capability in Xcode.
  4. Pass merchantIdentifier to StripeProvider.

Google Pay is one config flag plus an AndroidManifest.xml meta-data tag. Conversion lifts 20–30% on iOS when Apple Pay is offered.

Subscriptions: react-native-iap or RevenueCat?

For digital content, you have to use Apple/Google IAP. Two practical paths:

react-native-iap (free, DIY backend):

import { initConnection, requestPurchase, finishTransaction } from 'react-native-iap';

await initConnection();
const purchase = await requestPurchase({ sku: 'pro_monthly' });
// validate receipt on your backend, then:
await finishTransaction({ purchase, isConsumable: false });
Enter fullscreen mode Exit fullscreen mode

RevenueCat (free under ~$2.5K MTR, then 1% — handles all the receipt validation, entitlement, and analytics):

import Purchases from 'react-native-purchases';

await Purchases.configure({ apiKey: 'your_key' });
const offerings = await Purchases.getOfferings();
const { customerInfo } = await Purchases.purchasePackage(
  offerings.current.monthly
);
const isPro = customerInfo.entitlements.active['pro'] !== undefined;
Enter fullscreen mode Exit fullscreen mode

Rule of thumb: if you ship subscriptions and don't have a payments engineer, use RevenueCat. The hours you save on receipt validation, server-to-server notifications, and cross-platform entitlement state will pay for it in week one.

Testing Without Real Money

Stripe test cards I use most:

  • 4242 4242 4242 4242 — success
  • 4000 0027 6000 3184 — 3D Secure challenge
  • 4000 0000 0000 9995 — declined (insufficient funds)
  • 4000 0000 0000 0341 — fails on charge

Apple sandbox subscriptions renew at accelerated cadence (1 month = 5 minutes, up to 6 cycles). You can verify your renewal logic in an afternoon.

Pre-Ship Checklist

  • [ ] Successful card charge end-to-end
  • [ ] 3D Secure / SCA challenge completes
  • [ ] Apple Pay / Google Pay works
  • [ ] IAP purchase + restore + refund tested
  • [ ] Webhook idempotency (duplicate events don't double-grant)
  • [ ] Subscription cancellation eventually revokes access
  • [ ] Network drop mid-purchase doesn't lose the receipt

Common Pitfalls

  1. PCI scope creep — stay in SAQ A by always using PaymentSheet. The moment you build a custom card form, the audit burden explodes.
  2. SCA failures in Europe — let Stripe pick payment methods automatically; custom flows often skip the 3DS challenge.
  3. Idempotency keys — pass one on every server write. Retries that create duplicate intents charge the user twice.
  4. Currency mismatch — store currency next to amount. 1999 is not the same revenue in USD vs JPY.

Wrapping Up

Payments will always require thoughtful backend and compliance work. But the React Native scaffolding around them — paywalls, settings screens, restore-purchase flows — is repetitive plumbing.

If you want to skip the boilerplate, RapidNative generates production-ready React Native + Expo code from a sentence. Describe your paywall, iterate visually, drop in your Stripe and RevenueCat keys, and ship.

What's your stack — Stripe + RevenueCat? Pure react-native-iap? Curious what's working in 2026.

Top comments (0)