Save cards with the Orders API

CurrentLast updated: April 24th 2024, @ 3:47:01 pm


After customers save their credit or debit card, they can select it for faster checkout. Customers won't have to enter payment details for future transactions.

Save cards with the Orders API if you want to save cards during checkout but aren't PCI Compliant - SAQ A.

Availability

  • 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

Know before you code

  • The Orders API supports saving PayPal and card payment methods only.
  • Passing card data to the Orders API requires you to be PCI Compliant - SAQ D.

How it works

When a payer on your website saves their payment method, PayPal creates a customer record. PayPal then encrypts the payment method information and stores it in a digital vault. The vault is accessible only by the billing agreement holder.

  1. The payer saves their payment method.
  2. For a first-time payer, PayPal creates a customer ID. Store this within your system for future use.
  3. Pass a call into the Orders API. Include the payment method, customer ID, and an indication that the payment method should be saved.
  4. If the order is processed and the payment method is saved, you receive a payment method token in the Orders API response.
  5. Pass the payment method token into the Orders API to populate the checkout page with the saved payment method.

The checkout process is now shorter because it uses saved payment information.

Check eligibility

  1. Go to 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.

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.

Server side

Set up your server to call the Create Order API. When a payer is using a card to check out, the Orders API allows you to capture the payment in a single request. In the following sample, the Authorize and Capture requests occur in a single request, and the card is stored in PayPal's vault.

Use 3D Secure authentication to reduce the likelihood of fraud and improve transaction performance with supported cards. In some countries, authorizing a card can trigger a 3D Secure contingency. 3D Secure verification may occur in PSD2 countries, including members of the EU. For 3D Secure verification, pass SCA_ALWAYS or SCA_WHEN_REQUIRED in the payment_source.card.attributes.verification.method field for the create order request. The API response returns the order status as PAYER_ACTION_REQUIRED.

Request

Create an order with a card as a payment source and store the card in the vault with 3D Secure verification when required:

1curl -v -X POST "https://api-m.sandbox.paypal.com/v2/checkout/orders/" \
2 -H "Content-Type: application/json" \
3 -H "Authorization: Bearer ACCESS-TOKEN" \
4 -d '{
5 "intent": "CAPTURE",
6 "payment_source": {
7 "card": {
8 "number": "4111111111111111",
9 "expiry": "2026-02",
10 "name": "Firstname Lastname",
11 "billing_address": {
12 "address_line_1": "2211 N First Street",
13 "address_line_2": "Building 17",
14 "admin_area_2": "San Jose",
15 "admin_area_1": "CA",
16 "postal_code": "95131",
17 "country_code": "US"
18 },
19 "attributes": {
20 "verification": {
21 "method": "SCA_WHEN_REQUIRED"
22 },
23 "vault": {
24 "store_in_vault": "ON_SUCCESS"
25 }
26 }
27 }
28 },
29 "purchase_units": [
30 {
31 "amount": {
32 "currency_code": "USD",
33 "value": "101.00"
34 }
35 }
36 ]
37}

Response

Note: Store the payment_source.card.attributes.vault.id in your database. The vault ID represents the payer's card in future transactions.

Because 3D Secure verification wasn't required in this example, the API response doesn't return PAYER_ACTION_REQUIRED as the order status.

