Swish paymentsInvite only
Learn how to accept Swish, a popular payment method in Sweden.
Swish is a single-use payment method used in Sweden. It allows customers to authenticate and approve payments using the Swish mobile app and the Swedish BankID mobile app.
You get immediate notification on whether the payment succeeded or failed.
Required notices 
To comply with Swish rules, you must display the following text in your payment flow on the screen before the customer authorizes the Swish payment:
- For English localizations: “Stripe Technology Europe Limited (“Stripe”) has acquired the claim for payment. Therefore your payment will be made to Stripe.”
- For Swedish localizations: “Stripe Technology Europe Limited (“Stripe”) har övertagit fordran på betalning. Din betalning görs därför till Stripe.”
- For other languages, an equivalent translation of the above.
If you integrate Swish through a Stripe-hosted payment form or UI component such as Checkout or the Payment Element, Stripe displays this notice for you.
Set up StripeServer-sideClient-side
First, you need a Stripe account. Register now.
Server-side 
This integration requires endpoints on your server that talk to the Stripe API. Use the official libraries for access to the Stripe API from your server:
Client-side 
The React Native SDK is open source and fully documented. Internally, it uses the native iOS and Android SDKs. To install Stripe’s React Native SDK, run one of the following commands in your project’s directory (depending on which package manager you use):
Next, install some other necessary dependencies:
- For iOS, navigate to the ios directory and run
pod install
to ensure that you also install the required native dependencies. - For Android, there are no more dependencies to install.
Note
We recommend following the official TypeScript guide to add TypeScript support.
Stripe initialization
To initialize Stripe in your React Native app, either wrap your payment screen with the StripeProvider
component, or use the initStripe
initialization method. Only the API publishable key in publishableKey
is required. The following example shows how to initialize Stripe using the StripeProvider
component.
import { useState, useEffect } from 'react'; import { StripeProvider } from '@stripe/stripe-react-native'; function App() { const [publishableKey, setPublishableKey] = useState(''); const fetchPublishableKey = async () => { const key = await fetchKey(); // fetch key from your server here setPublishableKey(key); }; useEffect(() => { fetchPublishableKey(); }, []); return ( <StripeProvider publishableKey={publishableKey} merchantIdentifier="merchant.identifier" // required for Apple Pay urlScheme="your-url-scheme" // required for 3D Secure and bank redirects > // Your app code here </StripeProvider> ); }
Create a PaymentIntentServer-sideClient-side
Server-side
A PaymentIntent is an object that represents your intent to collect payment from a customer and tracks the lifecycle of the payment process through each stage.
To create and confirm a PaymentIntent
on your server:
- Specify the amount to collect and the currency.
- Add
swish
to the list of payment method types for yourPaymentIntent
. Make sure Swish is enabled in the Dashboard.
The returned PaymentIntent includes a client secret, that you’ll use to confirm the PaymentIntent. Send the client secret back to the client so you can use it in the next step.
Client-side
On the client, request a PaymentIntent from your server and store its client secret:
function PaymentScreen() { const fetchPaymentIntentClientSecret = async () => { const response = await fetch(`${API_URL}/create-payment-intent`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ currency: 'sek', }), }); const {clientSecret} = await response.json(); return clientSecret; }; const handlePayPress = async () => { // See below }; return ( <View> <Button onPress={handlePayPress} title="Pay" /> </View> ); }
The client secret is different from your API keys that authenticate Stripe API requests. Handle it carefully because it can complete the charge. Don’t log it, embed it in URLs, or expose it to anyone but the customer.
Set up a return URL (iOS only)Client-side
When a customer exits your app (for example to authenticate in Safari or their banking app), provide a way for them to automatically return to your app. Many payment method types require a return URL. If you don’t provide one, we can’t present payment methods that require a return URL to your users, even if you’ve enabled them.
To provide a return URL:
- Register a custom URL. Universal links aren’t supported.
- Configure your custom URL.
- Set up your root component to forward the URL to the Stripe SDK as shown below.
Note
If you’re using Expo, set your scheme in the app.
file.
import { useEffect, useCallback } from 'react'; import { Linking } from 'react-native'; import { useStripe } from '@stripe/stripe-react-native'; export default function MyApp() { const { handleURLCallback } = useStripe(); const handleDeepLink = useCallback( async (url: string | null) => { if (url) { const stripeHandled = await handleURLCallback(url); if (stripeHandled) { // This was a Stripe URL - you can return or add extra handling here as you see fit } else { // This was NOT a Stripe URL – handle as you normally would } } }, [handleURLCallback] ); useEffect(() => { const getUrlAsync = async () => { const initialUrl = await Linking.getInitialURL(); handleDeepLink(initialUrl); }; getUrlAsync(); const deepLinkListener = Linking.addEventListener( 'url', (event: { url: string }) => { handleDeepLink(event.url); } ); return () => deepLinkListener.remove(); }, [handleDeepLink]); return ( <View> <AwesomeAppComponent /> </View> ); }
For more information on native URL schemes, refer to the Android and iOS docs.
Confirm Swish paymentClient-side
When a customer taps to pay with Swish, complete the payment by calling confirmPayment. This presents a webview where the customer can complete the payment with Swish. Upon completion, the promise resolves with an object containing either a paymentIntent
field, or an error
field if an error occurred with the payment.
import {useConfirmPayment} from '@stripe/stripe-react-native'; function PaymentScreen() { const {confirmPayment, loading} = useConfirmPayment(); const fetchPaymentIntentClientSecret = async () => { // See above }; const handlePayPress = async () => { // Fetch the client secret from the backend. const clientSecret = await fetchPaymentIntentClientSecret(); const {error, paymentIntent} = await confirmPayment(clientSecret, { paymentMethodType: 'Swish', }); if (error) { console.log('Payment confirmation error: ', error); } else if (paymentIntent) { console.log('Successfully confirmed payment: ', paymentIntent); } }; return ( <View> <Button onPress={handlePayPress} title="Pay" disabled={loading} /> </View> ); }
Failed payments 
Swish uses multiple data points to decide when to decline a transaction (for example, there aren’t enough funds in the customer’s bank account, or the customer has clicked Cancel in the app).
In these cases, the PaymentMethod is detached and the PaymentIntent object’s status automatically transitions to requires_
.
Other than a payment being declined, for a Swish PaymentIntent with a status of requires_
, customers must complete the payment within 3 minutes. If no action is taken after 3 minutes, the PaymentMethod is detached and the PaymentIntent object’s status automatically transitions to requires_
.