kamiPay LogokamiPay Docs

Pay

Receive notifications about outgoing Pix payments

After you create a payment with payToPixKey, kamiPay keeps you updated on its progress through webhooks. You don't need to poll the status endpoint from your backend.

Handling Webhook Responses

You receive one webhook per state change. Every webhook has the same top-level fields:

FieldDescription
statusprocessing, done or failed.
transaction_hashAlways null. Payouts don't have an on-chain transaction.
dataPayment details. Its content depends on status (see below).
typeAlways pay.
timestampWhen the notification was generated, formatted as YYYY-MM-DD HH:MM:SS.ffffff+0000.
external_idThe external_id you sent when creating the payment, or null.
kamipay_idkamiPay identifier of the payment (txc_...).
service_typeAlways prepaid.

Processing

The bank received the payment and started settling it. It can still end in done or failed. If it succeeds, the receiver usually sees the money a few seconds later.

{
  "status": "processing",
  "transaction_hash": null,
  "data": {
    "operation_id": "txc_01m2710frffc488sxp08mg0qzx",
    "address_in": "0xca4xxxxxxxxxxxxxxx1f2fc",
    "usdt_amount": "9.780595",
    "brl_amount": "50.00",
    "bank_txid": "E54811417202609110123BGdlB7HYojX",
    "pix_key": "info@kamipay.io",
    "name": "Kamipay AR Servicos Digitais Ltda",
    "recipient_document": null,
    "recipient_ispb": null,
    "recipient_bank_name": "unknown"
  },
  "type": "pay",
  "timestamp": "2026-09-11 01:23:46.083563+0000",
  "external_id": "aaa-11112",
  "kamipay_id": "txc_01m2710frffc488sxp08mg0qzx",
  "service_type": "prepaid"
}

Done

The payment was successful. At this point the settlement is final and both the sender's and the receiver's banks confirmed it. Use bank_txid (the Pix End-to-End ID) as proof of payment for the receiver.

{
  "status": "done",
  "transaction_hash": null,
  "data": {
    "operation_id": "txc_01m2arg0d8f1r9y3cjzh44f894",
    "address_in": "0xca4xxxxxxxxxxxxxxx1f2fc",
    "usdt_amount": "59.826162",
    "brl_amount": "307.94",
    "bank_txid": "E27084098202609121211e4MQ09RFuyC",
    "pix_key": "info@kamipay.io",
    "name": "Kamipay AR Servicos Digitais Ltda",
    "recipient_document": "**.309.606/****-**",
    "recipient_ispb": "01027058",
    "recipient_bank_name": "Cielo S.A."
  },
  "type": "pay",
  "timestamp": "2026-09-12 12:12:00.261509+0000",
  "external_id": "aaa-11112",
  "kamipay_id": "txc_01m2arg0d8f1r9y3cjzh44f894",
  "service_type": "prepaid"
}

data fields (processing and done)

FieldDescription
operation_idIdentifier of the payment at the settling bank.
address_inYour active vault address. It can be null.
usdt_amountUSDT amount debited, as a string with 6 decimals.
brl_amountBRL amount paid, as a string with 2 decimals.
bank_txidPix End-to-End ID. It can be null or empty in processing.
pix_keyDestination Pix key.
nameName of the Pix key owner.
recipient_documentReceiver's CPF/CNPJ, obfuscated BACEN-style (***.456.789-** for CPF, **.345.678/****-** for CNPJ). It can be null, usually in processing.
recipient_ispb8-digit ISPB of the receiver's bank, or null.
recipient_bank_nameName of the receiver's bank, or "unknown" when it can't be resolved.

Failed

The payment failed. It can fail for several reasons, for example because the QR code expired or the receiving bank rejected it. In every case the funds are returned to your balance.

data only carries the normalized failure reason. See Payout Failure Reasons for the list of codes and how to react to each category.

{
  "status": "failed",
  "transaction_hash": null,
  "data": {
    "error_code": "PAYOUT_TEMPORARY_ERROR",
    "error_message": "A temporary error occurred. Please try again later.",
    "error_category": "internal"
  },
  "type": "pay",
  "timestamp": "2026-09-13 23:15:26.761384+0000",
  "external_id": "aaa-11112",
  "kamipay_id": "txc_01m2egvkt0fbbryev4z2whz7ga",
  "service_type": "prepaid"
}

If a completed payout is later refunded (for example, through a MED), you receive a Refund webhook, not a new Pay webhook.

If external_id is not provided, all webhooks will come with null value for that field. We strongly recommend all users to pass an external_id to this endpoint for better tracking and monitoring.

On this page