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.
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 Name | Header Value | Description |
---|---|---|
Accept | image/* | Returns a URL pointing to a svg image |
Accept | image/svg+xml | Returns a URL pointing to a svg image |
Accept | image/png | Returns 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 Name | Header Value | Description |
---|---|---|
Accept | text/targetUrl | Returns 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.
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
- Initiate a eCom or Recurring payment
- Receive the payment URL as response
- Post the payment URL to the QR API
- 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:
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.
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
- MobilePay
Basic flow for merchant redirect QR
-
Create a merchant redirect QR
-
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:
- Get all merchant callback QRs
- Get callback QR by ID
- Create or update callback QR
- Delete callback QR
- Create or Update MobilePay QR code
API inputs
Parameter | Description |
---|---|
merchantQrId | Merchant defined parameter. Together with MerchantSerialNumber , it uniquely identifies the QR code. |
locationDescription | A 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. |
qrImageFormat | The image format of the QR code returned by the API. Can be either PNG or SVG . Default is SVG . |
qrImageSize | The 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. |
category | Optional 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.
Parameter | Description |
---|---|
qrImageUrl | A link to the image containing the QR code. |
qrContent | The 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. |
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_STORE | VENDING |
---|---|
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
- MobilePay
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
- MobilePay
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.
The MobilePay QR contains a string like this:
https://qr.vipps.no/p/qwjhewqhueheuqwhuqwhe
.
Supply this string to the
POST:/v1/exchange
to get the customer's phone number.
For example:
-
By scanning a user's personal QR code, you get a string token.
-
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",
}' -
You will get a response, like this:
{
"msisdn": "4712345678",
"timestamp": 1634025600,
"version": "2.0"
}
API inputs
Parameter | Description |
---|---|
qrCode | The full content embedded in the QR code. |
requestedData | An 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
Parameter | Description |
---|---|
msisdn | The user's phone number. |
version | Specifies the QR code version. Available versions include 2.0 (current) and 1.0 (deprecated). |
timestamp | The 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:
-
When a user scans a merchant callback QR code, the webhook callback payload contains a
customerToken
string. -
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"
}
}' -
You will get a response, like this:
{
"msisdn": "4712345678",
"timestamp": 1634025600
}API inputs
Parameter Description customer
JSON object containing customerToken. requestedData
An 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
Parameter Description msisdn
The user's phone number. timestamp
The UTC timestamp, in seconds, indicating when the QR code was scanned.