Webhooks

We notify your server with an HTTP POST whenever a transaction changes state. The URL is the one you sent when creating the transaction:

FlowField that sets the URL
PIX-IN (POST /wallet/deposit/payment, method_pay=pix)postback
Card (POST /wallet/deposit/payment with method_pay=card, or POST /wallet/card/charge)postback
PIX-OUT (POST /pixout)baasPostbackUrl

Crypto withdrawals have no callback. Use POST /crypto/withdraw/status.

Request format

POST /your/callback/path HTTP/1.1
Content-Type: application/json
Accept: application/json

Every payload has status, idTransaction and typeTransaction. Branch on typeTransaction first, then on status.

Events

typeTransactionstatusWhenExtra fields
PIXpaidPIX charge paid. The only PIX-IN event.none
PAYMENTpaidPIX-OUT completed.none
PAYMENTcanceledPIX-OUT failed or cancelled. Amount returned to your balance.none
CARDpaidCard payment confirmed. USD balance credited.amount, currency
CARDcancelledCard charge ended without payment (session expired, or a direct API attempt failed asynchronously).amount, currency, failure_code, message, decline_code (when a decline happened)
CARDrefundedCharge fully refunded.amount, refund_amount, total_refunded, net_amount, currency
CARDpartially_refundedPart of the charge refunded.same as refunded
CARDdisputedChargeback opened. Disputed amount held.none
CARDdispute_wonChargeback resolved in your favor. Funds restored.none
CARDdispute_lostChargeback lost. Funds stay debited.none
CARD_REFUNDpending, succeeded, failed, canceled, requires_actionAn individual refund changed state. status is the refund state.refund_id, refund_status, amount, currency, failure_reason, arn

Note the two spellings: PIX-OUT uses canceled, card uses cancelled.

Payload examples

PIX-IN paid:

{ "status": "paid", "idTransaction": "a1b2c3d4e5f60718293a4b5c6d7e8f90", "typeTransaction": "PIX" }

PIX-OUT canceled:

{ "status": "canceled", "idTransaction": "F3A9C2D18B7E4C6A9D0E1F2A3B4C5D6E", "typeTransaction": "PAYMENT" }

Card paid:

{
  "status": "paid",
  "idTransaction": "3f2b8c1e-7a4d-4e3b-9c2a-1d5e6f7a8b9c",
  "typeTransaction": "CARD",
  "amount": 100.00,
  "currency": "USD"
}

Card cancelled:

{
  "status": "cancelled",
  "idTransaction": "3f2b8c1e-7a4d-4e3b-9c2a-1d5e6f7a8b9c",
  "typeTransaction": "CARD",
  "amount": 100.00,
  "currency": "USD",
  "failure_code": "insufficient_funds",
  "decline_code": "insufficient_funds",
  "message": "Your card has insufficient funds."
}

Card partially refunded:

{
  "status": "partially_refunded",
  "idTransaction": "3f2b8c1e-7a4d-4e3b-9c2a-1d5e6f7a8b9c",
  "typeTransaction": "CARD",
  "amount": 100.00,
  "refund_amount": 10.00,
  "total_refunded": 20.00,
  "net_amount": 80.00,
  "currency": "USD"
}

refund_amount is the amount of this event. total_refunded is cumulative. net_amount is amount - total_refunded.

Card disputed (dispute events carry no amounts; read them from the status endpoint):

{ "status": "disputed", "idTransaction": "3f2b8c1e-7a4d-4e3b-9c2a-1d5e6f7a8b9c", "typeTransaction": "CARD" }

Refund status changed:

{
  "status": "failed",
  "idTransaction": "3f2b8c1e-7a4d-4e3b-9c2a-1d5e6f7a8b9c",
  "typeTransaction": "CARD_REFUND",
  "refund_id": "re_3TestExample0000000001",
  "refund_status": "failed",
  "amount": 12.79,
  "currency": "USD",
  "failure_reason": "expired_or_canceled_card",
  "arn": null
}

The OpenAPI file lists each event under webhooks with its schema.

Responding and retries

Answer with any 2xx status as fast as possible. Do the heavy work after responding.

Your responseWhat we do
2xxDelivered. No more attempts.
5xx, 408, 425, 429, timeout (15 s) or connection errorRetry.
Any other 4xxPermanent failure. No retry.

Up to 6 attempts in total. Delays between attempts: 30 seconds, 2 minutes, 5 minutes, 15 minutes, 30 minutes (about 52 minutes overall). After that the callback is marked as failed. Use the status endpoints to recover anything you missed.

Do not answer 4xx for an event you do not handle; answer 200 and ignore it, or you lose the delivery.

Duplicates and ordering

  • The same event can arrive more than once (for example when your server processed it but timed out before answering). Make your handler idempotent: key on idTransaction plus status (plus refund_id for CARD_REFUND).
  • Events can arrive out of order. Do not move an order backwards: a late cancelled must not undo a paid.

Verifying a callback

Callbacks are not signed. There is no signature header and no shared secret. Anyone who learns your callback URL could post a fake payload. Before you release goods or money:

  1. Treat the callback only as a trigger.
  2. Fetch the transaction from the API with your credentials and act on that response:
    • PIX-IN and card: GET /transactions/payment/{idTransaction}
    • PIX-OUT: GET /transactions/pixout/{idTransaction}
    • Refunds: GET /wallet/card/refund/{refund_id}
  3. Check that idTransaction is one you created and that the amount matches your order.

Also recommended:

  • Use an HTTPS callback URL with a hard to guess path, for example https://example.com/callbacks/card/5f0c9e7d2b, and a different path per environment.
  • Reject payloads whose idTransaction you do not know.

Polling as a fallback

If callbacks fail or your endpoint was down, poll the status endpoints. For card charges still pending more than 3 minutes after creation, GET /transactions/payment/{idTransaction} refreshes the state from the card processor before responding, so it recovers a missed paid.


Did this page help you?