Alternative payment methods

Alternative payment methods (APMs) allow you to accept payments from customers around the globe who use their bank accounts, wallets, and local payment methods. When a buyer pays in a currency different than yours, PayPal handles currency conversion for you and presents conversion information to the buyer during checkout.

While the ability to display and accept APMs is included with the checkout integration, PayPal recommends subscribing to the CHECKOUT.ORDER.APPROVED webhook event in case a customer accidentally closes the browser and exits the checkout process after approving the transaction through their APM but before finalizing the transaction on your site.

On this page

Know before you code

How it works

How APMs work

APMs appear automatically and differ by country or region. The flow for completing a payment through an APM is:

  1. Buyer selects an APM at checkout.
  2. Buyer provides purchase details.
  3. Buyer is transferred from PayPal to the alternative payments provider (bank, wallet) to confirm the purchase.
  4. Buyer approves and confirms payment.
  5. Buyer returns to the merchant page to finalize the transaction.
  6. Merchant initiates completion of payment. PayPal moves the funds to the merchant.

Maintain default integration values

While the checkout integration includes APMs by default, they display only when the buyer is eligible for one of the methods and when the following default integration values are maintained:

Parameter Value Description
style.layout vertical Default. Buttons are stacked vertically with a maximum of four buttons. Recommended when:
  • Presenting a dynamic list of payment options on checkout and shopping cart pages.
  • Leveraging Checkout as a full stack payments platform.
intent capture The funds are captured immediately, while the buyer is present on your site.
commit true Show a Pay Now button in the Checkout flow. The final amount will not change after the buyer returns from PayPal to your site.
vault false Show all funding sources.

Because these are default values, you don't have to specify them in the PayPal JavaScript SDK call, but make sure that you don't explicitly change any of them by passing a non-default value for the parameter.

Note: APMs don't work with all payment configurations because some configurations change these default values. Payment configurations that don't work with APMs because they change these default values include: authorize and capture later, subscriptions, vaulting, and shipping changes callback scenarios.

Step 1: Subscribe to the CHECKOUT.ORDER.APPROVED webhook event

To subscribe to the CHECKOUT.ORDER.APPROVED event, copy the following code and modify it.

Tip: For a no-code option, subscribe to the Checkout order approved webhook event in your sandbox REST API app in the Developer Dashboard. Open then app you're using for development, scroll to the webhooks section, and click Add Webhook.

Sample request

API endpoint used: Create webhook

curl -v -X POST https://api.sandbox.paypal.com/v1/notifications/webhooks \
-H "Content-Type: application/json" \
-H "Authorization: Bearer Access-Token" \
-d '{
  "url": "https://example.com/example_webhook",
  "event_types": [
    {
      "name": "CHECKOUT.ORDER.APPROVED"
    }
  ]
}'

Modify the code

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

  • Access-Token - Your access token.
  • url - The URL of your webhook handler that listens for webhooks you're subscribed to.

Step result

A successful request results in the following:

  • A return status code of HTTP 201 Created.
  • A JSON response body that contains the webhook ID.
  • An entry for the webhook in the REST API app you're using for development. Open then app you're using and scroll to the webhooks section to confirm the webhook appears with the same ID returned in this call.

Sample response

{
    "id": "2CJ781045X895601X",
    "url": "https://example.com/example_webhook",
    "event_types": [{
        "name": "CHECKOUT.ORDER.APPROVED",
        "description": "An order has been approved by buyer."
    }],
    "links": [{
            "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks/2CJ781045X895601X",
            "rel": "self",
            "method": "GET"
        },
        {
            "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks/2CJ781045X895601X",
            "rel": "update",
            "method": "PATCH"
        },
        {
            "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks/2CJ781045X895601X",
            "rel": "delete",
            "method": "DELETE"
        }
    ]
}

Step 2: Update your webhook handler logic

A webhook handler is a script you create on your server that completes specific actions on webhooks that hit your listener URL. Each handler script implementation is different, but for this task, make sure you have logic in your handler script that verifies each CHECKOUT.ORDER.APPROVED event has a completed transaction in your database. An incomplete transaction might signal a dropped cart and you'll have to capture the payment to finalize the transaction.

The following resources might be useful as you create webhook handler code:

Step 3. Capture payments for orders not finalized

If there are incomplete transactions that indicate a customer completed authorization with their APM, but closed the window before finalizing the transaction on your site, you can capture the payments for those transactions.

To capture the payment for an authorized but incomplete transaction, copy the following code and modify it.

Sample request

API endpoint used: Capture payment for order

curl -v -X POST https://api.sandbox.paypal.com/v2/checkout/orders/2BE65243S8119680R/capture \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer Access-Token" \
  -H "PayPal-Request-Id: 123e4567-e89b-12d3-a456-426655440040" \

Modify the code

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

  • Access-Token - Your access token.
  • Order ID - In the URI for the API call, replace the sample ID with the order ID returned by the CHECKOUT.ORDER.APPROVED webhook event.
  • PayPal-RequestId - Replace the sample ID with a unique ID you generate. This ID helps prevent duplicate captures in the event that the API call is disrupted. See also: API Idempotency.

Step result

A successful request results in the following:

  • A return status code of HTTP 201 Created.
  • A JSON response body that contains details for the captured payment. Use the ID returned if you need to refund the transaction in the future.

Sample response

{
    "id": "2BE65243S8119680R",
    "purchase_units": [{
        "reference_id": "default",
        "shipping": {
            "name": {
                "full_name": "John Doe"
            },
            "address": {
                "address_line_1": "Badensche Straße 24",
                "admin_area_2": "Berlin-Wilmersdorf",
                "postal_code": "10715",
                "country_code": "DE"
            }
        },
        "payments": {
            "captures": [{
                "id": "9XR60255JN8591232",
                "status": "PENDING",
                "status_details": {
                    "reason": "RECEIVING_PREFERENCE_MANDATES_MANUAL_ACTION"
                },
                "amount": {
                    "currency_code": "EUR",
                    "value": "15.00"
                },
                "final_capture": true,
                "seller_protection": {
                    "status": "ELIGIBLE",
                    "dispute_categories": [
                        "ITEM_NOT_RECEIVED",
                        "UNAUTHORIZED_TRANSACTION"
                    ]
                },
                "links": [{
                        "href": "https://api.sandbox.paypal.com/v2/payments/captures/9XR60255JN8591232",
                        "rel": "self",
                        "method": "GET"
                    },
                    {
                        "href": "https://api.sandbox.paypal.com/v2/payments/captures/9XR60255JN8591232/refund",
                        "rel": "refund",
                        "method": "POST"
                    },
                    {
                        "href": "https://api.sandbox.paypal.com/v2/checkout/orders/2BE65243S8119680R",
                        "rel": "up",
                        "method": "GET"
                    }
                ],
                "create_time": "2020-02-26T22:52:00Z",
                "update_time": "2020-02-26T22:52:00Z"
            }]
        }
    }],
    "payer": {
        "name": {
            "given_name": "John",
            "surname": "Doe"
        },
        "email_address": "buyer@example.com",
        "payer_id": "PPFAH5AWAX7RS",
        "address": {
            "country_code": "DE"
        }
    },
    "links": [{
        "href": "https://api.sandbox.paypal.com/v2/checkout/orders/2BE65243S8119680R",
        "rel": "self",
        "method": "GET"
    }],
    "status": "COMPLETED"
}

Test the APM flow

Based on locale and country settings, APMs appear automatically and differ by country. You can force APMs to show in order to test an APM transaction.

  1. Add the following parameters to the PayPal JavaScript SDK call with an associated code:

    Sample call:

    <script
    src="https://www.paypal.com/sdk/js?client-id=YOUR_SB_CLIENT_ID&currency=EUR&locale=de_DE&buyer-country=DE">
    // Required. Replace YOUR_SB_CLIENT_ID with your sandbox client ID.
    </script>
    
  2. Test the transaction as a buyer.

    1. On your checkout page, click one of the APM payment buttons. For example, if you are testing a German APM transaction, you might select the Sofort button.
    2. Click the pre-fill information button at the top of the checkout screen to enter test user information. In the following example, you'd click Vorausgefüllte Angaben. Pre-fill button
    3. Enter a test email address. You can use the email address for your personal sandbox account.
    4. Click through the flow to complete the transaction. The simulation server displays options for testing successful and failed authorizations.
  3. Confirm the funds appear in the merchant account.

    1. Log into the PayPal sandbox using the business sandbox account from the Developer Dashboard.
    2. Verify that the funds, minus any fees, have been received in the business account.
  4. You can confirm the CHECKOUT.ORDER.APPROVED event fires as you expect in any of the following ways:

    • In Developer Dashboard - Confirm the Checkout order approved webhook appears in the REST API app you're using for development. Open then app you're using and scroll to the webhooks section to confirm the webhook appears with the same ID returned in the Create Webhook REST API call.
    • On your listener URL - Confirm your listener URL received the webhook when you completed a test transaction.
    • In your Webhook handler - Run any tests you've developed for your webhook handler script to confirm code updates you've made for handling the CHECKOUT.ORDER.APPROVED webhook.

Next steps

Test and go live

See also

Webhooks — Learn more about working with PayPal webhooks