Skip to main content

eCom API guide

Vipps Only available for Vipps. All new integrations should use the ePayment API.

API version: 2.0.0.

Important

All new integrations should use the ePayment API. See the eCom to ePayment Migration guide for help migrating older integrations.

Payment flows

The eCom API offers these types of flows:

Regular and express checkout

Information about how to retrieve settlements is provided in Knowledge base: Settlements.

Regular payment flow

This is the typical flow, where the user adds items to a shopping cart, enters the shipping address and pays.

The flow is as follows:

  1. The customer selects Vipps as the method of payment and enters their mobile number into the app or website.
  2. The merchant initiates the payment command, which the customer confirms the purchase through their Vipps app.
  3. If the purchase is approved, the merchant registers the sale in their system.

Customer approves

This diagram shows a simplified payment flow:

For examples of how eCommerce can work, see:

See Flow details for more in-depth details about using this flow in the browser, phone, or app.

Express checkout payment flow

Express Checkout (Hurtigkasse) expands upon the regular payment flow with the user selecting a shipping option and sharing their address with the merchant through the Vipps app.

Try it out on the Express checkout demo page.

Express checkout flow

See Express checkout payments for more details.

In-store flow

The In-store flow is the same as the regular flow except that the phone number is provided to the service provider who then initiates the payment through their Point of Sale (POS) system. See eCommerce API: How it works in the store for more information.

Checkout flow

The Checkout flow is the same as the regular flow except that, instead of confirming the purchase in the Vipps app, the customer consents to sharing their personal information (e.g., address, phone, and payment information). They then complete the purchase from the website where their information is automatically prefilled.

API endpoints

The eCom API offers functionality for online payments. Payments are supported in both web browsers and in native apps (via deep-linking).

OperationDescriptionEndpoint
Initiate paymentPayment initiation, the first request in the payment flow. This reserves an amount.POST:/ecomm/v2/payments
Capture paymentWhen an amount has been reserved, and the goods are (about to be) shipped, the payment must be captured.POST:/ecomm/v2/payments/{orderId}/capture
Cancel paymentThe merchant may cancel a reserved amount, but not on a captured amount.PUT:/ecomm/v2/payments/{orderId}/cancel
Refund paymentThe merchant may refund a captured amount.POST:/ecomm/v2/payments/{orderId}/refund
Get payment detailsThe full history of the payment.GET:/ecomm/v2/payments/{orderId}/details
Get order statusDeprecated, use Get payment details.Deprecated, use GET:/ecomm/v2/payments/{orderId}/details

Necessary endpoint from other APIs:

OperationDescriptionEndpoint
Get Access tokenFetch the access tokenPOST:/accesstoken/get

For integrating with the eCom API, see the eCom API checklist.

We recommend using the standard HTTP headers for all requests.

See Knowledge base: HTTP headers for details.

All API calls are authenticated with an access token and an API subscription key. See Get an access token in the Getting started guide, for details.

Initiate

Payment amounts must be in NOK, be non-zero and larger than 1 NOK (1 NOK = 100 øre).

Amounts are specified in minor units. For Norwegian kroner (NOK) that means 1 kr = 100 øre. Example: 499 kr = 49900 øre.

When you initiate a payment, it will normally only be reserved until you capture it.

This has some benefits:

  • If a payment has been reserved, the merchant can make a PUT:/ecomm/v2/payments/acme-shop-123-order123abc/cancel call to immediately release the reservation.
  • It is possible to reserve a higher amount and only capture a part of it (useful for electric car charging stations, etc.). It is also possible to capture the full amount with multiple captures ("partial capture").
Detailed example

API Specification: POST:/ecomm/v2/payments

A minimal example:

{
"customerInfo": {},
"merchantInfo": {
"merchantSerialNumber": "123456",
"callbackPrefix": "https://example.com/vipps/callbacks-for-payment-update-from-vipps",
"fallBack": "https://example.com/vipps/fallback-result-page-for-both-success-and-failure/acme-shop-123-order123abc"
},
"transaction": {
"orderId": "acme-shop-123-order123abc",
"amount": 20000,
"transactionText": "One pair of Vipps socks"
}
}

An express payment example with more parameters provided:

{
"customerInfo": {
"mobileNumber": "48059528"
},
"merchantInfo": {
"authToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1Ni <snip>",
"callbackPrefix": "https://example.com/vipps/callbacks-for-payment-update-from-vipps",
"consentRemovalPrefix": "https://example.com/vipps/consents/",
"fallBack": "https://example.com/vipps/fallback-result-page-for-both-success-and-failure/acme-shop-123-order123abc",
"merchantSerialNumber": 123456,
"shippingDetailsPrefix": "https://example.com/vipps/shipping/",
"paymentType": "eComm Express Payment",
"staticShippingDetails": [
{
"isDefault": "N",
"priority": 1,
"shippingCost": 99,
"shippingMethod": "Walking",
"shippingMethodId": "123abc"
},
{
"isDefault": "Y",
"priority": 2,
"shippingCost": 199,
"shippingMethod": "Running",
"shippingMethodId": "321abc"
}
]
},
"transaction": {
"amount": 20000,
"orderId": "acme-shop-123-order123abc",
"timeStamp": "2018-12-12T11:18:38.246Z",
"transactionText": "One pair of Vipps socks"
}
}

Please note: The phone number is optional and should only be sent if it is already known. Users should never be asked for the phone number, as they will either be automatically app-switched to the Vipps app, or they will be presented with the landing page. If the customer's phone number is needed by the merchant: Use scope and the Userinfo API.

Important: Do not send sensitive information in the transactionText field. See:

For questions relating to capturing the response, see Reserve and capture.

Additional implementation details (e.g., Callbacks, rate limiting) are in the Integration details section.

Vipps responds to the POST:/ecomm/v2/payments request with a URL. The URL is normally a https:// URL, which automatically opens the Vipps app, if the app is installed (and the landing page, if not).

It is possible to perform manual handling of the interaction between the user's Vipps app and the Vipps backend, although this is not recommended. For details, see Knowledge base: App flow recommendations.

Payment identification

A payment is uniquely identified by the combination of merchantSerialNumber and orderId:

  • merchantSerialNumber: The merchant's Vipps ID. Example: 123456.
  • orderId: Must be unique for the merchantSerialNumber. Example: acme-shop-123-order123abc. See: orderId recommendations.

Payment retries

If a user cancels or does not act on a payment, there is no way to "retry" the payment.

The initiate call is not idempotent, so the closest to a "retry" is to make a new initiate call with a new orderId. Vipps has no concept of relation between orders, so the "retry" payment is in no way connected to the first payment attempt.

Payment parameter recommendations

For some hints about what to use for the parameter values, see these pages in the Knowledge base:

