Pay-In
This endpoints should be used for manual inspection of different transactions.
Pay-In Status
kamiPay will automatically send webhooks for status update notifications but we recommend all integration to have this endpoint configured in case webhook was not properly received.
The main information about status progress will be found within the "data" key in the response.
So main status will be "ok" meaning, we acknowledge that we have that transaction and then within the data key you will have specific details of that transaction.
"TX not found" means nothing has been paid for that id yet, not a failed charge. The response is still HTTP 200, with a top-level "status": "failed" and "msg": "TX not found", as in the (TX not found) example below.
- kamiPay returns it for a QR just created, a QR that expired unpaid, and an id it doesn't know (except an unknown
e2e_id, see Query Parameters). - It isn't
data.status: "failed", which means the money was returned to the payer. Keep the order open. - kamiPay doesn't report unpaid QRs as expired: derive expiry yourself from the
expirationreturned when you created the QR.
Query Parameters
| Name | Type | Description |
|---|---|---|
| target | string | Required. Which id you send in id. For a charge: kamipay_id, external_id, operation_id, e2e_id or tx_id (see below) |
| type | string | Required. charge |
| id | string | Required. The charge's id, of the kind named in target |
| chain | string | Optional. polygon, the default and only supported value. Any other value is rejected with 422. |
A charge can be looked up by any of these ids, charges on a Printed Dynamic QR included:
target | id to send |
|---|---|
kamipay_id | The charge's kamiPay id: dqr_…, or cqr_… for a charge on a Printed Dynamic QR |
external_id | Your own order id, the external_id you sent when creating the QR |
operation_id | The operation_id the creation returned (ptxr_…) |
e2e_id | The Pix end-to-end id, the webhook's bank_txid, once the charge is paid |
tx_id | The Polygon transaction hash of the settlement, once the charge is done |
With target=e2e_id, an id kamiPay doesn't know returns HTTP 404 with "status": "not_found" instead of "TX not found". A Pix that reached kamiPay without being matched to any charge returns HTTP 202 with "status": "orphan": contact support for its refund.
Example Request
The examples look the charge up by kamipay_id; any of the five targets works the same way.
const target = "kamipay_id"
const type = "charge"
const id = "dqr_01kr3m9q5h7w2v4n6b8s3d5e9p"
const chain = "polygon"
const url = `${baseURL}/v2/status/tx_status?target=${target}&type=${type}&id=${id}&chain=${chain}`
const response = await fetch(url, {
method: "GET",
headers: {
Authorization: `Bearer ${access_token}`,
"Content-Type": "application/json",
},
});import requests
target = "kamipay_id"
type = "charge"
id = "dqr_01kr3m9q5h7w2v4n6b8s3d5e9p"
chain = "polygon"
url = f"{base_url}/v2/status/tx_status?target={target}&type={type}&id={id}&chain={chain}"
headers = {
'Authorization': f'Bearer {access_token}',
'Content-Type': 'application/json',
}
response = requests.get(url, headers=headers)package main
import (
"fmt"
"net/http"
)
func main() {
target := "kamipay_id"
typeParam := "charge"
id := "dqr_01kr3m9q5h7w2v4n6b8s3d5e9p"
chain := "polygon"
url := fmt.Sprintf("%s/v2/status/tx_status?target=%s&type=%s&id=%s&chain=%s",
baseURL, target, typeParam, id, chain)
// Create request
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", access_token))
req.Header.Add("Content-Type", "application/json")
// Make the request
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error making request:", err)
return
}
defer resp.Body.Close()
}Response
data.status follows the same steps as the Pay-In webhook:
processing: release the payer now. kamiPay has received the BRL and the payment is guaranteed, so don't make the payer wait fordone.donefollows when the USDt reaches your wallet, with its transaction hash. In the rare casedonedoesn't follow, contact support with thekamipay_id.done: the USDt was settled to your wallet, and the response carries its Polygon transaction hash intx_id, the same name the webhook uses, as in the (Success) example below.failed: an atypical case, described below.
failed is an atypical case, not a normal outcome, but your integration must handle it. A charge doesn't end failed in the normal flow. It can still happen in atypical cases, such as the same QR code being paid twice through a provider error, and it means the money was returned to the payer. The response then has "status": "ok" at the top level, but "status": "failed" inside the data object, as shown in the (Returned) example below.
{
"status": "ok",
"msg": "Request ok",
"data": {
"status": "done",
"qr_type": "dynamic",
"kamipay_id": "dqr_01kr3m9q5h7w2v4n6b8s3d5e9p",
"operation_id": "ptxr_01kr3m9p7n2s4d8h6e5b3t7w1k",
"bank_txid": "E29384756202604271548aB7cD3xY9mZ",
"bank_account_nr": "29384756-0001-0001349872",
"internal_pix_id": "8a3f1c9d72b46e08fd5a912ec47b3f06",
"amount_brl": "5.28",
"amount_usdt": "1.033355",
"tx_id": "0xa3f9b2c1e7d4865094bd28fa1c3e6b85907df42a3b9c1de80f5a672bc41e9d3f",
"address_out": "0x7a3F9b2C1e8D5462bA9c7F3e6D85907df41A2c3B",
"name": "Satoshi Nakamoto",
"timestamp": "2026-04-27 15:51:40.171821-03:00"
}
}timestampequals the webhook'stimestampfor the same status. Only in the few seconds between the charge being recordeddoneand itsdonewebhook being sent is it the time the status was recorded instead.amount_brl,amount_usdtandbank_account_nrfollow the rules in Data Fields:amount_brlhas 2 decimals andamount_usdt6, as strings, andbank_account_nrreads as in the webhook.
When the QR was generated with currency set to "ARS", the response also includes amount_ars with the original ARS amount. This field is not present for BRL or USDt charges.
{
"status": "ok",
"msg": "Tx Failed, returned",
"data": {
"status": "failed"
}
}{
"status": "failed",
"msg": "TX not found"
}{
"detail": "detailed error will be provided here"
}With an invalid or expired token:
{
"detail": "Could not validate credentials"
}{
"detail": "an unexpected error occurred"
}If this charge has been refunded, the data object also includes a refunds array (one entry per refund — partial refunds produce several), each reporting both legs (BRL + USDt). See Pay-In Refund status for its shape.