kamiPay LogokamiPay Docs

Stores

List, create and update stores associated with your merchant account.

Each merchant can have multiple stores. A store_id is used when creating QR Codes to route the settlement to the correct wallet. Use the endpoints below to manage your stores.

Access: every Account Administration endpoint needs credentials with the pay-in scope (the ones kamiPay gives you have it) and a user with a management role, which they normally have; otherwise 401 without the scope, or 403 without the role, so contact support.


List Stores

GET /v2/stores

Returns all stores associated with your merchant account.

Example Request

const url = `${baseURL}/v2/stores`

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

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

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

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

import (
  "fmt"
  "net/http"
)

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

  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,
    "store_name": "Main Store",
    "address": "Av. Paulista 1000",
    "phone_number": "+5511999999999",
    "email": "store@example.com"
  }
]

With an invalid or expired token:

{
  "detail": "Could not validate credentials"
}

With a valid token without the pay-in scope:

{
  "detail": "Token Profile Not Authorized for this Endpoint"
}
{
  "detail": "User role not authorized for this endpoint"
}

A plain-text body, not JSON:

Internal Server Error

Response Fields

FieldTypeDescription
merchant_idintegerYour merchant ID.
store_idintegerStore identifier. Use this when creating a QR Code.
store_namestringName of the store.
addressstringStore address.
phone_numberstringStore phone number.
emailstringStore email.

Create Store

POST /v2/stores

Creates a new store for the authenticated merchant. The store_id is assigned automatically and is scoped to your merchant account.

Body Parameters

NameTypeDescription
store_namestringRequired. Name of the store.
addressstringOptional. Store address.
phone_numberstringOptional. Store phone number.
emailstringOptional. Store email.

Example Request

const url = `${baseURL}/v2/stores`

const body = {
  store_name: "Downtown Branch",
  address: "Av. Paulista 1000",
  phone_number: "+5511999999999",
  email: "downtown@example.com",
}

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/stores"

body = {
  "store_name": "Downtown Branch",
  "address": "Av. Paulista 1000",
  "phone_number": "+5511999999999",
  "email": "downtown@example.com",
}

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() {
  url := baseURL + "/v2/stores"

  body := map[string]interface{}{
    "store_name":   "Downtown Branch",
    "address":      "Av. Paulista 1000",
    "phone_number": "+5511999999999",
    "email":        "downtown@example.com",
  }

  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": 2,
  "store_name": "Downtown Branch",
  "address": "Av. Paulista 1000",
  "phone_number": "+5511999999999",
  "email": "downtown@example.com"
}

With an invalid or expired token:

{
  "detail": "Could not validate credentials"
}

With a valid token without the pay-in scope:

{
  "detail": "Token Profile Not Authorized for this Endpoint"
}
{
  "detail": "User role not authorized for this endpoint"
}

A plain-text body, not JSON:

Internal Server Error

Response Fields

FieldTypeDescription
merchant_idintegerYour merchant ID.
store_idintegerNewly assigned store identifier.
store_namestringName of the store.
addressstring | nullStore address.
phone_numberstring | nullStore phone number.
emailstring | nullStore email.

Update Store

PATCH /v2/stores/{store_id}

Changes a store's details. Only the fields you send are changed: a field you leave out, or send as null, keeps its value, so a field can't be cleared.

Path Parameters

NameTypeDescription
store_idintegerRequired. The store to update.

Body Parameters

NameTypeDescription
store_namestringOptional. Name of the store. At least 1 character.
addressstringOptional. Store address.
phone_numberstringOptional. Store phone number.
emailstringOptional. Store email.

Example Request

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

const body = {
  phone_number: "+5511988888888",
}

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

store_id = 2
url = f"{base_url}/v2/stores/{store_id}"

body = {
  "phone_number": "+5511988888888",
}

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

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

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

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

  body := map[string]interface{}{
    "phone_number": "+5511988888888",
  }

  requestBody, _ := json.Marshal(body)

  req, _ := http.NewRequest("PATCH", 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": 2,
  "store_name": "Downtown Branch",
  "address": "Av. Paulista 1000",
  "phone_number": "+5511988888888",
  "email": "downtown@example.com"
}

With an invalid or expired token:

{
  "detail": "Could not validate credentials"
}

With a valid token without the pay-in scope:

{
  "detail": "Token Profile Not Authorized for this Endpoint"
}
{
  "detail": "User role not authorized for this endpoint"
}
{
  "detail": "Store not found"
}

A plain-text body, not JSON:

Internal Server Error

Response Fields

FieldTypeDescription
merchant_idintegerYour merchant ID.
store_idintegerThe store that was updated.
store_namestringName of the store.
addressstring | nullStore address.
phone_numberstring | nullStore phone number.
emailstring | nullStore email.

On this page