API mocks
On this page
Bre-B participant node (Colombia)
Bre-B is Colombia's instant payment rail. A business reaches it through its bank's participant node, and it uses the node to:
- register dynamic-QR payment requests;
- ask what happened to them;
- receive a signed notification for every credit to its business llave.
This mock is such a node for one business customer. It also plays the payer's bank: a test page pays or refuses a request, and a fixture sends a llave transfer without a QR.
Nodes publish their APIs to their customers under contract, and none is public. So this mock defines a neutral REST contract with what any node provides, in the rail's ISO 20022 vocabulary: ACSC settled, PDNG pending, RJCT rejected. Your adapter maps it to your bank's API. Testlie is not affiliated with Banco de la República or any participant, no money moves, and no bank is contacted.
Connect
Create a Bre-B participant node under Banking and set its webhook URL (for example https://<your app>/api/webhooks/breb). Send Authorization: Bearer <API key> on every call.
| Credential | Environment variable | Use |
|---|---|---|
| API key | BREB_NODE_API_KEY |
Bearer token |
| Business llave type and value | BREB_BUSINESS_LLAVE_TYPE, BREB_BUSINESS_LLAVE |
The llave credited, e.g. ALPHANUMERIC @testlie123456; payment requests must name it |
| Notification signing key (hex) | BREB_NODE_WEBHOOK_KEY |
HMAC-SHA256 key, as 32 bytes in hex, that signs each notification |
Errors are { "code", "message" }: UNAUTHORIZED (401), INVALID_BODY (400), LLAVE_NOT_OWNED and ALREADY_EXPIRED (422), NOT_FOUND (404), ALREADY_PAID (409).
API
| Call | |
|---|---|
POST /v1/payment-requests |
{ reference (≤ 35), amountMinor, currency: "COP", llave: { type, value }, expiresAt }. Returns 201 with qrTransactionId (the QR's tag 90, 19 characters), qrSecurityHash (tag 91, SHA-256, base64url), status: "PDNG" and payUrl. |
GET /v1/payment-requests/{qrTransactionId} |
`{ state: "paid" |
GET /v1/transfers?qrTransactionId= or ?reference= |
{ data: [...] }: the credits for a request (refused ones included) or a reference, newest first |
GET /v1/transfers/{transferId} |
One credit, with the notification's fields |
POST /__testlie/credits |
The payer's bank sends a credit: { reference, amountMinor, status?, qrTransactionId?, debtorAgent?, reasonCode? }. Leave out qrTransactionId for a llave transfer whose reference is, for example, a subscriber's account number. |
payUrl opens the simulated payer's bank. Pick a test bank (TESTBANK01, TESTBANK02 or TESTWALLET, which becomes the debtorAgent), then choose Pay, or Insufficient funds (RJCT AM04).
Credit notifications
Every credit is POSTed to the webhook URL as the node's envelope, Content-Type: application/json:
{ "payload": "{\"transferId\":\"TX…\",\"endToEndId\":\"E…\",\"qrTransactionId\":\"T…\",\"reference\":\"INV-1001\",\"amountMinor\":5000000,\"currency\":\"COP\",\"status\":\"ACSC\",\"creditorLlave\":\"@testlie123456\",\"settledAt\":\"2026-10-27T10:00:00.000Z\",\"debtorAgent\":\"TESTBANK01\"}",
"signature": "<hex HMAC-SHA256 of payload under the signing key>", "scheme": "hmac-sha256" }payload is the exact JSON string that was signed: verify the signature over those bytes, then parse it. Its fields:
transferId(TxId) andendToEndId;qrTransactionId, which isnullfor a llave transfer;reference,amountMinor(minor units) andcurrency;status;creditorLlave, the business llave;settledAt;debtorAgent, the paying participant's code, never the payer's account.
The webhook scenarios apply: delay, drop, duplicate, and bad signature (signed with another key). Failed deliveries are retried.
Scenarios
| Outcome | Credits |
|---|---|
| Auto / succeed | As asked: the page's choice, or the fixture's status (default ACSC) |
| Decline | RJCT, with the chosen reason code (AM04, AC06, AB05, FF01, MS03) |
| Requires action | PDNG at once, then ACSC after the mock's async delay. Both notifications are sent, and status queries follow. |