Process an inbound JDPI cash-in
Registers an inbound PIX credit that JDPI has settled to this participant (JDPI section 9.3.2). JDPI calls it once per received credit, after settlement; it is idempotent on the end-to-end id (the mandatory Chave-Idempotencia header), so a redelivery of a credit already registered answers 409 PIX-0029 rather than posting the credit twice.
On success the credit is posted to the receiving customer’s account and the response carries the three section 9.3.2 members: idReqJdPi, idCreditoSgct (the identifier of the credit entry this participant recorded) and dtHrCreditoSgct (when it was recorded). That response is an assertion that the money was booked; there is no field in it for a refusal.
NOT EVERY CREDIT LANDS ON A CUSTOMER ACCOUNT. This participant may also serve INDIRECT participants — other institutions that reach SPI through this participant’s ISPB and are registered here with POST /v1/indirects. When recebedor.ispb names one of them and its registration is ACTIVE, the credit is posted to THAT institution’s @pi_{ispb} settlement position instead of to a customer account. The destination is read from the registry row, never from the payload, and the recorded credit is stamped with the institution it belongs to. The 200 body is identical in both cases, so the response does not tell you which destination was used; that institution’s own movements are read with GET /v1/indirects//transactions.
An indirect credit also queues a NOTICE to the endpoint that registration carries (delivery.endpointUrl): one HTTPS POST forwarding this webhook’s JD body verbatim, carrying X-Lerian-Signature (‘sha256=’ followed by the hex HMAC-SHA256 of the exact body bytes under the registration’s shared secret) and X-Lerian-Timestamp (the send time in Unix seconds, not covered by the signature).
THE CREDIT IS NOT CONDITIONAL ON THE NOTICE, AND THE NOTICE IS NOT GUARANTEED BY THE CREDIT. When a notice is queued it rides the same database transaction as the credit, so a queued notice always belongs to money that was booked. The reverse does not hold: a credit posts and is answered 200 with NO notice queued at all when this deployment has no outbound queue configured, or when the verbatim JD body could not be retained for forwarding (retention is best-effort — it is skipped for an empty body and abandoned on a write failure, and the credit proceeds either way, because the money is not held hostage to the forwarding). Delivery of a notice that WAS queued is AT-LEAST-ONCE and independent of this 200: the same notice can arrive more than once, and it can also fail permanently while the money stays booked. So a receiving institution must dedup on endToEndId, and must treat GET /v1/indirects//transactions — not the notice — as the record of truth. Reconciling from that feed is not a fallback for a failed notice; it is the only way to see a movement whose notice was never queued.
Three ordering rules decide the destination and cannot be inferred from the payload:
- A pagador.ispb identifying Bacen (99999) short-circuits FIRST, ahead of any indirect matching, so it never reaches a settlement position either.
- A recebedor.ispb equal to this participant’s OWN ISPB is always resolved against this participant’s own customer records, never against the indirect registry.
- While this tenant’s indirect-participants feature is switched OFF, recebedor.ispb is not read against the registry at all: every credit is resolved ONLY against this participant’s own customer records, exactly as before indirect participants existed. Two things follow, and the second is the dangerous one. PIX-0119 becomes unreachable, because nothing consults the registry to find the receiver unserved. And a credit addressed to a registered institution is normally answered 404 PIX-0115, because no customer here holds that account number — but it is NOT refused on the account number alone. Should a local customer hold the same recebedor.nrConta AND the same recebedor.cpfCnpj, the credit is POSTED TO THAT CUSTOMER and answered 200, with the institution’s
@pi_{ispb}never involved; a number that collides under a different holder is refused 409 PIX-0117 instead. Sending recebedor.nrAgencia narrows that further — it is optional in section 9.3.2, and this participant adds it to the account lookup only when you send one, so a credit that omits it is matched on the account number alone. Register the institution AND enable the feature before pointing any credit at it.
A credit that CANNOT be registered is therefore answered with an HTTP error, never with a 200. Each carries a distinct code in the problem body’s code member:
- 404 PIX-0115 - the receiving account named by the credit was not found here. Check recebedor.nrAgencia/recebedor.nrConta, or recebedor.cpfCnpj when no account coordinates are sent.
- 404 PIX-0119 - recebedor.ispb is neither this participant’s own ISPB nor an ACTIVE indirect participant registered in this tenant. It covers both a receiver with no registration at all and one whose registration is not ACTIVE (suspended, closed, or a legacy row that never finished being set up); the two are deliberately not distinguished on the wire, because neither is something the sender can act on differently. It presupposes the indirect-participants feature is ON — with it off nothing consults the registry and this code cannot be answered at all.
- 409 PIX-0116 - recebedor.cpfCnpj names more than one account here, so the destination is undeterminable. Address the credit to specific account coordinates.
- 409 PIX-0117 - the account addressed by recebedor.nrAgencia/recebedor.nrConta belongs to a different holder than recebedor.cpfCnpj names.
- 409 PIX-0118 - the addressed account exists here but is not set up to receive credits.
- 409 PIX-0029 - this end-to-end id was already registered as a credit here. The redelivery posted nothing; the original credit stands.
- 500 PIX-0120 - a provisioning fault at this participant, not a problem with the request. The credit is safe to redeliver once it is corrected.
WHICH OF THOSE AN INDIRECT CREDIT CAN ACTUALLY HIT is a shorter list, because its destination comes from the registry rather than from a customer lookup — and the whole list below presupposes the indirect-participants feature is ON, since with it off there is no indirect path to be on. PIX-0119 is the one: it is what a receiver ISPB with no ACTIVE registration answers, and it exists only on this path. PIX-0115, PIX-0116, PIX-0117, PIX-0118 and PIX-0120 are all decided by the own-customer lookup and are unreachable once recebedor.ispb resolves to an ACTIVE registration — so seeing any of them means the credit was NOT treated as an indirect one. PIX-0029 behaves identically on both paths. A registry read that fails is a 500 like any other dependency failure: nothing is registered, and the credit is safe to redeliver.
One outcome acknowledges 200 WITHOUT posting a credit: a pagador.ispb identifying Bacen (99999), which this participant nulls by design. Its response carries the acknowledgement echo (idReqSistemaCliente, idReqJdPi, endToEndIdOriginal, endToEndIdDevolucao) and no idCreditoSgct.
Malformed payloads are rejected with 400 at the edge, before any resolution runs: 400 PIX-0061 for a body that fails schema validation, and 400 PIX-0061 for a missing endToEndId, a valor that is not a positive finite amount, or a malformed CPF/CNPJ or ISPB on either participant block.
Authorizations
JWT bearer token issued by the identity provider.
Headers
Idempotency key (= the endToEndId of the transaction). Mandatory per section 9.3.2.
"E0435879820200123221500000000001"
Body
Operation timestamp (ISO-8601).
"2026-06-20T10:00:00Z"
SPI end-to-end id (idempotency + dedup key).
"E2E-1"
JDPI request id (becomes the local row id when a UUID).
"JDPI-1"
The payer participant block.
The receiver participant block (the credit account source).
Payment initiation mechanism (section 9.3.2): 0 manual, 1 chave, 2 QR Code estatico, 3 QR Code dinamico, 6 ITP, 8 Pix Automatico, 9/10 Pix por aproximacao. Both QR values (2 and 3) book the credit on the QR route pair; every other value books on the key route pair.
0
Amount in reais (a JSON number).
100.5
The PIX key (present for key-initiated cash-ins).
"recipient@bank.com"
Payment initiator CNPJ (a v5.5.0 string).
"11144477735"
Accounting date (optional).
"2026-06-20"
Settlement timestamp (optional).
"2026-06-20T10:00:01Z"
Finality (eFinality).
0
Recipient conciliation id (stamped on the row + the 24h marker).
"CONC-1"
Free-text inter-client info.
"note"
Saque/troco PSS participant ISPB (a v5.5.0 string).
"12345678"
Agent modality (eModalityAgent).
0
Payment priority (ePaymentPriority).
0
Payment priority type.
0
Optional value-detail entries.
Response
OK
SGCT credit timestamp (ISO-8601), on a credited result.
"2026-06-20T10:00:01Z"
Request timestamp (ISO-8601).
"2026-06-20T10:00:00Z"
Echoed return end-to-end id.
"E2E-1"
Echoed original end-to-end id.
"E2E-1"
SGCT credit lançamento id (GUID), on a credited result.
"SGCT-1"
Echoed JDPI request id.
"JDPI-1"
Echoed client-system request id.
"JDPI-1"

