The trail
- Check the prerequisites, and grant access to whoever runs the setup.
- Set up payment-order signing, only if JD requires it for your institution.
- Provision the ledger and the holder records in Midaz and in the CRM.
- Create the accounting routes in Midaz.
- Configure the rail: the plugin settings.
- Send the payment that creates the limit rows.
- Prove the setup is complete, up to a registered Pix key.
- Add the optional capabilities that your institution needs.
Step 1: Check the prerequisites
You talk to three services. Do not confuse them. That is the most common first mistake.- The Pix plugin running. The plugin’s settings API must be enabled (
SYSTEMPLANE_ENABLED=true). Without it, every configuration call of step 5 answers404. On SaaS, Lerian enables it. - On a self-hosted deployment, the permission of the key lookup route,
entries-lookup(actionget), on the Pix roles in the Access Manager. With JD Courier, alsocourier-ownership(actionpost), for the Courier ownership route. Without its permission, each route answers403. - A bearer token for the ledger, one for the CRM, and one for the plugin, issued by the Access Manager. They can come from different audiences.
- The right access for whoever runs the setup. The access step below lists the groups. Without it, the calls answer
403. - Your institution’s ISPB: the 8-digit identifier of your accreditation at BACEN.
Grant access to whoever runs the setup
Why this step exists. Setting up Pix touches three products: the ledger (Midaz), the account holder records (CRM), and the Pix JD plugin itself. Each one checks its own permission. Without it, the call answers403 and nothing is written.
If you are an administrator, you already have everything. The Administrator group (admin-group) has full access to the three products. Go on to the next step.
To let someone else run the setup without being an administrator, add that person to the groups below in the Access Manager, through the console or through Update a User. This is the minimum access that covers every step on this page:
plugin-br-pix-jd-contributor-group) is enough. It cannot change the Pix configuration, so an operating mistake does not change how your money is routed. For someone who only reads, use Plugin PIX JD Viewer (plugin-br-pix-jd-viewer-group).
Prove that the access is right before you go on. With that person’s token:
GET /system/-/catalogmust answer200.- The first write under
/system, the integration binding in step 5, must answer204 No Content. A403there means the person is not in Plugin PIX JD Editor.
Step 2: Set up payment-order signing, if JD requires it
JD can require a signature on each payment order for your institution. Confirm this with JD. If JD requires it, follow Payment-order signing now, before any payment. If JD does not require it, skip this step.Step 3: Provision the ledger and the holder records
These steps run against Midaz and the CRM. They create the accounts that the rail posts to, and the holder records that it reads counterparties from. Access: Midaz Editor for the ledger steps, and Plugin CRM Contributor for the two CRM steps.Create the organization and the ledger
201 with no id in the body is not a success. Nothing can address the new object, not you and not a later cleanup. Stop there. Do not carry an empty id into the next step.Create the BRL asset, and wait for it to appear
BRL.201 and 409 are good answers. A ledger addresses an asset by its code, so “already exists” means the same as success.Two things happen here. The second one is easy to miss:- The ledger starts to accept accounts in that asset. Before this, it refuses every account with
0034 Asset Code Not Found. - Midaz creates the
@external/BRLaccount with the asset. It is the one account in a book that you can debit before any credit. The opening balance comes from it. It is also the counterparty of every settlement with the outside world.
Create one account per role
accountId of the business calls you make to the plugin. The alias (@payer) is the short name that the book reads and posts by. It comes back in the next step.Create the holder in the CRM
documentmust be a valid CPF or CNPJ, with correct check digits.typefollows the document length. UseNATURAL_PERSONfor a CPF (11 digits) andLEGAL_PERSONfor a CNPJ (14). The plugin turns this type into the number that goes to JD. A wrong type files the party as the wrong kind of person.externalIdholds the account’s ledger alias (@payer). The CRM calls it an external correlation identifier, so it looks optional. For this rail it is not. A Pix key registration for a holder withoutexternalIdanswers422 PIX-0108.addresses.primary.cityis required for QR codes and Pix Automático. It is the receiver city in the code. Without it, the plugin refuses to generate a QR and answers422 PIX-0033forpayee.city. No payment path reads the field, so its absence shows only when someone generates a QR.
Link the holder to the account
Fund the accounts
@external/BRL, which Midaz created with the asset, two steps above.@external/BRL load has two uses. One is the @pi settlement position of a hosted indirect participant. The other is a test or homologation environment, where no real Pix arrives. See The direct and indirect model for what each position is.@external/BRL in a body, but not in a path. The alias contains a slash, and the ledger route does not decode it. A balance read by path answers 404 or an empty 200. Posting from it is normal. Reading it that way is not.Step 4: Create the accounting routes
Each money path on this rail has its own pair of Midaz operation routes: one credit leg and one debit leg. There are eleven profiles. Step 5 stores the UUIDs of the routes in the plugin. Access: Midaz Editor. Which pairs you need. You do not create eleven pairs. Create one pair for each of the six payment profiles. The other profiles reuse a pair, or stay empty:in. A MED debit and a Pix Automático debit take money out, like out.
Create each leg with one call:
{"id": "..."}. Keep each id with its profile and its leg. Step 5 writes them.
Look up a route by title before you create it. With two routes of the same title, the next lookup can pick either one. If you provision the same book more than once, list first.
If your ledger validates routes, also create one Midaz transaction route per profile that you use. A ledger that validates routes refuses a posting that names no transaction route. See Transaction routing entities for how to create one.
Step 5: Configure the rail
The plugin keeps its live configuration in its systemplane. You write these values over the admin API, and they take effect without a redeploy or a restart. Every write is aPUT to /system/<namespace>/<key> with a {"value": ...} body. A success answers 204 No Content, with no body.
The tenant comes from the validated bearer, never from the URL or the body.
Access: every write below needs Plugin PIX JD Editor. These values decide which institution the plugin presents to JD and which accounts it posts to, so only that group and the administrators can change them. Any Pix JD group can read them.
GET /system/-/catalog lists every key with its type and description, and GET /system/-/catalog/<namespace>/<key> describes one key. The catalog is the source of truth. This page is a copy of it, and copies age.Write the JD integration binding
tenancy/jd_integration_binding, with no environment fallback. While the key is empty, the plugin starts and answers its health probe. It refuses every payment on every money route.What breaks without it. 409 PIX-0092, “Tenant Pix integration not provisioned”. The response text asks you to contact support and does not name the key. Search for the code.The value is a JSON document inside a string. The body is always {"value": ...}. Here value is not an object. It is a string, and its content is a JSON document. The plugin stores it with the inner quotes escaped:jq do the escaping:organizationId or ledgerId is absent or unusable, the plugin refuses every posting, refund, and inbound credit with 409 PIX-0106.value comes back as an object and not as a quoted string, you wrote the wrong form. If it comes back "", the write did not happen. Check the status code of the PUT. The real proof is behavior: money routes stop their 409 PIX-0092 answers.You cannot store a malformed ISPB through this route. The write validator uses the same decoder as the read. It refuses a 7-digit ISPB or a broken UUID at once, with 400 validation_error. You do not find the error on the first payment.409 PIX-0121, “Tenant Pix integration ISPB invalid”, when you follow this page. That code means that the binding exists and its ispb is not 8 digits, and this route cannot create that state. It shows only when a value reached the key by another path. Examples are a direct write to the plugin’s database, or a write from before the validator. Its message names both the key and the field to correct.409 PIX-0092. Do not do it in an environment that pays.Check the connection to JD
200 with the participant list, like this one (trimmed), proves that the plugin reached JD and received the participant catalog:Write the routing keys
tenant_policy namespace. Each one holds a string: the UUID of a route that exists in Midaz.409 PIX-0105: sent, received, QR code, and between your own accounts. A missing MED or Pix Automático leg refuses only that flow. refund_sent is the exception. While both of its legs are empty, the rail posts a devolução that you send on the out routes.204. If you do not use MED or Pix Automático, leave their profiles empty. That flow then refuses, which is better than a posting on an undefined route.The transaction route of each profile. Each profile also has an optional key, tenant_policy/routing.<profile>.transaction_route. Fill it when your ledger validates routes. The plugin then names that transaction route on every posting of the profile. Without it, such a ledger refuses the posting, and the plugin answers PIX-4011. When your ledger does not validate routes, leave these keys empty.Set the posting asset and the clearing account
tenant_policy namespace hold them, in both deployment modes:409 PIX-0106, “Tenant ledger configuration missing”. The response names the binding fields and the two keys. This code is not PIX-0105. A tenant can have all route legs and still refuse every posting, because the asset or the clearing account is empty.The deployment variables MIDAZ_ASSET_ID and MIDAZ_EXTERNAL_ID no longer exist. The plugin ignores them.Set the daily window
400. The plugin does not clamp it to the bound.Declare whether this deployment hosts indirect participants
plugin-br-pix-jd.indirects/enabled declares what the tenant is. A plain direct participant sets it to false.{"value":"true"} answers 400. If this deployment settles Pix for other institutions, step 8 sets it to true.Step 6: Create the transaction limit rows with one small payment
The product has no route to create what this step needs. What you expect. You provision an account and read its available limit. What happens.GET /v1/limits/available answers 404 PIX-0063, “The specified transaction limit was not found in the system. Please verify the identifier and try again.” GET /v1/limits answers {"data":[]}. The account looks broken, but it is not. This is the normal first state of an account that never sent a payment.
PIX-0063 names the thing that the plugin looked up. The error list shows its generic form, “The specified entity was not found in the system”. This route puts transaction limit in it. The code and the 404 stay the same.
Why you cannot create the rows. There is no creation route. PATCH /v1/limits updates rows that already exist. One thing creates the rows: the limit check of an outbound payment. When an account sends its first payment, the plugin finds no rows. It creates the defaults, reads them again, and continues.
So send one small outbound payment. One cent is enough.
Access: the payment needs Plugin PIX JD Contributor or Plugin PIX JD Editor. Changing a limit later with PATCH /v1/limits needs the same.
How to check. GET /v1/limits changes from {"data":[]} to a list. /v1/limits/available changes from 404 to 200.
Do this step after every step above. The payment must post, so it needs every value of steps 3 to 5. Without a route, for example, it fails with PIX-0105.
Step 7: Prove the setup is complete
Run these checks in order. Each one fails for a different reason. That makes the sequence more useful than a single smoke test.- The ledger accepts an account. Create a disposable account and delete it. If the book refuses, the refusal names the missing link. Without this check, the same problem comes back later as “account not found” inside a payment flow, three layers from its cause. Do not fund the probe account: Midaz refuses to delete an account with a balance. The delete needs Midaz Editor.
- The binding reads back as a quoted string with your ISPB, your organization, and your ledger, as shown in step 5.
GET /v1/banksanswers200with the list of Pix participants, as in the connection check of step 5.- The two
tenant_policy/midaz.*keys read back with the asset code and the clearing account alias. - The alias query returns your account, filtered by document, branch, and account number.
- A money route stops its
409 PIX-0092and409 PIX-0106answers. Use the call that you already make. You need no test harness. GET /v1/limitsreturns a list for the account that sent the payment of step 6.- A Pix key registers and shows in the account’s list. This check goes through the CRM, the binding, and the DICT at JD.
keyType 4 and no key: the DICT creates the key value. A random key needs no confirmation code, so it goes to the DICT on the first call:
status 2, “awaiting confirmation”. Register a Pix key entry describes every answer. Remove a test key when you are done with DELETE /v1/entries/{entryId}.
Step 8: Add the optional capabilities
Your setup ends at step 7 if your institution is one direct participant with one book, and it settles only the Pix of its own customers. Otherwise, continue on the page that applies:- Several books, or several direct participants on one deployment. Follow Multi-organization and ledgers.
- Settling Pix for other institutions. Follow Hosting indirect participants. It adds the encryption key, the hosting posture, the registration of each indirect participant, its own QR certificate if it has one, and the funding of its settlement position.
What each skipped step looks like
Every refusal below is a409, except the limits one. None of them goes away if you wait. Each one goes away when you provision the missing value.
PIX-0092 stops, payments do not always pass. It is the first barrier, not the last. With the binding in place, an empty accounting route still answers PIX-0105. A missing asset or clearing account still answers PIX-0106. Three codes have three causes and three different fixes.Do not retry a 409. Do retry its 503 sibling
The status tells you if the problem is your setup or an outage.
A 409 above is positive knowledge of absence. The rail read your configuration and found nothing there. Only an operator can supply the value, so a repeat of the request gets the same answer. A client that retries on this code loops forever. Each of those responses names what to set.
Most of those conditions have a 503 sibling. It applies when the rail could not read the configuration at all. The rail knows nothing about what you provisioned. The response names the dependency that failed, and a retry is the right action.
PIX-0121 is a special case. You cannot cause it through the admin API, because the write validator refuses a malformed ispb before it is stored. It shows only when a value reached the key by another path. See the binding in step 5.detail of each one.
Where to go next
Environment variables
Multi-organization and ledgers
Indirect participants
Direct Pix via JD
Pix JD error list
PIX-NNNN code, its status, and the detail text of the response.
