Hybrid Payment Ruleset
The complete set of rules governing Wallet Initiated Payment (WIP) Hybrid transactions, for both the Full and Partial flows.
This page is the authoritative reference for ECR integrators, PSPs, and WSPs working with the Aera Wallet hybrid payment flows. Every rule below is enforced by the Wallet during transaction processing — understanding them is essential to predict outcomes, build correct error handling, and reconcile sub-transaction reporting.
For walkthrough examples of each rule in action, see the Wallet Payment Scenarios documentation. For the full list of response codes referenced on this page, see Response codes.
📚 Table of Contents
- What is a Hybrid payment?
- Choosing a flow: Full vs Partial
- Rules common to both flows
- Interpreting transactionDetails
- Full Hybrid Payment rules
- Partial Hybrid Payment rules
- Allocation and prioritization
What is a Hybrid payment?
A Wallet Initiated Payment (WIP) Hybrid transaction settles a single basket across multiple payment methods in one customer authentication, using whichever instruments the customer holds in their Wallet that the merchant also accepts.
Today the Wallet can hold:
- Monizze vouchers (Meal vouchers, Eco vouchers)
- Xtra (Colruyt SDD)
Bancontact is referenced in some allocation scenarios for illustration but is not yet implemented.
The ECR is always the initiator of a WIP Hybrid sale and controls:
- Which flow to use —
fullPayment: true(Full) orfullPayment: false(Partial). - The total transaction amount.
- The amount allocated per voucher category (e.g.
FOOD,ECO). - Whether to include a withdrawal (cashback / cashout) — not currently supported.
Choosing a flow: Full vs Partial
| Behaviour | Full Hybrid | Partial Hybrid |
|---|---|---|
| Request flag | "fullPayment": "true" | "fullPayment": "false" |
| Whole basket must be coverable | Yes — otherwise the transaction fails and no funds are captured | No — the remaining amount is returned to the ECR |
| Reallocation on a failed authorization | Yes — failed amount is reallocated down the priority list | No — failed amount is added to remainingAmount and remainingCategories |
remainingAmount returned to the ECR | Never (success means full coverage by definition) | Yes, when coverage is incomplete |
| Outcome when nothing can be covered | responseCode: 1012 — insufficient funds, all authorizations cancelled | responseCode: 1012 — insufficient funds, all authorizations cancelled. |
| Use case | Standalone Wallet checkout — customer leaves once Wallet succeeds | Wallet covers what it can; ECR completes with a new transaction to cover any potential remaining amount. |
Rules common to both flows
These rules apply identically regardless of whether fullPayment is true or false.
Transaction-level reporting
- The ECR receives a single root
responseCodeindicating success or failure of the transaction as a whole. - The
amountwithin theamountDetailson the root level tells what has been successfully authorized. - The ECR also receives a
transactionDetailsarray containing one entry for every authorisation the Wallet attempted — including attempts that failed. One entry per payment method, and, for vouchers, one entry per voucher category used. - Every sub-transaction carries its own
transactionId,responseCode,externalResponseCode,amountDetails,paymentMethodanddebitCredit. Please note thattransactionIdcan benull, for example if the authorization has failed for this sub-transaction. - The
responseCodeon the root level tells the ECR the overall outcome; the per-sub-transactionresponseCodetells you what actually happened to each instrument. See Interpreting transactionDetails for how to walk the array.
Amounts
The WLW and the Aera PSP have different representations of amounts:
For the PSP all amountDetails.amount values — at the root level and inside transactionDetails — are expressed in minor units of the currency (i.e. cents for EUR). An amount of 2455 represents €24.55. Examples can be found in Aera PSP.
For WLW all amounts are expressed in decimal numbers with 2 decimals. An amount of €24.55 is represented as 24.55. Examples can be found in the WSP Transaction History.
Voucher and category rules
- A voucher sub-transaction always carries a
categoryfield indicating the voucher type used (e.g.FOOD,ECO). - A single sub-transaction is never split across two voucher types. If an amount is allocated to both
FOODandECOvoucher types (see Multi-category amounts), it produces separate sub-transactions per voucher type.
Multi-category amounts
When an amount in the request is annotated with multiple categories (e.g. ["FOOD", "ECO"]), the Wallet decides the split between voucher types based on:
- The consumer priority of payment instruments and what they support (available balance and supported categories).
- The WSP's configured priority (e.g.
FOODbeforeECO).
The Wallet does not honor the order of the categories sent by the ECR. If the transaction can not be covered in full (partial hybrid payment), details about what exactly is remaining will be reported to the ECR. See remainingCategories in Merchant Callback.
The payment instrument priority controls deduction order
The customer can choose which payment instrument to use by creating a custom priority. If the user has not created a custom priority, the default priority configured by the WSP will be used.
Cashback / cashout
Withdrawal amounts are not supported in the current version of the WIP Hybrid flows.
Interpreting transactionDetails
The transactionDetails array is the most important part of every hybrid response. It reports every authorisation the Wallet attempted, whether the attempt succeeded or failed. The ECR must inspect each sub-transaction's responseCode to determine what actually happened.
Every attempt is reported, with its attempted amount
For every payment method (and, for vouchers, every category) the Wallet touched during the transaction, a sub-transaction entry is produced — including:
- Successful authorisations.
- Failed authorizations that were subsequently reallocated to another payment method (Full flow).
Failed sub-transactions report the amount that was attempted against that instrument. They are never zeroed out.
Why every attempt is exposedReporting every attempt — with the attempted amount intact — is a hard requirement, not an implementation choice. Four reasons drive it:
- Scheme requirements. Aera is required by the payment schemes to expose what was attempted to the end customer, because the result the customer sees may differ from the payment proposal that was originally presented to them.
- Acquirer (Xtra / Colruyt) requirements. The ECR is responsible for presenting the payment result on the customer's device. Xtra additionally surfaces the same transaction in their own app's transaction history. Both views must reconcile.
- Aera transparency. The payment proposal and the funds actually deducted may differ — for example, when a balance changed mid-flow or a reallocation was triggered. The customer is entitled to see the difference.
- Partial-flow correctness. In Partial Hybrid, failed amounts must be reported with their attempted value so the customer is informed of what didn't go through. Setting them to zero would breach customer-information requirements and make remaining amount impossible to reconcile against the proposal.
How to determine what was actually paid
Walk the transactionDetails array and inspect each entry's responseCode:
responseCode | Meaning |
|---|---|
68611 | Sub-transaction authorised successfully. The amount was deducted from this instrument. |
68612 | Sub-transaction failed to authorise. The amount shown is the attempted value, not zero. No funds moved. |
To compute what the customer actually paid through the Wallet:
deducted = sum of amountDetails.amount where responseCode == 68611
- In a successful Full Hybrid (
responseCode == 0at the root level),deductedis guaranteed to equalamountDetails.amountat the root level. - In a Partial Hybrid,
deducted == amountDetails.amountat the root level. - In a failed Full Hybrid,
deducted == amountDetails.amount == 0at the root level. Any sub-transactions withresponseCode == 68614are cancelled with the relevant acquirers. Cancellation is not immediate; the underlying funds may be held briefly on the customer's instrument. See Authorisation holds and cancellation timing.
For the full list of response codes referenced on this page and elsewhere, see the Wallet response codes and PSP response codes.
Worked example
Take a successful Full Hybrid payment where Monizze failed and Xtra absorbed the reallocation:
- Root:
responseCode: 0,amount: 2455(€24.55). transactionDetails:MONIZZEFOOD—responseCode: 68612,amount: 700→ failed, reallocated.XTRA—responseCode: 68611,amount: 2455→ succeeded.
Sum of successful sub-transactions: 2455. Matches amountDetails.amount on the root level: 2455. The customer was deducted €24.55 in total, all from Xtra. The Monizze entry is reported so the customer can see that a €7.00 attempt was made against their meal voucher and failed — even though the basket was ultimately covered.
Full Hybrid Payment rules
Activated by "fullPayment": "true" in the WIP request.
1. Coverage is binary
The whole transaction must be coverable by the available payment methods in the Wallet. If it cannot be fully covered, the transaction is returned to the ECR as failed and no funds are deducted — any authorisations that succeeded along the way are cancelled with the relevant acquirers.
2. Pre-authorisation balance check
When all payment methods involved in the transaction support balance checks (today: Monizze and Xtra), the Wallet performs a balance check before building the allocation plan.
- If the combined available balance is sufficient, the Wallet proceeds to allocation.
- If the combined available balance is insufficient, the transaction fails at this step — before the customer is shown a payment proposal — with:
responseCode: 1012,externalResponseCode: 68600on the root level in the merchant callback.- No sub-transactions are produced, meaning no
transactionDetailsarray is provided. - No amount in
amountDetails.amounton the root level, since this field is only used for authorized amounts.
If at least one payment method involved does not support balance checks (e.g. Bancontact, once available), the pre-authorization balance check is skipped for the un-checkable methods and authorisation is attempted blindly.
3. Reallocation on authorisation failure
If a payment method is reached at the authorisation step and the authorisation fails, the Wallet does not give up. It reallocates the failed amount onto the next payment method down the priority list and re-attempts.
- The reallocated amount is added on top of any amount already destined for that next method.
- If the next payment method has a known balance and it does not cover both the already allocated amount and the reallocated amount. Then only the amount up to available balance will be reallocated to this payment method. The remaining amount is then reallocated to the next payment method (if any).
- If the cascade reaches the end of the priority list with funds still uncovered, the transaction is failed and all previously authorised amounts are cancelled with the relevant acquirers.
A reallocated transaction that ultimately succeeds is reported with both the failed sub-transaction (responseCode: 68612, carrying the attempted amount) and the successful downstream sub-transaction (responseCode: 68611) in transactionDetails. See Interpreting transactionDetails for how to read this correctly.
4. Successful sub-transaction totals match the root amount
When the transaction succeeds (responseCode: 0, externalResponseCode: 0), the sum of amountDetails.amount across all sub-transactions where responseCode == 68611 equals the root amountDetails.amount. Failed sub-transactions in the same array are excluded from this sum — they exist for customer transparency, not for accounting.
5. Authorisation holds and cancellation timing
When a Full Hybrid transaction fails after one or more sub-transactions have already been authorised — for example, a reallocation cascade that exhausts without coverage — the Wallet cancels each previously successful authorisation with the relevant acquirer. No funds ultimately move out of the customer's account.
Cancellation is not instantaneous. Authorizations are cancelled 90 seconds after they were made at the earliest. The exact delay is set by the acquirer and scheme rules; the payment methods Aera currently supports all use 90 seconds. This delay exists to avoid a race condition where a cancellation could collide with a capture and the customer ends up double-deducted, requiring a reversal or refund to put right.
What this means for the customer. During the cancellation window, the authorised amount is held on the payment instrument and cannot be spent. If the customer immediately re-attempts a payment using the same instrument, the available balance on that instrument will be lower for the duration of the hold. Once the cancellation processes, the held amount becomes available again as normal — no manual action required from the ECR or the customer.
What this means for the ECR. The ECR's response is final the moment the Wallet returns it; no further callback is sent when the underlying authorisations are eventually cancelled. ECR-side support and customer-care tooling should be aware that the customer's balance on cancelled instruments may briefly lag the transaction outcome. The responseCode for the specific sub-transactions (in transactionDetails) will in this case show: responseCode: 68614.
6. No remaining amount
Remaining amount is a Partial-flow concept and is never returned in a Full flow response.
Partial Hybrid Payment rules
Activated by "fullPayment": "false" in the WIP request.
1. Partial coverage is allowed
The Wallet will process the transaction even if it cannot fully cover the basket. The portion that could not be covered will be returned as remainingAmount.
2. No reallocation on failure
If a payment method's authorisation fails, the failed amount is not reallocated to the next method.
3. Remaining amount reporting
- A Partial transaction can return successfully (root
responseCode: 0) even when the authorized amount (amountDetails.amountat the root level) is less than the requested amount. Success at the root level in partial payment means "the Wallet processed what it could without errors", not "the basket is paid in full" — the ECR must always inspectremainingAmount.amountto decide whether to request additional payment. - When
amountDetails.amountat the root level (authorized amount) is equal the requested amount, the basket was fully covered by the Wallet and the ECR can treat the transaction as complete. - If any of any of the remaining amount was categorized (e.g.
FOOD,ECO and FOOD), it will be returned in a list calledremainingCategories. TheremainingCategoriesshould be comparable (identical structure) with thecategoriessent in the initial hybrid payment request from the ECR. - The field
remainingAmountis the sum of all categorized and non-categorized remaining amount. Any amount not reflected in theremainingCategorieslist, can be seen as a non-categorized amount. remainingAmountis not necessarily only amount that was tried authorized. If the wallet, based on balance checks deemed there to be any remaining amount (balance does not cover full amount), this amount will be added to theremainingAmountwithout being tried in an authorization.- If no amount was successfully authorized, the
remainingAmountandremainingCategoriesfields will not be populated, since it is implied that all is remaining and nothing is authorized.
4. Sub-transaction reporting is identical to Full
transactionDetails is structured the same way in both flows. Every authorization attempt is reported, successful or failed, with the attempted amount intact. The same 68611 / 68612 semantics apply per sub-transaction. See Interpreting transactionDetails.
The Partial flow leans on this contract more heavily than the Full flow does: failed amounts in transactionDetails are reflected in remainingAmount, and the customer sees both — what was attempted, what succeeded, and what is still owed.
Implementation note. Additional Partial-specific rules — for example, behavior when the Wallet cannot reach any payment method, or interaction with future cashback support — will be added to this section as they are finalised. ECR integrators should treat the four rules above as the current authoritative set.
Allocation and prioritisation
Three things determine which payment method is asked to deduct what amount, and in what order:
1. Consumer-chosen priority
The consumer can re-prioritize payment methods (e.g. put Bancontact above Xtra) from their device. The consumer cannot re-prioritize voucher types, only deactivate/activate them. If the consumer has not created a custom priority, the WSP default priority will be used.
2. WSP-configured priority
The WSP default priority is used unless the customer has chosen a custom priority.
3. Balance-check skip
If a payment method supports balance checks and the check shows zero available balance, that method is skipped in the allocation plan — the Wallet moves on to the next method without attempting an authorisation against it.
If the payment method supports balance checks, and the payment method is not allowed to perform transaction with unknown balance (e.g. due to balance check failed), the payment method will be skipped.
The combined effect of these three rules produces the allocation plan the Wallet then attempts to authorise.
See also
- Wallet Payment Scenarios — worked examples of every rule on this page.
- Request examples — payload templates for Full and Partial Hybrid requests.
- Response codes — full code catalogue.
- Supported payment methods — current list of payment instruments and their capabilities.
