Change payment methods

DocsLast updated: December 8th 2023, @ 8:10:55 am


Give your buyers the option to change the payment method for a specific transaction. For example, buyers might choose a credit card with more points or a bank account with more funds.

This page is for merchants who have a PayPal v1/billing agreements REST API billing agreement with their buyer. When changing the payment method, the buyer can select an existing payment method or add a new one.

Know before you code

  • The buyer must already have a billing agreement with the merchant before they can change their payment method. The billing agreement ID should be in your records.
  • The buyer can change the payment option only if they're present to complete the transaction.
  • This integration works for intent sale and authorize transactions.
  • This integration uses the v1/payments REST API.

How it works

The following is a sample workflow:

  1. Create a payment resource by calling the v1/payments API and passing the Billing Agreement ID in the application_context object.
  2. Get the HATEOAS URL from the response.
  3. On your website, display a hyperlink using the HATEOAS URL. Give the hyperlink a name, such as Options. You can use JavaScript to create a pop-up window when the user selects the hyperlink.
    options
    Figure 1: Checkout page with the option to change the payment method.
  4. Your buyer selects the hyperlink and changes the payment method.
  5. Your buyer proceeds with payment.

Step 1: Create a payment resource

Copy the following code and modify it.

Sample request

API endpoint used: Create payment

curl -v -X POST https://api-m.sandbox.paypal.com/v1/payments/payment\
-H "Content-Type: application/json" \
-H "Authorization: Bearer Access-Token" \
-d '{
  "intent": "sale",
  "payer": {
    "payment_method": "paypal"
  },
  "application_context": {
    "preferred_payment_source": {
      "token": {
        "id": "B-2J280200NT939550G",
        "type": "BILLING_AGREEMENT"
      }
    }
  },
  "transactions": [
    {
      "amount": {
        "total": "3.11",
        "currency": "USD",
        "details": {
          "subtotal": "3.00",
          "tax": "0.07",
          "shipping": "0.03",
          "handling_fee": "1.00",
          "shipping_discount": "-1.00",
          "insurance": "0.01"
        }
      },
      "description": "The payment transaction description.",
      "custom": "EBAY_EMS_90048630024435",
      "payment_options": {
        "allowed_payment_method": "INSTANT_FUNDING_SOURCE"
      },
      "soft_descriptor": "ECHI5786786",
      "item_list": {
        "items": [
          {
            "name": "hat",
            "description": "Brown hat.",
            "quantity": "5",
            "price": "0.3",
            "tax": "0.01",
            "sku": "1",
            "currency": "USD"
          },
          {
            "name": "handbag",
            "description": "Black handbag.",
            "quantity": "1",
            "price": "1.5",
            "tax": "0.02",
            "sku": "product34",
            "currency": "USD"
          }
        ],
        "shipping_address": {
          "recipient_name": "Brian Robinson",
          "line1": "4th Floor",
          "line2": "Unit #34",
          "city": "San Jose",
          "country_code": "US",
          "postal_code": "95131",
          "phone": "011862212345678",
          "state": "CA"
        }
      }
    }
  ],
  "note_to_payer": "Contact us for any questions on your order.",
  "redirect_urls": {
    "return_url": "https://example.com/return",
    "cancel_url": "https://example.com/cancel"
  }
}'

Modify the code

After you copy the code in the sample request, modify the following:

  • Change Access-Token to your access token.
  • Change return_url to the URL of the webpage where buyers land after completing a successful form submission.
  • Change cancel_url to the URL of the webpage where buyers land after cancelling a form submission.

Step result

A successful request returns:

  • A return status code of HTTP 201 Created.
  • A payment ID. In the sample response, the ID is PAYID-L2ZMPHI0XY83144MV337250T.
  • Multiple HATEOAS links.

Sample response

