# Save PayPal with the iOS SDK (/sdk/ios/save-with-purchase/paypal)



Allow customers to save their PayPal Wallet in order to eliminate the need to
re-enter payment details on subsequent purchases - leading to a faster
checkout experience.

> **Note:** **Important:** Don't save PayPal as a payment method during purchase. For more information about securely saving payment methods and optimizing the buyer experience, see our [Best practices guide](/platforms/checkout/standard/best-practices/).

Customers with a PayPal Wallet can:

* Review PayPal transactions and transaction history
* Review, add, or remove funding sources
* Review and cancel recurring payments
* Hold a balance in their PayPal account
* Use PayPal to send and receive money
* Withdraw money to a linked bank account
* Use PayPal to transact with merchants

## Use cases [#use-cases]

Businesses save payment methods if they want customers to:

* Check out without re-entering a payment method
* Pay after use, for example, ride-sharing and food delivery

## Availability [#availability]

### See supported countries [#see-supported-countries]

* Australia
* Austria
* Belgium
* Bulgaria
* Canada
* China
* Cyprus
* Czech Republic
* Denmark
* Estonia
* Finland
* France
* Germany
* Hong Kong
* Hungary
* Ireland
* Italy
* Japan
* Latvia
* Liechtenstein
* Lithuania
* Luxembourg
* Malta
* Netherlands
* Norway
* Poland
* Portugal
* Romania
* Singapore
* Slovakia
* Slovenia
* Spain
* Sweden
* United Kingdom
* United States

## Check eligibility [#check-eligibility]

