# Save PayPal with the Payment Method Tokens API (/api/payment-tokens/save-without-purchase/paypal)

Save a PayPal Wallet to the vault with the Payment Method Tokens v3 API, no purchase required.



No transaction is required when payment methods are saved with the [Payment Method Tokens API](/api/payment-tokens/v3). You can charge payers after a set amount of time. Payers don't need to be present when charged. A common use case is offering a free trial and charging payers after the trial expires.

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

## Availability [#availability]

Saving PayPal with the Payment Method Tokens API is available in the following countries and territories.

<CountryAvailabilityCheck
  regions="[
  {
    name: &#x22;Americas&#x22;,
    countries: [&#x22;Canada&#x22;, &#x22;United States&#x22;],
  },
  {
    name: &#x22;Asia&#x22;,
    countries: [&#x22;China&#x22;, &#x22;Hong Kong&#x22;, &#x22;Japan&#x22;, &#x22;Singapore&#x22;],
  },
  {
    name: &#x22;Europe&#x22;,
    countries: [
      &#x22;Austria&#x22;,
      &#x22;Belgium&#x22;,
      &#x22;Bulgaria&#x22;,
      &#x22;Cyprus&#x22;,
      &#x22;Czech Republic&#x22;,
      &#x22;Denmark&#x22;,
      &#x22;Estonia&#x22;,
      &#x22;Finland&#x22;,
      &#x22;France&#x22;,
      &#x22;Germany&#x22;,
      &#x22;Hungary&#x22;,
      &#x22;Ireland&#x22;,
      &#x22;Italy&#x22;,
      &#x22;Latvia&#x22;,
      &#x22;Liechtenstein&#x22;,
      &#x22;Lithuania&#x22;,
      &#x22;Luxembourg&#x22;,
      &#x22;Malta&#x22;,
      &#x22;Netherlands&#x22;,
      &#x22;Norway&#x22;,
      &#x22;Poland&#x22;,
      &#x22;Portugal&#x22;,
      &#x22;Romania&#x22;,
      &#x22;Slovakia&#x22;,
      &#x22;Slovenia&#x22;,
      &#x22;Spain&#x22;,
      &#x22;Sweden&#x22;,
      &#x22;United Kingdom&#x22;,
    ],
  },
  {
    name: &#x22;Oceania&#x22;,
    countries: [&#x22;Australia&#x22;],
  },
]"
/>

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

* This server-side integration uses the [Payment Method Tokens API](/api/payment-tokens/v3).
* The Payment Method Tokens API supports saving cards and PayPal Wallets.
* 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
* You must be approved and have your account configured for billing agreements to set up a reference transaction. Contact your account manager for details.

## 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 and Venmo accounts.
5. After PayPal reviews your eligibility, you'll see a status of **Success**, **Need more information**, or **Denied**.

## 1. Set up your account to save payments [#1-set-up-your-account-to-save-payments]

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.

## 2. Create a setup token to save PayPal Wallet [#2-create-a-setup-token-to-save-paypal-wallet]

The payer must authenticate and approve the creation of a billing agreement. Then you can create a setup token to save PayPal as a payment method.

The initial `POST` on `setup-tokens` completes the following actions:

* Returns a `PAYER_ACTION_REQUIRED` status
* Creates a temporary setup token
* Redirects to the `approve` URL

When saving a payer's PayPal Wallet for first time, the response to the `setup-token` request returns the PayPal-generated `customer.id` and the `setup_token_id`.

> **Info:** **Tip:** For a payer with previously-stored `payment_sources`, pass the `customer.id` in the `setup-token` request. This links additional `payment_sources` to the payer.

You can store a Merchant Customer ID aligned with your system to simplify the mapping of customer information within your system and PayPal when creating a setup token. This is an optional field that will return the value shared in the response.

To create a setup token for PayPal that triggers a payer action, copy and modify the following code:

```bash lineNumbers
curl -v -k -X POST 'https://api-m.sandbox.paypal.com/v3/vault/setup-tokens' \
 -H "Content-Type: application/json" \
 -H "Authorization: Bearer ACCESS-TOKEN" \
 -H "PayPal-Request-Id: REQUEST-ID" \
 -d '{
      "payment_source": {
          "paypal": {
              "description": "Description for PayPal to be shown to PayPal payer",
              "shipping": {
                  "name": {
                      "full_name": "Firstname Lastname"
                  },
                  "address": {
                      "address_line_1": "2211 N First Street",
                      "address_line_2": "Building 17",
                      "admin_area_2": "San Jose",
                      "admin_area_1": "CA",
                      "postal_code": "95131",
                      "country_code": "US"
                  }
              },
              "permit_multiple_payment_tokens": false,
              "usage_pattern": "IMMEDIATE",
              "usage_type": "MERCHANT",
              "customer_type": "CONSUMER",
              "experience_context": {
                  "shipping_preference": "SET_PROVIDED_ADDRESS",
                  "payment_method_preference":    "IMMEDIATE_PAYMENT_REQUIRED",
                  "brand_name": "EXAMPLE INC",
                  "locale": "en-US",
                  "return_url": "https://example.com/returnUrl",
                  "cancel_url": "https://example.com/cancelUrl"
              }
          }
      }
  }'
```

### Modify the code [#modify-the-code]

1. Copy the code sample.
2. Change `ACCESS-TOKEN` to your [sandbox access token](/api/rest/authentication).
3. Change `REQUEST-ID` to a set of unique alphanumeric characters such as a timestamp.
4. Use PayPal as the `payment_source`. Complete the rest of the source object for your use case and business.
5. Update the `return_url` value with the URL where the payer is redirected after they approve the flow.
6. Update the `cancel_url` value with the URL where the payer is redirected after they cancel the flow.

### Step result [#step-result]

A successful request results in the following:

* An HTTP response code of `200` or `201`. Returns `200` for an idempotent request.
* A status of `PAYER_ACTION_REQUIRED`.
* HATEOAS links:

| Rel       | Method | Description                                                                                                |
| --------- | ------ | ---------------------------------------------------------------------------------------------------------- |
| `approve` | `GET`  | Use this link to take your payer through a PayPal-hosted approval flow.                                    |
| `confirm` | `POST` | Make a POST request to use an approved setup token to save the PayPal Wallet and generate a payment token. |
| `self`    | `GET`  | Make a GET request to view the state of your setup token and payment method details.                       |

### Sample API response [#sample-api-response]

```javascript lineNumbers
{
  "id": "4G4976650J0948357",
  "customer": {
    "id": "customer_4029352051"
  },
  "status": "PAYER_ACTION_REQUIRED",
  "payment_source": {
    "paypal": {
      "description": "Description for PayPal to be shown to PayPal payer",
      "usage_pattern": "IMMEDIATE",
      "shipping": {
        "name": {
          "full_name": "Firstname Lastname"
        },
        "address": {
          "address_line_1": "2211 N First Street",
          "address_line_2": "Building 17",
          "admin_area_2": "San Jose",
          "admin_area_1": "CA",
          "postal_code": "95131",
          "country_code": "US"
        }
      },
      "permit_multiple_payment_tokens": false,
      "usage_type": "MERCHANT",
      "customer_type": "CONSUMER"
    }
  },
  "links": [
    {
      "href": "https://api-m.sandbox.paypal.com/v3/vault/setup-tokens/4G4976650J0948357",
      "rel": "self",
      "method": "GET",
      "encType": "application/json"
    },
    {
      "href": "https://sandbox.paypal.com/agreements/approve?approval_session_id=4G4976650J0948357",
      "rel": "approve",
      "method": "GET",
      "encType": "application/json"
    }
  ]
}
```

By default, the setup token expires after 3 days. After the payer completes the approval flow, you can upgrade the setup token to a full payment method token by calling [create-payment-tokens](/api/payment-tokens/v3/payment-tokens-create).

## 3. Create payment token [#3-create-payment-token]

You can store a Merchant Customer ID aligned with your system to simplify the mapping of customer information within your system and PayPal when creating a payment token. This is an optional field that will return the value shared in the response.

Use an approved setup token to save the payer's payment method to the vault. Then, copy the sample request code to generate a payment token:

### Sample API request [#sample-api-request]

```bash lineNumbers
curl -v -k -X POST 'https://api-m.sandbox.paypal.com/v3/vault/payment-tokens' \
 -H "Content-Type: application/json" \
 -H "Authorization: Bearer ACCESS-TOKEN" \
 -H "PayPal-Request-Id: REQUEST-ID" \
 -d '{
      "payment_source": {
          "token": {
              "id": "4G4976650J0948357",
              "type": "SETUP_TOKEN"
          }
      }
  }'
```

### Modify the code [#modify-the-code-1]

1. Copy the code sample.
2. Change `ACCESS-TOKEN` to your sandbox access token.
3. Change `REQUEST-ID` to a unique alphanumeric set of characters such as a time stamp.
4. Use `token` as the `payment source` and complete the rest of the source object for your use case and business.
5. Use your setup token ID to pass in the payment source parameter and `type` as the `SETUP_TOKEN`.

### Step result [#step-result-1]

A successful request results in the following:

* An HTTP response code of `200` or `201`. Returns `200` for an idempotent request.
* `ID` of the payment token and associated payment method information.
* HATEOAS links:

| Rel      | Method   | Description                                                                      |
| -------- | -------- | -------------------------------------------------------------------------------- |
| `self`   | `GET`    | Make a GET request to this link to retrieve data about the saved payment method. |
| `delete` | `DELETE` | Make a DELETE request to delete the payment token.                               |

### Sample API response [#sample-api-response-1]

```javascript lineNumbers
{
  "id": "jwgvx42",
  "customer": {
    "id": "customer_4029352051"
  },
  "payment_source": {
    "paypal": {
      "description": "Description for PayPal to be shown to PayPal payer",
      "usage_pattern": "IMMEDIATE",
      "shipping": {
        "name": {
          "full_name": "Firstname Lastname"
        },
        "address": {
          "address_line_1": "2211 N First Street",
          "address_line_2": "Building 17",
          "admin_area_2": "San Jose",
          "admin_area_1": "CA",
          "postal_code": "95131",
          "country_code": "US"
        }
      },
      "permit_multiple_payment_tokens": false,
      "usage_type": "MERCHANT",
      "customer_type": "CONSUMER",
      "email_address": "email@example.com",
      "payer_id": "AJM9JTWQJCFTA"
    }
  },
  "links": [
    {
      "rel": "self",
      "href": "https://api-m.sandbox.paypal.com/v3/vault/payment-tokens/jwgvx42",
      "method": "GET",
      "encType": "application/json"
    },
    {
      "rel": "delete",
      "href": "https://api-m.sandbox.paypal.com/v3/vault/payment-tokens/jwgvx42",
      "method": "DELETE",
      "encType": "application/json"
    }
  ]
}
```

## 4. Use saved payment token [#4-use-saved-payment-token]

After you create a payment method token, use the token instead of the payment method to create a purchase and capture the payment with the Orders API.

You can store a Merchant Customer ID aligned with your system to simplify the mapping of customer information within your system and PayPal. This is an optional field that will return the value shared in the response.

Set the `payment_source` to specify the payment source type. Set the `vault_id` to the payment method token you received.

### Sample API request with payment token associated with PayPal account [#sample-api-request-with-payment-token-associated-with-paypal-account]

Copy the following code sample and modify it.

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

### Modify the code [#modify-the-code-2]

1. Copy the code sample.
2. Change `ACCESS-TOKEN` to your [sandbox access token](/api/rest/authentication).
3. Change `REQUEST-ID` to a set of unique alphanumeric characters such as a time stamp.
4. Use the ID of your payment method token as the `vault_id`.

### Sample API response [#sample-api-response-2]

```javascript lineNumbers
{
  "id": "4TH21426N05692944",
  "status": "COMPLETED",
  "payment_source": {
    "paypal": {
      "email_address": "email@example.com",
      "account_id": "AJM9JTWQJCFTA",
      "name": {
        "given_name": "Firstname",
        "surname": "Lastname"
      },
      "address": {
        "country_code": "US"
      }
    }
  },
  "purchase_units": [
    {
      "reference_id": "default",
      "payments": {
        "captures": [
          {
            "id": "3B017991HX624902V",
            "status": "COMPLETED",
            "amount": {
              "currency_code": "USD",
              "value": "100.00"
            },
            "final_capture": true,
            "seller_protection": {
              "status": "ELIGIBLE",
              "dispute_categories": [
                "ITEM_NOT_RECEIVED",
                "UNAUTHORIZED_TRANSACTION"
              ]
            },
            "seller_receivable_breakdown": {
              "gross_amount": {
                "currency_code": "USD",
                  "value": "100.00"
                },
              "paypal_fee": {
                "currency_code": "USD",
                "value": "3.98"
              },
              "net_amount": {
                "currency_code": "USD",
                "value": "96.02"
              }
            },
            "links": [
              {
                "href": "https://api-m.sandbox.paypal.com/v2/payments/captures/3B017991HX624902V",
                "rel": "self",
                "method": "GET"
              },
              {
                "href": "https://api-m.sandbox.paypal.com/v2/payments/captures/3B017991HX624902V/refund",
                "rel": "refund",
                "method": "POST"
              },
              {
                "href": "https://api-m.sandbox.paypal.com/v2/checkout/orders/4TH21426N05692944",
                "rel": "up",
                "method": "GET"
              }
            ],
            "create_time": "2022-08-08T23:13:35Z",
            "update_time": "2022-08-08T23:13:35Z"
          }
        ]
      }
    }
  ],
  "payer": {
    "name": {
      "given_name": "Firstname",
      "surname": "Lastname"
    },
    "email_address": "email@example.com",
    "payer_id": "AJM9JTWQJCFTA",
    "address": {
        "country_code": "US"
    }
  },
  "links": [
    {
      "href": "https://api-m.sandbox.paypal.com/v2/checkout/orders/4TH21426N05692944",
      "rel": "self",
      "method": "GET"
    }
  ]
}
```

## Use payment token on behalf of payer [#use-payment-token-on-behalf-of-payer]

When the payer isn't present to check out, you can use the payment method token to create an order on behalf of the payer.

### 1. Retrieve a payer's payment method token [#1-retrieve-a-payers-payment-method-token]

If you stored the payment token the payer created on your site, skip this step.

To make a payment on behalf of the payer, retrieve the payment token they created. You'll need the customer ID that you assigned to this payer when saving the payment method.

### Sample API request [#sample-api-request-1]

**API endpoint used:** [Payment tokens](/api/payment-tokens/v3)

```bash lineNumbers
curl -v -k -X GET 'https://api-m.sandbox.paypal.com/v3/vault/payment-tokens?customer_id=customer_4029352051' \
 -H 'Authorization: Bearer ACCESS-TOKEN' \
 -H 'Content-Type: application/json'
```

### Modify the code [#modify-the-code-3]

1. Copy the code sample.
2. Change `ACCESS-TOKEN` to your [sandbox access token](/api/rest/authentication).
3. Pass the PayPal-generated `customer.id` to retrieve the payment token details associated with the payer.
4. If stored in the payment token, the response will return the Merchant Customer ID.

### Sample response [#sample-response]

```javascript lineNumbers
{
  "customer": {
    "id": "customer_4029352051"
  },
  "payment_tokens": [
    {
      "id": "jwgvx42",
      "customer": {
        "id": "customer_4029352051"
      },
      "payment_source": {
        "paypal": {
          "description": "Description for PayPal to be shown to PayPal payer",
          "shipping": {
            "name": {
              "full_name": "Firstname Lastname"
            },
            "address": {
              "address_line_1": "2211 N First Street",
              "address_line_2": "Building 17",
              "admin_area_2": "San Jose",
              "admin_area_1": "CA",
              "postal_code": "95131",
              "country_code": "US"
            }
          },
          "usage_type": "MERCHANT",
          "customer_type": "CONSUMER",
          "name": {
            "given_name": "Firstname",
            "surname": "Lastname",
            "full_name": "Firstname Lastname"
          },
          "email_address": "email@example.com",
          "payer_id": "AJM9JTWQJCFTA",
          "phone": {
            "phone_number": {
              "country_code": "US",
              "national_number": "408-208-9263"
            }
          }
        }
      },
      "links": [
        {
          "rel": "self",
          "href": "https://api-m.sandbox.paypal.com/v3/vault/payment-tokens/jwgvx42",
          "method": "GET",
          "encType": "application/json"
        },
        {
          "rel": "delete",
          "href": "https://api-m.sandbox.paypal.com/v3/vault/payment-tokens/jwgvx42",
          "method": "DELETE",
          "encType": "application/json"
        }
      ]
    }
  ],
  "links": [
    {
      "rel": "self",
      "href": "https://api-m.sandbox.paypal.com/v3/vault/payment-tokens?customer_id=customer_4029352051&page=1&page_size=5&total_required=false",
      "method": "GET",
      "encType": "application/json"
    },
    {
      "rel": "first",
      "href": "https://api-m.sandbox.paypal.com/v3/vault/payment-tokens?customer_id=customer_4029352051&page=1&page_size=5&total_required=false",
      "method": "GET",
      "encType": "application/json"
    },
    {
      "rel": "last",
      "href": "https://api-m.sandbox.paypal.com/v3/vault/payment-tokens?customer_id=customer_4029352051&page=1&page_size=5&total_required=false",
      "method": "GET",
      "encType": "application/json"
    }
  ]
}
```

### Step result [#step-result-2]

A successful request results in the following:

1. An HTTP response code of `200 OK`.
2. Payment method details and status for the provided payment token.
3. HATEOAS links:

| Rel      | Method   | Description                                                                      |
| -------- | -------- | -------------------------------------------------------------------------------- |
| `self`   | `GET`    | Make a GET request to this link to retrieve data about the saved payment method. |
| `delete` | `DELETE` | Make a DELETE request to delete the payment token from the vault.                |

### 2. Use payment method token with checkout [#2-use-payment-method-token-with-checkout]

After you get the payment method token ID, you can use a payment method token with checkout to create your order with the [Orders v2 API](/api/orders/v2).

```bash lineNumbers
curl -v -k -X POST 'https://api-m.sandbox.paypal.com/v2/checkout/orders' \
  -H "PayPal-Request-Id: YOUR-REQUEST-ID" \
  -H "Authorization: Bearer YOUR-ACCESS-TOKEN" \
  -H "PayPal-Client-Metadata-Id: YOUR-PAYPAL-CLIENT-METADATA-ID" \
  -H "Content-Type: application/json" \
  -d '{
       "intent": "CAPTURE",
       "purchase_units": [
         {
           "amount": {
             "currency_code": "USD",
             "value": "100.00"
           }
         }
       ],
       "payment_source": {
         "paypal": {
           "vault_id": "jwgvx42"
         }
       }
     }'
```

## Webhooks [#webhooks]

| Event                                    | Trigger                                                                                                                                  | Payment methods  |
| ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------- |
| `VAULT.PAYMENT-TOKEN.CREATED`            | A payment token is created to save a payment method.                                                                                     | Cards and PayPal |
| `VAULT.PAYMENT-TOKEN.DELETED`            | A payment token is deleted. The payer's payment method is no longer saved to the PayPal vault.                                           | Cards and PayPal |
| `VAULT.PAYMENT-TOKEN.DELETION-INITIATED` | A request to delete a payment token has been submitted to the [Payment Method Tokens API](/api/payment-tokens/v3/payment-tokens-delete). | PayPal           |

For more information on webhooks, see [webhooks](/api/rest/webhooks/).

## Next steps [#next-steps]

* [Test and go live](/api/rest/production/) with this integration.
  * Process PayPal Wallets with your live PayPal account by completing [production onboarding](https://www.paypal.com/bizsignup/entry/product/ppcp).
  * Remember to swap the credentials and API URL from sandbox to production when going live with your integration.
* 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.

## See also [#see-also]

* [Set up payment buttons](/checkout)
