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 of 3 BRL is required for payments. |
| from_address | string | Required. Specifies the sender wallet address. |
| external_id | string | Required. Your internal reference ID for this transaction. Must be unique for each payment attempt. Used to prevent duplicates and track transactions. |
Currency Handling: If you set the currency as BRL, the amount will be paid exactly unless the payment hits after the rate changes significantly (tolerance is 50cts USDT). If you set the currency as USDT, it'll be converted into BRL at the time of arrival with the actual exchange rate.
The minimum payment amount is 3 BRL.
Important: Always use kamipay_id and external_id as primary identifiers for tracking transactions. The transaction_hash field may occasionally contain a value but should be ignored for integration purposes.
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/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",
"transaction_hash": "", // May be empty for prepaid flow
"usdt_amount": 0.875934
},
"external_id": "testing123"
}Note: The transaction_hash field may occasionally contain a value but should be ignored. Always use kamipay_id and external_id for transaction tracking.
Payment Created (Processing)
{
"status": "created",
"kamipay_id": "txc_01jkg5vktaer5abc123kjgrsn2",
"data": null,
"external_id": "idempotency-1"
}Bad Request
{
"detail": "detailed error will be provided here"
}Unauthorized
{
"detail": "Incorrect Credentials"
}Conflict (Previous Transaction Cancelled)
{
"status": "canceled",
"kamipay_id": "txc_01jkg5vktaer5abc123kjgrsn2",
"data": null,
"external_id": "idemptency-1"
}Payment Failed (Transaction Cancelled)
{
"status": "canceled",
"kamipay_id": "txc_01jrazd7a9fqpp0bym8km1dbd6",
"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
{
"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. |
transaction_hash | Legacy field that may occasionally contain a value. Should be ignored for integration purposes. |
Important: Always use kamipay_id and external_id as your primary tracking mechanisms. Do not rely on the transaction_hash field.
Payment Processing
Payments are processed through our prepaid system, which provides:
- Fast settlement: Direct bank transfers settled in batches
- Reliable processing: No dependency on blockchain network conditions
- Transparent billing: Charges calculated on confirmed payments minus any refunds received
- 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): Monitor status via webhooks or status endpoint
- Failed payments (424): Generate new
external_idbefore retrying - Conflicts (409): Previous transaction was cancelled, can retry with same
external_id - Server errors (500/503): Safe to retry with same
external_idafter delay
Handling Parallel Requests
Status: Created (201)
When making requests while a previous transaction is still processing:
- Returns 201 status code
- Transaction was queued but is still processing
- The data field will be null
- Monitor via status endpoint or webhooks
Status: Cancelled (409/424)
- 409: Previous transaction cancelled due to internal issues, can retry
- 424: Current transaction failed to process, must use new
external_idto retry
The payment process is asynchronous. After receiving a 201 status code, monitor the transaction status using the status endpoint or set up webhooks to receive real-time notifications.
Be careful when specifying Pix keys. Each key type has a specific format, and sending incorrect formats will result in errors or delayed payments.