The landing page

When a user is directed to the url sent in the response to POST:/ecomm/v2/payments, they will either be taken to the Vipps app or to the Landing page.

Other relevant information

See below for helpful information, for example:

Reserve

When you initiate a payment, it will be reserved until you capture it:

  • When a payment is reserved it means the customer has approved the payment. The funds are still in the customer's account, but not available to spend on other things.
  • When a payment is captured it means the funds are moved from customer's account to merchant's account.
    • Captured funds will be settled to the merchant's settlement account after two business days. See Settlements for more details.

When the user confirms the purchase in Vipps, the payment status changes to RESERVE. The respective amount will be reserved for future capturing.

Capture

The eCom API supports reserve capture and direct capture:

  • Reserve capture is the default, and works for all types if payments. When you initiate a payment, it will be reserved until you capture it. The capture can be done a few seconds later, or several days later.
  • Direct capture is available in the eCom API for historical reasons, but not available in the newer ePayment API. When direct capture is configured for a sales unit, all payment reservations will instantly be captured, without the need for a separate capture request. This is provided for legacy reasons and was intended for situations where the product or service is immediately provided to the customer, and there is absolutely no chance that the service is not available or sold out, e.g. digital services. We have since moved away from this, and strongly recommend that all integrations use the ePayment API and reserve capture. Direct capture requires additional compliance checks of the merchant.
CAPTURE CONSIDERATIONS

You should capture as soon as is legally possible, because some banks will release the funds after some days, making it difficult to capture later. If it's not captured within the payment capture deadlines, it will be automatically cancelled.

However, be aware that it isn't legal to capture before the product or service is provided to the customer, as per the capture regulations.

tip

It's completely fine to use reserve capture almost exactly like direct capture: Just do the capture immediately after the reservation. The user experience is exactly the same.

Important things to consider for cancellations and refunds:

  • If a payment has been reserved (as with "reserve capture"), the merchant can make a "cancel" API request to immediately release the reservation and make available in the customer's account. This may be useful even in situations where it's "impossible" that the goods/service is sold out.
  • If a payment has been captured (as with "direct capture"), the merchant has to make a "refund" API request, and it then takes several days before the amount is available in the customer's account.
  • With "reserve capture" it is possible to reserve a higher amount and only capture a part of it (useful for electric car charging stations, etc.). It is also possible to capture the full amount with multiple captures ("partial capture").

Capture is done with POST:/ecomm/v2/payments/{orderId}/capture.

Use the idempotency key, X-Request-Id, in the capture call. Then, if a capture request fails for any reason, it can be retried with the same idempotency key. You can use any unique ID for your X-Request-Id.

See the X-Request-Id in the capturePaymentUsingPOST specification for details.

To perform a normal capture of the entire amount, amount can be omitted from the API request (i.e., not sent at all), set to null or set to 0. When doing a partial capture, you need to specify the amount.

Important

It is important to check the response of the /capture call. The capture is only successful when the response is HTTP 200 OK.

Capture can be made up to 180 days after reservation. Attempting to capture an older payment will result in a HTTP 400 Bad Request.

Types of capture

Reserve capture

Reserve capture is the normal flow.

When the end user approves an initiated payment, it will be reserved until you capture it. When the order is reserved, the amount is marked as reserved by the bank, but not transferred.

Direct capture

Important: Direct capture is available in the eCom API for historical reasons, but not available in the newer ePayment API.

When direct capture is activated, all payment reservations will instantly be captured.

With direct capture, Vipps MobilePay is responsible for the customer receiving the purchased product. Because of this, direct capture requires additional compliance checks.

A sales unit can only have one capture type, and it must be configured by Vipps MobilePay. You can't turn direct capture on or off as a merchant.

We strongly recommend using "reserve capture" in all situations.

Please note: We only offer "direct capture" for merchants that use Vipps MobilePay through a partner, and for merchants that have a Key Account Manager. "Direct capture" must be requested by the partner from the partner manager, or by KAM merchants from the Key Account Manager.

Please note: The Checkout API does not support "direct capture".

See the FAQ:

Partial capture

Partial capture may be used in cases where a partial order is shipped or for other reasons. It may be called as many times as required while there is a remaining amount that is reserved and has not yet been captured.

For this API, it is also possible to do a partial capture and send an optional parameter to explicitly free the remaining amount immediately.

More information about capture

See Knowledge base: reserve and capture for more details about the types of captures.

You should charge the customer when the product or service is delivered. For more details, see capture regulations.

Specific questions:

Cancel

The Cancel request allows the merchant to cancel a reserved or initiated transaction.

Please note that it is not possible to cancel a request that is over 180 days old. Attempting to cancel an older payment will result in a HTTP 400 Bad Request.

The payment flow can be aborted under certain circumstances:

  • When the user cancels (rejects) the initiated payment in Vipps.
  • When the merchant cancels.
  • Timeouts: If the user does not confirm, etc.

After cancellation, the order gets a new status:

  • If an order is cancelled by the merchant while it's in the RESERVE state, the status becomes VOID.
  • If an order is cancelled by the merchant while it's in the INITIATE state, the status becomes CANCEL.
  • If an order is cancelled by the user, the status becomes CANCEL.
Detailed example

PUT:/ecomm/v2/payments/acme-shop-123-order123abc/cancel

{
"merchantInfo": {
"merchantSerialNumber": "123456"
},
"transaction": {
"transactionText": "No socks for you!"
}
}

Response:

{
"orderId": "acme-shop-123-order123abc",
"transactionInfo": {
"amount": 20000,
"transactionText": "No socks for you!",
"status": "Cancelled",
"transactionId": "5001420063",
"timeStamp": "2018-11-14T15:31:10.004Z"
},
"transactionSummary": {
"capturedAmount": 0,
"remainingAmountToCapture": 0,
"refundedAmount": 0,
"remainingAmountToRefund": 0
}
}

Cancelling a pending order

If you wish to cancel a transaction before the customer can confirm the payment in Vipps, you can send a PUT:/ecomm/v2/payments/{orderId}/cancel request while the transaction is in the INITIATE stage.

This may be useful in face-to-face situations where a customer's phone runs out of battery, or if the customer suddenly changes their mind and wants to buy more and the amount for the payment increases. This should not be considered a consistent or guaranteed operation, as the /cancel request depends on actions taken by the user in the app.

If the PUT:/ecomm/v2/payments/{orderId}/cancel request is successful, the payment state in the response will be: CANCELLED.

Warning The GET:/ecomm/v2/payments/{orderId}/details endpoint however will return CANCEL, not CANCELLED.

A call to GET:/ecomm/v2/payments/{orderId}/details for the same order will return the following, regardless of whether the transaction has been reserved before the cancellation: CANCEL.

