> **Description:** Streamline your checkout process by letting customers select shipping options and confirm delivery details directly within the Vipps or MobilePay app.

> **AI agent:** Read [https://developer.vippsmobilepay.com/docs/knowledge-base/ai-tools.md](https://developer.vippsmobilepay.com/docs/knowledge-base/ai-tools.md) first. It covers keeping API keys and secrets out of generated code.

> **Full site overview:** For an overview of the entire site, read [https://developer.vippsmobilepay.com/llms.txt](https://developer.vippsmobilepay.com/llms.txt).

# Express

Streamline your checkout process by letting customers select shipping options and confirm delivery details directly within the Vipps or MobilePay app.

**TIP**

For a visual walkthrough of the customer's experience with Express, see [How Express works](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/how-it-works/express.md).

## Overview

With the *Express* feature, you can provide users with groups of shipping options,
which they can then choose from within the
Vipps or MobilePay app.
Place the *Express* button on your checkout screen or your product screens.

Four-screen Express flow (Vipps or MobilePay): (1) Product page with Express button. (2) Information sharing consent screen. (3) Delivery options with pick-up point and home delivery. (4) Payment summary.

The customer can update their address, if needed.

Express delivery address selection screen (Vipps or MobilePay): pre-filled current address with an option to search or enter a different delivery address.

The customer can select the delivery option from the main screen.

If additional options are available, the customer can select *Change* to view them in a new panel.
They can then choose their preferred option and return to the main screen.

Express shipping options screen (Vipps or MobilePay) showing available delivery methods such as pick-up points and home delivery, with estimated delivery dates.

The Express flow is as follows:

1. The user selects to pay with Vipps or MobilePay.
   - If they are on a PC, they will go through the [Vipps MobilePay landing page](https://developer.vippsmobilepay.com/docs/knowledge-base/landing-page.md),
   where they enter their phone number and the app opens.
   - If they are on a phone, their app will open, and they will switch to it.
1. In their Vipps or MobilePay app, they will provide consent for sharing their address with the merchant.
1. They then choose one of the displayed shipping options.
1. On the last page, the user confirms the final payment. The amount shown will include the shipping.
1. They will be directed back to your website, where you should show a confirmation of the payment.

## User consent and privacy

**Privacy terms**

As part of the Express flow, you will get access to the user's personal information.
Ensure that you comply with our [privacy terms](https://help.vippsmobilepay.com/en-NO/terms-and-privacy).

Users must approve sharing their profile information in order to proceed with Express. They can remove this consent later through their Vipps or MobilePay app.

We recommend that you don't keep their information any longer than needed for the shipping to be completed.

For more about profile sharing, see [Profile sharing feature](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/features/profile-sharing.md).

## Limitations

- When `shipping.allowedCountries` is not set, the shipping address must be in the country that corresponds to the
  payment currency. For example, a payment in DKK supports Danish shipping addresses by default.

- To ship to one or more other countries, set `shipping.allowedCountries` to the ISO 3166-1 alpha-2 country codes
  you support. The customer can select an address in any country in that list.

- The currency of every shipping option must match the payment currency.

- For payments using `WALLET`, the transaction currency must match the country where the sales unit is registered.
  PSPs using `CARD_PASSTHROUGH` can use any [supported currency](https://developer.vippsmobilepay.com/docs/APIs/psp-epayment-api/README.md), subject to their
  commercial agreement.

- You get the customer's address only after they consent in the app, as part of the payment. If you need the address
  before you create the payment, for example to create the order or calculate taxes, log the customer in with
  [Login](https://developer.vippsmobilepay.com/docs/APIs/login-api/README.md) first.

- After you create the payment, the only change to the total is the cost of the shipping option the customer selects.
  You can't update taxes or other parts of the order in the app.

## Authorization

All ePayment API requests must include a valid Bearer token in the `Authorization` header.
See [Authorization](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/concepts.md#authorization) for how to obtain one.

## Create an express payment

*Express* is initiated by sending a [create payment](https://developer.vippsmobilepay.com/redocusaurus/epayment-swagger-id.yaml) request with the following settings:

- Include the `shipping` property, filled out as described in [Shipping options](#shipping-options)
- Set `paymentMethod` to `WALLET`. If you are a Payment Service Provider, set `paymentMethod` to `CARD_PASSTHROUGH` instead
  -- see [PSP ePayment integration](https://developer.vippsmobilepay.com/docs/APIs/psp-epayment-api/epayment-psp-api-guide.md#create-an-express-payment).
- Set `profile.scope`. It must include `address`. Also include every other scope you need to deliver the order, usually `name email phoneNumber address`. You can't get missing details after the payment is completed.

See a detailed example

```bash
curl -X POST https://apitest.vipps.no/epayment/v1/payments \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR-ACCESS-TOKEN" \
-H "Ocp-Apim-Subscription-Key: YOUR-SUBSCRIPTION-KEY" \
-H "Merchant-Serial-Number: YOUR-MSN" \
-H "Idempotency-Key: YOUR-IDEMPOTENCY-KEY" \
-H "Vipps-System-Name: acme" \
-H "Vipps-System-Version: 3.1.2" \
-H "Vipps-System-Plugin-Name: acme-webshop" \
-H "Vipps-System-Plugin-Version: 4.5.6" \
-d '{
  "amount":{
    "currency":"NOK",
    "value":6000
    },
    "customer":{
        "phoneNumber":"4712345678"
    },
    "paymentMethod":{
        "type":"WALLET"
    },
    "profile": {
        "scope": "name email phoneNumber address"
    },
  "shipping": {
    "fixedOptions": [
        {
            "isDefault": true,
            "priority": 0,
            "type": "PICKUP_POINT",
            "brand": "POSTNORD",
            "options": [
                {
                    "id": "meny_grunerlokka",
                    "isDefault": true,
                    "amount": {
                        "currency": "NOK",
                        "value": 3900
                        },
                    "priority": 0,
                    "name": "Meny Grünerløkka",
                    "meta": "Henrik Ibsens Gate 1, 0000 Oslo",
                    "estimatedDelivery": "In 2 days"
                },
                {
                    "id": "bunnpris_skoyen",
                    "isDefault": false,
                    "amount": {
                        "currency": "NOK",
                        "value": 3900
                        },
                    "name": "Bunnpris Skøyen",
                    "priority": 1,
                    "meta": "Gatenavn 21, 0001 Oslo",
                    "estimatedDelivery": "In 2 days"
                }
            ]
        }
        ]
    },
  "reference": "2810171754658432260",
  "userFlow": "WEB_REDIRECT",
  "returnUrl": "https://developer.vippsmobilepay.com/docs/example-pages/result-page/",
  "paymentDescription": "Purchase of socks"
}'
```

### Shipping options

In the `shipping` property, you can specify either `fixedOptions` or `dynamicOptions` (not both).

  If you know the delivery options in advance, send only `fixedOptions`.

- [Fixed options](#fixed-options) - Specify all the shipping options.
- [Dynamic options](#dynamic-options) - Register a callback to generate dynamic options (optional)

**Important**

When using [Fixed options](#fixed-options), each shipping option must use the payment currency. By default, the
user's address must correspond to the payment currency. To support other shipping countries, set
`shipping.allowedCountries` when you create the payment.

With [Dynamic options](#dynamic-options), you have the flexibility to decide whether the address is supported.
If shipping to the specified address is not possible, return a `400` in the [callback response](#callback-response).
The app will then notify the user that delivery to the selected address is unavailable.

#### Fixed options

When you know the shipping options in advance, supply these through the `shipping.fixedOptions` property.
We accept only one of these options: `fixedOptions` or `dynamicOptions`, so please don't supply `dynamicOptions` if you already
know what the shipping options should be.

The `fixedOptions` property contains an array of one or more shipping groups.

Here is an example showing one type of shipping (e.g., home delivery with PostNord) and two options (standard or express delivery).

```json
 "shipping": {
        "fixedOptions": [
            {
                "brand": "POSTNORD",
                "type": "HOME_DELIVERY",
                "options": [
                    {
                        "id": "postnord-home-1",
                        "amount": {
                            "currency": "NOK",
                            "value": 19900
                        },
                        "name": "Posten home express",
                        "estimatedDelivery": "1 business day"
                    },
                    {
                        "id": "postnord-home-2",
                        "amount": {
                            "currency": "NOK",
                            "value": 9900
                        },
                        "name": "Posten home standard",
                        "estimatedDelivery": "3-5 business days"
                    }
                ]
            }
        ]
    }
```

As with other ePayment API requests, the `value` field is in minor units (e.g., 9900 is 99,- NOK).

##### Shipping groups

Each shipping group contains all the parameters needed for a shipping method.

The properties for each shipping group are:

- `type` (required): Enum specifying the delivery type: `HOME_DELIVERY`, `PICKUP_POINT`, `MAILBOX`, `IN_STORE`, `OTHER`
- `brand` (required): Enum representing the shipping provider (e.g., `BRING`, `DHL`). We'll add the logo based on the vendor in the apps.
    Here are the options (see [Brand logos](#brand-logos)):
    `BRING`, `DHL`, `FEDEX`, `GLS`, `GORDON`, `HELTHJEM`, `INSTABOX`, `MATKAHUOLTO`, `PORTERBUDDY`,
    `POSTEN`, `POSTI`, `POSTNORD`, `OTHER`
- `isDefault`: Boolean indicating whether this method is the default option. The default value is `false`. If no default is found, then the first option will be preselected.
- `priority`: Integer defining the display order (lower numbers appear higher in the app). If no priority is set, we show your options in the order you provide them. If some options have a priority set and others not, we'll show the prioritized options first and show the remaining options in the order you have specified them.
- `options` (required): This is an array with one or more delivery options for a shipping group. This is used for showing options with small differences, such as pickup locations or delivery times. Each array element contains the following:
  - `id` (required): Unique identifier for the shipping option. The ID of the selected option will be returned in the API after the payment is completed.
  - `amount` (required): Cost of the shipping in `currency` and `value` (e.g., NOK 3900 = NOK 39.00).
  - `name` (required): Name of the delivery point or store.
  - `isDefault`: Boolean indicating whether this is the default selection.
  - `priority`: Determines the order that options appear in the app, with lower numbers appearing higher.
  - `meta`: Additional information such as address or opening hours.
  - `estimatedDelivery`: Expected delivery (e.g., 'Ready in 2 hours', '17:00-19:00', '1-2 Days').

For more details, see the [Create payment spec](https://developer.vippsmobilepay.com/redocusaurus/epayment-swagger-id.yaml).

###### How the fields map to the app

Screenshot: Vipps Express shipping selection screen annotated to show how API fields map to UI elements -- shipping option title, description, price, meta text, and estimated delivery date are all labeled.

###### Shipping group with one option

An example of a shipping group with only one option:

```json
 "shipping": {
        "fixedOptions": [
            {
                "brand": "POSTNORD",
                "type": "HOME_DELIVERY",
                "options": [
                    {
                        "id": "postnord_home_1",
                        "amount": {
                            "currency": "NOK",
                            "value": 4900
                        },
                        "name": "Delivery to your door"
                    }
                ]
            }
        ]
    }
```

Full HTTP POST example

```bash
curl -X POST https://apitest.vipps.no/epayment/v1/payments \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR-ACCESS-TOKEN" \
-H "Ocp-Apim-Subscription-Key: YOUR-SUBSCRIPTION-KEY" \
-H "Merchant-Serial-Number: YOUR-MSN" \
-H "Idempotency-Key: YOUR-IDEMPOTENCY-KEY" \
-H "Vipps-System-Name: acme" \
-H "Vipps-System-Version: 3.1.2" \
-H "Vipps-System-Plugin-Name: acme-webshop" \
-H "Vipps-System-Plugin-Version: 4.5.6" \
-d '{
     "shipping": {
        "fixedOptions": [
            {
                "brand": "POSTNORD",
                "type": "HOME_DELIVERY",
                "options": [
                    {
                        "id": "postnord_home_1",
                        "amount": {
                            "currency": "NOK",
                            "value": 4900
                        },
                        "name": "Delivery to your door"
                    }
                ]
            }
        ]
    },
    "paymentMethod": {
        "type": "WALLET"
    },
    "profile": {
        "scope": "name email phoneNumber address"
    },
    "amount": {
        "currency": "NOK",
        "value": 49900
    },
    "customer": {
        "phoneNumber": "4512345678"
    },
    "reference": "acme-shop-123-order123abc",
    "returnUrl": "https://developer.vippsmobilepay.com/docs/example-pages/result-page/",
    "userFlow": "WEB_REDIRECT",
    "paymentDescription": "Descriptive message"
}'
```

###### Shipping group with multiple options

If you have more than one shipping option with the same brand and type (e.g., Postnord pickup points, PorterBuddy delivery times), add these to `options`.
You can specify the `priority` property, where lower numbers appear higher in the app, otherwise we will display them in the order you send them.
To set a default, use `isDefault`.

An example of a shipping group with two options (i.e., pickup points):

```json
"shipping": {
        "fixedOptions": [
            {
                "brand": "BRING",
                "type": "PICKUP_POINT",
                "options": [
                    {
                        "id": "bring_pickup_1",
                        "isDefault": true,
                        "amount": {
                            "currency": "NOK",
                            "value": 3900
                        },
                        "priority": 0,
                        "name": "Gellerup Shoppen"
                    },
                    {
                        "id": "bring_pickup_2",
                        "amount": {
                            "currency": "NOK",
                            "value": 3900
                        },
                        "name": "Pakkeboks Bazar Vest",
                        "priority": 1
                    }
                ]
            }
        ]
    }
```

###### Multiple shipping groups

Create a new shipping group for each unique brand and delivery type.
For example, if you offer `POSTNORD` for `HOME_DELIVERY` and `PICKUP_POINT`, provide two shipping groups.

An example with two shipping groups (i.e., same brand, different type of shipping):

```json
    "shipping": {
        "fixedOptions": [
            {
                "brand": "BRING",
                "type": "PICKUP_POINT",
                "options": [
                    {
                        "id": "bring_pickup_1",
                        "isDefault": true,
                        "amount": {
                            "currency": "NOK",
                            "value": 3900
                        },
                        "priority": 0,
                        "name": "Gellerup Shoppen"
                    },
                    {
                        "id": "bring_pickup_2",
                        "amount": {
                            "currency": "NOK",
                            "value": 3900
                        },
                        "name": "Pakkeboks Bazar Vest",
                        "priority": 1
                    }
                ]
            },
            {
                "brand": "BRING",
                "type": "HOME_DELIVERY",
                "options": [
                    {
                        "id": "bring_home_1",
                        "amount": {
                            "currency": "NOK",
                            "value": 2900
                        },
                        "name": "Delivery to your door"
                    }
                ]
            }
        ]
    },
```

###### Shipping groups containing time slots

Some companies, such as Porterbuddy, offer dates with time slots.

Screenshot: Vipps Express shipping selection screen showing Porterbuddy time-slot delivery options grouped by date, each with a time window and price (e.g., "Tomorrow 17:00-19:00 - 99 kr").

Here's a clear way to present delivery options when companies like Porterbuddy provide both dates and time slots:

- `name`: The shipment date (e.g., `"Tuesday 2026-01-30"`)
- `estimatedDelivery`: The delivery time slot for that date (e.g., `"17:00 - 19:00"`)
- `priority`: Start from 0 for the earliest time slot, then count up (0 is the first slot, 1 is next, and so on)

For example, add the following to your [`POST:/epayment/v1/payments`](https://developer.vippsmobilepay.com/redocusaurus/epayment-swagger-id.yaml) request:

```json
 "shipping": {
        "fixedOptions": [
            {
                "brand": "PORTERBUDDY",
                "type": "HOME_DELIVERY",
                "options": [
                    {
                        "id": "porterbuddy_4417",
                        "amount": {
                            "currency": "NOK",
                            "value": 3900
                        },
                        "name": "Tuesday 2026-01-13",
                        "estimatedDelivery": "17:00 - 19:00"
                    },
                    {
                        "id": "porterbuddy_5410",
                        "amount": {
                            "currency": "NOK",
                            "value": 1900
                        },
                        "name": "Wednesday 2026-01-14",
                        "estimatedDelivery": "10:00 - 12:00"
                    }
                ]
            }
        ]
    },
```

#### Dynamic options

**TIP**

If you already know the available shipping options, you don't need to send dynamic options.

Instead, use `fixedOptions` to avoid the extra communication between our backend and your server. This makes the checkout faster and reduces the risk of drop-offs or errors.

Only use dynamic options when you don't know the user's address and need us to send it to you, so that you can respond with the relevant delivery options. If you already have the address or fixed delivery destinations (for example, in-store pickup), use fixed options.

Dynamic shipping options let you provide live delivery methods based on the user's address.

We send the user's address to your callback endpoint, and you return one or more groups of shipping options. These are then shown to the user on the shipping screen in the Vipps or MobilePay app.

Enable dynamic shipping by setting `shipping.dynamicOptions` in the
[create payment](https://developer.vippsmobilepay.com/redocusaurus/epayment-swagger-id.yaml) request.

To use dynamic options, include:

- **`callbackUrl`** - URL to your callback endpoint.
- **`callbackAuthorizationToken`** - Token used to securely authorize callbacks from our servers.

For example, add the following to the [`POST:/epayment/v1/payments`](https://developer.vippsmobilepay.com/redocusaurus/epayment-swagger-id.yaml) request.

```json
"shipping": {
  "dynamicOptions": {
    "callbackUrl": "https://example.com/shipping",
    "callbackAuthorizationToken": "Bearer eyJhbGciOi..."
  }
}
```

For more details, see the [Create payment spec](https://developer.vippsmobilepay.com/redocusaurus/epayment-swagger-id.yaml).

##### Callback request

We will provide the address to you as a JSON object with the following properties:

- **`reference`** (required): The unique identifier for the payment, specified when initiating the payment.
- **`AddressLine1`** (required): First address line.
- **`AddressLine2`**: Second address line.
- **`City`** (required): City name.
- **`PostCode`** (required): Postcode of the address in local country format.
- **`Country`** (required): The country of the address in ISO 3166-1 alpha-2 format.

For example:

```json
{
"reference": "shop-123-order123",
"AddressLine1": "Robert Levins gate 5",
"AddressLine2": "Apt 4",
"City": "Oslo",
"PostCode": "0154",
"Country": "NO"
}
```

For more details, see the callback section of the [Create payment spec](https://developer.vippsmobilepay.com/redocusaurus/epayment-swagger-id.yaml).

##### Callback response

Your server should respond with the shipping option groups in this JSON format:

`{ "groups": [ {shipping options 1}, {shipping options 2}, ... ] }`

The `groups` property contains an array with one or more shipping groups.
Each shipping group contains the properties described in [Shipping groups](#shipping-groups).

For example:

```json
{
  "groups": [
    {
      "isDefault": true,
      "priority": 0,
      "type": "PICKUP_POINT",
      "brand": "POSTNORD",
      "options": [
        {
          "id": "meny_grunerlokka",
          "isDefault": true,
          "amount": {
            "currency": "NOK",
            "value": 3900
          },
          "priority": 0,
          "name": "Meny Grünerløkka",
          "meta": "Henrik Ibsens Gate 1, 0000 Oslo",
          "estimatedDelivery": "In 2 days"
        },
        {
          "id": "bunnpris_skoyen",
          "isDefault": false,
          "amount": {
              "currency": "NOK",
              "value": 3900
              },
          "name": "Bunnpris Skøyen",
          "priority": 1,
          "meta": "Gatenavn 21, 0001 Oslo",
          "estimatedDelivery": "In 2 days"
        }
      ]
    }
  ]
}
```

## Get payment details

When you [create an Express payment](#create-an-express-payment)
and the user gives their consent, you will receive `shippingDetails` and `userDetails` in the
[`GET:/epayment/v1/payments/{reference}`](https://developer.vippsmobilepay.com/redocusaurus/epayment-swagger-id.yaml) response.
You can also get this information through the [ePayment webhook payload](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/webhooks.md#webhook-payload).

The `shippingDetails` object provides information about the shipment:

- `address` - An object that holds the recipient's shipping address, including: `addressLine1`, `addressLine2`, `city`, `country`, `postCode`.
- `shippingCost` - The cost of shipping, specified in minor currency units. For example, 9900 (99.00 NOK).
- `shippingOptionId` - The ID of the selected shipping option.
- `shippingOptionName` - The name of the selected shipping option.

The `userDetails` object contains the profile information the user has consented to share.

If the payment was created with [order details](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/features/pre-built-order-management-api-integration.md), we also set the
shipping order line there to the selected shipping method. If the customer changes their selection, the line is
updated, so it reflects their final choice.

For example:

```json
"shippingDetails": {
    "address": {
        "addressLine1": "BOKS 6300, ETTERSTAD",
        "addressLine2": "",
        "city": "OSLO",
        "country": "NO",
        "postCode": "0603"
    },
    "shippingCost": 0,
    "shippingOptionId": "posten2",
    "shippingOptionName": "Postibutikk"
},
"userDetails": {
    "email": "test.user@example.com",
    "firstName": "Test",
    "lastName": "User",
    "mobileNumber": "4712345678",
    "addresses": [
        {
            "addressLine1": "BOKS 6300, ETTERSTAD",
            "addressLine2": "",
            "city": "OSLO",
            "country": "NO",
            "postCode": "0603"
        },
        {
            "addressLine1": "Robert Levins gate 5",
            "addressLine2": "",
            "city": "Oslo",
            "country": "NO",
            "postCode": "0152"
        }
    ]
}
```

**Capture the authorized amount**

The amount the customer authorizes is the amount you sent when you created the payment, plus the cost of the
shipping option they selected. Capture `aggregate.authorizedAmount` from the response, not the amount you sent.
If you capture only your original amount, the shipping cost is never captured.

## Sequence diagram

Detailed Express flow

```mermaid
sequenceDiagram
    autonumber
    actor C as Customer
    participant M as Merchant backend
    participant ePayment as ePayment API
    participant Webhooks as Webhooks API

    C->>M: Click the Express button
    M->>ePayment: Create an Express payment with WALLET and shipping options<br />(POST /epayment/v1/payments)
    ePayment-->>M: redirectUrl and payment reference
    M->>C: Handle app switch with redirectUrl (tip: use Widget SDK)

    ePayment->>C: Ask to share address with merchant
    C->>ePayment: Consent to share profile information

    opt Dynamic shipping (shipping.dynamicOptions)
        ePayment->>M: Merchant dynamic shipping callback<br />(POST callbackUrl with reference and address)
        M->>M: Calculate shipping methods and costs
        M-->>ePayment: Return shipping groups (shipping options)
    end

    ePayment->>C: Show available shipping methods
    C->>ePayment: Select a shipping option

    ePayment->>ePayment: Update payment amount
    ePayment->>C: Ask the customer to confirm the total amount
    C->>ePayment: Confirm the total amount, cancel, or let the payment expire

    opt The customer confirmed the total amount
        ePayment->>ePayment: Reserve amount on customer card<br />(payment state = AUTHORIZED)
    end

    Webhooks-->>M: Webhook: the payment was authorized, aborted, or expired
    M->>ePayment: Poll for payment info, as a backup if the webhook is delayed or missed
    ePayment-->>M: Current state, with shippingDetails and userDetails

    alt The payment was aborted or expired
        M->>C: Return the customer to the page they started from
    else The payment was authorized
        M->>C: Display order confirmation
        M->>M: Prepare order (pack goods, ready to dispatch)

        M->>ePayment: Capture payment
        ePayment-->>M: Response with capturedAmount
        M->>M: Verify capturedAmount matches the expected full amount<br />before shipping
        M->>C: Hand the order to the carrier and ship it<br />(only after full capture verified)
    end

```

  Customer clicks the Express button on the merchant site.
  Merchant creates an Express payment via the ePayment API with the wallet payment method and shipping
  options.
  ePayment API returns a redirectUrl and payment reference to the merchant.
  Merchant handles the app switch with the redirectUrl. We recommend using the Widget SDK for this.
  ePayment API asks the customer to consent to sharing their address with the merchant. The customer does not
  yet see the total amount including shipping.
  Customer consents to sharing their profile information.
  If dynamic shipping is configured: ePayment API sends a callback to the merchant with the customer's address.
  The merchant calculates the shipping methods and costs, and returns the shipping groups to the ePayment API.
  ePayment API shows the available shipping methods to the customer.
  Customer selects a shipping option.
  ePayment API updates the payment amount and asks the customer to confirm the total amount.
  Customer confirms the total amount, cancels, or lets the payment expire.
  If the customer confirmed the total amount, the ePayment API reserves the amount on the customer's card
  (payment state becomes AUTHORIZED).
  Webhooks API sends the merchant an authorized, aborted, or expired event.
  Merchant polls the ePayment API for the payment info, as a backup if the webhook is delayed or missed, and
  gets the current state, including the shipping details and the user details.
  If the payment was aborted or expired, the merchant returns the customer to the page they started from, and the
  flow ends.
  If the payment was authorized, the merchant displays order confirmation to the customer.
  Merchant prepares the order (packs goods, makes ready to dispatch).
  Merchant captures the payment via the ePayment API, which responds with the captured amount. The merchant
  verifies that the captured amount matches the expected full amount before shipping.
  Merchant hands the order to the carrier and ships it (only after full capture is verified).

## Button guidelines

Choose one of these button formats for Express:

1. **"Buy now with Vipps/MobilePay"** (Recommended) - Full call-to-action text
2. **"Vipps Express / MobilePay Express"** - Compact format
3. **Icon + "Express"** - For limited-width areas (e.g., shopping cart pop-ups)

**NOTE**

For **Option 3** (Icon + "Express"), use the **white logo versions**, as these are optimized for display on Vipps orange or MobilePay blue backgrounds.

Download the white icons:

- [Vipps smile icon (white)](https://developer.vippsmobilepay.com/img/logos/vipps-white.svg)
- [MobilePay logo icon (white)](https://developer.vippsmobilepay.com/img/logos/mobilepay-white.svg)

**You must use the approved button text for your market.**

These are the approved button texts for each supported language, including the allowed ways to combine the logo
with the name.

#### Vipps

| Language | Full text | Compact | With icon |
| --- | --- | --- | --- |
| Danish | Køb nu med Vipps | Vipps Ekspres | Ekspres |
| Finnish | Osta nyt Vippsillä | Vipps Express | Express |
| Norwegian | Kjøp nå med Vipps | Vipps Ekspress | Ekspress |
| Swedish | Köp nu med Vipps | Vipps Express | Express |
| English | Buy now with Vipps | Vipps Express | Express |

In the *With icon* column, put the white logo icon on an orange background
before the language-specific word for Express.

#### MobilePay

| Language | Full text | Compact | With icon |
| --- | --- | --- | --- |
| Danish | Køb nu med MobilePay | MobilePay Ekspres | Ekspres |
| Finnish | Osta nyt MobilePaylla | MobilePay Express | Express |
| Norwegian | Kjøp nå med MobilePay | MobilePay Ekspress | Ekspress |
| Swedish | Köp nu med MobilePay | MobilePay Express | Express |
| English | Buy now with MobilePay | MobilePay Express | Express |

In the *With icon* column, put the white logo icon on a blue background
before the language-specific word for Express.

**Get the approved buttons**

You don't need to build the buttons yourself. Download all the approved Express buttons, in every language and
format, as a zip file from the
[Buttons section of the brand guidelines](https://brand.vippsmobilepay.com/document/61#/branding/online/buttons).

If you can dynamically generate buttons with JavaScript,
see our [JavaScript button library](https://developer.vippsmobilepay.com/docs/knowledge-base/buttons.md).

## Brand logos

Here are the brands we currently have in the app.

If you need another logo, [let us know](https://developer.vippsmobilepay.com/docs/contact.md).