{
  "id": "PAYID-L2ZMPHI0XY83144MV337250T",
  "intent": "sale",
  "state": "created",
  "payer": {
    "payment_method": "paypal"
  },
  "application_context": {
    "preferred_payment_source": {
      "token": {
        "id": "B-02R904040B876314G",
        "type": "BILLING_AGREEMENT"
      }
    }
  },
  "transactions": [
    {
      "amount": {
        "total": "30.11",
        "currency": "USD",
        "details": {
          "subtotal": "30.00",
          "tax": "0.07",
          "shipping": "0.03",
          "insurance": "0.01",
          "handling_fee": "1.00",
          "shipping_discount": "-1.00"
        }
      },
      "description": "The payment transaction description.",
      "custom": "EBAY_EMS_90048630024435",
      "soft_descriptor": "ECHI5786786",
      "payment_options": {
        "allowed_payment_method": "INSTANT_FUNDING_SOURCE",
        "recurring_flag": false,
        "skip_fmf": false
      },
      "item_list": {
        "items": [
          {
            "name": "hat",
            "sku": "1",
            "description": "Brown hat.",
            "price": "3.00",
            "currency": "USD",
            "tax": "0.01",
            "quantity": 5
          },
          {
            "name": "handbag",
            "sku": "product34",
            "description": "Black handbag.",
            "price": "15.00",
            "currency": "USD",
            "tax": "0.02",
            "quantity": 1
          }
        ],
        "shipping_address": {
          "recipient_name": "Brian Robinson",
          "line1": "4th Floor",
          "line2": "Unit #34",
          "city": "San Jose",
          "state": "CA",
          "postal_code": "95131",
          "country_code": "US",
          "phone": "011862212345678"
        }
      },
      "related_resources": []
    }
  ],
  "note_to_payer": "Contact us for any questions on your order.",
  "create_time": "2020-05-06T14:20:13Z",
  "links": [
    {
      "href": "https://api-m.sandbox.paypal.com/v1/payments/payment/PAYID-L2ZMPHI0XY83144MV337250T",
      "rel": "self",
      "method": "GET"
    },
    {
      "href": "https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-9GB66157FY002784C",
      "rel": "approval_url",
      "method": "REDIRECT"
    },
    {
      "href": "https://api-m.sandbox.paypal.com/v1/payments/payment/PAYID-L2ZMPHI0XY83144MV337250T/execute",
      "rel": "execute",
      "method": "POST"
    }
  ]
}

Step 2: Redirect the buyer

Use the HATEOAS URL returned in step 1 to redirect the buyer so they can log in to their PayPal account, choose the payment method, and approve the transaction.

{
"href": "https://www.sandbox.paypal.com/checkoutnow?token={id}",
"rel": "approve",
"method": "GET"
}

Step 3: Make the payment

After the buyer chooses the payment method and approves the transaction, the PayPal window closes. The API then redirects the buyer to the return_url from the Create payment API call.

Once the buyer confirms their payment method, make the payment by calling the HATEOAS link with rel:execute to complete the transaction.

Copy the following code:

Sample request

API endpoint used: Execute the payment

curl -v -X POST https://api-m.sandbox.paypal.com/v1/payments/payment/{payment_id}/execute\
-H "Content-Type: application/json" \
-H "Authorization: Bearer Access-Token" \
-d '{
  "payer_id": "4BFTN5WTU4HME"
}'

After you copy the code in the sample request, replace payment_id with the ID of the payment that you need to execute.

The payer_id is the ID of the payer that PayPal passes in the return_url.

Step result

A successful request returns:

  • The HTTP 201 Created status code.
  • A JSON response body that shows the executed payment details.

Sample response