1{
2 "id": "5O190127TN364715T",
3 "status": "COMPLETED",
4 "payment_source": {
5 "card": {
6 "last_digits": "1111",
7 "brand": "VISA",
8 "attributes": {
9 "vault": {
10 "id": "nkq2y9g",
11 "customer" : {
12 "id" = "ROaPMoZUaV"
13 },
14 "status" : "VAULTED",
15 "links": [{
16 "href": "https://api-m.sandbox.paypal.com/v3/vault/payment-tokens/7dyps8w",
17 "rel": "self",
18 "method": "GET"
19 },
20 {
21 "href": "https://api-m.sandbox.paypal.com/v3/vault/payment-tokens/7dyps8w",
22 "rel": "delete",
23 "method": "DELETE"
24 },
25 {
26 "href": "https://api-m.sandbox.paypal.com/v2/checkout/orders/5O190127TN364715T",
27 "rel": "up",
28 "method": "GET"
29 }
30 ]
31 }
32 }
33 }
34 },
35 "purchase_units": [{
36 "reference_id": "refernece_id_1001",
37 "payments": {
38 "captures": [{
39 "id": "9ET27879VC451574K",
40 "status": "COMPLETED",
41 "amount": {
42 "currency_code": "USD",
43 "value": "100.00"
44 },
45 "final_capture": true,
46 "disbursement_mode": "INSTANT",
47 "seller_protection": {
48 "status": "NOT_ELIGIBLE"
49 },
50 "seller_receivable_breakdown": {
51 "gross_amount": {
52 "currency_code": "USD",
53 "value": "100.00"
54 },
55 "paypal_fee": {
56 "currency_code": "USD",
57 "value": "3.00"
58 },
59 "net_amount": {
60 "currency_code": "USD",
61 "value": "97.00"
62 }
63 },
64 "invoice_id": "invoice_id_8L181959W1796210B",
65 "custom_id": "custom_id_1001",
66 "links": [{
67 "href": "https://api-m.sandbox.paypal.com/v2/payments/captures/9ET27879VC451574K",
68 "rel": "self",
69 "method": "GET"
70 },
71 {
72 "href": "https://api-m.sandbox.paypal.com/v2/payments/captures/9ET27879VC451574K/refund",
73 "rel": "refund",
74 "method": "POST"
75 },
76 {
77 "href": "https://api-m.sandbox.paypal.com/v2/checkout/orders/0M526810X2956752F",
78 "rel": "up",
79 "method": "GET"
80 }
81 ],
82 "create_time": "2022-05-04T21:24:00Z",
83 "update_time": "2022-05-04T21:24:00Z",
84 "processor_response": {
85 "avs_code": "A",
86 "cvv_code": "M",
87 "response_code": "0000"
88 }
89 }]
90 }
91 }],
92 "links": [{
93 "href": "https://api-m.sandbox.paypal.com/v2/checkout/orders/5O190127TN364715T",
94 "rel": "self",
95 "method": "GET"
96 }]
97 }

In the response from the Authorize or Capture request, the Orders v2 API interacts with the Vault v3 API. The Vault v3 API allows a card to be saved.

As seen previously, payment_source.card.attributes.vault has the relevant information with the vault.id (when vault.status is VAULTED) which can be used for subsequent payments.

Check Orders API response

Saving a payment source does not require the payer to be present after the payment has been authorized or captured. In order to keep checkout times as short as possible for payers, the Orders API is optimized to return a response as soon as a payment is captured.

This means that the payment may be authorized or captured, and a successful response is returned from the Orders API without the provided payment_source being vaulted. The Orders response after authorization or capture will instead return attributes.vault.status as "APPROVED", instead of "VAULTED".

An example of the attributes object from this scenario:

1"attributes": {
2 "vault": {
3 "status": "APPROVED",
4 "links": [
5 {
6 "href": "https://api-m.sandbox.paypal.com/v2/checkout/orders/5O190127TN364715T",
7 "rel": "up",
8 "method": "GET"
9 }
10 ]
11 }
12 }

Save approved payment source

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.

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:

1{
2 "id":"WH-1KN88282901968003-82E75604WM969463F",
3 "event_version":"1.0",
4 "create_time":"2022-08-15T14:13:48.978Z",
5 "resource_type":"payment_token",
6 "resource_version":"3.0",
7 "event_type":"VAULT.PAYMENT-TOKEN.CREATED",
8 "summary":"A payment token has been created.",
9 "resource":{
10 "time_created":"2022-08-15T07:13:48.964PDT",
11 "links":[
12 {
13 "href":"https://api-m.sandbox.paypal.com/v3/vault/payment-tokens/9n6724m",
14 "rel":"self",
15 "method":"GET",
16 "encType":"application/json"
17 },
18 {
19 "href":"https://api-m.sandbox.paypal.com/v3/vault/payment-tokens/9n6724m",
20 "rel":"delete",
21 "method":"DELETE",
22 "encType":"application/json"
23 }
24 ],
25 "id":"9n6724m",
26 "payment_source":{
27 "card":{
28 "last_digits":"1111",
29 "brand":"VISA",
30 "expiry":"2027-02",
31 "billing_address":{
32 "address_line_1":"2211 N First Street",
33 "address_line_2":"17.3.160",
34 "admin_area_2":"San Jose",
35 "admin_area_1":"CA",
36 "postal_code":"95131",
37 "country_code":"US"
38 }
39 }
40 },
41 "customer":{
42 "id":"695922590"
43 }
44 },
45 "links":[
46 {
47 "href":"https://api-m.sandbox.paypal.com/v1/notifications/webhooks-events/WH-1KN88282901968003-82E75604WM969463F",
48 "rel":"self",
49 "method":"GET"
50 },
51 {
52 "href":"https://api-m.sandbox.paypal.com/v1/notifications/webhooks-events/WH-1KN88282901968003-82E75604WM969463F/resend",
53 "rel":"resend",
54 "method":"POST"
55 }
56 ]
57 }

As seen previously, the resource.id field is the vault ID. The resource.customer.id is the PayPal-generated customer ID.

Next steps