Note If the order is in the state RESERVED and then cancelled by the merchant, the status will be VOID.

Please note: If the user is already in a 3-D Secure session, the payment cannot be cancelled as described above.

Cancelling a partially captured order

If you wish to cancel an order that you have partially captured, send a PUT:/ecomm/v2/payments/{orderId}/cancel request with shouldReleaseRemainingFunds: true in the body. The payment must be RESERVED for this to take effect.

If shouldReleaseRemainingFunds is not set, it will default to false.

When shouldReleaseRemainingFunds is set to false, any request to cancel after a partial or full capture has been performed will be rejected.

This is a useful and recommended feature, as it releases any reserved balance as soon as the card issuer and/or bank permits.

Detailed example
{
"merchantInfo": {
"merchantSerialNumber": "123456"
},
"transaction": {
"transactionText": "No socks for you!"
},
"shouldReleaseRemainingFunds": true
}

Response:

{
"orderId": "acme-shop-123-order123abc",
"transactionInfo": {
"amount": 20000,
"transactionText": "No socks for you!",
"status": "Cancelled",
"transactionId": "5001420063",
"timeStamp": "2018-11-14T15:31:10.004Z"
},
"transactionSummary": {
"capturedAmount": 10000,
"remainingAmountToCapture": 0,
"refundedAmount": 0,
"remainingAmountToRefund": 10000
}
}

Please note: Once this operation has been performed, there will be zero funds remaining to capture. Do not call this endpoint until you are sure you have captured all you need.

Refund

All integrations with the eCom API must support refunds.

The merchant can initiate a refund of the captured amount. The refund can be a partial or full.

It usually takes 2-3 bank days until the money is in the customer's account, depending on the bank(s). It can take much longer, up to 10 days, and depends on the bank(s).

Partial refunds are done by specifying an amount which is lower than the captured amount. The refunded amount cannot be larger than the captured amount.

In a capture request, the merchant may also use the X-Request-Id header. See Idempotency for details.

Refunds can be made up to 365 days after reservation. Attempting to refund an older payment will result in a HTTP 400 Bad Request.

Detailed example

POST:/ecomm/v2/payments/acme-shop-123-order123abc/refund

{
"merchantInfo": {
"merchantSerialNumber": "123456"
},
"transaction": {
"amount": 20000,
"transactionText": "Refund of Vipps socks"
}
}

Response:

{
"orderId": "acme-shop-123-order123abc",
"transaction": {
"amount": 20000,
"transactionText": "Refund of Vipps socks",
"status": "Refund",
"transactionId": "5600727726",
"timeStamp": "2018-11-14T15:23:02.286"
},
"transactionSummary": {
"capturedAmount": 20000,
"remainingAmountToCapture": 0,
"refundedAmount": 20000,
"remainingAmountToRefund": 0
}
}

For details about cancelling the remaining reservation after a partial capture, see Cancelling a partially captured order

See also FAQ: Refunds.

Get payment details

GET:/ecomm/v2/payments/{orderId}/details retrieves the full history of a payment and the status of the operations.

Payment states

#From-stateTo-stateDescriptionOperation
0-InitiatePayment initiationINITIATE
1-The merchant has initiated the paymentINITIATE
-The user has accepted the payment and amount has been reservedRESERVE
-CancelThe user has cancelled the orderCANCEL
2ReserveCaptureThe merchant captures the payment and shipsCAPTURE
-CancelThe merchant has cancelled the orderVOID
3Capture--A final state: Payment fully processedCAPTURE
-RefundThe merchant has refunded the money to the userREFUND
4Cancel--A final state: Payment cancelled-
5Refund--A final state: Payment refunded-

Requests and responses

Please note that the response from GET:/ecomm/v2/payments/{orderId}/details always contains the entire history of payments for the order, not just the current status.

Important: The operationSuccess field indicates whether an operation was successful or not.

ResponseDescription
INITIATEPayment initiated by merchant
RESERVEPayment reserved by user accepting the payment in Vipps
CAPTUREPayment captured by merchant (after RESERVE)
REFUNDPayment refunded by merchant (after CAPTURE)
CANCELPayment cancelled by user in Vipps
SALEPayment captured with direct capture by merchant
VOIDPayment cancelled by merchant
Detailed example
{
"orderId": "acme-shop-123-order123abc",
"transactionSummary": {
"capturedAmount": 20000,
"remainingAmountToCapture": 0,
"refundedAmount": 20000,
"remainingAmountToRefund": 0,
"bankIdentificationNumber": 492560
},
"transactionLogHistory": [
{
"amount": 20000,
"transactionText": "Refund of Vipps socks",
"transactionId": "5600727726",
"timeStamp": "2018-11-14T15:23:02.286Z",
"operation": "REFUND",
"requestId": "1542208972",
"operationSuccess": true
},
{
"amount": 20000,
"transactionText": "One pair of Vipps socks",
"transactionId": "5001420058",
"timeStamp": "2018-11-14T15:22:46.680Z",
"operation": "CAPTURE",
"requestId": "1542208966",
"operationSuccess": true
},
{
"amount": 20000,
"transactionText": "One pair of Vipps socks",
"transactionId": "5001420062",
"timeStamp": "2018-11-14T15:21:22.126Z",
"operation": "RESERVE",
"requestId": "",
"operationSuccess": true
},
{
"amount": 20000,
"transactionText": "One pair of Vipps socks",
"transactionId": "5001420062",
"timeStamp": "2018-11-14T15:21:04.697Z",
"operation": "INITIATE",
"requestId": "",
"operationSuccess": true
}
]
}

Please note:

  • The transactionSummary will not be part of the response if the user does not react to the landing page or app-switch.
  • The bankIdentificationNumber will only be part of transactionSummary in the response of the GET:/ecomm/v2/payments/{orderId}/details endpoint.
  • If paymentType is set to eComm Express Payment you will get shippingDetails and userDetails in addition to transactionLogHistory and transactionSummary.
  • If you initiate the payment with a scope to use with the Userinfo API you will also get a userDetails object containing the user's information:
"userDetails": {
"bankIdVerified": 0,
"email": "user@example.com",
"firstName": "Ada",
"lastName": "Lovelace",
"mobileNumber": "12345678",
"userId": "c06c4afe-d9e1-4c5d-939a-177d752a0944"
}

See Knowledge base: Polling guidelines.

Flow details

Phone and mobile browser flow

A payment is initiated with a call to POST:/ecomm/v2/payments.

Push notification

Triggered by the payment initiation, the landing page will automatically detect if it is being invoked on a phone, and whether Vipps is installed on the phone. If Vipps is installed, Vipps will automatically be opened.

