> **Description:** Generate static QR codes that send notifications when scanned, ideal for unmanned locations like vending machines.

# Merchant callback QR codes

**TIP**

For a visual walkthrough of the merchant callback QR flow, see [How the QR API works with merchant callback](https://developer.vippsmobilepay.com/docs/APIs/qr-api/how-it-works/qr-merchant-callback-api-howitworks.md).

**Test environment**

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.

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.

**IMPORTANT**

Before the merchant will receive any event notifications, they need to subscribe to the [`user.checked-in.v1` webhook](https://developer.vippsmobilepay.com/docs/APIs/webhooks-api/events.md).

The following endpoints are provided:

* [Get all merchant callback QRs](https://developer.vippsmobilepay.com/redocusaurus/qr-swagger-id.yaml)
* [Get callback QR by ID](https://developer.vippsmobilepay.com/redocusaurus/qr-swagger-id.yaml)
* [Create or update callback QR](https://developer.vippsmobilepay.com/redocusaurus/qr-swagger-id.yaml)
* [Delete callback QR](https://developer.vippsmobilepay.com/redocusaurus/qr-swagger-id.yaml)
* [Create or Update MobilePay QR code](https://developer.vippsmobilepay.com/redocusaurus/qr-swagger-id.yaml)

Merchant callback QR code flow

```mermaid
sequenceDiagram
  autonumber
  actor user as Vipps/MP App
  participant qr as QR Code
  participant Merchant
  participant qrApi as QR API
  participant webhooks as Webhooks API
  participant ePayment as ePayment API

  loop One call for each merchantQrId
    Merchant ->> qrApi: PUT:/qr/v1/merchant-callback/{merchantQrId}
    qrApi ->> Merchant: Response: 200 OK
  end

  Merchant ->> qrApi: GET:/qr/v1/merchant-callback
  qrApi ->> Merchant: Response: List of all QR Codes

  Merchant ->> Merchant: Print and put up QR codes in store

  Merchant ->> webhooks: Register callbackUrl for user.checked-in.v1

  user ->> qr: Scan QR code
  user ->> user: Waiting for merchant

  webhooks ->> Merchant: Send user.checked-in.v1 callback

  Merchant ->> ePayment: Trigger payment flow with customerToken from callback
  ePayment ->> user: Push payment information

```

  For each merchantQrId: Merchant creates or updates a QR code in the QR API (PUT:/qr/v1/merchant-callback/&#123;merchantQrId&#125;). QR API returns 200 OK.
  Merchant retrieves the list of all QR codes (GET:/qr/v1/merchant-callback).
  Merchant prints and puts up QR codes in the store.
  Merchant registers a callbackUrl for the user.checked-in.v1 event with the Webhooks API.
  User scans the QR code and waits for the merchant.
  Webhooks API sends the user.checked-in.v1 callback to the Merchant.
  Merchant triggers the payment flow with the customerToken from the callback via the ePayment API.
  ePayment API pushes payment information to the user.

## API reference

### 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`. See [QR code formats](https://developer.vippsmobilepay.com/docs/APIs/qr-api/api-guide/code-formats.md) for more details. |
| `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. See [QR code formats](https://developer.vippsmobilepay.com/docs/APIs/qr-api/api-guide/code-formats.md) for more details. |
| `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

Only those parameters that are not already described are shown here.

| 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. |

**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](https://developer.vippsmobilepay.com/redocusaurus/qr-swagger-id.yaml) endpoint.

### How to create a merchant callback QR code

To create a merchant callback QR code, call the
[`PUT:/qr/v1/merchant-callback/{merchantQrId}`](https://developer.vippsmobilepay.com/redocusaurus/qr-swagger-id.yaml) 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:

```json
{
  "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](#fetching-the-merchant-callback-qr-codes) described below.

#### Setting category

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

| `IN_STORE` | `VENDING` |
|----------|----------|
|     |    |

Screenshots: Two Vipps app waiting screens side by side. Left (IN_STORE): a merchant icon at the top and the message "Waiting for store" with animated loading dots. Right (VENDING): the same merchant icon with the message "Choose your product on the vending machine" and loading dots.

### 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}`](https://developer.vippsmobilepay.com/redocusaurus/qr-swagger-id.yaml) 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 that 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}`](https://developer.vippsmobilepay.com/redocusaurus/qr-swagger-id.yaml).

### 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`.

Both endpoints support optional query parameters for customizing the returned QR code:

* `qrImageFormat` to choose the image format
* `qrImageSize` to set the size.

See [QR code formats](https://developer.vippsmobilepay.com/docs/APIs/qr-api/api-guide/code-formats.md) for all available options.

To fetch a single QR code, call the endpoint:
[`GET:/qr/v1/merchant-callback/{merchantQrId}?qrImageFormat=PNG&qrImageSize=500`](https://developer.vippsmobilepay.com/redocusaurus/qr-swagger-id.yaml).

An example of the response looks like this:

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

The QR code image can be printed, or it can be displayed on a 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`](https://developer.vippsmobilepay.com/redocusaurus/qr-swagger-id.yaml).

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:

```json
{
  [
    {
      "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.

### Callback from QR

**IMPORTANT**

Webhooks are essential for merchant callback QR codes. Without a webhook subscription, you won't receive notifications when customers scan your QR codes.

To receive notifications when a customer scans your merchant callback QR code, you must:

1. Set up webhooks with the [Webhooks API](https://developer.vippsmobilepay.com/docs/APIs/webhooks-api/README.md)
2. Subscribe to the [`user.checked-in.v1` event](https://developer.vippsmobilepay.com/docs/APIs/webhooks-api/events.md)

When a customer scans your QR code, you'll receive a webhook notification.

### 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.

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](https://developer.vippsmobilepay.com/redocusaurus/qr-swagger-id.yaml) request:

    ```bash
    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:

    ```json
    {
    "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.  |

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