Handle shipping options with Express Component

Allow customers to select their preferred shipping option in the wallet's interface.

๐Ÿšง

This feature of Mollie Components is in private beta. If you are interested in early access you can reach out to us.

With the Express Component you can offer available shipping options to your customer directly in the wallet's interface. You specify the pre-shipping subtotal and when an option is selected the amount will automatically be updated. This allows you to offer express payment methods earlier in your checkout process.

Fixed shipping options

If you do not need to dynamically determine shipping options based on a shipping address, you can provide an up-front list of available shipping options.

Add available shipping options to the Checkout Session

When creating the Checkout Session, add an array with shipping options to the shipping.options property. You can set a description, a reference and specify the amount. The requiredCustomerDetails property should also include shipping-address to ensure that a shipping address will be collected.

curl -X POST https://api.mollie.com/v2/sessions \
  -H "Authorization: Bearer live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "amount": { "currency": "EUR", "value": "10.00" },
    "description": "Order #12345",
    "lines": [ "..." ],
    "redirectUrl": "https://example.org/order/12345/result",
    "requiredCustomerDetails": ["shipping-address"],
    "shipping": {
      "options": [
        {
          "reference": "standard",
          "description": "Standard delivery",
          "amount": { "currency": "EUR", "value": "3.99" }
        },
        {
          "reference": "express",
          "description": "Express delivery",
          "amount": { "currency": "EUR", "value": "9.99" }
        }
      ]
    }
  }'
โš ๏ธ

You cannot add a line item with a type of shipping_fee when providing shipping.options.

Dynamic shipping options

When shipping options are dependent on your customer's shipping address, you can set up a server-side callback. Mollie will call this endpoint whenever the your customer selects a shipping address so you can determine new shipping options for the address.

Set up a callback endpoint

On your server, add an endpoint that can accept the shipping-address-changed event. The event will include the sessionId and a partial shippingAddress that can be used to calculate new shipping options. The full shipping address will be available on the Checkout Session and Payment once the payment is successful.

{
  "event": "shipping-address-changed",
  "sessionId": "sess_xxxxx",
  "shippingAddress": {
    "postalCode": "1015CW",
    "city": "Amsterdam",
    "region": "Noord-Holland",
    "country": "NL"  
  }
}

When processing the event, make sure the event is shipping-address-changed . You can use the sessionId to match the event to a Checkout Session. Once you have determined the available shipping options add them to the response of your endpoint. You have to return an array of options where each requires a reference, description and amount.

{
  "options": [
    {
      "reference": "standard",
      "description": "Standard delivery",
      "amount": { "currency": "EUR", "value": "3.99" }
    },
    {
      "reference": "express",
      "description": "Express delivery",
      "amount": { "currency": "EUR", "value": "9.99" }
    }
  ]
}
โš ๏ธ

Your endpoint needs to respond within 15 seconds. When the callback times out your customer will be shown an error and will not be able to complete the payment.

Handling an unsupported address

If you cannot deliver to the customer's shipping address you should respond with a 422 status code, an error type and a free format detail field. The type will be used to show a localized error message in the UI. The detail field is used for logging puposes and will not be shown to your customer.

{
  "type": "https://docs.mollie.com/reference/errors/unsupported-postal-code",
  "status": 422,
  "detail": "Shipping to PO boxes is not supported."
}

By setting a specific error type your customer will see a more detailed error message. You can use one of the below error types.

Error typeDescription
unsupported-addressGeneric error that the provided address is not supported.
unsupported-postal-codeThe provided postal code is not supported.
unsupported-countryThe provided country is not supported.

Add the callback url to the Checkout Session

When creating the Checkout Session add your endpoint's URL to the shipping.callbackUrl property. The requiredCustomerDetails property should also include shipping-address to ensure that a shipping address will be collected.

curl -X POST https://api.mollie.com/v2/sessions \
  -H "Authorization: Bearer live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "amount": { "currency": "EUR", "value": "10.00" },
    "description": "Order #12345",
    "lines": [ "..." ],
    "redirectUrl": "https://example.org/order/12345/result",
    "requiredCustomerDetails": ["shipping-address"],
    "shipping": {
      "callbackUrl": "https://www.my-website.com/api/shipping-options
    }
  }'
โš ๏ธ

You cannot add shipping.options or a line item with a type of shipping_fee when setting the shipping.callbackUrl.

Reading the selected option

When your customer completes the payment using the Express Component, both the Checkout Session and Payment will reflect the shopper's choice: amount is the final total, and a shipping_fee line item is added with the details of the selected option. Use the reference to identify which shipping option was chosen and trigger the appropriate fulfilment flow.

{
  "amount": { "currency": "EUR", "value": "13.99" },
  "lines": [
    {
      "description": "T-Shirt",
      "quantity": 1,
      "unitPrice": { "currency": "EUR", "value": "10.00" },
      "totalAmount": { "currency": "EUR", "value": "10.00" }
    },
    {
      "type": "shipping_fee",
      "description": "Standard delivery",
      "reference": "standard",
      "quantity": 1,
      "unitPrice": { "currency": "EUR", "value": "3.99" },
      "totalAmount": { "currency": "EUR", "value": "3.99" }
    }
  ],
  "shippingAddress": {
    "givenName": "Jan",
    "familyName": "de Vries",
    "streetAndNumber": "Keizersgracht 126",
    "city": "Amsterdam",
    "region": "Noord-Holland",
    "postalCode": "1015 CW",
    "country": "NL"
  }
}

Behaviour for other components

Shipping option selection is only supported for the Express Component. You can still load other components if shipping.options or shipping.callbackUrl is provided on the Checkout Session, however these will not be able to offer shipping option selection.

It is therefore recommended to only use the Checkout Session with the Express Component. For other components follow these steps:

  1. Render your own UI to allow the customer to select their shipping option.
  2. When the shopper selects an option, create a new Checkout Session with the updated amount and lines and initialize the component(s) with the clientAccessToken.

Did this page help you?