Vipps installed

  1. Vipps is invoked (with app-switch).
  2. The user accepts or rejects the payment request in Vipps.
  3. The Vipps backend makes a call to the merchant's callbackPrefix with information about the payment.
  4. Once payment process is completed, Vipps redirects to the fallBack URL that merchant provided earlier (see above).

Vipps not installed

  1. The landing page (in the browser) prompts the user for the phone number.
  2. The Vipps backend sends a push notification to the user's phone, and also displays a notification on the landing page for the user to continue the payment in Vipps on the phone.
  3. The user accepts or rejects the payment in Vipps.
  4. The Vipps backend makes a call to the merchant's callbackPrefix with information about the payment.
  5. Once the payment process is completed, Vipps redirects to the fallBack URL that the merchant provided earlier.

Please note:

  1. Vipps cannot guarantee that the user will get to the fallBack URL, since the user may switch away from Vipps or "kill" the app, or there may be network or battery problems, etc. before the URL is opened. If the merchant relies 100 % on users visiting the fallback URL, there will be problems: The user has completed the payment, but the merchant ignores it.
  2. If the user has started the payment in an embedded browser, such as in Facebook or Instagram, it is not possible for Vipps to open the fallBack URL in the embedded browser. The phone OS will always open URLs in the default browser. See: Knowledge base: Recommendations regarding handling redirects.
  3. Because of the above, a successful payment must not rely on session cookies in the browser.
  4. Vipps cannot guarantee a particular sequence of callback and fallback, as this depends on user actions, network connectivity/speed, etc. Because of this, it is not possible to base an integration on a specific sequence of events.
  5. URLs must be valid. See: Knowledge base: URL Validation

Desktop flow

Desktop landing page

  1. The landing page will be opened in the desktop browser.
  2. The landing page will prompt for the user’s phone number. If the phone number is known, it should be prefilled by the merchant.
  3. Vipps sends a push notification the user's phone, with a notification on the landing page to continue the payment in Vipps on the phone.
  4. The user accepts or rejects the payment in Vipps.
  5. The Vipps backend makes a call to the merchant's callbackPrefix with information about the payment. See: Callbacks.
  6. Once the payment process is completed, the landing page will redirect to the fallBack URL that merchant provided earlier.

Payments initiated in an app

If payments are always initiated in the merchant's native app, there is no need to pass any additional parameters. Vipps will handle everything automatically.

It is also possible to send the optional isApp parameter, but this comes with extra responsibility. For details, see Knowledge base: App flow recommendations.

Express checkout payments

Express Checkout allows the user to select a shipping option and share their address with the merchant through the Vipps app.

Express Checkout is designed for shipping products with a delivery address and a shipping method. It's mandatory for the user to select the address and shipping method to ensure that the item is delivered to the right place in the right way.

Vipps Hurtigkasse works this way, as seen from the user's side:

  1. The user clicks the Vipps Hurtigkasse button.
  2. The user consents to sharing address information in Vipps.
  3. The user confirms the amount, delivery address and delivery method in Vipps.
note
  • If you only need the user's information, you should use a normal payment and the Userinfo API.
  • It is not possible to specify scope with Express checkout.
  • If you only need the user's information, you should use Profile sharing. You should avoid asking the customer in a pub for the shipping method for the drinks, etc.

To perform an express checkout, the merchant needs to specify "paymentType": "eComm Express Payment" in the POST:/ecomm/v2/payments call, and support the POST:[shippingDetailsPrefix]​/v2​/payments​/{orderId}​/shippingDetails and DELETE:[consentRemovalPrefix]/v2/consents/{userId} endpoints.

Express checkout API endpoints required on the merchant side

The below endpoints are provided by the merchant and consumed by Vipps during Express Checkout payments. These endpoints are not required when using regular checkout.

These endpoints are to be implemented by merchants in order for Vipps to make calls to them. The documentation is included in the API specification for reference only - these endpoints are not callable at Vipps.

OperationDescriptionEndpoint
Get shipping detailsUsed to fetch shipping information, 10-second timeoutPOST:[shippingDetailsPrefix]/v2/payments/{orderId}/shippingDetails
Transaction UpdateA callback to the merchant for receiving post-payment information.POST:[callbackPrefix]/v2/payments/{orderId}
Remove user consentUsed to inform merchant when the Vipps user removes consent to share information.DELETE:[consentRemovalPrefix]//v2/consents/{userId}

Shipping and static shipping details

The shipping methods presented to the user in Vipps are fetched from the merchant's POST:[shippingDetailsPrefix]​/v2​/payments​/{orderId}​/shippingDetails endpoint.

If the shipping methods and cost can be known in advance, the staticShippingDetails field in POST:​/ecomm​/v2​/payments may be used to provide the shipping details up front, and thereby avoid an extra round-trip between the Vipps backend and the merchant's server.

When using staticShippingDetails the shipping costs for the available shipping methods are then sent directly, eliminating the need for the user to first select shipping method and then for the merchant to calculate the cost for it.

We recommend using staticShippingDetails if possible, as it gives a faster payment process and a better user experience. It also eliminates timeout problems caused by delays in the merchant's or shipping partner's calculations of cost.

Detailed example of get shipping details

The POST:[shippingDetailsPrefix]/v2/payments/{orderId}/shippingDetails API endpoint on the merchant's side allows Vipps to get the shipping cost and method based on the provided address and product details. This endpoint is required for Express Checkout.

Request:

{
"addressId": 3960,
"addressLine1": "Dronning Eufemias gate 42",
"addressLine2": null,
"country": "Norway",
"city": "OSLO",
"postCode": "0191",
"addressType": "H"
}

Response:

{
"addressId": 3960,
"orderId": "123456abc",
"shippingDetails": [
{
"isDefault": "N",
"priority": 1,
"shippingCost": 99,
"shippingMethod": "Walking",
"shippingMethodId": "123abc"
},
{
"isDefault": "Y",
"priority": 2,
"shippingCost": 199,
"shippingMethod": "Running",
"shippingMethodId": "321abc"
}
]
}

Sequence diagram with and without staticShippingDetails:

To get information about the payment, use callbacks and polling.

Vipps complies with GDPR, and requires the user's consent before any information is shared with the merchant. The merchant must provide a URL (consentRemovalPrefix) that Vipps can call to delete the data. Vipps allows the user to later remove this consent (via the Vipps app: Profile > Security > Access to your information > Companies that remember you).

note

The personal information shared with the merchant is available for 7 days after reservation. After this, all customer information will be replaced with "[Expired]" in subsequent calls to GET:/ecomm/v2/payments/{orderId}/details.

The DELETE:[consentRemovalPrefix]/v2/consents/{userId} API endpoint on the merchant's side allows Vipps to send an end user's consent removal request to the merchant. This endpoint is required for Express Checkout.

