> **Description:** Step-by-step guide for migrating from eCom to ePayment API with mapping of endpoints and payment flows.

# Migrate from eCom to ePayment

## Overview

The ePayment API expands upon the functionality of the eCom API and simplifies existing flows.
Merchants currently using the eCom API should find the ePayment API familiar and intuitive.

The ePayment API is *backwards compatible* with the eCom API.
Payments initiated via the eCom API can be captured, refunded, cancelled, and retrieved using the ePayment API, but not vice versa.

**Important**

Payments initiated with the ePayment API can't be modified or retrieved using the eCom API.
Merchants are advised to fully migrate to the ePayment API.
However, it is possible to migrate one endpoint at a time,
*provided that the Create Payment endpoint is migrated last*.

## Key differences

### New features

The ePayment API [Express](#express) solution contains all the features of the eCom API.

New features include:

* [Freestanding card payments](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/features/freestanding-card-payments.md)
* [Specify customer present](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/features/customer-present-payments.md)
* [Minimum user age](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/features/minimum-user-age.md)
* [Add metadata](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/features/metadata.md)

### Support for Finland and Denmark

The ePayment API can be used by merchants in Finland and Denmark, in addition to Norway.

See [Offering Vipps MobilePay in the Nordics](https://developer.vippsmobilepay.com/docs/knowledge-base/across-borders.md) for details.

### Callbacks are replaced with webhooks

The ePayment API does not use callbacks, therefore, `callbackPrefix` is no longer used.
To get a report of events taking place for a payment request,
register [webhooks](#webhooks).

### User flow parameters

Skipping the landing page is now specified with the new `userFlow` parameter rather than
the complex `isApp` of eCom.
See [User flow](#user-flow).

### Get event log

New [Get event log](#get-payment-event-log) endpoint lets you get a history of all the events (e.g., authorize, capture, refund) that happen to a payment.

### Parameter name changes

These parameter names are remapped across all the endpoints and responses:

| eCom                    | ePayment                          |
| ----------------------- | --------------------------------- |
| `X-Request-Id`          | `Idempotency-Key`                 |
| `orderId`               | `reference`                       |
| `merchantInfo.fallback` | `returnUrl`                       |
| `transactionText`       | `paymentDescription`              |
| `mobileNumber`          | `phoneNumber` (MSISDN format)     |
| `amount`                | `amount.currency`, `amount.value` |
| `Merchant-Serial-Number`| (moved to the header)             |
| `callbackPrefix`        | (deleted)                         |

All the endpoints have changed, as shown in the sections that follow.

## Endpoints

* [Create](#create)
* [Capture](#capture)
* [Cancel](#cancel)
* [Refund](#refund)
* [Get payment details](#get-payment-details)
* [Get payment event log](#get-payment-event-log)

### Create

**eCom initiate payment endpoint**

[`POST:/ecomm/v2/payments`](https://developer.vippsmobilepay.com/redocusaurus/ecom-swagger-id.yaml)

**ePayment create payment endpoint**

[`POST:/epayment/v1/payments`](https://developer.vippsmobilepay.com/redocusaurus/epayment-swagger-id.yaml)

**Required header parameters**

* `Authorization`
* `Ocp-Apim-Subscription-Key`

**Required header parameters**

* `Authorization`
* `Ocp-Apim-Subscription-Key`
* `Merchant-Serial-Number` 🆕
* `Idempotency-Key` 🆕

**Required body parameters**

* `transaction`
  * `amount` -> `amount.value`
  * `orderId` -> `reference`
  * `transactionText` -> `paymentDescription`
* `customerInfo` -> `customer`
* `merchantInfo`
  * `callbackPrefix` -> Removed
  * `fallBack` -> `returnUrl`
  * `merchantSerialNumber` ->  Moved to header

**Required and related body parameters**

* `amount`
  * `currency` - NOK, DKK, EUR (must match the currency of your sales unit)
  * `value` - Amount in minor units
* `reference`
* `customer`
* `returnUrl`
* `paymentDescription`
* [`paymentMethod`](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/operations/create.md#paymentmethod) 🆕
  * `type` - Typically set to `WALLET`
* [`userFlow`](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/operations/create.md#userflow) 🆕 - Typically set to `WEB_REDIRECT` (normal flow).

See [parameters](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/operations/create.md#parameters) for details.

*Example of payload:*

```json
{
  "customerInfo": {
    "mobileNumber": "12345678"
    },
  "transaction": {
    "orderId": "acme-shop-123-order123abc",
    "transactionText": "Phone cover",
    "amount": 20000
  },
  "merchantInfo": {
    "fallBack": "https://example.com/fb",
    "callbackPrefix": "https://example.com/cb",
    "merchantSerialNumber": "123456"
  }
}
```

*Example of payload:*

```json
{
  "customer":{
      "phoneNumber":"4712345678"
  },
  "reference":"acme-shop-123-1234589",
  "paymentDescription": "Phone cover",
  "amount":{
      "value":20000,
      "currency":"NOK"
  },
  "returnUrl":"https://example.com/fb",
  "userFlow":"WEB_REDIRECT",
  "paymentMethod":{
      "type":"WALLET"
  }
}
```

**Response**

* `orderId` ->  `reference`
* `url` -> `redirectUrl`

*Example response:*

```json
{
  "orderId": "acme-shop-123-order123abc",
  "url": "https://api.vipps.no/<snip>"
}
```

**Response**

* `reference`
* `redirectUrl`

*Example response:*

```json
{
  "reference": "acme-shop-123-order123abc",
  "redirectUrl": "https://example.com"
}
```

**eCom details**

* [API spec](https://developer.vippsmobilepay.com/redocusaurus/ecom-swagger-id.yaml)
* [Create payment guide](https://developer.vippsmobilepay.com/docs/APIs/ecom-api/vipps-ecom-api.md#initiate)

**ePayment details**

* [API spec](https://developer.vippsmobilepay.com/redocusaurus/epayment-swagger-id.yaml)
* [Create payment guide](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/operations/create.md)

### Capture

When you start a payment, the amount is first **reserved**. You then need to **capture** it to complete the transaction.
You can capture **right away** or [**any time within 180 days**](https://developer.vippsmobilepay.com/docs/knowledge-base/reserve-and-capture.md#capture-deadlines).

>  **Important**: The ePayment API supports *reserve capture only*.
> This means there's **no** *direct capture* option, unlike the eCom API.

### Why reserve capture?

Reserve capture gives you more flexibility:

* Supports partial capture
* Cancel the reservation at any time before capture, instantly freeing up the funds in the customer's account.
* Perfect when the final amount isn't known at the time of payment, for example:
  * [Vending machines](https://developer.vippsmobilepay.com/docs/recommended-flows/vending-machines/qr-direct-to-payment-in-app.md)

**Typical flow**:

* Reserve a higher amount.
* Capture only what's needed.
* Cancel the rest.

For more details, see [Reserve capture vs. Direct capture](https://developer.vippsmobilepay.com/docs/knowledge-base/reserve-and-capture.md#reserve-capture-vs-direct-capture).

### Partial capture

The ePayment API supports **partial captures** -- handy when shipping items separately, so you can capture payment for each shipment as it goes out.

**eCom capture**

[`POST:/ecomm/v2/payments/{orderId}/capture`](https://developer.vippsmobilepay.com/redocusaurus/ecom-swagger-id.yaml)

**ePayment capture**

[`POST:/epayment/v1/payments/{reference}/capture`](https://developer.vippsmobilepay.com/redocusaurus/epayment-swagger-id.yaml)

**Path parameters**

* `orderId` -> `reference`

**Path parameters**

* `reference`

**Required header parameters**

* `Authorization`
* `Ocp-Apim-Subscription-Key`
* `X-Request-Id` -> `Idempotency-Key`

**Required header parameters**

* `Authorization`
* `Ocp-Apim-Subscription-Key`
* `Idempotency-Key` 🆕
* `Merchant-Serial-Number` 🆕

**Body parameters**

* `transaction`
  * `amount` -> `modificationAmount.value`
  * `transactionText` - Removed
* `merchantInfo`
  * `merchantSerialNumber` - Moved to the header

**Body parameters**

* `modificationAmount`
  * `value`
  * `currency` - `NOK`, `DKK`, `EUR`

*Example of payload:*

```json
{
  "merchantInfo": {
    "merchantSerialNumber": "123456"
  },
  "transaction": {
    "amount": 49900,
    "transactionText": "Phone cover"
  }
}
```

*Example of payload:*

```json
{
  "modificationAmount": {
    "currency": "NOK",
    "value": 49900
  }
}

```

**Response**

* `orderId` - Same as `reference`
* `transactionInfo`
  * `amount` - Correlates to `amount.value`
  * `status` - Correlates to `state`
  * `timeStamp`
  * `transactionId`
  * `transactionText`
* `transactionSummary` - Similar to `aggregate`
  * `capturedAmount`
  * `refundedAmount`
  * `remainingAmountToCapture`
  * `remainingAmountToRefund`
  * `bankIdentificationNumber`
* `paymentInstrument` - No longer returned

**Response**

* `reference`
* `amount`
  * `currency`
  * `value`
* `state`
* `aggregate`
  * `authorizedAmount`
  * `cancelledAmount`
  * `capturedAmount`
  * `refundedAmount`
* [`pspReference`](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/concepts.md#understanding-pspreference)

*Example response:*

```json
{
 "paymentInstrument": "Mastercard",
 "orderId": "acme-shop-123-order123abc",
 "transactionInfo": {
   "amount": 49900,
   "status": "Captured",
   "timeStamp": "2018-12-12T11:18:38.246Z",
   "transactionId": "5432123456",
   "transactionText": "Phone cover"
  },
  "transactionSummary": {
   "capturedAmount": 49900,
   "refundedAmount": 0,
   "remainingAmountToCapture": 0,
   "remainingAmountToRefund": 49900,
   "bankIdentificationNumber": 123456
  }
}

```

*Example response:*

```json
{
  "amount": {
    "currency": "NOK",
    "value": 49900
  },
  "state": "CREATED",
  "aggregate": {
    "authorizedAmount": {
      "currency": "NOK",
      "value": 49900
    },
    "cancelledAmount": {
      "currency": "NOK",
      "value": 0
    },
    "capturedAmount": {
      "currency": "NOK",
      "value": 49900
    },
    "refundedAmount": {
      "currency": "NOK",
      "value": 0
    }
  },
  "pspReference": "3343121302",
  "reference": "acme-shop-123-order123abc"
}
```

**eCom details**

* [API spec](https://developer.vippsmobilepay.com/redocusaurus/ecom-swagger-id.yaml)
* [Capture guide](https://developer.vippsmobilepay.com/docs/APIs/ecom-api/vipps-ecom-api.md#capture)

**ePayment details**

* [API spec](https://developer.vippsmobilepay.com/redocusaurus/epayment-swagger-id.yaml)
* [Capture guide](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/operations/capture.md)

### Cancel

The cancel endpoint is used to cancel reserved payments.

There is no `shouldReleaseRemainingFunds` flag in the new ePayment API endpoint.
Cancelling a payment will always cancel the entire remaining not-captured amount; this is irreversible.

So, if you want to capture part of the reserved amount, you should send the [capture](#capture) request first.
Then send the cancel request, [`POST:/epayment/v1/payments/{reference}/cancel`](https://developer.vippsmobilepay.com/redocusaurus/epayment-swagger-id.yaml). There is no amount specified.

**eCom cancel**

[`PUT:/ecomm/v2/payments/{orderId}/cancel`](https://developer.vippsmobilepay.com/redocusaurus/ecom-swagger-id.yaml)

**ePayment cancel**

[`POST:/epayment/v1/payments/{reference}/cancel`](https://developer.vippsmobilepay.com/redocusaurus/epayment-swagger-id.yaml)

**eCom path parameters**

* `orderId` -> `reference`

**ePayment path parameters**

* `reference`

**eCom required header parameters**

* `Authorization`
* `Ocp-Apim-Subscription-Key`

**ePayment required header parameters**

* `Authorization`
* `Ocp-Apim-Subscription-Key`
* `Merchant-Serial-Number` 🆕

**eCom body parameters**

* `transaction`
  * `amount` - Removed
  * `transactionText` - Removed
* `merchantInfo`
  * `merchantSerialNumber` - Moved to the header

**ePayment body parameters**

* `cancelTransactionOnly` 🆕 - Only cancel transaction if it has not been authorized.

*Example of payload:*

```json
{
  "merchantInfo": {
    "merchantSerialNumber": "123456"
  },
  "transaction": {
    "transactionText": "Phone cover"
  },
  "shouldReleaseRemainingFunds": false
}
```

*Example of payload:*

```json
{
  "cancelTransactionOnly": true
}

```

**Response**

* `orderId` -> `reference`
* `paymentInstrument` -> Deleted
* `transactionInfo`
  * `amount` -> Correlates to `amount.value`
  * `status` -> Correlates to `state` Enum: `Cancelled`, `Captured`, `Refund`
  * `timeStamp`
  * `transactionId`
  * `transactionText`
* `transactionSummary` -> Similar to `aggregate`
  * `capturedAmount`
  * `refundedAmount`
  * `remainingAmountToCapture`
  * `remainingAmountToRefund`
  * `bankIdentificationNumber`

**Response**

* `reference`
* `amount`
  * `currency`
  * `value`
* [`state`](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/concepts.md#payment-states) - `CREATED`, `ABORTED`, `EXPIRED`, `AUTHORIZED`, `TERMINATED`
* `aggregate`
  * `authorizedAmount`
  * `cancelledAmount`
  * `capturedAmount`
  * `refundedAmount`
* [`pspReference`](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/concepts.md#understanding-pspreference)

*Example response:*

```json
{
  "paymentInstrument": "Mastercard",
  "orderId": "acme-shop-123-order123abc",
  "transactionInfo": {
    "amount": 49900,
    "status": "Captured",
    "timeStamp": "2018-12-12T11:18:38.246Z",
    "transactionId": "5432123456",
    "transactionText": "Phone cover"
  },
  "transactionSummary": {
    "capturedAmount": 49900,
    "refundedAmount": 0,
    "remainingAmountToCapture": 0,
    "remainingAmountToRefund": 49900,
    "bankIdentificationNumber": 123456
  }
}
```

*Example response:*

```json
{
  "amount": {
    "currency": "NOK",
    "value": 49900
  },
  "state": "CREATED",
  "aggregate": {
    "authorizedAmount": {
      "currency": "NOK",
      "value": 49900
    },
    "cancelledAmount": {
      "currency": "NOK",
      "value": 49900
    },
    "capturedAmount": {
      "currency": "NOK",
      "value": 49900
    },
    "refundedAmount": {
      "currency": "NOK",
      "value": 49900
    }
  },
  "pspReference": "3343121302",
  "reference": "acme-shop-123-order123abc"
}
```

**eCom details**

* [API spec](https://developer.vippsmobilepay.com/redocusaurus/ecom-swagger-id.yaml)
* [Cancel guide](https://developer.vippsmobilepay.com/docs/APIs/ecom-api/vipps-ecom-api.md#cancel)

**ePayment details**

* [API spec](https://developer.vippsmobilepay.com/redocusaurus/epayment-swagger-id.yaml)
* [Cancel guide](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/operations/cancel.md)

### Refund

**eCom refund**

[`POST:/ecomm/v2/payments/{orderId}/refund`](https://developer.vippsmobilepay.com/redocusaurus/ecom-swagger-id.yaml)

**ePayment refund**

[`POST:/epayment/v1/payments/{reference}/refund`](https://developer.vippsmobilepay.com/redocusaurus/epayment-swagger-id.yaml)

**Path parameters**

* `orderId` -> `reference`

**Path parameters**

* `reference`

**Required header parameters**

* `Authorization`
* `Ocp-Apim-Subscription-Key`
* `X-Request-Id` -> `Idempotency-Key`

**Required header parameters**

* `Authorization`
* `Ocp-Apim-Subscription-Key`
* `Merchant-Serial-Number` 🆕
* `Idempotency-Key` 🆕

**Body parameters**

* `transaction`
  * `amount` -> `modificationAmount.value`
  * `transactionText` -> Removed
* `merchantInfo`
  * `merchantSerialNumber` - Moved to the header

**Body parameters**

* `modificationAmount`
  * `currency`
  * `value`

*Example of payload:*

```json
{
  "merchantInfo": {
    "merchantSerialNumber": "123456"
  },
  "transaction": {
    "amount": 49900,
    "transactionText": "Phone cover"
  }
}
```

*Example of payload:*

```json
{
  "modificationAmount": {
    "currency": "NOK",
    "value": 49900
  }
}

```

**Response**

* `orderId` -> `reference`
* `transaction`
  * `amount` -> `amount.value`
  * `status` -> `state`
  * `timeStamp`
  * `transactionId`
  * `transactionText`
* `transactionSummary` -> `aggregate`
  * `capturedAmount`
  * `refundedAmount`
  * `remainingAmountToCapture`
  * `remainingAmountToRefund`
  * `bankIdentificationNumber`

**Response**

* `reference`
* `amount`
  * `currency`
  * `value`
* [`state`](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/concepts.md#payment-states) (values have changed)
* `aggregate`
  * `authorizedAmount`
  * `cancelledAmount`
  * `capturedAmount`
  * `refundedAmount`
* [`pspReference`](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/concepts.md#understanding-pspreference)

*Example:*

```json
{
  "orderId": "acme-shop-123-order123abc",
  "transaction": {
    "amount": 49900,
    "status": "Captured",
    "timeStamp": "2018-12-12T11:18:38.246Z",
    "transactionId": "5432123456",
    "transactionText": "Phone cover"
  },
  "transactionSummary": {
    "capturedAmount": 49900,
    "refundedAmount": 0,
    "remainingAmountToCapture": 0,
    "remainingAmountToRefund": 49900,
    "bankIdentificationNumber": 123456
  }
}

```

*Example:*

```json
{
  "reference": "acme-shop-123-order123abc",
  "amount": {
    "currency": "NOK",
    "value": 49900
  },
  "state": "CREATED",
  "aggregate": {
    "authorizedAmount": {
      "currency": "NOK",
      "value": 49900
    },
    "cancelledAmount": {
      "currency": "NOK",
      "value": 49900
    },
    "capturedAmount": {
      "currency": "NOK",
      "value": 49900
    },
    "refundedAmount": {
      "currency": "NOK",
      "value": 49900
    }
  },
  "pspReference": "3343121302"
}
```

**eCom details**

* [API spec](https://developer.vippsmobilepay.com/redocusaurus/ecom-swagger-id.yaml)
* [eCom refund guide](https://developer.vippsmobilepay.com/docs/APIs/ecom-api/vipps-ecom-api.md#cancel)

**ePayment details**

* [API spec](https://developer.vippsmobilepay.com/redocusaurus/epayment-swagger-id.yaml)
* [Refund guide](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/operations/refund.md)

### Get payment details

Retrieve the full history of a payment and the status of the operations.

**eCom get payment details**

[`GET:/ecomm/v2/payments/{orderId}/details`](https://developer.vippsmobilepay.com/redocusaurus/ecom-swagger-id.yaml)

**ePayment get payment details**

[`GET:/epayment/v1/payments/{reference}`](https://developer.vippsmobilepay.com/redocusaurus/epayment-swagger-id.yaml)

**Path parameters**

* `orderId` -> `reference`

**Path parameters**

* `reference`

**Required header parameters**

* `Authorization`
* `Ocp-Apim-Subscription-Key`

**Required header parameters**

* `Authorization`
* `Ocp-Apim-Subscription-Key`
* `Merchant-Serial-Number`

**Body parameters**

(none)

**Body parameters**

(none)

**eCom response parameters**

* `orderId` -> `reference`
* `transactionLogHistory` (array)
  * `amount` -> `amount.value`
  * `operation` -> Correlates to `state`
     ("INITIATE" "RESERVE" "SALE" "CAPTURE" "REFUND" "CANCEL" "VOID")
  * `operationSuccess`
  * `requestId`
  * `timeStamp`
  * `transactionId`
  * `transactionText`
* `transactionSummary` -> Similar to `aggregate`
  * `capturedAmount`
  * `refundedAmount`
  * `remainingAmountToCapture`
  * `remainingAmountToRefund`
  * `bankIdentificationNumber`

Additional properties when Express or Profile Sharing has been used:

* `shippingDetails` - Closely matches `shippingDetails` in ePayment
* `userDetails` - Closely matches `userDetails` in ePayment with this exception:
  * `mobileNumber` (no country code)
  * `userId` - no correlation in ePayment
* `sub` - Correlates to `profile.sub`

**ePayment response parameters**

* `reference`
* `aggregate`
  * `authorizedAmount`
  * `cancelledAmount`
  * `capturedAmount`
  * `refundedAmount`
* `amount`
  * `currency`
  * `value`
* [`state`](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/concepts.md#payment-states) - `CREATED`, `ABORTED`, `EXPIRED`, `AUTHORIZED`, `TERMINATED`
* `paymentMethod`
  * `type` - `WALLET` or `CARD`
* [`pspReference`](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/concepts.md#understanding-pspreference)
* `redirectUrl`

Additional properties supplied when Express or Profile Sharing has been used:

* `shippingDetails`
* `userDetails` - Correlates to `userDetails` in eCom.  `mobileNumber` (includes country code)
* `profile`
  * `sub` - `profile.sub` correlates to `sub` in eCom.

*Example response:*

```json
{
  "orderId": "acme-shop-123-order123abc",
  "transactionLogHistory": [
   {
    "amount": 0,
    "operation": "RESERVE",
    "operationSuccess": true,
    "requestId": "12983921873981899000",
    "timeStamp": "2026-01-05T12:27:42.311Z",
    "transactionId": "5001446662",
    "transactionText": "Phone cover"
   }
  ],
  "transactionSummary": {
    "capturedAmount": 49900,
    "refundedAmount": 0,
    "remainingAmountToCapture": 0,
    "remainingAmountToRefund": 49900,
    "bankIdentificationNumber": 123456
  },
}
```

*Example response:*

```json
{
  "aggregate": {
      "authorizedAmount": {
          "currency": "NOK",
          "value": 49900
      },
      "cancelledAmount": {
          "currency": "NOK",
          "value": 49900
      },
      "capturedAmount": {
          "currency": "NOK",
          "value": 0
      },
      "refundedAmount": {
          "currency": "NOK",
          "value": 0
      }
  },
  "amount": {
      "currency": "NOK",
      "value": 49900
  },
  "state": "AUTHORIZED",
  "paymentMethod": {
      "type": "WALLET"
  },
  "profile": {},
  "pspReference": "37c34d8<snip>",
  "reference": "acme-shop-123-order123abc"
}
```

**eCom details**

* [API spec](https://developer.vippsmobilepay.com/redocusaurus/ecom-swagger-id.yaml)
* [Get payment guide](https://developer.vippsmobilepay.com/docs/APIs/ecom-api/vipps-ecom-api.md#get-payment-details)

**ePayment details**

* [API spec](https://developer.vippsmobilepay.com/redocusaurus/epayment-swagger-id.yaml)
* [Get payment guide](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/operations/get_info.md)

### Get payment event log

The ePayment API offers a new endpoint that lets you see all the events for a specific payment.

**ePayment get payment event log**

[`GET:/epayment/v1/payments/{reference}/events`](https://developer.vippsmobilepay.com/redocusaurus/epayment-swagger-id.yaml)

**Path parameter:**

* `reference` - same as `orderId`

**Required header parameters:**

* `Authorization`
* `Ocp-Apim-Subscription-Key`

*Example response:*

```json
[
  { // Create Payment example event
    "reference": "acme-shop-123-order123abcd",
    "pspReference": "83b3fdb0-9547-4ec5-bdb7-5600ce70e792",
    "name": "CREATED",
    "amount": { "currency": "NOK", "value": 49900 },
    "timestamp": "2026-01-27T10:51:44.5333258Z",
    "idempotencyKey": "219986263-dedf-4b8e-a424-8d042eee4012",
    "success": true
  },
  { // Payment authorized example event
    "reference": "acme-shop-123-order123abcd",
    "pspReference": "1304787731",
    "name": "AUTHORIZED",
    "amount": { "currency": "NOK", "value": 49900 },
    "timestamp": "2026-01-27T10:51:59.378Z",
    "idempotencyKey": "219986263-dedf-4b8e-a424-8d042eee4012",
    "success": true
  },
  { // Captured Payment example event
    "reference": "acme-shop-123-order123abcd",
    "pspReference": "2018200034",
    "name": "CAPTURED",
    "amount": { "currency": "NOK", "value": 49900 },
    "timestamp": "2026-01-27T10:52:07.748Z",
    "idempotencyKey": "219986263-dedf-4b8e-a424-8d042eee4012",
    "success": true
  }
]
```

**ePayment details:**

* [API spec](https://developer.vippsmobilepay.com/redocusaurus/epayment-swagger-id.yaml)
* [Get event log guide](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/operations/get_event_log.md)

## Error handling

Both eCom and ePayment return HTTP response codes; however, the standard response body format has changed.

The standard response body format for the ePayment error messages follows
[RFC 7807](https://tools.ietf.org/html/rfc7807).

See [ePayment error handling](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/errors.md).

## User flow

In the eCom API, merchants could choose between three flows by specifying the parameters
`isApp` and `skipLandingPage`.

In ePayment: Instead of specifying the parameters, you now decide which flow you want through the
`userFlow` property. Here's how the fields correspond to each other:

* `isApp: false` and `skipLandingPage: false` -> `WEB_REDIRECT`
* `isApp: true` and `skipLandingPage: false`  -> `NATIVE_REDIRECT`
* `skipLandingPage: true`                     -> `PUSH_MESSAGE`

The ePayment API also supports a new flow:
[the `QR` flow](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/features/qr-payments.md).
The QR flow provides you with a direct link to a one-time payment QR code that the user can scan and pay from their app.

## Payment states

A payment will not change state after becoming `AUTHORIZED`. This is because a payment can be *partially* captured, and also *partially* refunded.
It is therefore not practical to have states like "captured" or "refunded", since it is not possible to give all the information with just the state.
A payment can be *partially* captured, *partially* refunded, or cancelled, but it will not change the state.

Here is a state comparison:

| eCom state | ePayment state | Description                                                                  |
| ---------- | -------------- | ---------------------------------------------------------------------------- |
| `INITIATE` | `CREATED`      | The payment has been initiated. The user has not yet acted upon the payment. |
| `RESERVE`  | `AUTHORIZED`   | The user has accepted the payment in the app. This is a final state.         |
| `VOID`     | `ABORTED`      | The payment has been actively stopped by the user. The user has aborted the payment before authorization. This is a final state. |
|            | `EXPIRED`      | The payment has expired. The user did not act on the payment within the payment expiration time. This is a final state. |
|            | `TERMINATED`   | The merchant has cancelled the payment before authorization. The merchant has terminated the payment via the cancel endpoint. This is a final state. |
| `CAPTURE`  |                | (deleted)             |
| `REFUND`   |                | (deleted)             |
| `CANCEL`   |                | (deleted)             |
| `SALE`     |                | (deleted)             |

For details, see [ePayment payment states](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/concepts.md#payment-states).

## Webhooks

The ePayment API supports webhooks, whereas the eCom API only supports callbacks.

To receive webhook notifications, register the URLs that will accept a POST request whenever a payment event occurs.

Webhook events are available for payments initiated through the ePayment API. For example
payment created, payment aborted, and payment expired.

Note that you should not rely on webhooks alone, and should poll according to the
[polling recommendations](https://developer.vippsmobilepay.com/docs/knowledge-base/polling-guidelines.md).

**INFO**

The Webhooks API provides *guaranteed delivery*: If the callback is not successful
(we do not get the expected `HTTP 200 OK` response from you), we will retry for several days.
In addition, you can now receive webhooks for *all* adjustments to your payment.

See:

* [Webhooks](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/webhooks.md)
* [ePayment webhook events](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/webhooks.md)

## Feature migrations

### Express

The new [Express](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/features/express.md)
has more features than [eCom](https://developer.vippsmobilepay.com/docs/APIs/ecom-api/vipps-ecom-api.md#express).
You get a nicer experience in the app because you will get brand icons, and you can create groupings
where there are several options available per group.

Screenshot: Express shipping options screen showing available delivery methods for the customer to choose from.

**key differences**

Key differences from eCom Express to ePayment Express include:

* **Shipping groups**
  In ePayment Express, shipping options are organized into **groups** using the `shipping.fixedOptions` array. Each group is defined by a combination of:

  * **brand** (e.g., POSTEN, HELTHJEM, DHL)
  * **type** (e.g., HOME_DELIVERY, PICKUP_POINT, MAILBOX, IN_STORE, OTHER)

  Within each group, there can be multiple **sub-options** in the `options` array. Each sub-option represents a specific delivery choice, such as a particular store location or delivery method.

* **Callback for dynamic shipping details**
  The format of the callback information has changed.

* **Consent removal**
  The ePayment API does not require you to support the consent removal options, but we do recommend that you don't keep their information any longer than needed for the shipping to be completed.

In the new Express, split your options into groups with the same type and brand.
For details, see [Express shipping options](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/features/express.md#shipping-options).

**eCom Express**

[`POST:/ecomm/v2/payments`](https://developer.vippsmobilepay.com/redocusaurus/ecom-swagger-id.yaml)

**ePayment Express**

[`POST:/epayment/v1/payments`](https://developer.vippsmobilepay.com/redocusaurus/epayment-swagger-id.yaml)

**eCom body parameters**

Same as for the regular [eCom create payment request](#create)
with these changes:

* `merchantInfo`
  * `consentRemovalPrefix` - no longer required
  * `staticShippingDetails` (see Fixed options below)
  * `shippingDetailsPrefix` (see Dynamic options below)
  * `authToken` (see Dynamic options below)

**ePayment body parameters**

Same as for the regular [ePayment create payment request](#create)
with these additions:

* `paymentMethod.type` - Set to `WALLET`
* `profile.scope` - Set to `"name address email phoneNumber"`
* `shipping`
  * `fixedOptions`  (see Fixed options below)
  * `dynamicOptions` (see Dynamic options below)

**eCom fixed options**

* `staticShippingDetails` -> `shipping.fixedOptions`

  * `isDefault`
  * `priority`

The following are moved to the specific options within each group (`fixedOptions.options.[array_item]`):

* `shippingCost` -> `amount.value` **(now minor units)**
* `shippingMethod` -> `name`
* `shippingMethodId` -> `id`

**ePayment fixed options**

* [`fixedOptions`](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/features/express.md#fixed-options)
  * `isDefault` (**Boolean**)
  * `priority`
  * `type` - `HOME_DELIVERY`, `PICKUP_POINT`, and others
  * `brand` - `BRING`, `DHL`, `FEDEX`, and others
  * `options` (array)
    * `id`
    * `amount` (`currency`, `value`)
    * `name`
    * `isDefault`
    * `priority`
    * `meta`
    * `estimatedDelivery`

**eCom dynamic options**

* `shippingDetailsPrefix` -> `callbackUrl`
* `authToken` -> `callbackAuthorizationToken`

**ePayment dynamic options**

* [`dynamicOptions`](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/features/express.md#dynamic-options)
  * `callbackUrl`
  * `callbackAuthorizationToken`

**eCom payload example**

```json
{
  "merchantInfo": {
    "staticShippingDetails": [
      {
        "isDefault": "Y",
        "priority": 1,
        "shippingCost": 59,
        "shippingMethod": "POSTEN - In the mailbox",
        "shippingMethodId": "shippingMethodId1"
      },
      {
        "isDefault": "N",
        "priority": 2,
        "shippingCost": 39,
        "shippingMethod": "POSTEN - Oslo S",
        "shippingMethodId": "shippingMethodId2"
      },
      {
        "isDefault": "N",
        "priority": 3,
        "shippingCost": 39,
        "shippingMethod": "POSTEN - Bjørvika",
        "shippingMethodId": "shippingMethodId3"
      }
    ],
    "fallBack": "https://example.com/fb",
    "callbackPrefix":"https://example.com/cb",
    "consentRemovalPrefix": "https://example.com/cm",
    "merchantSerialNumber": "123456",
    "paymentType": "eComm Express Payment",
    "shippingDetailsPrefix": "https://example.com/s"
  },
  "customerInfo": {
    "mobileNumber": "12345678"
  },
  "transaction": {
    "orderId": "acme-shop-123-order123abc",
    "transactionText": "Phone cover",
    "amount": 20000
  }
}
```

**ePayment payload example**

```json
{
"shipping": {
  "fixedOptions": [ {
      "isDefault": true,
      "priority": 1,
      "type": "HOME_DELIVERY",
      "brand": "POSTEN",
      "options": [{
        "isDefault": true,
        "priority": 1,
        "amount": { "currency": "NOK", "value": 5900 },
        "name": "Posten:Home delivery",
        "id": "shippingMethodId1"
        }]
    },
    {
        "type": "PICKUP_POINT",
        "brand": "POSTEN",
        "options": [{
            "isDefault": true,
            "priority": 1,
            "amount": { "currency": "NOK", "value": 3900 },
            "name": "POSTEN - Oslo S",
            "id": "shippingMethodId3"
            },
            {
            "amount": { "currency": "NOK", "value": 3900 },
            "name": "POSTEN - Bjørvika",
            "id": "shippingMethodId4"
        }]
    }
    ]
  },
  "profile": { "scope": "name address email phoneNumber" },
  "customer": { "phoneNumber": "4712345678" },
  "amount": { "currency": "NOK", "value": 20000 },
  "paymentMethod": { "type": "WALLET" },
  "reference": 2810171754658432260,
  "userFlow": "WEB_REDIRECT",
  "returnUrl": "https://example.com",
  "paymentDescription": "Purchase of socks"
}
```

**eCom details**

* [API spec](https://developer.vippsmobilepay.com/redocusaurus/ecom-swagger-id.yaml)
* [Express guide](https://developer.vippsmobilepay.com/docs/APIs/ecom-api/vipps-ecom-api.md#express)

**ePayment details:**

* [API spec](https://developer.vippsmobilepay.com/redocusaurus/epayment-swagger-id.yaml)
* [Express guide](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/features/express.md)

#### Shipping address callbacks

For both **ePayment** and **eCom**, you need to provide an endpoint that we can call to share the customer's address with you.
You define and host this endpoint on your side -- we'll call it when we need to send you the shipping address details.

We send the address in **almost the same structure** for both products -- see the difference table below.

**eCom merchant callback**

Endpoint:
[`POST:[shippingDetailsPrefix]​/v2​/payments​/{orderId}​/shippingDetails`](https://developer.vippsmobilepay.com/api/ecom#tag/Merchant-Endpoints/operation/fetchShippingCostUsingPOST)

**ePayment merchant callback**

Endpoint:
[`POST:[merchant-dynamic-shipping-callback]`](https://developer.vippsmobilepay.com/api/epayment/#tag/Merchant-Endpoints)

**eCom callback body structure**

* `addressLine1` -> `AddressLine1`
* `city` -> `City`
* `country` -> `Country`
* `postCode` -> `PostCode`
* `addressId` -> replaced by the payment reference

**ePayment callback body structure**

* `AddressLine1`
* `City`
* `Country`
* `PostCode`
* `reference` 🆕 - The unique identifier for the payment

**eCom callback response**

The response must follow this schema.

* `shippingDetails` -> `groups`
  * `isDefault` (now **Boolean**)
  * `priority`
  * `shippingCost` -> `amount.value`
  * `shippingMethod` -> `name`
  * `shippingMethodId` -> `id`
* `addressId` -> removed
* `orderId` -> removed

Note that several parameters
are removed from the top level and specified within the options for
each array element.

**ePayment callback response**

The response must follow this schema.

* `groups` (array)
  * `isDefault`
  * `priority`
  * `type 🆕` - `HOME_DELIVERY`, `PICKUP_POINT`, and others
  * `brand` 🆕 - `BRING`, `DHL`, `FEDEX`, and others
  * `options`
    * `id`
    * `isDefault`
    * `amount` (`currency`, `value`)
    * `name`
    * `priority`
    * `meta`
    * `estimatedDelivery`

**eCom details**

* [API spec: Fetch Shipping Cost & Method](https://developer.vippsmobilepay.com/redocusaurus/ecom-swagger-id.yaml)

**ePayment details:**

* [API spec: Merchant dynamic shipping callback](https://developer.vippsmobilepay.com/redocusaurus/epayment-swagger-id.yaml)
(Look under *Responses > 200* for the schema of your reply)

### Set order details

The ePayment API comes with
[order management](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/features/pre-built-order-management-api-integration.md)
built-in.

In eCom, you had to create and attach order details using the Order Management API, but now
you can add the details directly to your payment request.

You can add order lines to attach order details shown to the user in the app.
Alternatively, supply a URL to show the user an invoice or similar.
All are accessible before the user accepts the payment.

You just add the `receipt` to the create payment request.

See
[Set order details](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/features/pre-built-order-management-api-integration.md)
for an example.

### One-time payment QR codes

The ePayment API lets you create a one-time payment QR code without the QR API.

You just set the `userFlow` to `QR` and provide an optional `qrFormat`.

```json
"userFlow": "QR",
"qrFormat": {
  "format": "IMAGE/SVG+XML",
  "size": 1024
}
```

For examples, see [One-time payment QR](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/features/qr-payments.md).

### Profile sharing

The ePayment [profile sharing](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/api-guide/features/profile-sharing.md)
feature works similarly to in eCom.
You only need to update your `scope` parameter to an object, like this:

```json
"profile": {
        "scope": "name phoneNumber address birthDate"
    }
```

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

## Report API and settlements

The eCom API and ePayment API use different identification for payments:

* eCom payments are identified with the `orderId` that is specified when the payment is initiated.
* ePayment payments are identified with the `reference` in the same way.

When retrieving data about the payments using the
[Report API](https://developer.vippsmobilepay.com/docs/APIs/report-api/README.md)
there is also a difference:

* eCom API payments will have an automatically generated `transactionId` for each payment operation, such
  as capture and refund.
* ePayment API payments will have a `pspReference` that works similarly.

**INFO**

The `transactionId` in the eCom API is identical to the `pspReference` in the Report API,
but the `pspReference` in the ePayment API has no relation to the `pspReference` in the Report API.

See the Report API's
[Entry type reference](https://developer.vippsmobilepay.com/docs/APIs/report-api/api-guide/entry-types.md)
for more details.

## Verification and go live

Before going live with your new ePayment solution you must verify your solution.
You do this by going through all the points in the
[ePayment checklist](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/checklist.md).
Please ensure that you have implemented all endpoints and evaluated the
*Quality assurance* and *Avoid integration pitfalls*.
If you have any questions about any of the points in the checklist, please feel free to
[contact us](https://developer.vippsmobilepay.com/docs/contact.md#technical-questions-about-our-apis).

Once you are satisfied with the integration and the checklist, you can go live.

Before going live with your new ePayment solution, we must verify your solution. You do this by going through all the points in the
[ePayment checklist](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/checklist.md). Please ensure that you have implemented all endpoints and evaluated the
*Quality assurance* and *Avoid integration pitfalls*.

Once you have filled out the checklist, please send it to
[developer@vippsmobilepay.com](mailto:developer@vippsmobilepay.com)
(or through your Slack channel) including a video of the payment flow.

Once your checklist is approved, you can go live with your merchants according to your own plan.
Please let us know how you plan for going live, whether it is all merchants at once or in batches.

**[ePayment checklist ->](https://developer.vippsmobilepay.com/docs/APIs/epayment-api/checklist.md)**

> **Full site overview:** For every page in this documentation, read [https://developer.vippsmobilepay.com/llms.txt](https://developer.vippsmobilepay.com/llms.txt).
