zrobank-doc-api

Transaction Approval

Flow to require multiple approvals before a Pix payment is executed in BaaS API.

Instead of sending a Pix payment directly, the payer creates a transaction approval request. The payment is only released after the approvers registered in the wallet cast enough approval votes.

Prerequisite

You will need:

Approver setup is a prerequisite managed outside this BaaS flow. Have an authorized wallet administrator provision the APPROVER and, when required, APPROVER_MASTER roles before enabling approval settings. Provision access to view the relevant requests as well as permission to vote; approval permission alone does not grant every other action in this guide.

Provisioning Approvers through the Users API

The BaaS approval endpoints do not assign roles to wallet users. If the approvers are not configured yet, use the Users API with its required authentication and headers, including x-wallet-uuid for the same wallet used in this guide. The update must be performed by the wallet owner or an authorized wallet administrator; do not grant administrative privileges just to let a user vote. If your integration only has BaaS access, arrange this setup with the wallet administrator before enabling the approval setting.

  1. GET /operations/permissions/types lists the available permission type tags.
  2. GET /operations/permissions/users lists wallet members and their current permission_types.
  3. PATCH /operations/permissions updates an existing member. Send user_id and permission_types, including APPROVER for common approval or APPROVER_MASTER for master approval.

The submitted permission_types list replaces the member’s current roles; it does not append to them. Include the complete intended list, preserving other roles the member still needs. Confirm access to read requests separately from permission to vote or cancel. ROOT cannot be assigned, and this endpoint cannot change the wallet owner’s permissions.


Flow Overview

graph TD
    A[1: List Approval Types] --> B[2: Create Approval Setting]
    B --> C[3: Decode Pix Key]
    C --> D[4: Create Approval Request]
    D --> E[5: Approve as Approver]
    E --> F[6: Check Request State]
    F --> G{State?}
    G -- PENDING --> E
    G -- APPROVED --> H[Payment released]
    G -- CANCELED --> I[Request canceled]
    G -- EXPIRED --> J[Start a new request]

Steps 1 and 2 are executed once, when configuring the wallet. Steps 3 to 6 are executed on every payment that falls under the setting.


Approval Rules

A request is approved when the votes match the setting. Votes are counted by the permission type of the voting user, and approver_master_required decides whether master votes are counted apart.

approver_master_required How votes are counted Approval condition
false (or omitted) single counter — the voter’s role is not considered total votes >= approvers_quantity
true two counters — APPROVER and the wallet owner fill the common count, APPROVER_MASTER fills the master count common votes >= approvers_quantity and master votes >= approver_master_quantity

Eligibility to vote is the same in both cases — APPROVER, APPROVER_MASTER, and the wallet owner. The flag changes only how the votes are counted.

How a vote is classified:

Voting is granted to the APPROVER and APPROVER_MASTER permission types only. CLIENT and ADMIN cannot vote even when master approval is not required.

The wallet owner can vote without being assigned APPROVER. The owner’s vote counts as common unless the owner also has APPROVER_MASTER, in which case it counts only as a master vote. Each eligible user contributes at most one vote to a request.

Numeric example — setting with approvers_quantity: 2, approver_master_required: true, approver_master_quantity: 1:

Votes cast Common Master State
2 approvers 2 0 PENDING — master vote still missing
1 approver + 1 master 1 1 PENDING — one common vote still missing
2 approvers + 1 master 2 1 APPROVED

Master votes do not count toward approvers_quantity. Size the setting accordingly: the example above needs three distinct voters.

Before enabling the setting, confirm that the wallet has enough distinct eligible voters in each category. Creating the setting does not check whether the wallet currently has enough eligible voters to satisfy it. A successful creation response therefore does not guarantee that requests can receive all required votes. Count an owner with APPROVER_MASTER only toward the master requirement. Without all required votes, a request remains PENDING until canceled or expired. Use the request’s state to confirm approval; a 201 vote response alone does not confirm that all required votes were received.


Step 1: List Approval Types

GET /permissions/transaction-approval-types

List the transaction types that support the approval flow. Use it to confirm that the transaction type you want to protect is available.