When receiving this request, the merchant is obliged to handle the user details as per the GDPR guidelines. The request path will include a userId that Vipps will have provided as part of callback and also made accessible through GET:/ecomm/v2/payments/{orderId}/details.

Profile sharing

Vipps offers the possibility for merchants to ask for the user's profile information as part of the payment flow.

To enable the possibility to fetch profile information for a user, the merchant can add a scope parameter to the initiate call: POST:/ecomm/v2/payments. See Userinfo API guide.

Profile sharing call-by-call guide

Scenario: You want to complete a payment and get the name and phone number of a customer. Details about each step are described in the sections below.

  1. Retrieve the access token: POST:/accesstoken/get.
  2. Add scope to the transaction object and include the scope you wish to get access to (valid scope) before calling POST:/ecomm/v2/payments Include the scopes you need access to (e.g., "name address email phoneNumber birthDate"), separated by spaces.
  3. The user consents to the information sharing and perform the payment in Vipps.
  4. Retrieve the sub by calling GET:/ecomm/v2/payments/{orderId}/details
  5. Using the sub from step 4, call GET:/vipps-userinfo-api/userinfo/{sub} to retrieve the user's information.

An example similar to this, but with ePayment, is shown in the Userinfo quick start guide.

Please note: The sub is added asynchronously, so if the /details request is made within (milli)seconds of the payment approval in the app, it may not be available. If that happens, simply make another /details request. See Polling guidelines in the Knowledge base for more recommendations.

Get userinfo

Once the user completes the session, a unique identifier sub can be retrieved from the GET:/ecomm/v2/payments/{orderId}/details endpoint.

Example sub format:

"sub": "c06c4afe-d9e1-4c5d-939a-177d752a0944",

This sub is a link between the merchant and the user and can be used to retrieve the user's details from the Userinfo API: GET:/vipps-userinfo-api/userinfo/{sub}

See: Userinfo API.

Integration details

Callbacks

Callbacks allow Vipps to send the merchant information about the payment. Callback are made for the following events:

  • Payment successful
  • Payment failed
  • Payment rejected
  • Payment timed out

Please note: Callback offer a faster user experience than polling, but you can't rely on callbacks alone. You must also poll GET:/ecomm/v2/payments/{orderId}/details.

See Knowledge base: Polling for polling guidelines.

Important:

  • Vipps makes one attempt at a callback and cannot guarantee that it succeeds, as it depends on network, firewalls and other factors that Vipps cannot control. If the communication is broken during the process for some reason and Vipps is not able to execute callback to the merchant's server, the callback will not be retried.
  • Vipps callbacks require a response within 3 seconds; otherwise, they will time out.
  • Callback URLs must use HTTPS.

The callback request body is different for the different payment types:

  • "eComm Regular Payment": The callback contains the order and transaction details.
  • "eComm Express Payment": The callback contains the order and transaction details and in addition the user details and shipping details.
  • If Profile sharing is used: The callback is the same as for "eComm Express Payment".

See:

Callback URLs

The callback URLs are generated by appending the orderId to the callbackPrefix sent in the POST:/ecomm/v2/payments/{orderId} call. The callbackPrefix is for an API endpoint on the merchant's side. See the API specifications.

For example, if your callbackPrefix is https://example.com/vipps/callback and the orderId is acme-shop-123-order123abc, Vipps will append /v2/payments/acme-shop-123-order123abc (note the leading slash) to https://example.com/vipps/callback and make a callback to https://example.com/vipps/callback/v2/payments/acme-shop-123-order123abc.

Again:

  • callbackPrefix + /v2/payments/ + {orderId}
  • https://example.com/vipps/callback + /v2/payments/ + acme-shop-123-order123abc

Important:

  • URLs must be valid. For details, see Knowledge base: URL Validation.
  • Vipps does not support sending requests to all ports, so to be safe use common port numbers such as: 80, 443, 8080.
  • Vipps does not support callback URLs that return HTTP 301 Redirect, HTTP 302 Permanently Moved or HTTP 307 Temporary Redirect. Vipps will not follow to a Location. The callback URLs must be directly reachable.
Detailed example

Below are two examples of payment update callbacks with POST:[callbackPrefix]/v2/payments/{orderId}.

Example: "eComm Regular Payment" callback:

{
"merchantSerialNumber": 123456,
"orderId": "acme-shop-123-order123abc",
"transactionInfo": {
"amount": 20000,
"status": "RESERVED",
"timeStamp": "2018-12-12T11:18:38.246Z",
"transactionId": "5001420062"
}
}

Example: "eComm Express Payment" callback:

{
"merchantSerialNumber": 123456,
"orderId": "acme-shop-123-order123abc",
"shippingDetails": {
"address": {
"addressLine1": "Dronning Eufemias gate 42",
"addressLine2": "Att: Rune Garborg",
"city": "OSLO",
"country": "NO",
"zipCode": "0191" // Postcode (apologies for not using postCode as elsewhere)
},
"shippingCost": 99,
"shippingMethod": "By cannon",
"shippingMethodId": "53DBB6BA-89DB-4997-B444-5E9F1681E3D3"
},
"transactionInfo": {
"amount": 20000,
"status": "RESERVE",
"timeStamp": "2018-12-12T11:18:38.246Z",
"transactionId": "5001420062"
},
"userDetails": {
"firstName": "Ada",
"lastName": "Lovelace",
"email": "user@example.com",
"mobileNumber": "12345678",
"userId": "1234567"
}
}

Please note: Regular payments use RESERVED, but express payments use RESERVE. We apologize for this, but it is technical debt, and it cannot be corrected in this version of the API, as that would break backwards compatibility.

How to test your own callbacks

We recommend using HTTPie for testing your callbacks.

  1. Create a JSON file with the callback request payload based on the example for POST:[callbackPrefix]/v2/payments/{orderId}:

      {
    "merchantSerialNumber": 123456,
    "orderId": "acme-shop-123-order123abc",
    "transactionInfo": {
    "amount": 20000,
    "status": "RESERVED",
    "timeStamp": "2018-12-12T11:18:38.246Z",
    "transactionId": "5001420062"
    }
    }

    Save this JSON file as callback.json.

  2. Build your callback URL. In this example, the callbackPrefix is https://example.com/vipps/callback, and the orderId is acme-shop-123-order123abc.

  3. Test the callback by making a POST request to your callback URL with the JSON file as request body:

    POST https://example.com/vipps/callback/v2/payments/acme-shop-123-order123abc < callback.json
  4. If it does not return HTTP 200 OK, your callback handling does not work, and you must correct it.

Authorization for callbacks

