Pular para o conteúdo principal

Critical warnings

These are the failure modes that cause financial incidents in new integrations. Each one is short, specific, and has cost somebody money.

1. Generating a new externalId on retry​

What breaks: a network timeout becomes a duplicate payment.

The externalId is the idempotency key. Reusing it on a retry lets LB Pay recognise the repeated intent and return the original transaction. Generating a fresh UUID tells the platform this is an unrelated operation — and it executes a second time.

➡️ Idempotency

2. Treating a timeout as a failure​

What breaks: you refund a player whose withdrawal actually settled, and pay twice.

A timeout or a 503 means no answer — not no transaction. Wait, then query by externalId, and act on what the GET returns.

➡️ Retries and timeouts

3. Cancelling a withdrawal without querying it first​

What breaks: you cancel a withdrawal that already settled, and pay the player twice.

A cancellation is a decision about an outcome. If you have not confirmed the outcome, you are guessing — and the API is the only thing that knows.

Never cancel a withdrawal request without first running the GET:

GET /v1/pix/withdraw/{externalId}

Act on what it returns. If it is still INITIATED, CONFIRMED or PROCESSING, the answer is to wait, not to cancel.

➡️ Retries and timeouts

4. Closing a charge on the first payment error​

What breaks: you discard a deposit the player is about to pay, and the money arrives with nobody expecting it.

A failed payment attempt does not cancel the QR Code. The charge stays valid until it is paid or expires, and the player can simply try again.

What you receive is an error webhook with no final status — pixChargeRejected carries "status": "pending" and a rejectedReason. It is a progress report, not an outcome.

Your system must accept that event without treating it as terminal, keep the charge open, and keep waiting for the real ending: pixChargePaid or pixChargeExpired.

➡️ Deposits

5. Acting on a transitional status​

What breaks: you cancel or reverse a withdrawal that was still in flight.

INITIATED, PENDING, PROCESSING and CONFIRMED mean the outcome is unknown. Never return balance, cancel an operation, or block a retry while a transaction is in one of them.

➡️ Pix Out reference

6. Not deduplicating webhooks​

What breaks: the player is credited twice for one deposit.

The platform retries delivery. The same pixChargePaid can arrive more than once. Enforce uniqueness on endToEndId at the database level, not in application code.

➡️ Credit exactly once

7. expiresIn out of sync with your interface​

What breaks: players who pay a valid-looking QR Code are rejected.

If the charge expires in 300 s and your countdown shows 10 minutes, payments made after minute 5 fail. Use at least 600 s and drive the countdown from expiresAt.

➡️ Deposits

8. Retrying 422 with the same data​

What breaks: support noise, and automatic compliance blocks on your account.

A 422 is a business rule the platform already evaluated. Sending the same request again will be rejected the same way, every time.

What resolves it is different data — and what "different" means depends on the direction:

FlowWhat the player must do
DepositPay again from a bank account registered under their own CPF. A retry with a compliant account succeeds.
WithdrawalSupply a different destination account that belongs to them. The one they sent is not theirs.

So do not retry automatically, and do not present it to the player as a system error. Surface it as an actionable message: the account must be in their own name.

➡️ CPF Shield

9. No contingency polling​

What breaks: every event lost during a deploy stays lost.

Webhooks are not guaranteed. A sweeping job that resolves transactions stuck in a transitional state is mandatory, not optional — and it should back off as the transaction ages, so a busy minute does not turn into a poll storm.

A schedule that works:

Age of the transactionInterval
< 30 sdo not poll — wait for the webhook
30 s – 2 minevery 30 s
2 – 10 minevery 2 min, plus an internal alert past 5 min
10 – 60 minevery 10 min
> 1 hhourly, and escalate to a human queue

Each step roughly quadruples the interval: the transactions that resolve normally cost you two or three queries, and the rare stuck one is still watched hours later without flooding the API.

➡️ Contingency polling

10. Not storing the endToEndId​

What breaks: you cannot refund, reconcile, or answer a support question.

➡️ Statement

11. Releasing player balance before the debit is final​

What breaks: the player spends balance that is already leaving the account.

Debit the wallet before calling the withdrawal endpoint and mark it "processing". Return it only on a confirmed FAILED.

➡️ Withdrawals