PaymentFlow
PaymentFlow splits collection and confirmation. presentPaymentFlow collects the payment method and returns a pending card. confirmPaymentFlow confirms the Intent later, usually after a review screen.
Use a PaymentIntent or a SetupIntent. Create those objects on your server. See Server Integration.
Platform support
| Platform | PaymentFlow |
|---|---|
| iOS | Native PaymentSheet.FlowController |
| Android | Native PaymentSheet.FlowController |
| Web | stripe-pwa-elements card modal |
Web supports paymentIntentClientSecret or setupIntentClientSecret, plus optional withZipCode. Native-only options such as defaultBillingDetails, shippingDetails, billingDetailsCollectionConfiguration, enableApplePay, enableGooglePay, style, and returnURL are ignored on web.
1. createPaymentFlow
Fetch client-safe secrets from your backend, then call createPaymentFlow. Provide either paymentIntentClientSecret or setupIntentClientSecret. customerId and customerEphemeralKeySecret are optional together. If you set customerId, you must also set customerEphemeralKeySecret.
import { firstValueFrom } from 'rxjs';
import { PaymentFlowEventsEnum, Stripe } from '@capacitor-community/stripe';
const { paymentIntent, ephemeralKey, customer } = await firstValueFrom(
this.http.post<{
paymentIntent: string;
ephemeralKey: string;
customer: string;
}>(environment.api + 'intent', {}),
);
await Stripe.createPaymentFlow({
paymentIntentClientSecret: paymentIntent,
customerEphemeralKeySecret: ephemeralKey,
customerId: customer,
merchantDisplayName: 'rdlabo',
});
method createPaymentFlow(...)
createPaymentFlow(options: CreatePaymentFlowOption) => Promise<void>
interface CreatePaymentFlowOption
| Prop | Type | Description | Default |
|---|---|---|---|
paymentIntentClientSecret |
string |
Any documentation call 'paymentIntent' Set paymentIntentClientSecret or setupIntentClientSecret | |
setupIntentClientSecret |
string |
Any documentation call 'paymentIntent' Set paymentIntentClientSecret or setupIntentClientSecret | |
defaultBillingDetails |
DefaultBillingDetails |
Optional defaultBillingDetails This is ios/android only. not support web. https://docs.stripe.com/payments/mobile/collect-addresses?payment-ui=mobile&platform=ios#set-default-billing-details | |
shippingDetails |
AddressDetails |
Optional shippingDetails This is android only. ios requires an address element. https://docs.stripe.com/payments/mobile/collect-addresses?payment-ui=mobile&platform=android#prefill-addresses | |
billingDetailsCollectionConfiguration |
BillingDetailsCollectionConfiguration |
Optional billingDetailsCollectionConfiguration This is ios/android only. not support web. https://docs.stripe.com/payments/mobile/collect-addresses?payment-ui=mobile&platform=ios#customize-billing-details-collection | |
customerEphemeralKeySecret |
string |
Any documentation call 'ephemeralKey' | |
customerId |
string |
Any documentation call 'customer' | |
enableApplePay |
boolean |
If you set payment method ApplePay, this set true | false |
applePayMerchantId |
string |
If set enableApplePay false, Plugin ignore here. | |
enableGooglePay |
boolean |
If you set payment method GooglePay, this set true | false |
GooglePayIsTesting |
boolean |
false, | |
countryCode |
string |
use ApplePay and GooglePay. If set enableApplePay and enableGooglePay false, Plugin ignore here. | "US" |
merchantDisplayName |
string |
"App Name" | |
returnURL |
string |
"" | |
paymentMethodLayout |
'automatic' | 'horizontal' | 'vertical' |
"automatic" | |
style |
'alwaysLight' | 'alwaysDark' |
iOS Only | undefined |
withZipCode |
boolean |
Platform: Web only Show ZIP code field. | true |
currencyCode |
string |
use GooglePay. Required if enableGooglePay is true for setupIntents. | "USD" |
2. presentPaymentFlow
Call presentPaymentFlow only after createPaymentFlow succeeds. The returned cardNumber is a masked value. The Intent is not confirmed yet.
const presentResult = await Stripe.presentPaymentFlow();
console.log(presentResult); // { cardNumber: "●●●● ●●●● ●●●● ****" }
method presentPaymentFlow()
presentPaymentFlow() => Promise<{ cardNumber: string; }>
If the customer cancels, the promise rejects or the Canceled event fires. Do not call confirmPaymentFlow until Created or a successful presentPaymentFlow result.
3. confirmPaymentFlow
const confirmResult = await Stripe.confirmPaymentFlow();
if (confirmResult.paymentResult === PaymentFlowEventsEnum.Completed) {
// Update UI only. Confirm the Intent with a webhook before fulfilling.
}
method confirmPaymentFlow()
confirmPaymentFlow() => Promise<{ paymentResult: PaymentFlowResultInterface; }>
type alias PaymentFlowResultInterface
PaymentFlowEventsEnum.Completed | PaymentFlowEventsEnum.Canceled | PaymentFlowEventsEnum.Failed
Treat Canceled as cancellation and Failed as an error. Neither result authorizes fulfillment by itself.
4. addListener
Register result listeners once at application startup. Prefer events over the Promise after Android Activity recreation, including the Created event. See Event Listeners.
await Promise.all([
Stripe.addListener(PaymentFlowEventsEnum.Created, (info) => {
console.log(info.cardNumber);
}),
Stripe.addListener(PaymentFlowEventsEnum.Completed, () => {
console.log('PaymentFlowEventsEnum.Completed');
}),
Stripe.addListener(PaymentFlowEventsEnum.Canceled, () => {
console.log('PaymentFlowEventsEnum.Canceled');
}),
Stripe.addListener(PaymentFlowEventsEnum.Failed, (error) => {
console.log('PaymentFlowEventsEnum.Failed', error);
}),
]);
enum PaymentFlowEventsEnum
| Member | Value |
|---|---|
Loaded |
"paymentFlowLoaded" |
FailedToLoad |
"paymentFlowFailedToLoad" |
Opened |
"paymentFlowOpened" |
Created |
"paymentFlowCreated" |
Completed |
"paymentFlowCompleted" |
Canceled |
"paymentFlowCanceled" |
Failed |
"paymentFlowFailed" |
Reference
import { firstValueFrom } from 'rxjs';
import { PaymentFlowEventsEnum, Stripe } from '@capacitor-community/stripe';
(async () => {
Stripe.addListener(PaymentFlowEventsEnum.Completed, () => {
console.log('PaymentFlowEventsEnum.Completed');
});
// Connect to your backend endpoint, and get every key.
const { paymentIntent, ephemeralKey, customer } = await firstValueFrom(this.http.post<{
paymentIntent: string;
ephemeralKey: string;
customer: string;
}>(environment.api + 'intent', {}));
// Prepare PaymentFlow with CreatePaymentFlowOption.
await Stripe.createPaymentFlow({
paymentIntentClientSecret: paymentIntent,
// setupIntentClientSecret: setupIntent,
customerEphemeralKeySecret: ephemeralKey,
customerId: customer,
});
// Collect payment details. The Intent is not confirmed yet.
const presentResult = await Stripe.presentPaymentFlow();
console.log(presentResult); // { cardNumber: "●●●● ●●●● ●●●● ****" }
// Confirm PaymentFlow. Completed.
const confirmResult = await Stripe.confirmPaymentFlow();
if (confirmResult.paymentResult === PaymentFlowEventsEnum.Completed) {
// Happy path
}
})();