If you provide the authToken when initiating a payment with POST:/ecomm/v2/payments/{orderId}, the authToken will be sent as an Authorization header in the callback and shipping details requests. Please note that this is unrelated to the authentication required by the Vipps API.

API spec: POST:[callbackPrefix]/v2/payments/{orderId}

Vipps callback servers

The callbacks from Vipps are made from the servers described in Vipps request servers.

Please make sure that requests from these servers are allowed through firewalls, etc.

Callback statuses

These are the statuses provided by Vipps in the callbacks by [callbackPrefix]/v2/payments/{orderId}:

Callback typeResponseDescription
Regular checkoutRESERVEDPayment reserved by user accepting the payment in Vipps.
SALEPayment captured with direct capture by merchant (after RESERVED).
RESERVE_FAILEDReserve capture failed because of insufficient funds, invalid card or similar.
SALE_FAILEDDirect capture failed because of insufficient funds, invalid card or similar.
CANCELLEDPayment cancelled by the user in Vipps.
REJECTEDUser did not act on the payment (timeout, etc.).
Express checkoutRESERVEPayment reserved by user accepting the payment in Vipps (it is correct that this is different from RESERVED for regular checkout - sorry.)
SALEPayment captured with direct capture, by merchant (after RESERVE).
RESERVE_FAILEDReserve failed because of insufficient funds, invalid card or similar.
SALE_FAILEDDirect failed because of insufficient funds, invalid card or similar.
CANCELLEDPayment cancelled by user in Vipps.
REJECTEDUser did not act on the payment (timeout, etc.).

For a full history of a payment, use [callbackPrefix]/v2/payments/{orderId}/details. See Get payment details for more information.

See: Knowledge base: Timeouts.

eCom API HTTP response codes

This API returns the following HTTP statuses in the responses:

  • 200 OK
  • 201 Created
  • 204 No Content
  • 400 Bad Request
  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not Found
  • 409 Conflict
  • 429 Too Many Requests
  • 500 Server Error

For more information about the HTTP response codes and JSON object in the responses, see HTTP response codes and errors in the Knowledge base.

For details about the specific eCom errors and responses, see Errors, as well as the ePayment OpenAPI specification.

Errors

Error object in the response

See also eCom API HTTP response codes.

[
{
"errorGroup": "Payment",
"errorMessage": "Refused by issuer because of expired card",
"errorCode": "44"
}
]
{
"statusCode": 401,
"message": "Access denied due to invalid subscription key. Make sure to provide a valid key for an active subscription."
}

Error groups

Error groupsDescription
AuthenticationAuthentication Failure because of wrong credentials provided
PaymentFailure while doing a payment authorization
InvalidRequestRequest contains invalid parameters
VippsErrorInternal Vipps application error
UserError related to the Vipps user (Example: Not a Vipps user)
MerchantErrors regarding the merchant

Error codes

Please note: Vipps is only allowed to provide all of these errors through the API, and that we have to send VippsError (99) in cases where we are not allowed to provide more details. The same goes for errors from our PSP: We may not be allowed to pass on the details to merchants.

In case of errors: Use Get payment details to retrieve all the information about the payment.

Error groupError CodeError Message (and some explaining text for some errors)
Payment41"The user does not have a valid card." The customer must add a card.
Payment42"Refused by the issuer." The customer must contact the issuer, typically the bank.
Payment43"Refused by the issuer: Invalid amount."
Payment44"Refused by the issuer: Expired card." The customer must add a card.
Payment45"Reservation failed, reason unknown." Most common: The customer has not acted upon the payment. We can't know the reason for this. See Timeouts.
Payment51"Cannot cancel an orderId that has already been captured." Cannot cancel, do a refund instead.
Payment52"Cancellation failed, reason unknown." Cancel failed.
Payment53"Cannot cancel an orderId that is not reserved."
Payment61"The total capture amount exceeds the reserved amount. You cannot capture a higher amount than the user has accepted. Check the payment details". This is in rare cases caused by rounding errors on the merchant's side. Check the payment details.
Payment62"The amount you tried to capture is not reserved. The user must accept the payment before capture can be done."
Payment63"Capture failed an unknown reason. Retrieve the payment details to see the full details." Use payment details to see the exact status.
Payment71"Cannot refund a higher amount than the captured amount." This is in rare cases caused by rounding errors on the merchant's side.
Payment72"Cannot refund a reserved order. The orderId can be canceled instead." Cancel instead.
Payment73"Cannot refund a canceled order."
Payment74"Refund failed during debit from the merchant's account."
Payment93Captured amount must be the same in an idempotent retry. The same Idempotency-Key can't be used with different request payloads.
Payment95"Payments can only be refunded up to 365 days after reservation. See the FAQ." or "Direct capture is not allowed. See the Checkout documentation." See Reserve and capture.
Payment98"Payments can only be captured up to 180 days after reservation. See the FAQ." Payments can only be captured up to 180 days after reservation. See Reserve and capture.
Payment1082This person is not BankID verified. This only applies for test users.
VippsError91"The transaction is not allowed." Typically shown when attempting to capture a cancelled order.
VippsError92"The transaction has already been processed."
VippsError93"The capture request must be identical to the previous request(s) in an idempotent retry." or "The refund request must be identical to the previous request(s) in an idempotent retry."
VippsError94Order locked and is already processing. This can occur for a short period of time if a bank has problems, and Vipps needs to wait and/or clean up. Retry the same request later, with the same idempotency key.
VippsError98"Too many concurrent requests. See the FAQ." Used only to prevent obviously incorrect API use. See Rate limiting.
VippsError99"Internal error. In some cases, this is caused by an incorrect API request. Please check the request." In practice this is always due to a combination of a bad request from the merchant and inadequate validation at our end. See Why do I get HTTP 500 Internal Server Error?.
user81"The phone number is either incorrectly formatted (see the API specification), is not a Vipps user, or the user cannot pay businesses. Vipps cannot give more details." We can't give all the details, as we can't reveal if the user is blocked, is too young to pay businesses, etc.
user82"The user's app version is not supported." The user must upgrade the app.
Merchant31"The merchant is blocked. The merchant can contact customer service for details." We can't reveal the details. See Why do I get Merchant unavailable, deleted, deactivated or not allowed to make payments.
Merchant32"The receiving limit of merchant is exceeded." The merchant has received more money than allowed. The merchant can contact customer service for details.
Merchant33"The merchant's payment request limit is exceeded." The merchant has requested more money than allowed. Can contact customer service for details.
Merchant34"Duplicate orderId. The orderId must be unique for each MSN. It has already been used for this MSN." The orderId has already been used for another payment for this MSN. The orderId must be unique for the MSN. Follow the orderId recommendations.
Merchant35"The orderId 'acme-shop-123-order123abc' does not exist for MSN 654321." Follow the orderId recommendations.
Merchant36"The merchant's agreement has not been signed." The merchant can contact customer service for details.
Merchant37"The merchant and/or sales unit is unavailable, deleted, deactivated or blocked for payments." We can't reveal the details. See Why do I get Merchant unavailable, deleted, deactivated or not allowed to make payments
Merchant38"The sales unit is not allowed to skip the landing page. See the FAQ." See the landing page.
Merchant39"The sales unit is not allowed to initiate long-living payments."
Merchant51"The Nin scope is not allowed." See who can get access.
Merchant97"The sales unit is not allowed to perform payments. See the FAQ." Typically shown for a merchant that has only applied for Login API, and has not been through the required compliance checks for making payments. See Why do I get "Merchant Not Allowed for Ecommerce Payment".
InvalidRequest-The field name will be the error code. Contains a description about what exactly the field error is.

