React Native payments
Take payments in your React Native app, on both stores, with one API.
Collect the card with Stripe's React Native card field, or open Flint's hosted checkout in an in-app browser. Either way your backend pays one Flint order, and Flint keeps the order, the tax, the receipt, and the refund. The same app ships to the App Store and Google Play, Expo included.
curl -X POST https://api.withflintpay.com/v1/orders/ord_1kmn0aExample/pay \
-H "Authorization: Bearer $FLINT_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: pay-ord_1kmn0aExample-pm_1kmn0aExample" \
-d '{
"action": "pay",
"payment_source": {
"credential_type": "token",
"token": "pm_1kmn0aExample"
},
"expected_outstanding_money": {
"amount": 3800,
"currency": "USD"
},
"expected_version": 1790760000,
"buyer_contact": { "email": "ada@example.com" }
}'The card the app collected, as a Stripe payment method, pays the Flint order in one request. Flint confirms the payment; the app never does.
One integration
React Native code for iOS and Android, and one backend endpoint that pays the order.
No key in the app
Your Flint API key stays on your server. The app only ever holds Stripe's publishable key.
An order, not a charge
Line items, tax, receipt, refunds, and the paid webhook, all on the one order.
01In your own screen
Stripe's card field in the app. Flint on your backend.
Keep checkout inside your app's own UI. The app makes one Stripe call to turn the card into a payment method, and your backend does the rest.
1. Create the order. Your backend creates a Flint order from the cart and reads it back. The read’s payment_collection.stripe has the publishable_key and account_id the app gives StripeProvider.
2. Collect the card. The app shows Stripe’s CardField and calls createPaymentMethod. Card numbers go from the field to Stripe, never through your servers or Flint’s.
3. Pay the order. Your backend sends the payment method to POST /v1/orders/{order_id}/pay with the total the buyer saw. If the order changed in the meantime, Flint refuses before charging.
4. Handle 3D Secure. If the issuer asks for it, the response is requires_action with a client secret. The app calls handleNextAction, and your backend resumes the payment.
Ship from the order.paid webhook or a fresh read of the order, not from what the app reports. Test with 4242 4242 4242 4242 and the 3D Secure test cards in a sandbox.
import { Button } from "react-native";
import {
CardField,
StripeProvider,
useStripe,
} from "@stripe/stripe-react-native";
// collection = payment_collection.stripe, sent by your backend
export function Checkout({ collection }) {
return (
<StripeProvider
publishableKey={collection.publishable_key}
stripeAccountId={collection.account_id}
>
<PayForm />
</StripeProvider>
);
}
function PayForm() {
const { createPaymentMethod, handleNextAction } = useStripe();
async function pay() {
const { paymentMethod, error } = await createPaymentMethod({
paymentMethodType: "Card",
});
if (error) return showError(error.message);
// your backend pays the Flint order with paymentMethod.id
let result = await post("/checkout/pay", { token: paymentMethod.id });
if (result.status === "requires_action") {
// 3D Secure, then ask your backend to resume the attempt
await handleNextAction(result.client_secret);
result = await post("/checkout/resume");
}
if (result.status === "succeeded") showConfirmation();
else showStatus(result);
}
return (
<>
<CardField postalCodeEnabled style={{ height: 50 }} />
<Button title="Pay" onPress={pay} />
</>
);
}post, showError, and showStatus are your own helpers. The backend returns the attempt's status and, for 3D Secure, the client secret.
02Hosted checkout
Or open Flint checkout in an in-app browser.
Your backend creates a checkout session for the order, and the app opens its URL. Buyers pay by card, Apple Pay, Google Pay, bank debit, or Affirm, depending on the payment options you turn on.
Wallets with no setup. Checkout runs on Flint’s domain, so Apple Pay and Google Pay appear on supported devices without an Apple merchant ID, a certificate, or a domain to register.
The system browser view. openBrowserAsync from expo-web-browser opens Safari View Controller on iOS and a Chrome Custom Tab on Android, and it works in Expo Go.
The order tells you it’s paid. The success redirect is an HTTPS page on your domain, and it only informs the buyer. When the buyer closes the browser on iOS, or the app comes back to the foreground on Android, the app asks your backend whether the order is paid.
import { AppState } from "react-native";
import * as WebBrowser from "expo-web-browser";
async function checkPaid() {
const { payment_status } = await get("/checkout/order");
if (payment_status === "paid") showConfirmation();
}
async function checkout(cart) {
// your backend creates the order and the checkout session
const { url } = await post("/checkout/session", { cart });
// on iOS this settles when the buyer closes the browser
await WebBrowser.openBrowserAsync(url);
await checkPaid();
}
// on Android it settles as soon as the tab opens, so check again
// when the app comes back to the foreground
AppState.addEventListener("change", (state) => {
if (state === "active") checkPaid();
});post and get call your own backend.
03Included
Everything after the charge, already built.
A Stripe PaymentIntent carries an amount, and your backend has to know what that amount was for. A Flint order carries the line items behind the total, and the store features below work from it, for every order from both apps.
Orders and catalog
Products and variants live in Flint. The app sends variant ids and quantities, and Flint prices the order, so a modified app can't change a price.
Sales tax
Flint calculates US sales tax on the order automatically, or records the result from your own tax engine.
Receipts
Flint emails the buyer a receipt when the order is paid. Turn it off and send your own from the webhook if you prefer.
Refunds
Refund the whole order, an amount, or specific line items, from the API or the dashboard.
Customer accounts
A hosted account where buyers see their orders, subscriptions, and returns, branded and on your domain if you like.
Subscriptions
Recurring plans with trials, renewals, and failed-payment handling, for boxes, memberships, and services used outside the app.
Gift cards
Sell gift cards from your catalog, email the code, and let buyers redeem them at checkout.
Dashboard
Orders, refunds, customers, and payouts in the Flint dashboard, for whoever runs the business day to day.
Orders priced from your catalog, so the app sends ids and quantities, not prices.
POST /v1/ordersHosted checkout with cards, Apple Pay, and Google Pay, opened from the app.
POST /v1/checkout-sessionsRefund a whole order, an amount, or specific line items.
POST /v1/refundsRecurring plans for boxes, memberships, and services.
POST /v1/subscriptionsGift cards issued by API or sold from your catalog, and redeemed at checkout.
POST /v1/gift-cardsOne webhook when the order is paid, for fulfillment.
order.paidreviewed 2026-10-30 against the orders, checkout sessions, refunds, subscriptions, and gift cards guides · refunds guide · corrections: Flint Help
04Store rules
What the App Store and Google Play let you sell this way.
Both stores separate digital content from physical goods and real-world services. Flint takes payments for the second kind.
Apple. Guideline 3.1.1 requires in-app purchase to unlock features or functionality, such as subscriptions, premium content, or a full version. Guideline 3.1.3(e) says an app selling physical goods or services used outside the app must use a method other than in-app purchase, such as Apple Pay or card entry.
Google. The Play Payments policy requires Play Billing for in-app digital goods and services, and says Play Billing must not be used for physical goods, such as groceries or clothing, or physical services, such as transportation, food delivery, or tickets for live events.
Take with Flint
Physical products, deliveries, food orders, bookings, event tickets, and services people use in the real world.
Use the store's billing
Unlocking app features, premium content, in-app currency, and subscriptions to the app itself.
This is a summary of each store’s own pages, not legal advice, and neither store’s review is something Flint can promise. Check both policies against your app.
05Before you build
Four things to know up front.
US businesses, USD
Flint onboards businesses based in the United States and takes online payments in US dollars. Buyers can pay with cards issued anywhere.
Keys stay on the server
Anything shipped in an app binary is public. Your Flint API key lives on your backend; the API key security guide covers scopes and rotation.
Expo Go works
Stripe's React Native SDK and expo-web-browser are both included in Expo Go, so either path runs while you build.
HTTPS redirects
Checkout redirect URLs must be HTTPS. Custom schemes such as myapp:// or exp:// are refused, so redirect to a page on your domain.
Sources
Where the store and SDK facts come from.
Apple requires in-app purchase to unlock features or content, and a method other than in-app purchase for physical goods and services used outside the app. App Review Guidelines, 3.1.1 and 3.1.3(e)
developer.apple.comGoogle requires Play Billing for in-app digital goods and services, and says it must not be used for physical goods or physical services. Google Play Payments policy
support.google.com@stripe/stripe-react-native is included in Expo Go. Expo: Stripe
docs.expo.devopenBrowserAsync opens SFSafariViewController on iOS and a Chrome Custom Tab on Android, and is included in Expo Go. Expo: WebBrowser
docs.expo.devCardField collects the card, and createPaymentMethod turns it into a payment method. Stripe: card payments in React Native
docs.stripe.comhandleNextAction takes a PaymentIntent client secret and runs the authentication step. Stripe React Native: handleNextAction
stripe.dev
last reviewed 2026-10-30 · corrections: Flint Help
06Start
Pay a test order from your app.
Sign up, create a test API key in your sandbox, and put it on your backend. Add @stripe/stripe-react-native to the app, pay an order with 4242 4242 4242 4242, any future expiry, and any CVC, and watch it turn paid in the dashboard.
3.79% + 35¢ on cards · no monthly fee · free sandbox · no credit card
The build, in reading order
- 01Embedded paymentsCollection guidance, pay, 3D Secure, and resume.
- 02Checkout sessionsThe hosted path and its redirects.
- 03Apple Pay and Google PayWhat wallets need on each surface.
- 04iOS app paymentsThe same backend, for a Swift app.
- 05Android app paymentsThe same backend, for a Kotlin app.
- 06PricingEvery rate, published.
Or run npm install -g @flintpay/cli && flint signup to create your account and a sandbox key from the terminal. CLI guide
FAQ
Questions React Native developers ask first.
Can I use Stripe PaymentSheet with Flint?
No. PaymentSheet’s server-confirm flow expects a PaymentIntent client secret back from your server, and a successful Flint payment doesn’t return one, so the sheet can’t finish. Use Stripe’s CardField and createPaymentMethod instead, and have your backend pay the Flint order with the payment method. It’s fewer moving parts: the app makes one Stripe call, and Flint confirms the payment. Or open Flint’s hosted checkout in an in-app browser.
Does it work with Expo?
Yes. Expo lists @stripe/stripe-react-native and expo-web-browser as included in Expo Go, so the card field and hosted checkout both run there while you build. Flint itself runs on your backend, so nothing about it depends on how the app is built. Expo’s Stripe page covers the setup.
Do I have to use Apple In-App Purchase or Google Play Billing instead?
It depends on what you sell. Apple's App Review Guidelines require in-app purchase to unlock features or content inside the app, and require a method other than in-app purchase, such as Apple Pay or card entry, for physical goods and services used outside the app. Google Play's Payments policy requires Play Billing for in-app digital goods and services, and says it must not be used for physical goods or physical services. Flint is for the second kind: physical products, deliveries, bookings, tickets, and other real-world services. Read both policies for your own app; neither store's review is something Flint can promise.
Can buyers pay with Apple Pay or Google Pay?
Yes, on Flint’s hosted checkout. Open it from the app with expo-web-browser, and Apple Pay and Google Pay appear on supported devices with no merchant ID, certificate, or domain setup, because checkout runs on Flint’s domain. Apple Pay inside a native iOS app isn’t supported, so the card field path takes cards. Apple Pay and Google Pay setup has the details.
How does 3D Secure work in the app?
When the card’s issuer asks for authentication, Flint’s pay response has status: "requires_action" and a client secret in client_action.stripe.payment_intent.client_secret. Your backend passes it to the app, the app calls handleNextAction with it, and your backend resumes the payment. Pass that secret only to handleNextAction, never to a confirm call. Declines and payment attempts covers every outcome.
Can checkout redirect back to my app with a myapp:// link?
No. Hosted checkout's redirect URLs, and the return URL for redirect payments such as Affirm, must be absolute HTTPS URLs, so custom schemes like myapp:// and exp:// are refused. Point the redirect at an HTTPS page on your own domain. The redirect only tells the buyer what happened: your app should confirm the payment with your backend.
Is there a Flint React Native SDK?
No. Flint is an API your backend calls with a secret key, and no Flint key ever goes in the app. The app uses Stripe's React Native SDK for card entry, or an in-app browser for hosted checkout. Because everything Flint-specific is on your backend, the hosted checkout path works the same from a Flutter, Swift, or Kotlin app.
What does it cost?
3.79% + 35¢ per card payment, with no monthly fee and no setup fee. International cards add 1.50%. Subscription payments add 0.40%, and automatic sales tax adds 0.50% on payments where Flint calculates tax. The sandbox is free and needs no credit card.
Who can sell with Flint?
Businesses based in the United States, selling in US dollars, online. Buyers can pay with cards issued anywhere.