Paying Pix
Send payments to Brazilian bank accounts via Pix
This endpoint allows you to make payments from USDT to any given Pix key, which will reflect the balance in seconds into any bank account in Brazil.
Payments are processed through our prepaid system with direct bank settlement for optimal speed and reliability.
Request Body
| Name | Type | Description |
|---|---|---|
| pix_key | string | Required. The Pix key of the recipient. Can be a CPF/CNPJ, email, phone number, or random key. |
| currency | string | Required. Either 'BRL' or 'USDT'. Determines how the amount is interpreted. |
| amount | float | Required. Amount to be sent. Minimum value is 0.5 (validated as USDT equivalent regardless of the currency field). |
| from_address | string | Required. The sender wallet address. Must be a whitelisted address registered in your merchant wallets. |
| external_id | string | Recommended. Your internal reference ID for this transaction. Must be unique for each payment attempt. Used to prevent duplicates and track transactions. If omitted, idempotency and deduplication via external_id will not be available. |
Currency Handling: If the payout currency is set to BRL, kamiPay sends exactly the BRL amount requested. If the payout currency is set to USDT, kamiPay calculates the BRL amount at payout creation time using the current exchange rate and sends that resulting BRL amount.
The minimum payment amount is 0.5 (validated as USDT equivalent). Sending an amount lower than 0.5 will result in a 400 error.
Example Request
const url = `${baseURL}/v1/payments/payToPixKey`;
const body = {
"currency": "BRL",
"amount": 4.10,
"pix_key": "user@example.com", // CPF/CNPJ/email/Phone/pixkey
"from_address": "0x1c0aCF853xxxxx9488fEdce1ab4",
"external_id": "payment-unique-id-001" // Must be unique for each attempt
};
const response = await fetch(url, {
method: "POST",
headers: {
Authorization: `Bearer ${access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify(body)
});import requests
import json
url = f"{base_url}/v1/payments/payToPixKey"
body = {
"currency": "BRL",
"amount": 4.10,
"pix_key": "user@example.com", # CPF/CNPJ/email/Phone/pixkey
"from_address": "0x1c0aCF853xxxxx9488fEdce1ab4",
"external_id": "payment-unique-id-001" # Must be unique for each attempt
}
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 := fmt.Sprintf("%s/v1/payments/payToPixKey", baseURL)
// Create request body
requestBody, _ := json.Marshal(map[string]interface{}{
"currency": "BRL",
"amount": 4.10,
"pix_key": "user@example.com", // CPF/CNPJ/email/Phone/pixkey
"from_address": "0x1c0aCF853xxxxx9488fEdce1ab4",
"external_id": "payment-unique-id-001", // Must be unique for each attempt
})
// Create request
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
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
Payment Successfully Processed
{
"status": "ok",
"kamipay_id": "txc_01jrazd7a9fqpp0bym8km1dbd6",
"data": {
"status": "broadcasted",
"usdt_amount": 0.875934
},
"external_id": "testing123"
}Always use kamipay_id and external_id for transaction tracking. The external_id field is only present in the response if it was provided in the request.
Payment Created (Processing)
Returned when the external_id matches an existing transaction that is still being processed or has already been completed.
{
"status": "created",
"kamipay_id": "txc_01jkg5vktaer5abc123kjgrsn2",
"data": null,
"external_id": "idempotency-1"
}Bad Request
The response format for 400 errors varies depending on the validation that failed.
Invalid PIX key format:
{
"detail": {
"msg": "Description of the format error",
"reformated_key": null,
"name": null
}
}Invalid amount (below minimum):
{
"detail": "Wrong amount USDt:0.3. Minimum USDt:0.5"
}Invalid currency:
{
"detail": "Currency should be BRL, USDT"
}Invalid or non-whitelisted from_address:
{
"detail": "Incorrect Address: 0xInvalidAddress123"
}Missing pix_key:
{
"detail": "pix_key is required"
}Unauthorized
Invalid or expired token:
{
"detail": "Incorrect Credentials"
}Valid token but insufficient permissions:
{
"detail": "Token Profile Not Authorized for this Endpoint"
}Conflict (Previous Transaction Cancelled)
Returned when the external_id matches an existing transaction that was previously cancelled. To retry, you must use a new external_id, since re-sending the same one will return this same 409 response.
{
"status": "canceled",
"kamipay_id": "txc_01jkg5vktaer5abc123kjgrsn2",
"data": null,
"external_id": "idempotency-1"
}Payment Failed (Transaction Cancelled)
The payment was attempted but failed at the gateway level. The transaction is permanently cancelled.
{
"status": "canceled",
"kamipay_id": "txc_01jrazd7a9fqpp0bym8km1dbd6",
"data": null,
"external_id": "testing123"
}Critical: This status indicates the transaction could NOT be processed and should be considered failed. If you want to retry the payment, you must use a new external_id.
Internal Server Error
{
"detail": "An unexpected error occurred."
}Service Unavailable
Returned when the payment gateway is under maintenance.
{
"detail": "Service is temporarily unavailable due to maintenance"
}Transaction Identifiers
| Identifier | Description |
|---|---|
kamipay_id | Primary identifier provided by kamiPay to monitor a specific transaction until completion. Always use this for transaction tracking. |
external_id | Your transaction identifier. Must be unique for each payment attempt. Essential for preventing duplicates, tracking in webhooks, and status endpoints. Only present in responses if it was provided in the request. |
Important: Always use kamipay_id and external_id as your primary tracking mechanisms.
Response Statuses Returned by This Endpoint
This endpoint can return the following status values in the response body:
| Status | HTTP Code | Description |
|---|---|---|
ok | 200 | Payment was successfully processed. The data object contains the transaction details. |
created | 201 | A transaction with this external_id already exists and is either in progress or completed. No new transaction is created. |
canceled | 409 | A transaction with this external_id was previously cancelled. You must use a new external_id to retry. |
canceled | 424 | The payment was attempted but failed at the gateway level. The transaction is permanently cancelled. You must use a new external_id to retry. |
For detailed transaction status tracking (e.g., intermediate processing states, final settlement confirmation), use the status endpoint or webhooks. This endpoint only returns the initial synchronous result of the payment attempt.
Payment Processing
Payments are processed through our prepaid system, which provides:
- Fast settlement: Direct bank transfers settled in batches
- Consistent identifiers: Same tracking system (
kamipay_idandexternal_id) regardless of underlying processing method
Error Handling & Retries
Status Code 424 - Critical Failure: When receiving a 424 status code, the transaction has failed permanently. To retry the payment, you must generate a new external_id. Using the same external_id will result in duplicate prevention mechanisms blocking the request.
Retry Guidelines
- Successful payments (200): No retry needed
- Processing payments (201): Do not retry. Monitor status via webhooks or status endpoint
- Failed payments (424): Generate a new
external_idbefore retrying - Conflicts (409): The previous transaction with this
external_idwas cancelled. You must use a newexternal_idto retry, as re-sending the same one will return409again - Server errors (500/503): Safe to retry with the same
external_idafter a short delay
Handling Parallel Requests
Status: Created (201)
When making requests while a previous transaction with the same external_id is still processing:
- Returns 201 status code
- The existing transaction is still being processed; no new transaction is created
- The
datafield will benull - Monitor via status endpoint or webhooks
Status: Cancelled (409/424)
- 409: A previous transaction with this
external_idwas cancelled. Use a newexternal_idto retry - 424: The current transaction failed to process at the gateway level. Use a new
external_idto retry