See also the ePayment OpenAPI specification.

Rate limiting

We have added rate limiting to our APIs (HTTP 429 Too Many Requests) to prevent fraudulent and wrongful behavior, and to increase the stability and security of our APIs. The limits should not affect normal behavior, but please contact us if you notice any unexpected behavior.

The "Key" column specifies what we consider to be the unique identifier, and what we "use to count". The limits are of course not total limits.

APILimitKeyExplanation
Initiate2 per minuteorderId + MSNTwo calls per minute for each unique orderId
Cancel5 per minuteorderId + MSNFive calls per minute for each unique orderId
Capture5 per minuteorderId + MSNFive calls per minute for each unique orderId
Refund5 per minuteorderId + MSNFive calls per minute for each unique orderId
Status120 per minuteorderId + subscription key120 calls per minute for each unique orderId
Details120 per minuteorderId + subscription key120 calls per minute for each unique orderId

Please note: The "Key" column is important. The above means that we allow two Initiate calls per minute per unique orderId for that MSN. This is to prevent too many initiate calls for the same payment. The overall limit for number of different payments is far higher than 2. The same goes for Capture: You can make five capture calls per minute for one unique orderId, and the limit for capture calls for different orderId values is far higher.

Partner keys

In addition to the normal authentication, we offer partner keys which let a partner make API calls on behalf of a merchant.

See: Partner keys.

Idempotency

In a capture request, the merchant may also use the X-Request-Id header. This header is an idempotency header ensuring that, if the merchant retries a request with the same X-Request-Id, the retried request will not make additional changes.

See the Idempotency header for more details.

Example Request:

POST:/ecomm/v2/payments/acme-shop-123-order123abc/capture

{
"merchantInfo": {
"merchantSerialNumber": "123456"
},
"transaction": {
"amount": 20000,
"transactionText": "Socks on the way! Tracking code: abc-tracking-123"
}
}

Response:

{
"orderId": "acme-shop-123-order123abc",
"transactionInfo": {
"amount": 20000,
"timeStamp": "2018-11-14T15:22:46.736Z",
"transactionText": "Socks on the way! Tracking code: abc-tracking-123",
"status": "Captured",
"transactionId": "5001420058"
},
"transactionSummary": {
"capturedAmount": 20000,
"remainingAmountToCapture": 0,
"refundedAmount": 0,
"remainingAmountToRefund": 20000
}
}

Exception handling

The section below explains how Vipps handles different exception and errors. See also HTTP response codes and errors.

Connection timeout

Defining a socket timeout period is the common measure to protect server resources and is expected. However, the time needed to fulfil a service requests depends on several systems, which impose longer timeout period than usually required.

We recommend setting no less than 1 second socket connection timeout and 5 seconds socket read timeout while communicating with Vipps.

A good practice is, if/when the socket read timeout occurs, to call GET:/ecomm/v2/payments/{orderId}/details and check status of last transaction in transaction history prior to executing the service call again.

Callback aborted or interrupted

If the communication is broken during payment process for some reason, either because of network problems, that the user abruptly closes the app or something else, and Vipps is not able to execute callback, the callback will not be retried.

In other words, if the merchant doesn’t receive any confirmation on payment request call within callback time frame, merchant must call GET:/ecomm/v2/payments/{orderId}/details to get the response of payment request.

PSP connection issues

In cases of communication problems with Vipps' PSP, the response from Vipps will be an error (see HTTP response codes and errors).

The merchant should then call GET:/ecomm/v2/payments/{orderId}/details to check if the transaction request is processed before making a new call, using same idempotency key (see Idempotency).

Clean-up strategies

Vipps recommends merchants implement a robust clean up strategy for all orders where the goods or services are not issued to the user.

An example case would be:

Bank X is having issues and transactions for their customers are slow (15+ seconds) for a significant period of time. As a result of this the user decides to close the Vipps app while the transaction is being processed, they do not then see the final result in the Vipps app. This transaction will eventually result in a successful reservation. The user then returns to the Merchants app, but as the entry was not via an expected app-switch from the Vipps app, state is not correctly resumed. The user attempts a second payment, which this time goes through in a timely manner, and upon app-switch back the user is issued their goods/services.

The user has now two reservations and only received goods/services once. It is the merchant's responsibility here to ensure the first order, for which no goods/services were issued, should be cancelled to remove the reservation from the customers account.

Vipps recommends polling GET:/ecomm/v2/payments/{orderId}/details until either a REJECT, USER_CANCEL, RESERVE or SALE status is received, and then performing the appropriate action based on the status of product issuing. The user should also be notified that the merchant has issued any product to ensure they do not naturally retry the purchase. This includes using SMS/email strategy if it is unclear that the user in on the merchant's website/app to see confirmation.

Recommendations for handling very high traffic

At peak traffic, like Black Friday, it is especially important to have a robust integration.

We strongly recommend using "reserve capture", and not "direct capture", so it is possible to cancel a payment without making a refund.

  • Make sure you poll GET:/ecomm/v2/payments/{orderId}/details, and do not rely on the callback from Vipps, and also don't rely on the user reaching the callback URL.
  • Consider if you should cancel or complete the payment if the payment takes much longer than normal, so much that the user may give up.
    • If you sell a ticket: It may be good to always issue the ticket if the user has approved the payment, even if the processing of the payment takes much longer than normal and the user "gives up".
    • If you sell food at a restaurant: If the payment takes so long that the user gives up and tries to order again: It may be smart to cancel the previous order, even though the user did approve the payment.

It is also important that the merchant's and/or partner's systems are able to handle the peak traffic.

See also:

App integration

Configure your app or website to trigger Vipps (sometimes called "app-switching").

This may be done in two ways:

  1. From a mobile or desktop browser. See Desktop flow
  2. From an iOS or Android native app

After the user has finished (or cancelled) the payment in the Vipps app, they should be returned to your app or website through the specified fallBack URL.

