kamiPay LogokamiPay Docs
Account administration

Checkouts

List and create checkouts (cajas) within your stores.

Each store can have multiple checkouts (cajas). Each checkout is linked to one of your merchant wallets, which determines where the settlement goes when a QR Code is paid. Use the endpoints below to manage your checkouts.

Before creating a checkout, you need a wallet_id from your merchant account. Use the Wallets endpoint to retrieve your available wallets.


List Checkouts for a Store

GET /v2/stores/{store_id}/checkouts

Returns all checkouts for a given store, scoped to your merchant account. Returns 404 if the store doesn't exist or belongs to a different merchant.

Path Parameters

NameTypeDescription
store_idintegerRequired. The store ID to query checkouts for.

Example Request

const store_id = 1
const url = `${baseURL}/v2/stores/${store_id}/checkouts`

const response = await fetch(url, {
  method: "GET",
  headers: {
    Authorization: `Bearer ${access_token}`,
  },
});
import requests

store_id = 1
url = f"{base_url}/v2/stores/{store_id}/checkouts"

headers = {
  "Authorization": f"Bearer {access_token}",
}

response = requests.get(url, headers=headers)
package main

import (
  "fmt"
  "net/http"
)

func main() {
  store_id := 1
  url := fmt.Sprintf("%s/v2/stores/%d/checkouts", baseURL, store_id)

  req, _ := http.NewRequest("GET", url, nil)
  req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", accessToken))

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

Response

[
  {
    "merchant_id": 1,
    "store_id": 1,
    "checkout_id": 1,
    "checkout_desc": "Main register",
    "wallet_id": 3
  }
]
{
  "message": "Unauthorized",
  "request_id": "30e87ab5xxxxxxxxxxxxf8249f594cfb"
}
{
  "detail": "Store not found"
}
{
  "detail": "Internal Server Error"
}

Response Fields

FieldTypeDescription
merchant_idintegerYour merchant ID.
store_idintegerThe store this checkout belongs to.
checkout_idintegerCheckout identifier. Use this when creating a QR Code.
checkout_descstringDescription of the checkout.
wallet_idintegerWallet associated with this checkout. Settlements go to this wallet's address.

Create Checkout

POST /v2/stores/{store_id}/checkouts

Creates a new checkout within a store. The checkout_id is assigned automatically and is scoped to the store. The wallet_id must belong to your merchant account — cross-merchant wallet assignment is not allowed.

Path Parameters

NameTypeDescription
store_idintegerRequired. The store to create the checkout in.

Body Parameters

NameTypeDescription
checkout_descstringRequired. Description of the checkout (e.g. "Register 1", "Self-service kiosk").
wallet_idintegerRequired. The wallet to associate with this checkout. Must belong to your merchant account.

Example Request

const store_id = 1
const url = `${baseURL}/v2/stores/${store_id}/checkouts`

const body = {
  checkout_desc: "Register 1",
  wallet_id: 3,
}

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

store_id = 1
url = f"{base_url}/v2/stores/{store_id}/checkouts"

body = {
  "checkout_desc": "Register 1",
  "wallet_id": 3,
}

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

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

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

func main() {
  store_id := 1
  url := fmt.Sprintf("%s/v2/stores/%d/checkouts", baseURL, store_id)

  body := map[string]interface{}{
    "checkout_desc": "Register 1",
    "wallet_id":     3,
  }

  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

{
  "merchant_id": 1,
  "store_id": 1,
  "checkout_id": 2,
  "checkout_desc": "Register 1",
  "wallet_id": 3
}
{
  "detail": "Wallet not found"
}
{
  "message": "Unauthorized",
  "request_id": "30e87ab5xxxxxxxxxxxxf8249f594cfb"
}
{
  "detail": "Store not found"
}
{
  "detail": "Internal Server Error"
}

400 Wallet not found is returned when the wallet_id doesn't exist or belongs to a different merchant. This prevents cross-merchant wallet assignment.

Response Fields

FieldTypeDescription
merchant_idintegerYour merchant ID.
store_idintegerThe store this checkout belongs to.
checkout_idintegerNewly assigned checkout identifier.
checkout_descstringDescription of the checkout.
wallet_idintegerThe wallet linked to this checkout.

Checkout Configs

Each checkout has a flexible key–value configuration store (checkout_configs) that lets you toggle features on a per-checkout basis. The tuple (merchant_id, store_id, checkout_id, config_type) is unique, so re-using a config_type overwrites the previous value.

The most relevant config_type today is default_qr. Setting default_qr=printed_dynamic_qr on a checkout makes create_dynamic_pix dispatch to the Printed Dynamic QR flow for that checkout.

Configure with care. These endpoints write directly to your checkout's configuration. A misconfigured checkout (wrong config_type, unsupported config_value, or a value that points to a resource that doesn't exist — e.g. setting default_qr=printed_dynamic_qr on a checkout that has no Printed Dynamic QR assigned) can break future charges on that checkout. Use these endpoints at your own risk. If you're not sure how to configure a checkout, contact support and we'll help you set it up.

Set a Checkout Config

POST /v2/stores/{store_id}/checkouts/{checkout_id}/configs

Upserts a single (config_type, config_value) row for the given checkout. Returns 404 if the checkout doesn't exist or doesn't belong to your merchant.

Path Parameters

NameTypeDescription
store_idintegerRequired. The store the checkout belongs to.
checkout_idintegerRequired. The checkout to configure.

Body Parameters

NameTypeDescription
config_typestringRequired. The configuration key (for example, default_qr).
config_valuestringRequired. The configuration value (for example, printed_dynamic_qr).

Example Request

const store_id = 1
const checkout_id = 500
const url = `${baseURL}/v2/stores/${store_id}/checkouts/${checkout_id}/configs`

const body = {
  config_type: "default_qr",
  config_value: "printed_dynamic_qr",
}

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

store_id = 1
checkout_id = 500
url = f"{base_url}/v2/stores/{store_id}/checkouts/{checkout_id}/configs"

body = {
  "config_type": "default_qr",
  "config_value": "printed_dynamic_qr",
}

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

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

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

func main() {
  store_id := 1
  checkout_id := 500
  url := fmt.Sprintf("%s/v2/stores/%d/checkouts/%d/configs", baseURL, store_id, checkout_id)

  body := map[string]interface{}{
    "config_type":  "default_qr",
    "config_value": "printed_dynamic_qr",
  }

  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

{
  "merchant_id": 1,
  "store_id": 1,
  "checkout_id": 500,
  "config_type": "default_qr",
  "config_value": "printed_dynamic_qr"
}
{
  "message": "Unauthorized",
  "request_id": "30e87ab5xxxxxxxxxxxxf8249f594cfb"
}
{
  "detail": "Checkout not found"
}
{
  "detail": "Validation error: config_type and config_value must be non-empty"
}
{
  "detail": "Internal Server Error"
}

Response Fields

FieldTypeDescription
merchant_idintegerYour merchant ID.
store_idintegerThe store the checkout belongs to.
checkout_idintegerThe checkout that was configured.
config_typestringThe configuration key that was set.
config_valuestringThe configuration value that was set.

List Checkout Configs

GET /v2/stores/{store_id}/checkouts/{checkout_id}/configs

Returns every checkout_configs row for the given checkout, ordered by config_type. Returns an empty array when the checkout has no configs, and 404 if the checkout doesn't exist or doesn't belong to your merchant.

Path Parameters

NameTypeDescription
store_idintegerRequired. The store the checkout belongs to.
checkout_idintegerRequired. The checkout to inspect.

Example Request

const store_id = 1
const checkout_id = 500
const url = `${baseURL}/v2/stores/${store_id}/checkouts/${checkout_id}/configs`

const response = await fetch(url, {
  method: "GET",
  headers: {
    Authorization: `Bearer ${access_token}`,
  },
});
import requests

store_id = 1
checkout_id = 500
url = f"{base_url}/v2/stores/{store_id}/checkouts/{checkout_id}/configs"

headers = {"Authorization": f"Bearer {access_token}"}

response = requests.get(url, headers=headers)
package main

import (
  "fmt"
  "net/http"
)

func main() {
  store_id := 1
  checkout_id := 500
  url := fmt.Sprintf("%s/v2/stores/%d/checkouts/%d/configs", baseURL, store_id, checkout_id)

  req, _ := http.NewRequest("GET", url, nil)
  req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", accessToken))

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

Response

[
  {
    "merchant_id": 1,
    "store_id": 1,
    "checkout_id": 500,
    "config_type": "default_qr",
    "config_value": "printed_dynamic_qr"
  }
]
{
  "message": "Unauthorized",
  "request_id": "30e87ab5xxxxxxxxxxxxf8249f594cfb"
}
{
  "detail": "Checkout not found"
}
{
  "detail": "Internal Server Error"
}

On this page