Skip to main content

QR API guide

The QR API provides you with tools for generating these types of QR codes:

  • Merchant redirect - Generate QR codes that redirect the user to your website.
  • One-time payment - Generate QR codes that open the user's Vipps or MobilePay app and provide the payment suggestions for approval. This allows you to initiate a Vipps or MobilePay payment without needing to ask for the customer's telephone number.
  • Merchant callback - Generate QR codes that will result in a callback to the merchant when scanned by the user. This is typically used to let the merchant know that a user is ready to pay.

All types of QR codes share the same authentication and overall design, but have slight difference in behavior and how they are made.

API version: 1.2.0.

Payment flows involving QR codes

Different solutions for different setups

Depending on the merchant setup, there can be multiple ways to implement the payment flow. This section tries to sketch an overview of what is possible, and what might be the best approach depending on the merchant setup today.

In all cases, the ePayment API will be used for integrating payments. The main differences are with pairing the customer that wants to pay, with the given checkout that wants to issue the payment.

The next sections will contain the recommended approaches based on what capabilities the merchant has available at their checkouts.

note

The developer documentation in Vipps MobilePay describes using webhooks instead of polling for payment statuses in the ePayment API. Polling however, is still possible and a valid way to follow the payment status. However, it will not be possible to detect user check-in with polling.

Checkout has QR scanning capabilities

This is our recommended flow. If the merchant has the possibility to scan a QR code at their checkouts, they can use the 'Merchant Scan' approach. Before the payment is initiated the merchant scans a QR on the customer phone which will contain the customer info needed to initiate the payment. The payment is then initiated with the userFlow parameter set to "PUSH_MESSAGE" together with the personalQr parameter set to the full content of the QR scanned. See the In-store payments example.

Checkout has customer facing screens

In this scenario, there is one solution simpler than all others. Here, the merchant doesn't need the customer information before they initiate the payment. They simply initiate the payment where the userFlow parameter is set to QR. Then, the response will contain a link to a dynamic QR code, which the checkout then downloads and shows on their customer facing screen. The user scans the QR and completes the payment flow. This flow is described in more detail in the ePayment API guide, where it also is shown how to specify the image format and size of the QR being created.

Checkout neither has QR scanners nor customer facing screens

In these scenarios, the PoS merchants must use static QR codes as stickers. These QRs can work in two different ways.

The first option is where the QR code contains a link to a merchant website where the merchant will then ask for the customer info needed. This QR is referred to as a Merchant Redirect QR. See the Static QR directing to the merchant site for payment example.

The second option is called Merchant Callback QRs. When the QR is scanned by a customer, Vipps MobilePay will send a callback to an endpoint that is hosted by the merchant. The callback will contain a customerToken that is used to initiate the payment towards the customer. See the In-store using Merchant Callback QR example.

Before you begin

This document assumes you have signed up as an organization with Vipps MobilePay and have retrieved your API credentials for the test environment from portal.vippsmobilepay.com.

HTTP headers

We strongly recommend using the standard HTTP headers for all requests.

Authentication

All API calls are authenticated with an access token and an API subscription key. See Get an access token for more details.

QR code formats

The QR code image will be returned as a URL in the response for one-time payment, merchant redirect and merchant callback QR codes. Opening this URL will return the image in the format and resolution set in the request. The URL to the image will look like this:

"url":"https://qr-generator-prod-app-service.azurewebsites.net/qr-generator/v1?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...."

The URL to the image does not require any authentication and can be shown wherever you want. Note that one-time payment QR codes eventually will time out - trying to open the URL to the one-time payment QR image after its expiry while will return a 404 Not Found error. Merchant redirect QR codes can be opened forever.

QR Image format

The API currently supports generating QR codes in either PNG or SVG image formats. If PNG is chosen, it is also possible to set the resolution of the image.

For Merchant-Callback QR codes, the image format and size are set in optional query parameters. If not provided, the default is an SVG image. One-time payment and Merchant Redirect QR codes are using headers to set the image format and size. The below table describes how.