When the user arrives back in your app or website, perform a call to the payment details endpoint to check the state of the transaction. While some state of the eCom operation can be derived from things like whether or not user returned successfully from the Vipps app, the most reliable approach to know the state of the payment is always to query the eCom API once the user arrive back in the merchant app/website.

App switching

We recommend that you always use the universal links/asset links (starting with https) as they contain built-in logic to handle both desktop and mobile flow. They are more secure than the deep link flow and provide a better user experience.

Please see Knowledge base: App flow recommendations for more details.

Legacy information

This information is outdated. We recommend that you use universal links or asset links now for improved security.

warning

On Apple, we recommend universal links. On Android, we recommend asset links, also called "App links". See Knowledge base: App flow recommendations.

  1. The merchant must pass the URL scheme of the app into the fallBack field in the initiate payment request. See App-switch on iOS and App-switch on Android for specifics.
  2. The merchant app should open Vipps deeplink received from the initiate payment request.
  3. Once the operation in Vipps is completed, Vipps will redirect the user to the deeplink specified in the fallBack field.
  4. The merchant app should query the payment details endpoint for updated status on the payment once user returns from Vipps.

Please note: Vipps will append a status at the end of the fallback URL. For example, if your fallBack URL is merchantApp://result?myAppData, Vipps will append the status like: merchantApp://result?myAppData&status=301 or merchantApp://result?myAppData&status=100. This status is deprecated, and should no longer be used. Query the payment details endpoint for latest status instead.

App-switch on iOS

Vipps on iOS requires a URL scheme in order to support app-switch.

See the official Apple documentation: Defining a Custom URL Scheme for Your App

Switch from merchant app to Vipps

Below is sample code to open iOS Vipps application with deeplinkURL.

NSString *url = deeplinkURL; // Use the deeplinkURL provided in the API response
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:url]]) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]]; }
else {
// No Vipps app installed: Open app store page.
// Once user installs Vipps, calling app needs to initiate deeplinking again in order to get the callback
[[UIApplication sharedApplication] openURL:[NSURL URLWithString: @"https://itunes.apple.com/no/app/Vipps-by-dnb/id984380185"]];
}

Example of a deeplinkURL:

vipps://?token=eyJraWQiOiJqd3RrZXkiLCJhbGciOiJSUzI1NiJ9.ey <snip>

Please note: For production it's vipps://, but for our test environment it's vippsMT://.

Redirect back to the merchant app from Vipps app

Once the operation in Vipps is completed, Vipps will open the fallback URL. For app-to-app integration, merchant app needs to be registered for a URL scheme and pass the URL scheme in fallBack URL in the Vipps backend API. The Vipps mobile application will use the URL to launch the merchant application.

App-switch on Android

Vipps is launched with a standard intent, using the URL returned from the eCom API when the payment is created (e.g., "url": "vipps://?token=eyJraWQiOiJqd3RrZXki..").

Example of how to open Vipps:

package com.example.app

import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri

class MyActivity : Activity() {
companion object {
const val vippsPackageName = "no.dnb.vipps"
const val vippsRequestCode: Int = TODO("insert your own custom identifier for tracking vipps app intents")
}

// use deeplinkUrl from ecom response payload
fun openVippsApp(deeplinkUrl: String) {
try {
val pm = applicationContext.packageManager
val packageInfo = pm.getPackageInfo(vippsPackageName, PackageManager.GET_ACTIVITIES)
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(deeplinkUrl))
startActivityForResult(intent, vippsRequestCode)
} catch (e: PackageManager.NameNotFoundException) {
// No Vipps app installed! Open the Vipps page on Google Play
val playStoreUrl = "https://play.google.com/store/apps/details?id=$vippsPackageName"
val intent = Intent(Intent.ACTION_VIEW).setData(Uri.parse(playStoreUrl))
startActivity(intent)
}
}
}
Switching back to the merchant app from Vipps app

Once the user has paid (or cancelled), Vipps supports two ways to return to the merchant native app:

1: Let Vipps deeplink back into the merchant app using their URL scheme (e.g., merchantapp://). This is the default/suggested approach.

2: Just close Vipps, fall back to the merchant app, pick up the thread again there in onActivityResult().

In both cases, the merchant app should query the eCom API for updated status on the payment once user returns from Vipps.

Return to merchant app by actively deeplinking into it from Vipps

With this approach, the merchant app has to have its own URL scheme registered so Vipps can actively open the merchant app again after payment/cancellation.

In the example below, MainActivity is the receiving activity and Vipps opens it once the payment is done.

To receive a call back from Vipps to an activity, a filter has to be set for that activity. In the merchant app, set a filter in the Manifest file:

<activity android:name=".MainActivity" android:label="@string/app_name" android:launchMode="singleInstance">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="sampleApps" />
</intent-filter>
</activity>

Please note: The scheme should be same specified in fallBack URL sent to the eCom API when the payment is created.

The Vipps application will send the result to the merchant app by starting a new activity with the fallBack URL as a URL parameter in the intent.

The merchant app can make their receiving activity a singleInstance to handle the response in same activity.

The receiving MainActivity has to override the onNewIntent method to handle result send by Vipps:

override fun onNewIntent(intent: Intent) {
// Call the eCom API, check the status of the eCom payment
}
Redirect back to merchant app by simply closing Vipps

With this approach, the merchant app does not have to register/handle deeplink URLs.

In order to use this approach, when creating the payment in the merchant has to pass fallback attribute like this:

"fallBack": "INTENT"

(and only "INTENT", no parameters etc.)

This will cause Vipps to simply close after a successful or cancelled eCom payment, and fall back to the calling merchant app.

The merchant app activity that resumes again (after Vipps closes) has to override onActivityResult method to pick up the thread again here. Example:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
// Call the eCom API, check the status of the eCom payment
}

Testing

To facilitate automated testing in The Vipps Test Environment (MT) the eCom API provides a "force approve" endpoint to avoid manual payment confirmation in the Vipps app: POST:/ecomm/v2/integration-test/payments/{orderId}/approve

The "force approve" endpoint allows developers to approve a payment through the Vipps eCom API without the use of Vipps. This is useful for automated testing. The endpoint is only available in our test environment.

Important: All test users must manually approve at least one payment in Vipps (using the app) before "force approve" can be used for that user. If this has not been done, you will get an error. This is because the user needs to be registered as "BankID verified" in the backend, and this happens automatically in the test environment when using Vipps (the app), but not with "force approve".

Please note: Vipps Hurtigkasse (express checkout) and skipLandingPage is not supported by the force approve endpoint.

See Knowledge base: Recommendations regarding handling redirects.

Help us improve our documentation

Did you find what you were looking for?