kamiPay LogokamiPay Docs

Magic QRs

Create fixed, printable QR codes and attach per-sale charges to them.

Magic QRs are permanent, printable QR codes designed for physical points of sale. A single Magic QR is created once and placed at a checkout — it never changes. When the merchant is ready to charge a customer, the standard QR Code Creation endpoint automatically attaches a charge to it: the customer scans the same printed QR and their banking app shows the amount to pay.

Charges expire in 5 minutes.

Recommended flow: use the QR Code Creation endpoint (create_dynamic_pix_b2b) with the checkout_id and store_id of the checkout that has a Magic QR configured. kamiPay will automatically assign the charge to the Magic QR and return a linked dynamic QR. Both can be scanned to complete the same payment — whichever the customer scans first settles the transaction.

How charges work

Charges are managed automatically — you don't call a separate charge endpoint. Instead, you configure which checkouts use a Magic QR as their default, and from that point the standard create_dynamic_pix_b2b call handles everything:

  1. kamiPay detects that the checkout_id + store_id has a Magic QR as its default.
  2. A charge is created and attached to the printed QR — the customer scanning it will see the amount.
  3. A standard dynamic QR is also returned in the response, linked to the same charge.
  4. Either QR can be used to pay. Once one is paid, the other is invalidated.
Merchant POS              kamiPay                  Gateway             Customer
      │                      │                         │                   │
      │  POST                │                         │                   │
      │  create_dynamic_     │                         │                   │
      │  pix_b2b             │                         │                   │
      │  (checkout_id,       │                         │                   │
      │   store_id, amount)  │                         │                   │
      │─────────────────────►│                         │                   │
      │                      │                         │                   │
      │                      │  Checkout has Magic QR  │                   │
      │                      │  → attach charge to QR  │                   │
      │                      │────────────────────────►│                   │
      │                      │◄────────────────────────│                   │
      │                      │                         │                   │
      │◄─────────────────────│                         │                   │
      │  { emv,              │                         │                   │
      │    magic_qr_emv,     │                         │                   │
      │    operation_id, … } │                         │                   │
      │                      │                         │                   │
      │  Show dynamic QR     │                         │                   │
      │  (or customer scans  │                         │                   │
      │   the printed one)   │                         │                   │
      │                      │                         │◄──── Scans QR ────│
      │                      │                         │   Payment settled  │
      │                      │◄──────── Webhook ───────│                   │
      │◄──── Notification ───│                         │                   │
      │                      │                         │                   │

Checkout configuration

To enable Magic QRs for a checkout, contact the kamiPay team. We will configure the checkout_id and store_id mapping on our end. Once set up, no changes are needed in your integration — the existing create_dynamic_pix_b2b call will pick up the Magic QR automatically.


Create Magic QR

POST /v2/magic_qrs

Registers a new permanent QR code linked to a specific checkout and store. If a Magic QR already exists for the given checkout_id, the existing one is returned with HTTP 200 instead of 201.

Body Parameters

NameTypeDescription
checkout_idintegerRequired. Identifies the checkout terminal where the QR will be placed.
store_idintegerRequired. Identifies the store that owns the checkout.

Example Request

const url = `${baseURL}/v2/magic_qrs`;

const body = {
  checkout_id: 1,
  store_id: 1,
};

const response = await fetch(url, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${access_token}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify(body),
});
import requests

url = f"{base_url}/v2/magic_qrs"

body = {
    "checkout_id": 1,
    "store_id": 1,
}

headers = {
    "Authorization": f"Bearer {access_token}",
    "Content-Type": "application/json",
}

response = requests.post(url, headers=headers, json=body)
package main

import (
  "bytes"
  "encoding/json"
  "fmt"
  "net/http"
)

func main() {
  url := baseURL + "/v2/magic_qrs"

  body := map[string]interface{}{
    "checkout_id": 1,
    "store_id":    1,
  }

  requestBody, _ := json.Marshal(body)

  req, _ := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
  req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", accessToken))
  req.Header.Add("Content-Type", "application/json")

  client := &http.Client{}
  resp, err := client.Do(req)
  if err != nil {
    fmt.Println("Error:", err)
    return
  }
  defer resp.Body.Close()
}

Response

{
  "kamipay_id": "mqr_a1b2c3d4e5f6",
  "qr_emvcode": "00020101021226930014br.gov.bcb.pix...",
  "qr_location_id": "loc_xyz789",
  "address": "0x46d52020**********1fbdcc297d",
  "checkout_id": 1,
  "merchant_id": 42,
  "store_id": 1,
  "network_id": 1,
  "created_at": "2024-11-01T10:00:00Z"
}
{
  "kamipay_id": "mqr_a1b2c3d4e5f6",
  "qr_emvcode": "00020101021226930014br.gov.bcb.pix...",
  "qr_location_id": "loc_xyz789",
  "address": "0x46d52020**********1fbdcc297d",
  "checkout_id": 1,
  "merchant_id": 42,
  "store_id": 1,
  "network_id": 1,
  "created_at": "2024-10-15T08:30:00Z"
}
{
  "detail": "Invalid checkout_id or store_id"
}
{
  "detail": "Unauthorized"
}
{
  "detail": "Internal Server Error during magic QR creation"
}

Response Fields

FieldTypeDescription
kamipay_idstringUnique identifier for this Magic QR.
qr_emvcodestringThe EMV string to render as the permanent, printable QR code.
qr_location_idstringGateway-side location identifier for this QR.
addressstringMerchant wallet address associated with this QR.
checkout_idintegerThe checkout this QR belongs to.
merchant_idintegerThe merchant that owns this QR.
store_idintegerThe store this QR belongs to.
network_idintegerBlockchain network identifier.
created_atstringISO 8601 timestamp of when the Magic QR was created.

HTTP 200 means a Magic QR already existed for the given checkout_id. The existing record is returned unchanged — no new QR is created.

On this page