Header NameHeader ValueDescription
Acceptimage/*Returns a URL pointing to a svg image
Acceptimage/svg+xmlReturns a URL pointing to a svg image
Acceptimage/pngReturns a URL pointing to a PNG image
Size[100 - 2000]The header value is an integer between 100 and 2000. For example a value of 500 results in a PNG image in resolution 500x500. Only relevant when requesting a PNG QR code. If PNG is chosen, and Size is not set, the default resolution is 1024x1024

Custom QR codes

It is also possible to create a custom QR code. This will require an approval from Vipps MobilePay before use, so we can validate the styling and design of the QR.

If a custom QR code is desired, see the design guidelines.

To create a custom QR code the qrContent is required. For one-time payment and Merchant-redirect QR codes, the following Accept header value needs to be used:

Header NameHeader ValueDescription
Accepttext/targetUrlReturns the qrContent of the QR

For Merchant-callback QR the qrContent is returned for all QR codes returned, so no special request modification is needed.

One-time payment QR codes

You can use the QR API to generate QR codes that can be scanned by a customer in a physical store setting. Once the QR code is scanned, the Vipps or MobilePay app will automatically open with the payment ready for approval. This avoids them needing to provide their phone number.

These QR codes are generated for each unique payment.

One-time payment QR Flow

The QR code, when scanned from either the native camera or the Vipps or MobilePay app, will automatically open an eCom or Recurring payment in the app, where the payment can be completed. See a detailed example of how it works.

Every payment needs a unique orderId. See Recommendations for reference and orderId.

The purchase will time out after 10 minutes, so it's not possible to print these QR codes.

One-Time Payment QR code with ePayment API

One-time payment QR is already included as a feature in the payment requests using the ePayment API.

Basic flow for One-Time Payment QR code with eCom or Recurring payments

  1. Initiate a eCom or Recurring payment
  2. Receive the payment URL as response
  3. Post the payment URL to the QR API
  4. Receive a URL to a QR code in desired format (PNG or SVG)

See the Quick start guide for examples of generating QR codes.

Initiate a payment with the eCom API

Before creating the QR code you must initiate a payment with the eCom API as is described in depth in the eCom API guide.

The request to the eCom initiate endpoint POST:/ecomm/v2/payments will return a response like this (the url is truncated, but the format is correct):

{
"orderId": "acme-shop-123-order123abc",
"url": "https://api.vipps.no/dwo-api-application/v1/deeplink/vippsgateway?v=2&token=eyJraWQiOiJqd3RrZXkiLC <snip>"
}

Be aware that the URL is only valid for 10 minutes.

Creation of One-Time Payment QR code

Now that you have the url from the eCom API you can create a QR code using the following endpoint:

POST:qr​/v1/

Example of a request for a QR code image using Accept: image/png:

Headers:

Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1Ni <snip>
Ocp-Apim-Subscription-Key: 0f14ebcab0ec4b29ae0cb90d91b4a84a
Accept: image/png
Merchant-Serial-Number: 123456
Vipps-System-Name: Acme Commerce
Vipps-System-Version: 3.1.2
Vipps-System-Plugin-Name: acme-pos
Vipps-System-Plugin-Version 4.5.6

Body:

{
"url": "https://api.vipps.no/dwo-api-application/v1/deeplink/vippsgateway?v=2&token=eyJraWQiOiJqd3RrZXkiLC <snip>"
}

The response will be similar to this, where the URL in the body of the response will be a link to the image as defined in the accept header:

{
"url":"https://qr-generator-prod-app-service.azurewebsites.net/qr-generator/v1?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9....",
"expiresIn": 247
}

Please note: The expiresIn value is in seconds.

Polling

On one-time payment QR codes, you will need to get the result of the payment by polling with the GET:/ecomm/v2/payments/{orderId}/details request.

In a physical context, we recommend a polling interval of one second. See polling guidelines for information.

Once the QR code has been opened in the app, the transactionId field in transactionLogHistory will be set (it will not exist before the QR code has been scanned). Once this field is set, you can safely show a waiting for user message on your POS screen while the user finishes the payment.

Body once the QR has been opened by a user

{
"orderId": "acme-shop-123-order123abc",
"transactionLogHistory": [
{
"amount": 20000,
"operation": "INITIATE",
"operationSuccess": true
"timeStamp": "2018-11-14T15:21:04.697Z",
"transactionId": "5001420062",
"transactionText": "One pair of socks",
}
]
}

Merchant redirect QR codes

Merchant redirect QR codes allows you to make printable QR codes that redirect the user to your webpage. This can be used for one-offs, such as TV commercials; as well as for permanent use cases, such as stickers, billboards, and magazine ads.

&quot;MerchantRedirect QR Flow&quot;

The QR code, when scanned from the native camera or the Vipps MobilePay scanner, will take the customer straight to the web page.

See a detailed example of How the QR API works with merchant redirect with examples of what the user will encounter.

Merchant redirect QR codes don't time out, and they don't require the Vipps or MobilePay app to be installed.

The QR API allows for creating, updating, getting, and deleting of merchant redirect QR codes. You can later change the URL through the API without generating a new QR code.

Below is an example merchant redirect QR:

Vipps demo QR

Basic flow for merchant redirect QR

  1. Create a merchant redirect QR

  2. Later, if needed, you can:

    a. Get the QR by ID

    b. Update the URL to the QR

    c. Delete the QR

See the quick start guide for examples of generating merchant redirect QR codes.

Creation of merchant redirect QR

To create a merchant redirect QR, make a HTTPS POST to: POST:/qr/v1/merchant-redirect

An example body like this:

{
"id": "billboard_1",
"redirectUrl": "https://example.com/myProduct"
}

Will return a response like this:

{
"id": "billboard_1",
"url":"https://qr-generator-prod-app-service.azurewebsites.net/qr-generator/v1?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...."
}

The id parameter is required, and is defined by the merchant. You can later use this ID to update the merchant redirect QR codes

Updating and deletion of QR codes

Updating QR codes is a very similar procedure to creating them. When a QR code is updated, nothing happens to the QR itself. But, when the QR is scanned, the user will be redirected to the new URL. The change is instantaneous. To update the QR code, make PUT:/qr/v1/merchant-redirect/{id} request and with the new redirectUrl in the request body:

{
"id": "billboard_1",
"redirectUrl": "https://example.com/completelyDifferentProductThanBefore"
}

And the response will be exactly the same as for generating the QR the first time - and it will still point to the same image.

{
"id": "billboard_1",
"url":"https://qr-generator-prod-app-service.azurewebsites.net/qr-generator/v1?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...."
}

The DELETE:/qr/v1/merchant-redirect/{id} does what one might expect, it deletes the QR. Once deleted, merchants can generate a new QR with the same ID but the already-printed-QR will never work again.

In addition to the DELETE-endpoint, it is also possible to add a ttl-attribute in the original POST-request. This attribute sets how many seconds the QR will live, before it is deleted permanently.

Tip: If you want the same QR in different formats, perform GET calls on the same id with different accept headers and test what works best.

Merchant callback QR codes

There is an issue that the test app requires you to go back to the home screen after scanning the QR. There, you will see the payment request when it is initiated. This is not an issue in production.

Please note: Before the merchant will receive any callbacks, they need to subscribe to the user.checked-in.v1 webhook.

A merchant callback QR is a special type of QR code that sends a message (i.e., "callback") when it is scanned in the Vipps or MobilePay app. The unique ID for the QR is provided in the callback message, enabling you to identify which QR code has been scanned. When you get the message, you know that someone is at your location and trying to pay with Vipps MobilePay. You can then use their customer token to initiate a payment which they can approve immediately in their Vipps or MobilePay app.

Merchant callback QRs are the best solution for self-checkout, vending machines, or similar situations where there is no cashier, buttons, or other ways of letting the user communicate how they want to pay.

The following endpoints are provided:

API inputs

ParameterDescription
merchantQrIdMerchant defined parameter. Together with MerchantSerialNumber, it uniquely identifies the QR code.
locationDescriptionA description of where the QR code will be used. It will be shown in the app when the user has scanned the QR code. Max length is 36 characters.
qrImageFormatThe image format of the QR code returned by the API. Can be either PNG or SVG. Default is SVG.
qrImageSizeThe resolution of the QR code returned. Only relevant in conjunction with qrImageFormat set to PNG. Default is 1024 which results in a PNG image in 1024x1024 resolution.
categoryOptional category for the QR code that will control the message displayed in the app while waiting for the payment to show.

API outputs

Here is described only those parameters that are already described.

ParameterDescription
qrImageUrlA link to the image containing the QR code.
qrContentThe content of the QR code. It is the text that is embedded in the QR code which is scanned by the Vipps or MobilePay app.
note

Even though the QR itself doesn't expire, the qrImageUrl URL may change due to security concerns. However, you will be able to get the new image link using the Get callback QR by ID endpoint.

How to create a merchant callback QR code

To create a merchant callback QR code, call the PUT:/qr/v1/merchant-callback/{merchantQrId} endpoint.

The endpoint takes the merchantQrId as a path parameter and requires a request body containing the locationDescription parameter.

An example body looks like this:

{
"locationDescription": "Kiosk",
"category": "IN_STORE"
}

If the endpoint succeeds, the QR code has been created.

Please note: The QR code will not be returned from the endpoint. Instead, the merchant needs to call the dedicated GET endpoints described below.

Setting category

Currently, two QR code categories exist. IN_STORE is the default category, and VENDING is secondary. The will be shown in the apps like this:

IN_STOREVENDING
IN_STOREVENDING

How to update or delete a merchant callback QR code

The QR code is based on the merchantQrId and merchantSerialNumber. These properties will never change.

So the only properties that can be updated on a QR code are category and locationDescription. To update the properties, just call the PUT:/qr/v1/merchant-callback/{merchantQrId} endpoint again with the new values. The QR code will be updated accordingly.

If a QR code is not needed any more, it is best practice to delete it. There are at least two reasons for that:

  • If a user scans the QR code, they will be informed that the QR code is not found. This is preferred to having the user waiting with no knowledge the QR code is no longer in use.
  • When the merchant needs to print all QR codes for a particular merchantSerialNumber, then QR codes that are not in use will not be printed.

To delete a QR code, the merchant will simply have to call the endpoint DELETE:/qr/v1/merchant-callback/{merchantQrId}.

Fetching the merchant callback QR codes

There are two endpoints for fetching created QR codes. One for getting a specific QR code and one for fetching all QR codes belonging to a merchantSerialNumber.

Common for both endpoints is the possibility to choose the format of the image returned, as well at the size of the QR code. These properties are defined as optional query parameters called qrImageFormat and qrImageSize respectively.

To fetch a single QR code, the merchant has to call the endpoint: GET:/qr/v1/merchant-callback/{merchantQrId}?qrImageFormat=PNG&qrImageSize=500.

An example of the response looks like this:

{
"merchantSerialNumber": "12345",
"merchantQrId": "27072f82-c4b6-49cd-9838-10f21d87496e",
"locationDescription": "Kiosk",
"qrImageUrl": "https://qr.vipps.no/generate/qr.png?...",
"qrContent": "https://qr.vipps.no/..."
}

Now, the QR code image can be printed or accessed directly from the device that faces the customer. The image is located at the qrImageUrl.

To fetch all QR codes belonging to a merchantSerialNumber, the merchant needs to call the endpoint: GET:/qr/v1/merchant-callback?qrImageFormat=PNG&qrImageSize=500.

The only difference is the absence of the merchantQrId path parameter.

An example of a response from this endpoint is the same as the previous, except it returns a list:

{
[
{
"merchantSerialNumber": "12345",
"merchantQrId": "27072f82-c4b6-49cd-9838-10f21d87496e",
"locationDescription": "Kiosk",
"qrImageUrl": "https://qr.vipps.no/generate/qr.png?...",
"qrContent": "https://qr.vipps.no/..."
},
{
"merchantSerialNumber": "12345",
"merchantQrId": "b1482233-17a1-434d-bcd1-6ea38b15eddb",
"locationDescription": "Bakery",
"qrImageUrl": "https://qr.vipps.no/generate/qr.png?...",
"qrContent": "https://qr.vipps.no/..."
}
]
}

The endpoint that returns a list is nice to have if the merchant has many QR codes in the same location. It will make printing easier.

Sequence diagram

Here is a sequence diagram that showcases how to use the merchant callback QR code feature:

Personal QR exchange endpoint

Every Vipps and MobilePay user has a personal QR code available in their Vipps or MobilePay app.

Vipps personal QR

To allow your customers to pay for their goods and services without assistance, you can provide them with a 2D QR scanner where they can scan their own personal QR codes as part of the checkout process.

Vipps scan

The Vipps personal QR currently contains a string like this: https://qr.vipps.no/28/2/01/031/4712345678?v=1, however, we plan to update this format in the future, so your implementation should use the exchange QR endpoint, POST:/v1/exchange, to get the customer's phone number instead of parsing this string.

For example:

  1. By scanning a user's personal QR code, you get a string token.

  2. Supply the string in the POST:/v1/exchange request:

    curl -X POST https://apitest.vipps.no/qr/v1/exchange \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer YOUR-ACCESS-TOKEN" \
    -H "Ocp-Apim-Subscription-Key: YOUR-SUBSCRIPTION-KEY" \
    -H "Merchant-Serial-Number: YOUR-MSN" \
    -H "Vipps-System-Name: acme" \
    -H "Vipps-System-Version: 3.1.2" \
    -H "Vipps-System-Plugin-Name: acme-webshop" \
    -H "Vipps-System-Plugin-Version: 4.5.6" \
    -d '{
    "qrCode": "https://qr.vipps.no/p/qwjhewqhueheuqwhuqwhe",
    }'
  3. You will get a response, like this:

    {
    "msisdn": "4712345678",
    "timestamp": 1634025600,
    "version": "2.0"
    }

API inputs

ParameterDescription
qrCodeThe full content embedded in the QR code.
requestedDataAn array of strings where you enter the type of data you want in return. There is currently only one option, so this field is optional. Example: ["MSISDN"].

API outputs

ParameterDescription
msisdnThe user's phone number.
versionSpecifies the QR code version. Available versions include 2.0 (current) and 1.0 (deprecated).
timestampThe UTC timestamp, in seconds, indicating when the QR code was generated. Available only in version 2.0.

Customer token exchange endpoint

When a user scans a merchant callback QR code with their Vipps or MobilePay app, your system will receive a customer token that can be exchanged for the user's phone number.

See Merchant callback QR for more information.

For example:

  1. When a user scans a merchant callback QR code, the webhook callback payload contains a customerToken string.

  2. Supply the token in the POST:/v1/exchange/customer request:

    curl -X POST https://apitest.vipps.no/qr/v1/exchange/customer \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer YOUR-ACCESS-TOKEN" \
    -H "Ocp-Apim-Subscription-Key: YOUR-SUBSCRIPTION-KEY" \
    -H "Merchant-Serial-Number: YOUR-MSN" \
    -H "Vipps-System-Name: acme" \
    -H "Vipps-System-Version: 3.1.2" \
    -H "Vipps-System-Plugin-Name: acme-webshop" \
    -H "Vipps-System-Plugin-Version: 4.5.6" \
    -d '{
    "customer": {
    "customerToken": "qwieyiqwyeiuqwyeiuywqiueyiwquy"
    }
    }'
  3. You will get a response, like this:

    {
    "msisdn": "4712345678",
    "timestamp": 1634025600
    }

    API inputs

    ParameterDescription
    customerJSON object containing customerToken.
    requestedDataAn array of strings where you enter the type of data you want in return. There is currently only one option, so this field is optional. Example: ["MSISDN"].

    API outputs

    ParameterDescription
    msisdnThe user's phone number.
    timestampThe UTC timestamp, in seconds, indicating when the QR code was scanned.

Help us improve our documentation

Did you find what you were looking for?