Optional query params: page, size, sort, order

Returns per item: id, transaction_type_id, transaction_type_tag, description, created_at


Step 2: Create the Approval Setting

POST /permissions/transaction-approval-settings/pix-payment

Create the rule that decides when a Pix payment of this wallet requires approval. Transaction type and currency are fixed by the endpoint — you do not send them.

Only the wallet owner can create or delete a setting. No permission type grants these two endpoints, so an APPROVER, CLIENT, or ADMIN user receives 403.

Required body:

Optional body:

{
  "approvers_quantity": 2,
  "min_amount": 100000000,
  "approver_master_required": true,
  "approver_master_quantity": 1
}

Returns: id, created_at

Important:

See Approval Rules before choosing the quantities.

Replacing a Setting

DELETE /permissions/transaction-approval-settings/{id}

Settings are immutable — to change the quantities or min_amount, delete the current setting and create a new one. Wallet owner only. The request is rejected while the setting still has PENDING approval requests, so cancel or wait for them first.


Step 3: Decode the Pix Key

POST /pix/payments/decode/by-key

Decode the destination Pix key and save the returned id. The approval request references the decoded key instead of the raw key.


Step 4: Create the Approval Request

POST /permissions/transaction-approval-requests/pix-payment-by-key

Create the approval request for a Pix payment by key. This replaces the direct payment call when the amount falls under an existing setting.

Required body:

Optional body:

Returns: id, render_request_body, state, created_at

Expected initial state: PENDING

Use render_request_body to display the pending payment to the approvers: it carries the payment data in a presentation-ready shape.


Step 5: Approve the Request

POST /permissions/transaction-approvals

Each approver calls this endpoint once. One call is one approval vote.

Required body:

Returns: id, created_at

Integration rules:


Step 6: Check the Request State

GET /permissions/transaction-approval-requests/{id}

Source of truth for the current state of the request.

Returns: id, user_name, transaction_approval_setting_id, render_request_body, amount, transaction_type_tag, state, votes, approvers_quantity, created_at

There is no webhook for transaction approvals. Poll this endpoint to follow the request.

State Meaning Action
PENDING Waiting for the remaining approval votes Keep polling, or have the missing approvers call Step 5
APPROVED Every required vote was cast Payment released. Follow it through the Pix payment endpoints
CANCELED Canceled by a user of the wallet Create a new request if the payment is still needed
EXPIRED Not approved by the end of the payment date — pending requests expire on the day after their payment_date Create a new request

Scheduled payments: expiration is keyed on the payment date, not on the creation date. A request created without payment_date uses the creation date, so it expires the day after it is created. A request scheduled for a future date stays PENDING and keeps accepting votes until the day after that date.

Reading votes: it is the total number of votes cast, master and common together. When approver_master_required is true, votes >= approvers_quantity alone does not mean the request is approved — use state, and GET /permissions/transaction-approvals if you need the breakdown.


Step 7: Cancel the Request

DELETE /permissions/transaction-approval-requests/{id}

Cancel a request that should not be paid. This is how a payment is refused.

Cancellation requires permission for this action in the selected wallet. An authorized caller can cancel a request created by another user of that wallet. The approver role alone does not grant cancellation permission. Only PENDING requests can be canceled.

Returns: id, user_name, transaction_approval_setting_id, render_request_body, amount, transaction_type_tag, state, votes, created_at

Resulting state: CANCELED


Minimal Integration Sequence

  1. GET /permissions/transaction-approval-types to confirm the transaction type.
  2. Confirm that the wallet users have the required approval and request access permissions (see Prerequisite).
  3. POST /permissions/transaction-approval-settings/pix-payment and save the returned id.
  4. On each payment: POST /pix/payments/decode/by-key, then POST /permissions/transaction-approval-requests/pix-payment-by-key.
  5. Each approver calls POST /permissions/transaction-approvals with the request id.
  6. Poll GET /permissions/transaction-approval-requests/{id} until APPROVED, CANCELED, or EXPIRED.

Other Endpoints


Error Handling

403:

Request not found:

422 on create setting:

422 on approve: