Collection Payment Validation
How a collection accepts or rejects each incoming Bre-B payment — amount rules, expiration, expected payers, and every rejection reason
When a customer pays one of your collections, Mono validates the payment before accepting it. The rules are the ones you set when creating the collection: how much can be paid, until when, and by whom. A payment that breaks a rule is rejected automatically, and the rejection reason tells you exactly which rule it broke. This page explains each rule and every reason you can receive.
Collections vs. payment attempts
A collection is your Bre-B receiving endpoint (a QR code or payment key). Each individual
payment against it is a payment attempt, with its own state — separate from the
collection's lifecycle. A
rejected attempt does not change the collection's state; it only increments its
failed_attempts counter.
How a payment attempt is validated
Every incoming payment becomes a payment attempt that moves through one of three outcomes:
| Attempt state | Meaning | Final |
|---|---|---|
created | Attempt received, validation in progress | No |
successful | Payment was successful | Yes |
rejected | Payment was rejected by Mono based on the collection's rules | Yes |
failed | Payment failed due to external reasons (bank, provider, timeouts) | Yes |
For rejected and failed attempts, the attempt's state_reason field names
the exact cause — the full list is in the
reference table below.
The rules you control
Who can pay — expected_payers
If you provide expected_payers when creating the collection, only those
payers are allowed — anyone else is rejected with payer_not_allowed. Each
expected payer is identified by their Colombian identity document:
document_type— one ofCC,CE,NIT,NUIP,PPT,PEP,PASS,TIdocument_number— the document number of the expected payer
Leave expected_payers empty to accept payments from anyone. See
UC6 — Client invoice
for a worked example.
How much can be paid — amount bounds
All amounts are integers in centavos (e.g. 10000000 = COP 100,000.00).
Two levels of bounds apply:
| Field | Applies to | Rule | Rejection reason |
|---|---|---|---|
minimum_attempt_amount | each attempt | Minimum amount allowed per payment attempt (multiple_use collections only) | amount_below_minimum |
maximum_attempt_amount | each attempt | Maximum amount allowed per payment attempt (multiple_use collections only) | amount_exceeds_maximum |
total_maximum_amount | the running total | Maximum total the collection can receive — when reached, the collection becomes paid | amount_exceeds_total_maximum |
total_minimum_amount | the running total | Minimum total required for the collection to be considered fulfilled | amount_below_total_minimum |
usage_mode decides how attempts accumulate:
single_use— the collection accepts only one successful payment.multiple_use— the collection accepts multiple payments untiltotal_maximum_amountis reached.
Until when — expires_at / expires_in
Set the collection's deadline either as an absolute ISO-8601 datetime
(expires_at) or in seconds from now (expires_in) — they are mutually
exclusive on the request. A payment after the deadline is rejected with
collection_expired. See
UC7 — Flash sale
for a worked example.
On or off — enabled
enabled controls whether the collection can receive payments at all. Payments
against a disabled collection are rejected with collection_disabled — useful
for pausing a collection without deleting it.
Rejection reasons reference
The attempt's state_reason (present only on rejected / failed attempts)
names the cause:
Tied to your collection's rules and state:
state_reason | The payment was rejected because… |
|---|---|
payer_not_allowed | the payer is not in the collection's expected_payers list |
amount_below_minimum | the attempt is below minimum_attempt_amount |
amount_exceeds_maximum | the attempt is above maximum_attempt_amount |
amount_exceeds_total_maximum | it would push the total received past total_maximum_amount |
amount_below_total_minimum | it is below the collection's total_minimum_amount requirement |
collection_expired | the collection's expires_at / expires_in deadline has passed |
collection_disabled | the collection has enabled: false |
collection_paid | the collection already reached paid (its total maximum, or single use) |
collection_discarded | the collection was discarded |
collection_invalid_state | the collection is not in a state that accepts payments |
collection_not_found | no collection matches the payment's key |
collection_pruning | the collection's key is being pruned |
External / operational causes (outside your collection's configuration):
rejected_by_bank, provider_unavailable, lock_timeout, risk_control,
internal_error, mono_timeout, breb_timeout, unknown.
Observing rejections in your integration
- Webhooks — every unsuccessful attempt fires
collection.attempt_unsuccessfulcarrying the attempt with itsstate_reason; successful ones firecollection.attempt_successful. - Polling — list attempts with List collection attempts.
- A rejected attempt never moves the collection out of its current state — it
only increments the collection's
failed_attemptscounter.
Next steps
- Collection lifecycle — how the collection itself moves between states.
- Collection use cases — ready-made rule combinations (fixed price, restricted payer, flash sale…).
- Create collections — the full request reference for every field on this page.