{
  {
    "id": "PAYID-L2ZMPHI0XY83144MV337250T",
    "intent": "sale",
    "state": "approved",
    "cart": "28010880FR2210136",
    "payer": {
      "payment_method": "paypal",
      "status": "VERIFIED",
      "payer_info": {
        "email": "sb-vftg0329193@personal.example.com",
        "first_name": "John",
        "last_name": "Doe",
        "payer_id": "4BFTN5WTU4HME",
        "shipping_address": {
          "recipient_name": "Brian Robinson",
          "line1": "4th Floor",
          "line2": "Unit #34",
          "city": "San Jose",
          "state": "CA",
          "postal_code": "95131",
          "country_code": "US"
        },
        "country_code": "US"
      }
    },
    "transactions": [
      {
        "amount": {
          "total": "30.11",
          "currency": "USD",
          "details": {
            "subtotal": "30.00",
            "tax": "0.07",
            "shipping": "0.03",
            "insurance": "0.01",
            "handling_fee": "1.00",
            "shipping_discount": "-1.00"
          }
        },
        "payee": {
          "merchant_id": "AXQJVJNJYCL2J",
          "email": "jeet-usb1@paypal.com"
        },
        "description": "The payment transaction description.",
        "custom": "EBAY_EMS_90048630024435",
        "soft_descriptor": "PAYPAL *JEETPATELST ECHI5786786",
        "item_list": {
          "items": [
            {
              "name": "hat",
              "sku": "1",
              "description": "Brown hat.",
              "price": "3.00",
              "currency": "USD",
              "tax": "0.01",
              "quantity": 5
            },
            {
              "name": "handbag",
              "sku": "product34",
              "description": "Black handbag.",
              "price": "15.00",
              "currency": "USD",
              "tax": "0.02",
              "quantity": 1
            }
          ],
          "shipping_address": {
            "recipient_name": "Brian Robinson",
            "line1": "4th Floor",
            "line2": "Unit #34",
            "city": "San Jose",
            "state": "CA",
            "postal_code": "95131",
            "country_code": "US"
          },
          "shipping_phone_number": "011862212345678"
        },
        "related_resources": [
          {
            "sale": {
              "id": "4FR33985CW436351L",
              "state": "completed",
              "amount": {
                "total": "30.11",
                "currency": "USD",
                "details": {
                  "subtotal": "30.00",
                  "tax": "0.07",
                  "shipping": "0.03",
                  "insurance": "0.01",
                  "handling_fee": "1.00",
                  "shipping_discount": "-1.00"
                }
              },
              "payment_mode": "INSTANT_TRANSFER",
              "protection_eligibility": "ELIGIBLE",
              "protection_eligibility_type": "ITEM_NOT_RECEIVED_ELIGIBLE,UNAUTHORIZED_PAYMENT_ELIGIBLE",
              "transaction_fee": {
                "value": "1.17",
                "currency": "USD"
              },
              "receivable_amount": {
                "value": "30.11",
                "currency": "USD"
              },
              "exchange_rate": "0.692213615971749",
              "parent_payment": "PAYID-L26E5MY3U933524UB102730M",
              "create_time": "2020-05-13T19:49:25Z",
              "update_time": "2020-05-13T19:49:25Z",
              "links": [
                {
                  "href": "https://api-m.sandbox.paypal.com/v1/payments/sale/4FR33985CW436351L",
                  "rel": "self",
                  "method": "GET"
                },
                {
                  "href": "https://api-m.sandbox.paypal.com/v1/payments/sale/4FR33985CW436351L/refund",
                  "rel": "refund",
                  "method": "POST"
                },
                {
                  "href": "https://api-m.sandbox.paypal.com/v1/payments/payment/PAYID-L26E5MY3U933524UB102730M",
                  "rel": "parent_payment",
                  "method": "GET"
                }
              ],
              "soft_descriptor": "PAYPAL *JEETPATELST ECHI5786786"
            }
          }
        ]
      }
    ],
    "failed_transactions": [],
    "create_time": "2020-05-13T19:46:58Z",
    "update_time": "2020-05-13T19:49:25Z",
    "links": [
      {
        "href": "https://api-m.sandbox.paypal.com/v1/payments/payment/PAYID-L26E5MY3U933524UB102730M",
        "rel": "self",
        "method": "GET"
      }
    ]
  }
}

See also

Billing Agreements and Reference Transactions