On this page
No Headings
Last updated: July 7, 2026
In certain countries, Apple allows apps to link to an external website for processing payments. Use these guides to learn on how to enable this type of flow using PayPal.
Please refer to this repository for sample integration: https://github.com/paypal-examples/paypal-ios-sdk-demo-app
Accept PayPal, credit, and debit card payments using the PayPal Mobile iOS SDK. Use customizable PayPal buttons with your custom checkout UI to align with your business branding. For more implementation details, see the PayPal GitHub repository.
PayPal uses the following REST API credentials, which you can get from the developer dashboard:
You need a combination of PayPal and third-party tools:
You can use Postman to explore and test PayPal APIs. Learn more in our Postman guide.
This integration requires a sandbox business account with the Advanced Credit and Debit Card Payments capability. Your account should automatically have this capability.
To confirm that Advanced Credit and Debit Card Payments are enabled for you, check your sandbox business account as follows:
Note: If you created a sandbox business account through sandbox.paypal.com, and the advanced credit and debit card payments status for the account is disabled, complete the sandbox onboarding steps.
Add 3D Secure to reduce the chance of fraud and improve the payment experience by authenticating a cardholder through their card issuer.
Visit our 3D Secure page to see if 3D Secure is required in your region and learn more about implementing 3D Secure in your app.
Integrate 3 different types of payments using the PayPal Mobile SDK:
Build and customize the card fields to align with your branding.
Add the CardPayments package dependency for your app using Swift Package Manager or CocoaPods:
https://github.com/paypal/paypal-ios/ as the repository URL.CardPayments framework.Include PayPal/CardPayments in your Podfile:
# Podfile
pod 'PayPal/CardPayments'A CardClient helps you attach a card to a payment.
In your iOS app:
CLIENT_ID to construct a CoreConfig.CardClient using your CoreConfig object.let coreConfig =CoreConfig(clientID:"CLIENT_ID",environment:.sandbox)
let cardClient =CardClient(config: coreConfig)On your server:
Create an ORDER_ID by using the Orders v2 API.
Pass your ACCESS_TOKEN in the Authorization header. To get an ACCESS_TOKEN, use the Authentication API.
Note: This access token is only for the sandbox environment. When you're ready to go live, request a live access token by changing the request sandbox endpoint to https://api-m.paypal.com/v1/oauth2/token.
Pass the intent. You'll need to pass either AUTHORIZE or CAPTURE as the intent type. This type must match the /authorize or /capture endpoint you use to process your order.
curl --location --request POST 'https://api-m.sandbox.paypal.com/v2/checkout/orders/' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
--data-raw '{
"intent": "CAPTURE|AUTHORIZE",
"purchase_units": [
{
"amount": {
"currency_code": "USD",
"value": "5.00"
}
}
]
}'{
"id":"ORDER_ID",
"status":"CREATED"
}When a buyer starts a payment, send the ORDER_ID from your server to your client app.
A CardRequest object:
ORDER_ID.Build a card object with the buyer's card details:
let card =Card(
number:"4005519200000004",
expirationMonth:"01",
expirationYear:"2025",
securityCode:"123",
cardholderName:"Jane Smith",
billingAddress:Address(
addressLine1:"123 Main St.",
addressLine2:"Apt. 1A",
locality:"City",
region:"IL",
postalCode:"12345",
countryCode:"US"
)
)Collecting a billing address can reduce the number of authentication challenges to customers.
Build a CardRequest with the card object and your ORDER_ID:
let cardRequest =CardRequest(
orderID:"ORDER_ID",
card: card,
sca:.scaAlways// default value is .scaWhenRequired
)3D Secure is supported for all card payments to comply with the Second Payment Services Directive (PSD2). PSD2 is a European Union regulation that introduces Strong Customer Authentication (SCA) and other security requirements.
Select your SCA launch option type using the sca parameter in the CardRequest initializer:
SCA.scaWhenRequired launches an SCA challenge when applicable. This is enabled by default.SCA.scaAlways requires an SCA challenge for all card transactions.After your CardRequest has the card details, call cardClient.approveOrder() to process the payment.
classMyViewController:UIViewController{
func cardCheckoutTapped(cardRequest:CardRequest){
cardClient.approveOrder(request: cardRequest)
}
}Set up your CardDelegate to handle successful payments, errors, cancellations, and 3D Secure transaction flows.
extension MyViewController:CardDelegate{
func setupCardClient(){
cardClient.delegate= self
}
// MARK: - CardDelegate
func card(_ cardClient:CardClient, didFinishWithResult result:CardResult){
// Order was approved and is ready to be captured/authorized (refer to the next step)
}
func card(_ cardClient:CardClient, didFinishWithError error:CoreSDKError){
// handle the error by accessing `error.localizedDescription`
}
func cardDidCancel(_ cardClient:CardClient){
// 3D Secure auth was canceled by the user
}
func cardThreeDSecureWillLaunch(_ cardClient:CardClient){
// 3D Secure auth will launch
}
func cardThreeDSecureDidFinish(_ cardClient:CardClient){
// 3D Secure auth did finish successfully
}
}Submit your ORDER_ID for authorization or capture when the PayPal iOS SDK calls the didFinishWithResult method.
Call the authorize endpoint of the Orders V2 API to place the money on hold:
curl --location --request POST 'https://api-m.sandbox.paypal.com/v2/checkout/orders/ORDER_ID/authorize' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
--data-raw ''Call the capture endpoint of the Orders V2 API to capture the money immediately:
curl --location --request POST 'https://api-m.sandbox.paypal.com/v2/checkout/orders/ORDER_ID/capture' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
--data-raw ''Before going live, test your integration in the sandbox environment.
Learn more about the following resources on the Card Testing page:
Note: Use the credit card generator to generate additional test credit cards for sandbox testing.
When prompted for required data for the sandbox business request, such as a phone number, enter any number that fits the required format. Because this is a sandbox request, the data doesn't have to be factual.
Before you go live, you'll need to complete live onboarding to be eligible to process cards with your live PayPal account.
After you integrate a payment method, add a payment button to your page to start the payment process. You can also add fraud protection to your app.
The PaymentButtons module provides a set of PayPal-branded buttons to seamlessly integrate with PayPal web and native payments.
Follow these steps to add PayPal buttons to your integration:
Add the PaymentButtons package dependency for your app using Swift Package Manager or CocoaPods:
https://github.com/paypal/paypal-ios/ as the repository URL.PaymentButtons framework.Include PayPal/PaymentButtons in your Podfile:
# Podfile
pod 'PayPal/PaymentButtons'The PaymentButtons module provides 3 buttons that you can use in your application:
PayPalButton: A generic PayPal button.PayPalPayLater: A PayPal button with a PayLater label.PayPalCredit: A PayPal button with the PayPalCredit logo.These buttons include customization options such as color, shape, size, and labels. Here's how to style the button corner radius:
| Value | Description | Button |
|---|---|---|
rectangle | Button shape with sharp corners. | |
rounded | Recommended Button shape with rounded corner radius. The default button shape. | |
pill | Button in pill shape. | |
custom(CGFloat) | Customize the button's corner radius. The minimum value is 10 px and is applied to all 4 corners. |
Add buttons using either UKit or SwiftUI as follows:
class MyViewController: UIViewController {
lazy var payPalButton: PayPalButton = {
let payPalButton = PayPalButton()
payPalButton.addTarget(self, action: #selector(payPalButtonTapped), for: .touchUpInside)
return payPalButton
}()
@objc func payPalButtonTapped() {
// Insert your code here
}
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(payPalButton)
}
}struct MyApp: View {
@ViewBuilder
var body: some View {
VStack {
PayPalButton.Representable() {
// Insert your code here
}
}
}
}If you have fulfilled the requirements for accepting Advanced Credit and Debit Card Payments for your business account, review the Move your app to production page to learn how to test and go live.
If this is your first time testing in a live environment, follow these steps:
Important: The code for the integration checks eligibility requirements, so the payment card fields only display when the production request is successful.