Shipping module

Current

Last updated: Jan 15th, 5:00pm

Overview

The PayPal shipping module presents shipping details to a buyer during the PayPal flow. The merchant has several options available for controlling how shipping addresses and shipping options are handled. The server-side shipping callbacks allow you to update the shipping and order amount information as buyers make changes on the PayPal review page.


Merchant and buyer interaction

Buyers can use the shipping module to specify the shipping address and shipping options on the PayPal review page. The system sends a callback to the merchant's URL with the updated shipping information.

When the buyer provides their shipping address, PayPal sends a callback to the merchant server with the buyer's address using the server-side shipping callbacks. In response, the merchant can send PayPal the shipping options and updated order cost amounts.

You can use server-side callbacks to:

  • Verify that you support the shipping method.
  • Update shipping costs.
  • Change line items in the cart.
  • Inform the buyer that you do not support their shipping method.

The following sample PayPal review page shows a buyer's shipping address and options:

image

How it works

The shipping address and options callback process involves the following steps:

  1. A buyer clicks on the PayPal button displayed on the merchant site.
  2. The merchant makes a Create Order API request to PayPal to set up the PayPal flow, including the parameters needed to enable the server-side callbacks.
  3. The buyer is taken to the PayPal flow where they are authenticated and shown the PayPal review page.
  4. PayPal makes a server-side callback to the merchant's server with the default shipping address from the buyer's PayPal wallet.
  5. The merchant processes the callback and responds with shipping options for the address and updated order amount.
  6. PayPal updates the review page to reflect the merchant's revised order amount and shipping options.
  7. If the buyer changes the shipping address or shipping options, a callback is made to the merchant. The merchant's response updates the PayPal review page.
  8. The buyer clicks the pay button on the PayPal review page to complete the transaction, which is returned to the merchant.
  9. The merchant may make a Show Order Details API call to get the final PayPal order information and verify it still matches the information in their system.
  10. The merchant captures the PayPal order to complete the transaction.

Create order

PayPal uses the PayPal Orders v2 API Create Order request to set up the PayPal flow used by the buyer to approve a PayPal transaction. There are several ways to determine how the shipping address and options are displayed on the PayPal review page and which events create callbacks when the buyer interacts with them.


Enabling server-side callbacks

The payment_source.paypal.experience_context.order_update_callback_config object is used to enable and configure server-side callbacks during the PayPal flow. The callback_url field specifies the endpoint on your servers where PayPal sends the callback request. The callback_events array specifies which callback events you support. The PayPal flow supports the following events:

  • SHIPPING_ADDRESS: This event happens when the PayPal review page loads for the first time and when the buyer changes their shipping address. We recommend merchants to subscribe only to SHIPPING_ADDRESS. This requires a merchant to respond with all the shipping options and amounts calculated on the initial callback. Since all options have been returned, the merchant callback does not have to be called when the selection option changes. This method reduces delays and the number of requests for PayPal.
  • SHIPPING_OPTION: This event happens when the buyer selects new shipping options and when they change shipping options. We recommend merchants subscribe to this if they want to be notified or need to recalculate amounts with their callback URL when a selected shipping option changes for the current address. If SHIPPING_OPTION is not needed by the merchant, they should subscribe to SHIPPING_ADDRESS.


Configuring shipping preferences

The shipping preference is a set using the payment_source.paypal.experience_context.shipping_preference field. There are 3 possible values:

  • GET_FROM_FILE: This default preference retrieves the customer-provided shipping address from PayPal.
  • NO_SHIPPING: This option removes the shipping address information from the PayPal review page and the API response. However, the shipping.phone_number and shipping.email_address fields are returned for digital goods delivery.
  • SET_PROVIDED_ADDRESS: The PayPal review page shows the shipping address provided by the merchant in the create order request. The buyer cannot change this address on the PayPal site. If the merchant does not pass an address, the buyer can choose the address on PayPal.

If you do not pass a shipping preference, the default behavior is GET_FROM_FILE. The PayPal review page shows the default shipping address from the buyer's PayPal wallet. The buyer can select a different shipping address from their wallet or add a new address.

Callbacks happen if the shipping preference is GET_FROM_FILE.

Passing a shipping address

