Accept a PayPal payment
Learn how to accept PayPal payment, a digital wallet popular with businesses in Europe.
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 Stripe iOS SDK is open source, fully documented, and compatible with apps supporting iOS 13 or above.
Note
For details on the latest SDK release and past versions, see the Releases page on GitHub. To receive notifications when a new release is published, watch releases for the repository.
Configure the SDK with your Stripe publishable key on app start. This enables your app to make requests to the Stripe API.
Create a PaymentIntentServer-sideClient-side
Server-side
Stripe uses a payment object, called a PaymentIntent, to track and handle all the states of the payment until it’s completed. Create a PaymentIntent
on your server, specifying the amount to collect and the currency. If you already have an integration using the Payment Intents API, add paypal
to the list of payment method types for your PaymentIntent.
Included in the returned PaymentIntent is a client secret, which is used to securely complete the payment process instead of passing the entire PaymentIntent object. Send the client secret back to the client so you can use it in later steps.
Include a custom description
By default, the order details on the PayPal users purchase activity page displays the order amount. You can change this by providing a custom description in the description
property.
Customize the preferred locale
By default, the PayPal authorization page is localized based on variables such as the merchant’s country. You can set this to your customer’s preferred locale using the preferred_
property. The value must be a two-character lowercased language code, followed by a hyphen (-
), followed by a two-character uppercased country code. For example, the value for a French-language user in Belgium would be fr-BE
.
You can set the PayPal authorization page to your customer’s preferred locale through the preferred_locale property. See the following table for supported locales:
Value | Locale | Country |
---|---|---|
cs-CZ | Czech | The Czech Republic |
da-DK | Danish | Denmark |
de-AT | German | Austria |
de-DE | German | Germany |
de-LU | German | Luxembourg |
el-GR | Greek | Greece |
en-GB | English | United Kingdom |
en-US | English | United States of America |
es-ES | Spanish | Spain |
fi-FI | Finnish | Finland |
fr-BE | French | Belgium |
fr-FR | French | France |
fr-LU | French | Luxembourg |
hu-HU | Hungarian | Hungary |
it-IT | Italian | Italy |
nl-BE | Dutch | Belgium |
nl-NL | Dutch | Netherlands |
pl-PL | Polish | Poland |
pt-PT | Portuguese | Portugal |
sk-SK | Slovak | Slovakia |
sv-SE | Swedish | Sweden |
Statement descriptors with PayPal
The descriptor that appears on the buyer’s bank statement is set by PayPal, and by default is PAYPAL *YOUR_
. If you set the statement_
field when creating the PaymentIntent
, its value is appended to the one set by PayPal, up to a total limit of 22 characters.
For example, if your business name in PayPal is BUSINESS
and you set statement_
to order_
, buyers see PAYPAL *BUSINESS order
on their bank account statement.
Client-side
On the client, request a PaymentIntent from your server and store its client secret.
Submit the payment to StripeClient-side
When a customer taps to pay with PayPal, confirm the PaymentIntent
to complete the payment. Configure an STPPaymentIntentParams
object with the PaymentIntent
client secret.
The client secret is different from your API keys that authenticate Stripe API requests. Handle this carefully as 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
The iOS SDK presents a webview in your app to complete the PayPal payment. When authentication is finished, the webview can automatically dismiss itself instead of having your customer close it. To enable this behavior, configure a custom URL scheme or universal link and set up your app delegate to forward the URL to the SDK.
Pass the URL as the return_
when you confirm the PaymentIntent. After webview-based authentication is finished, Stripe redirects the user to the return_
.
Confirm PayPal payment
Complete the payment by calling STPPaymentHandler confirmPayment
. This presents a webview where the customer can complete the payment with PayPal. Upon completion, the completion block is called with the result of the payment.
You can find the payment owner’s name, email, payer ID, and transaction ID in the payment_method_details property.
Field | Value |
---|---|
payer_ | The email address of the payer on their PayPal account. |
payer_ | The name of the payer on their PayPal account. |
payer_ | A unique ID of the payer’s PayPal account. |
transaction_ | A unique transaction ID generated by PayPal. |
{ "charges": { "data": [ { "payment_method_details": { "paypal": { "payer_id": "H54KFE9XXVVYJ", "payer_email": "jenny@example.com", "payer_name": "Jenny Rosen", "transaction_id": "89W40396MK104212M" }, "type": "paypal" }, "id": "src_16xhynE8WzK49JbAs9M21jaR", "object": "source", "amount": 1099, "client_secret": "src_client_secret_UfwvW2WHpZ0s3QEn9g5x7waU", "created": 1445277809, "currency": "eur", "flow": "redirect",
OptionalHandle post-payment events
Stripe sends a payment_intent.succeeded event when the payment completes. Use the Dashboard, a custom webhook, or a partner solution to receive these events and run actions, like sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow.
Listen for these events rather than waiting on a callback from the client. On the client, the customer could close the browser window or quit the app before the callback executes, and malicious clients could manipulate the response. Setting up your integration to listen for asynchronous events also helps you accept more payment methods in the future. Learn about the differences between all supported payment methods.
Receive events and run business actions 
There are a few options for receiving and running business actions.
Manually
Use the Stripe Dashboard to view all your Stripe payments, send email receipts, handle payouts, or retry failed payments.
Custom code
Build a webhook handler to listen for events and build custom asynchronous payment flows. Test and debug your webhook integration locally with the Stripe CLI.
Prebuilt apps
Handle common business events, like automation or marketing and sales, by integrating a partner application.