1. Go to [paypal.com](https://www.paypal.com) and sign in with your business account.
2. Go to **Account Settings** > **Payment Preferences** > **Save PayPal and Venmo payment methods**.
3. In the Save PayPal and Venmo payment methods section, select **Get Started**.
4. When you submit profile details, PayPal reviews your eligibility to save PayPal Wallets.
5. After PayPal reviews your eligibility, you'll see a status of **Success**, **Need more information**, or **Denied**.

## How it works [#how-it-works]

PayPal encrypts payment method information and stores it in a digital vault
for that customer.

1. Create an order with a PayPal payment source.
2. Present PayPal Web Checkout to the payer using the PayPal SDK.
3. After the payer completes PayPal Web Checkout, capture or authorize the order.
4. On success, store the PayPal-generated customer ID and Payment Token found in the capture or authorize response in your server-side database for future reference.
5. When a customer returns to your app and is ready to check out, use the PayPal-generated payment token as a payment source when creating an order.

The checkout process for returning payers can now be made shorter by using
saved payment information.

## Know before you code [#know-before-you-code]

* This integration requires a PayPal Developer account.
* This procedure modifies an existing [standard payments](/platforms/checkout/standard/) or [advanced credit and debit card payments](/platforms/checkout/advanced/) integration.
* Your payments integration must have a [server-side capture call](/api/orders/v2/orders-capture) or a [server-side authorization and capture call](/api/orders/v2/orders-capture).
* To save payment methods, you must be able to uniquely identify payers. For example, payers create an account and log in to your site.
* Complete the steps in [Get started](/api/rest/) to get the following sandbox account information from the Developer Dashboard:
  * Your sandbox account login information
  * Your access token

## 1. Set up sandbox to save payment methods [#1-set-up-sandbox-to-save-payment-methods]

Set up your sandbox and live business accounts to save payment methods:

1. Log in to the Developer Dashboard.
2. Under **REST API apps**, select your app name.
3. Under **Sandbox App Settings** > **App Feature Options**, check **Accept payments**.
4. Expand **Advanced options**. Confirm that **Vault** is selected.

To go live, you'll need to be vetted for PayPal Wallet. You can start the
vetting process from the Merchant Servicing Dashboard.

* Only your sandbox business account is enabled for vaulting payment methods. Your developer account remains unaffected.
* You'll complete production onboarding when you're ready to go live.

> **Note:** **Tip:** When prompted for data such as a phone number for the
> sandbox business request, enter any number that fits the required format.
> Since this is a sandbox request, the data doesn't have to be factual.

## 2. Add a button to initiate a transaction [#2-add-a-button-to-initiate-a-transaction]

Add a button to your app's UI to complete a purchase with PayPal:

<div className="pl-[1.625rem]" />

```javascript lineNumbers
PayPalButton.Representable(){
// Create order server-side (see next step)
}
```

## 3. Create an order [#3-create-an-order]

Set up your server to call the Orders API. Set the
`payment_source` to `paypal` and request vaulting of the
payment source when the transaction completes successfully.

### Create order request [#create-order-request]

Modify the following request to create an order and initiate a vault for a
PayPal payment source:

<div className="pl-[1.625rem]" />

```bash lineNumbers
curl -v -X POST https://api-m.sandbox.paypal.com/v2/checkout/orders/ \\
 -H "Content-Type: application/json"\\
 -H "Authorization: Bearer ACCESS-TOKEN"\\
 -H "PayPal-Request-Id: REQUEST-ID"\\
 -d '{
    "intent": "CAPTURE",
    "purchase_units": [{
      "amount": {
        "currency_code": "USD",
        "value": "100.00"
      }
    }],
    "payment_source": {
      "paypal": {
        "attributes": {
          "vault": {
            "store_in_vault": "ON_SUCCESS",
            "usage_type": "MERCHANT",
            "customer_type": "CONSUMER"
          }
        },
      }
    }
  }'
```

### Create order response [#create-order-response]

Return the `id` to your client to call the payer approval flow if
the `payment_source` needs payer approval.

> **Note:** **Note:** The request to save a PayPal payment source is made
> when an order is created with the
> `payment_source.attributes.vault.store_in_vault` property set to
> `true`. Vault details are available only after an order is
> authorized or captured.

<div className="pl-[1.625rem]" />

```json lineNumbers
{
  "id": "5O190127TN364715T",
  "status": "PAYER_ACTION_REQUIRED",
  "payment_source": {
    "paypal": {}
  },
  "links": [
    {
      "href": "https://api-m.sandbox.paypal.com/v2/checkout/orders/5O190127TN364715T",
      "rel": "self",
      "method": "GET"
    },
    {
      "href": "https://www.paypal.com/checkoutnow?token=5O190127TN364715T",
      "rel": "payer-action",
      "method": "GET"
    }
  ]
}
```

## 4. Start PayPal Web Checkout [#4-start-paypal-web-checkout]

Locate the `id` property in the Orders API response JSON. This is
the Order ID.

Send `orderId` to the iOS SDK to allow it to start PayPal Web
Checkout:

<div className="pl-[1.625rem]" />

```javascript lineNumbers
func startPayPalVaultDuringPurchase(){
let order =myCreateOrderFunc(amount:10.00,vaultPaymentMethodOnSuccess:true)
let config =CoreConfig(clientID:"CLIENT_ID",environment:.live)
let payPalClient =PayPalWebCheckoutClient(config: config)
  payPalClient.delegate= self
let payPalRequest =PayPalWebCheckoutRequest(orderID: order.id,fundingSource:.paypal)
  payPalWebCheckoutClient.start(request: payPalRequest)
}
func payPal(
_ payPalClient:PayPalWebCheckoutClient,
  didFinishWithResult result:PayPalWebCheckoutResult
){
// After the payer approves, authorize or capture the transaction on your server (see next step)
}
func payPal(
_ payPalClient:PayPalWebCheckoutClient,
  didFinishWithError error:CoreSDKError
){
// Handle error
}
func payPalDidCancel(_ payPalClient:PayPalWebCheckoutClient){
// PayPal Checkout cancelled
}
```

## 5. Authorize or capture order [#5-authorize-or-capture-order]

After the payer approves, do one of the following on your server:

* Capture the order using the Orders API if the `intent` passed to create the order was `CAPTURE`
* Authorize the order using the Orders API if the `intent` passed to create the order was `AUTHORIZE`

When capture or authorization succeeds, a `vault.id` is created.

### Authorize order request [#authorize-order-request]

<div className="pl-[1.625rem]" />

```bash lineNumbers
curl -v -X POST https://api-m.sandbox.paypal.com/v2/checkout/orders/5O190127TN364715T/authorize \\
 -H "Content-Type: application/json"\\
 -H "Authorization: Bearer ACCESS-TOKEN"\\
 -d '{}'
```

### Capture order request [#capture-order-request]

<div className="pl-[1.625rem]" />

```bash lineNumbers
curl -v -X POST https://api-m.sandbox.paypal.com/v2/checkout/orders/5O190127TN364715T/capture \\
 -H "Content-Type: application/json"\\
 -H "Authorization: Bearer ACCESS-TOKEN"\\
 -d '{}'
```

### Capture order response [#capture-order-response]

The HTTP response codes `HTTP 2xx` or `HTTP 200` are
returned for a successful request.

The capture is successful if the
`purchase_units[0].payments.captures.status` is
`COMPLETED`. You can confirm with the payer that the payment has
been captured.

In the response from the authorize or capture request, the Orders v2 API
interacts with the Payment Method Tokens v3 API. The Payment Method Tokens v3
API allows a PayPal Wallet to be saved. The response from the Orders v2 API
contains the:

* `vault.id`
* `customer.id`
* `vault.status`
* `links` for the payment token of a recently saved PayPal Wallet.

#### Capture order [#capture-order]

<div className="pl-[1.625rem]" />

```json lineNumbers
{
"id":"5O190127TN364715T",
"status":"COMPLETED",
"payment_source":{
"paypal":{
"attribute":{
"vault":{
"id":"3nqvjt3n",
"customer":{
"id":"208743798"
},
"status":"VAULTED",
"links":[{
"href":"https://api-m.sandbox.paypal.com/v3/vault/payment-tokens/3nqvjt3n",
"rel":"self",
"method":"GET"
},
{
"href":"https://api-m.sandbox.paypal.com/v3/vault/payment-tokens/3nqvjt3n",
"rel":"delete",
"method":"DELETE"
},
{
"href":"https://api-m.sandbox.paypal.com/v2/checkout/orders/5O190127TN364715T",
"rel":"up",
"method":"GET"
}
]
}
},
"name":{
"given_name":"Firstname",
"surname":"Lastname"
},
"email_address":"customer@example.com",
"phone_number":{
"national_number":"2025212022"
},
"account_id":"QYR5Z8XDVJNXQ",
"address":{
"country_code":"US"
},
}
},
"payer":{
"name":{
"given_name":"Firstname",
"surname":"Lastname"
},
"email_address":"customer@example.com",
"phone_number":{
"national_number":"2025212022"
},
"payer_id":"QYR5Z8XDVJNXQ",
"address":{
"country_code":"US"
}
}
"purchase_units":[{
"reference_id":"d9f80740-38f0-11e8-b467-0ed5f89f718b",
"payments":{
"captures":[{
"id":"3C679366HH908993F",
"status":"COMPLETED",
"amount":{
"currency_code":"USD",
"value":"100.00"
},
"seller_protection":{
"status":"ELIGIBLE",
"dispute_categories":[
"ITEM_NOT_RECEIVED",
"UNAUTHORIZED_TRANSACTION"
]
},
"final_capture":true,
"seller_receivable_breakdown":{
"gross_amount":{
"currency_code":"USD",
"value":"100.00"
},
"paypal_fee":{
"currency_code":"USD",
"value":"3.00"
},
"net_amount":{
"currency_code":"USD",
"value":"97.00"
}
},
"create_time":"2022-01-01T21:20:49Z",
"update_time":"2022-01-01T21:20:49Z",
"links":[{
"href":"https://api-m.sandbox.paypal.com/v2/payments/captures/3C679366HH908993F",
"rel":"self",
"method":"GET"
},
{
"href":"https://api-m.sandbox.paypal.com/v2/payments/captures/3C679366HH908993F/refund",
"rel":"refund",
"method":"POST"
}
]
}]
}
}],
"links":[{
"href":"https://api-m.sandbox.paypal.com/v2/checkout/orders/5O190127TN364715T",
"rel":"self",
"method":"GET"
}]
}
```

#### Save approved payment source [#save-approved-payment-source]

If the payment has been authorized or captured, the payer does not need to be
present to save a `payment_source`. To keep checkout times as short
as possible, the Orders API responds as soon as payment is captured.

If the `attributes.vault.status` returned after payment is
`APPROVED`, you won't have a `vault.id` yet. An example
of the `attributes` object from this scenario is in the following
sample:

<div className="pl-[1.625rem]" />

```json lineNumbers
"attributes":{
"vault":{
"status":"APPROVED",
"links":[
{
"href":"https://api-m.sandbox.paypal.com/v2/checkout/orders/5O190127TN364715T",
"rel":"up",
"method":"GET"
}
]
}
}
```

The Payment Method Tokens API still saves the payment source even after the
Orders API returns its response and sends a webhook after the payment source
is saved.

In order to retrieve a `vault_id` when an
`APPROVED` status is returned, you'll need to subscribe to the
`VAULT.PAYMENT-TOKEN.CREATED`
[webhook](/api/rest/webhooks/).

The Payment Method Tokens API sends a webhook after the payment source is
saved. An example of the `VAULT.PAYMENT-TOKEN.CREATED` webhook
payload is shown in the following sample:

<div className="pl-[1.625rem]" />

```json lineNumbers
{
  "id": "WH-72S4353495632143A-68K769747M133873M",
  "event_version": "1.0",
  "create_time": "2022-08-27T01:25:57.462Z",
  "resource_type": "payment_token",
  "resource_version": "3.0",
  "event_type": "VAULT.PAYMENT-TOKEN.CREATED",
  "summary": "A payment token has been created.",
  "resource": {
    "time_created": "2022-08-26T18:25:57.449PDT",
    "links": [
      {
        "href": "https://api-m.sandbox.paypal.com/v3/vault/payment-tokens/7vrxmrw",
        "rel": "self",
        "method": "GET",
        "encType": "application/json"
      },
      {
        "href": "https://api-m.sandbox.paypal.com/v3/vault/payment-tokens/7vrxmrw",
        "rel": "delete",
        "method": "DELETE",
        "encType": "application/json"
      }
    ],
    "id": "3nqvjt3n",
    "payment_source": {
      "paypal": {
        "permit_multiple_payment_tokens": false,
        "usage_type": "MERCHANT",
        "customer_type": "CONSUMER",
        "email_address": "email@example.com",
        "payer_id": "VTR4JYK7STE7J"
      }
    },
    "customer": {
      "id": "208743798"
    }
  },
  "links": [
    {
      "href": "https://api-m.sandbox.paypal.com/v1/notifications/webhooks-events/WH-72S4353495632143A-68K769747M133873M",
      "rel": "self",
      "method": "GET"
    },
    {
      "href": "https://api-m.sandbox.paypal.com/v1/notifications/webhooks-events/WH-72S4353495632143A-68K769747M133873M/resend",
      "rel": "resend",
      "method": "POST"
    }
  ]
}
```

In the previous example, the `resource.id` field is the vault ID.
The `resource.customer.id` is the PayPal-generated customer ID.

## 6. Test your integration [#6-test-your-integration]

Run the following tests in the PayPal sandbox to ensure you can save PayPal
Wallets.

### Save payment method [#save-payment-method]

1. In your app, initiate a transaction by selecting the PayPal button.
2. Log in to the payer account and complete PayPal Web Checkout.
3. Capture the transaction.
4. Store the PayPal-generated customer ID in your system.
5. Log in to [sandbox](https://www.sandbox.paypal.com/) with your merchant account and verify the transaction.
6. Return to your app and initiate another transaction. Use the PayPal-generated payment token as a payment source.
7. Verify that the transaction captures successfully without having to complete PayPal Web Checkout again.

## Next steps [#next-steps]

* [Test and go live](/reference/production/) with this integration.
* Change the credentials and API URLs from `api-m.sandbox.paypal.com` to `api-m.paypal.com` when going live with your integration.
* You can [create orders](/api/orders/v2/orders-create) without the `payment_source.paypal.attributes.vault` for subsequent or recurring transactions.
* You can [get a payment token](/api/payment-tokens/v3/payment-tokens-get), [list all payment tokens](/api/payment-tokens/v3/customer-payment-tokens-get), [delete a payment token](/api/payment-tokens/v3/payment-tokens-delete), and more with the Payment Method Tokens API.