If you have a shipping address from the buyer, pass it to PayPal on the create order request. If you pass a shipping address with a shipping preference of GET_FROM_FILE, it will display on the PayPal review page, where the buyer can change the shipping address. You can use the shipping preference SET_PROVIDED_ADDRESS to prevent the buyer from changing the shipping address on the PayPal review page.
If your transaction does not involve shipping, you can pass the shipping preference SET_PROVIDED_ADDRESS, and no shipping information will be displayed on the PayPal review page.

Here is a sample Create Order API request to a merchant with callback config:

    1curl -v -X POST https://api-m.sandbox.paypal.com/v2/checkout/orders \
    2-H 'Content-Type: application/json' \
    3-H 'PayPal-Request-Id: 7b92603e-77ed-4896-8e78-5dea2050476a' \
    4-H 'Authorization: Bearer 6V7rbVwmlM1gFZKW_8QtzWXqpcwQ6T5vhEGYNJDAAdn3paCgRpdeMdVYmWzgbKSsECednupJ3Zx5Xd-g' \
    5-d '{
    6 "intent": "CAPTURE", "payment_source": {
    7 "paypal": {
    8 "experience_context": {
    9 "user_action": "PAY_NOW",
    10 "shipping_preference": "GET_FROM_FILE",
    11 "return_url": "https://example.com/returnUrl",
    12 "cancel_url": "https://example.com/cancelUrl",
    13 "order_update_callback_config": {
    14 "callback_events": ["SHIPPING_ADDRESS", "SHIPPING_OPTIONS"],
    15 "callback_url": "https://example.com/orders?cart_id=h98h98h&session_id=89h788fg8"
    16 }
    17 }
    18 }
    19 }, "purchase_units": [{
    20 "reference_id": "d9f80740-38f0-11e8-b467-0ed5f89f718b",
    21 "items": [{
    22 "name": "T-Shirt",
    23 "description": "Super Fresh Shirt",
    24 "unit_amount": {
    25 "currency_code": "USD",
    26 "value": "50.00"
    27 },
    28 "quantity": "1",
    29 "category": "PHYSICAL_GOODS",
    30 "sku": "sku01",
    31 "image_url": "https://example.com/static/images/items/1/tshirt_green.jpg",
    32 "url": "https://example.com/url-to-the-item-being-purchased-1",
    33 "upc": {
    34 "type": "UPC-A",
    35 "code": "123456789012"
    36 }
    37 }, {
    38 "name": "Shoes",
    39 "description": "Running, Size 10.5",
    40 "sku": "sku02",
    41 "unit_amount": {
    42 "currency_code": "USD",
    43 "value": "25.00"
    44 },
    45 "quantity": "2",
    46 "category": "PHYSICAL_GOODS",
    47 "image_url": "https://example.com/static/images/items/1/shoes_running.jpg",
    48 "url": "https://example.com/url-to-the-item-being-purchased-2",
    49 "upc": {
    50 "type": "UPC-A",
    51 "code": "987654321012"
    52 }
    53 }],
    54 "amount": {
    55 "currency_code": "USD",
    56 "value": "100.00",
    57 "breakdown": {
    58 "item_total": {
    59 "currency_code": "USD",
    60 "value": "100.00"
    61 }
    62 }
    63 }
    64 }]
    65 }

    Server-side shipping callbacks

    The Server-Side Callback API request to a merchant is consistent with GET orders and includes selected addresses and options outside of the order object.

    • Sending order data is structurally similar to making a GET request.
    • PayPal will send updated shipping addresses and options separately from the order to avoid confusion.
    • If the address or option is incomplete, PayPal will not set it in order to prevent misunderstandings.
    • PayPal will embed the cart identifier in the callback URL if merchants cannot associate their shopping cart with the order.
    • Merchants with client-side shopping carts should include item details when they create the order for server-side shipping callbacks.


    Callback request to merchant for shipping address event

    The following sample is a PayPal server-side callback request to the merchant for a shipping event. The callback identifies the order, shipping_address, shipping_option, and purchase_units.

      1{
      2 "title": "Shipping Options Callback Request - Shipping Address and Shipping Options Event",
      3 "description": "The PayPal callback server sends request with a buyer's shipping address, the shipping option the buyer selected, and the purchase_units of the order, to the merchant listener URL. The merchant responds with a the appropriate tax calculation and breakdown for the given address and shipping option combination.",
      4 "runnable": true,
      5 "operationId": "server.callback",
      6 "request": {
      7 "method": "POST",
      8 "path": "v2/checkout/orders/order-update-callback",
      9 "headers": {
      10 "Content-Type": "application/json"
      11 },
      12 "body": {
      13 "id": "5O190127TN364715T",
      14 "shipping_address": {
      15 "country_code": "US",
      16 "admin_area_1": "TX",
      17 "admin_area_2": "Dallas",
      18 "postal_code": "75001"
      19 },
      20 "shipping_option": {
      21 "id": "2",
      22 "amount": {
      23 "currencyCode": "USD",
      24 "value": "20.00"
      25 },
      26 "type": "SHIPPING",
      27 "label": "Free Shipping"
      28 },
      29 "purchase_units": [{
      30 "reference_id": "d9f80740-38f0-11e8-b467-0ed5f89f718b",
      31 "amount": {
      32 "currency_code": "USD",
      33 "value": "100.00"
      34 }
      35 }]
      36 }
      37 },

      Callback request fields

      Field

      Description

      Data type

      id

      Unique identifier for the shipping order. For example, 5O190127TN364715T.

      string

      shipping_address

      Shipping address information. Includes country_code, admin_area_1, admin_area_2, and postal_code.

      object

      country_code

      Identifies the shipping address country. For example, US.

      string

      admin_area_1

      Identifies the shipping address state or region. For example, TX.

      string

      admin_area_2

      Identifies the shipping address, city, or municipality. For example, Dallas.

      string

      postal_code

      Identifies the postal code. For example, 7500.

      number

      shipping_option

      Shipping option information. Includes id, amount, type, and label.

      string

      id

      Indicates the type of shipping option. For example, 2.

      number

      amount

      Shipping option amount. Includes currencyCode and value.

      object

      currencyCode

      Indicates the type of currency. For example, USD.

      string

      value

      String denoting the shipping option price, formatted as X.XX. For example, 20.00.

      number

      type

      An enum that indicates the type of shipping. For example, SHIPPING or PICKUP

      string

      label

      Dropdown menu option selected by the buyer. Indicates whether the shipping is free or not. For example, Free Shipping.

      string

      purchase_units

      Defines the purchase unit. Includes reference_id and amount.

      object

      reference_id

      Identifier associated with the purchase units. For example, d9f80740-38f0-11e8-b467-0ed5f89f718b.

      string

      amount

      Purchase amount. Includes currency_code and value.

      object

      currency_code

      Indicates the type of currency. For example, USD.

      string

      value

      String denoting the purchase price, formatted as X.XX. For example, 100.00.

      number

      Merchant response

      The merchant response to a PayPal server-side callback request is similar to an order. A change to the customer’s shipping address or options can affect the following fields within the data structure:

      • purchase_units[].shipping.options represent the shipping modules associated with the purchase units within the order. The purchase order field includes contact and delivery information, including phone number, PayPal account email address, order ID, and reference ID.
      • purchase_units[].amount represents the purchase unit amount in the order.

      PayPal can handle these changes by taking one of the following approaches:

      • Asking the merchant to return an updated order limited to the fields that can be changed.
      • Asking the merchant to return a list of patch operations.


      Merchant success response

      When the order request is acceptable, the merchant responds with a success message that contains amount and shipping option changes.

      Here is a sample HTTP 200 OK callback response from a merchant with shipping options and amount updates.

        1{
        2 "id": "8HFTASDATTV",
        3 "purchase_units": [{
        4 "reference_id": "d9f80740-38f0-11e8-b467-0ed5f89f718b",
        5 "amount": {
        6 "currency_code": "USD",
        7 "value": "105.00",
        8 "breakdown": {
        9 "item_total": {
        10 "currency_code": "USD",
        11 "value": "100.00"
        12 },
        13 "tax_total": {
        14 "currency_code": "USD",
        15 "value": "5.00"
        16 },
        17 "shipping": {
        18 "currency_code": "USD",
        19 "value": "0.00"
        20 }
        21 }
        22 },
        23 "shipping_options": [{
        24 "id": "1",
        25 "amount": {
        26 "currencyCode": "USD",
        27 "value": "0.00"
        28 },
        29 "type": "SHIPPING",
        30 "label": "Free Shipping",
        31 "selected": true
        32 }, {
        33 "id": "2",
        34 "amount": {
        35 "currencyCode": "USD",
        36 "value": "7.00"
        37 },
        38 "type": "SHIPPING",
        39 "label": "USPS Priority Shipping",
        40 "selected": false
        41 }, {
        42 "id": "3",
        43 "amount": {
        44 "currencyCode": "USD",
        45 "value": "10.00"
        46 },
        47 "type": "SHIPPING",
        48 "label": "1-Day Shipping",
        49 "selected": false
        50 }]
        51 }]
        52}

        Merchant success response fields

        A merchant response can include the fields identified in the following table.

        Field

        Description

        Date type

        id

        Identifies the merchant. For example, 8HFTASDATTV.

        string

        purchase_units

        Purchase unit information. Includes reference_id and amount.

        object

        reference_id

        Uniquely identifies the purchase transaction. For example, d9f80740-38f0-11e8-b467-0ed5f89f718b.

        string

        amount

        Purchase unit amount in the order. Includes currency_code,value, and breakdown.

        object

        currency_code

        Code indicating the amount currency type. For example, USD.

        string

        value

        String denoting the purchase unit amount in the order, formatted as X.XX. For example, 105.00.

        amount

        breakdown

        Amount breakdown. Includes item_total, tax_total, and shipping.

        object

        item_total

        Amount item breakdown. Includes currency_code and value.

        object

        currency_code

        Amount item total currency type. For example, USD.

        string

        value

        Amount item value. For example, 100.0.

        number

        tax_total

        Amount tax breakdown. Includes currency_code and value

        object

        currency_code

        Currency type of the amount tax total. For example, USD.

        string

        value

        String denoting thetax_total amount, formatted as X.XX. For example, 5.00.

        number

        shipping

        Amount shipping breakdown. Includes currency_code and value.

        object

        currency_code

        Amount shipping currency type. For example, USD.

        string

        value

        String denoting the value. amount, formatted as X.XX. For example, 0.00.

        In this example, there are no shipping costs associated with the purchase unit.

        number

        shipping_options

        Shipping option details. Includes id, amount, type, label, and selected.

        object

        id

        Shipping option identifier. For example, 1.

        number

        amount

        Amount for the selected shipping option. For example, currencyCode and value.

        object

        currencyCode

        Type of currency required for the selected shipping option. For example, USD.

        string

        value

        String denoting the value. amount for the selected shipping option, formatted as X.XX. For example, 0.00. The value depends upon the selected label.

        number

        type

        An enum that indicates the type of delivery for the selected option. For example, SHIPPING or PICKUP.

        string

        label

        Dropdown menu option selected by the buyer. Indicates the type of SHIPPING. For example, Free Shipping.
        Other labels include USPS Priority Shipping and 1-Day Shipping.

        string

        selected

        Determines which option is selected by default. Possible values are true or false.

        boolean

        The order amount is automatically updated based on the options chosen by the buyers. You can use the onShippingOptionsChange() callback to update your own database with the new cost amount.

        Merchant decline response

        A merchant can issue a 422 error to decline a callback event. This could occur when:

        • The merchant rejects a shipping address.
        • A server-side callback request to a merchant fails or times out.
        • The merchant returns a poorly formatted response.

        PayPal mechanisms handle these issues, minimizing disruptions throughout the process. Here are a few examples of merchant-declined callback events and associated descriptions:

        Callback event type

        Error

        Description

        Shipping address

        ADDRESS_ERROR

        Your order can't be shipped to this address.

        Shipping address

        COUNTRY_ERROR

        Your order can't be shipped to this country.

        Shipping address

        STATE_ERROR

        Your order can't be shipped to this state.

        Shipping address

        ZIP_ERROR

        Your order can't be shipped to this zip.

        Shipping option

        METHOD_UNAVAILABLE

        The shipping method you selected is unavailable. To continue, choose another way to get your order.

        Shipping option

        STORE_UNAVAILABLE

        Part of your order isn't available at this store.


        Here is a sample decline callback from the merchant. In this case, there is an HTTP 422 Unprocessable Entity response, which is a country error.

          1{
          2 "name": "UNPROCESSABLE_ENTITY",
          3 "details": [{
          4 "issue": "COUNTRY_ERROR"
          5 }]
          6}

          If you accept cookies, we’ll use them to improve and customize your experience and enable our partners to show you personalized PayPal ads when you visit other sites. Manage cookies and learn more