Skip to main content

Quickstart

Complete a full PIX deposit in the staging environment — from credentials to a credited balance — in about 15 minutes. You need curl, a publicly reachable HTTPS endpoint for webhooks, and staging credentials.

Nothing here moves real money.

The whole flow​

Steps 1–3 and 6 are calls you make. Step 5 is the one you receive — and it is the step most integrations get wrong, because it arrives asynchronously and can arrive more than once.

Step 1 — Get an access token​

curl --request POST \
--url 'https://api.sdb.lbpay.com.br/v1/oauth2/token' \
--header 'accept: application/json' \
--header 'content-type: multipart/form-data' \
--form client_id=YOUR_CLIENT_ID \
--form grant_type=client_credentials \
--form client_secret=YOUR_CLIENT_SECRET

Export the token so the following steps can reuse it:

export TOKEN="the_access_token_you_received"
export API="https://api.sdb.lbpay.com.br/v1"

The token is valid for 2 hours. See Authentication for automatic renewal.

Step 2 — Register your webhook​

Deposits are confirmed asynchronously. Register the endpoint that will receive events before you create a charge, or you will have no way of learning that the payment arrived.

Put your endpoint online first

LB Pay probes the URL during registration. If it is unreachable, still returning 404, or not yet serving HTTPS, this call fails with webhook_unreachable or webhook_timeout — not later, but right here.

curl --request PUT \
--url "$API/webhook" \
--header "Authorization: Bearer $TOKEN" \
--header 'content-type: application/json' \
--data '{
"url": "https://your-platform.example.com/webhooks/lbpay",
"type": 0,
"authenticationType": 1,
"authentication": { "type": "bearer", "token": "YOUR_WEBHOOK_TOKEN" },
"events": ["pixChargePaid", "pixChargeExpired"]
}'

type selects the domain this configuration covers — 0 Pix In, 1 Pix Out, 2 Pix Refund. The token is yours: LB Pay sends it back on every notification so you can reject anything that does not carry it.

Your endpoint must respond 2xx within 5 seconds. Persist the event and return immediately; do the business logic afterwards, off the request path — see Webhooks.

Step 3 — Create a deposit charge​

curl --request POST \
--url "$API/pix/deposit/immediate-charge" \
--header "Authorization: Bearer $TOKEN" \
--header 'content-type: application/json' \
--data '{
"externalId": "3f2b1c4e-9a7d-4e21-b8f0-5c6d7e8a9b01",
"amount": 5000,
"expiresIn": 600,
"pixKey": "YOUR_OPERATOR_PIX_KEY",
"expectedPayer": { "taxId": "12345678909" }
}'
Amounts are integers, in cents

5000 is R$ 50,00. Sending 50.00 is not a smaller amount — it is a different request altogether. This applies to every endpoint that moves money.

FieldWhy it matters
externalIdYour own identifier, unique per operation, up to 100 characters. It is the idempotency key — persist it before sending. See Idempotency.
expiresInLifetime of the QR Code in seconds. Use at least 600, and make sure the countdown you show the player matches it exactly.
pixKeyThe destination key — yours, not the player's. This is the account being credited.
expectedPayer.taxIdThe player's CPF. Ownership rules compare it against the CPF that actually pays — see Ownership rules.

The response returns 201 with a chargeId, the copy-and-paste payload in brCode, and status PENDING.

Step 4 — Simulate the payment​

In staging you do not need a bank app. Simulate the player paying:

curl --request POST \
--url "$API/pix/mock/simulate-payment" \
--header "Authorization: Bearer $TOKEN" \
--header 'content-type: application/json' \
--data '{
"chargeId": "THE_CHARGE_ID_FROM_STEP_3",
"receiverCnpj": "YOUR_RECEIVING_CNPJ"
}'

chargeId and receiverCnpj are both required. Everything else — amount, payer details — is recovered from the charge you created in step 3.

Staging only

mock/simulate-payment does not exist in production. It is the supported way to exercise the credit path during development and homologation.

Step 5 — Receive pixChargePaid​

Your endpoint receives a POST describing the event. This is the signal — and the only signal — that authorises crediting the player's wallet.

{
"event": "pixChargePaid",
"status": "paid",
"chargeId": "...",
"externalId": "3f2b1c4e-9a7d-4e21-b8f0-5c6d7e8a9b01",
"endToEndId": "E12345678202608181200abcdef12345",
"amount": 5000
}
Credit exactly once

The platform retries webhook delivery, so the same event can arrive more than once. Before crediting, check whether you have already processed this endToEndId. Skipping this check credits the player twice for one deposit.

Store the endToEndId — it is the identifier that ties this transaction to statements, refunds and support tickets.

If the event never arrives, do not assume failure. Query the charge directly:

curl --request GET \
--url "$API/pix/deposit/immediate-charge/THE_CHARGE_ID" \
--header "Authorization: Bearer $TOKEN"

Webhooks are the primary channel; polling is the mandatory fallback. See Polling.

Step 6 — Confirm the balance​

curl --request GET \
--url "$API/balance/realtime" \
--header "Authorization: Bearer $TOKEN"

The deposited amount is now reflected in your LB Pay balance.

What to build next​

You have the happy path. Production readiness is mostly about the unhappy ones:

NextWhy
IdempotencyPrevents duplicate payments after a network error
Retries and timeoutsA timeout is not a failure
WithdrawalsThe most critical flow for iGaming
Go Live checklistThe formal acceptance criteria for production access