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 ErrorResponse Fields
| Field | Type | Description |
|---|---|---|
| merchant_id | integer | Your merchant ID. |
| store_id | integer | Store identifier. Use this when creating a QR Code. |
| store_name | string | Name of the store. |
| address | string | Store address. |
| phone_number | string | Store phone number. |
| string | Store 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
| Name | Type | Description |
|---|---|---|
| store_name | string | Required. Name of the store. |
| address | string | Optional. Store address. |
| phone_number | string | Optional. Store phone number. |
| string | Optional. 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 ErrorResponse Fields
| Field | Type | Description |
|---|---|---|
| merchant_id | integer | Your merchant ID. |
| store_id | integer | Newly assigned store identifier. |
| store_name | string | Name of the store. |
| address | string | null | Store address. |
| phone_number | string | null | Store phone number. |
| string | null | Store 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
| Name | Type | Description |
|---|---|---|
| store_id | integer | Required. The store to update. |
Body Parameters
| Name | Type | Description |
|---|---|---|
| store_name | string | Optional. Name of the store. At least 1 character. |
| address | string | Optional. Store address. |
| phone_number | string | Optional. Store phone number. |
| string | Optional. 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 ErrorResponse Fields
| Field | Type | Description |
|---|---|---|
| merchant_id | integer | Your merchant ID. |
| store_id | integer | The store that was updated. |
| store_name | string | Name of the store. |
| address | string | null | Store address. |
| phone_number | string | null | Store phone number. |
| string | null | Store email. |