Credit exposure ( credit_exposure )
A credit_exposure measures credit currently granted and consumed by a buyer with a merchant. It is the counterpart of the credit limit : the limit sets the authorized ceiling, while exposure tracks what is actually committed.
Role
Where the receivable receivable aggregates existing invoices to answer “how much does this buyer owe me?”, the credit_exposure exposure answers “how much credit have I granted this buyer, and how much remains open?”.
Exposure is a persisted object — unlike receivable, it is not recalculated from invoices. It is built explicitly by orchestration processes, movement by movement, through an immutable ledger. This lets it cover flows that do not yet have an issued invoice, such as credit authorization or financing an order in progress, or that involve a financing company.
There is at most one exposure per tuple (buyer_id, merchant_id, currency).
Identifier and structure
Each exposure has a stable identifier prefixed with cex_. Every ledger movement uses prefix cem_.
{
"object": "credit_exposure",
"id": "cex_2b4d1f8a9c3e7f5b",
"buyer_id": "cmp_3a8f1d9c2b4e7f6a",
"merchant_id": "mer_1a2b3c4d5e6f7a8b",
"currency": "eur",
"status": "active",
"authorized_amount_excluding_tax": 500000,
"authorized_amount_including_tax": 600000,
"consumed_amount_excluding_tax": 100000,
"consumed_amount_including_tax": 120000,
"released_amount_excluding_tax": 0,
"released_amount_including_tax": 0,
"settled_amount_excluding_tax": 83334,
"settled_amount_including_tax": 100000,
"cancelled_amount_excluding_tax": 0,
"cancelled_amount_including_tax": 0,
"expired_amount_excluding_tax": 0,
"expired_amount_including_tax": 0,
"outstanding_amount_excluding_tax": 416666,
"outstanding_amount_including_tax": 500000,
"movements": [
{
"id": "cem_1a2b3c4d5e6f7a8b",
"type": "credit_granted",
"amount_excluding_tax": 500000,
"amount_including_tax": 600000,
"source_type": "checkout_session",
"source_id": "cs_5e2d8f1a9b3c4d7e",
"created_at": "2026-06-17T10:00:00.000Z"
},
{
"id": "cem_9f2e1a4b3c8d7e6f",
"type": "credit_settled",
"amount_excluding_tax": 83334,
"amount_including_tax": 100000,
"source_type": "payment",
"source_id": "pay_4a7b2e9f1c3d8a5e",
"created_at": "2026-06-18T09:15:00.000Z"
}
],
"metadata": {},
"created_at": "2026-06-17T10:00:00.000Z",
"updated_at": "2026-06-18T09:15:00.000Z"
}Fields
| Field | Type | Description |
|---|---|---|
id | string | Exposure identifier (prefix `cex_`). |
object | string | Always "credit_exposure". |
buyer_id | string | Buyer company (`cmp_…`). |
merchant_id | string | Merchant. |
currency | string | ISO 4217 currency in lowercase (for example `eur`). Together with (`buyer_id`, `merchant_id`) it forms the unique key. |
status | enum | `active` or `closed`. |
basis | enum | Basis used by the `amount` projection: `excluding_tax` or `including_tax`. |
amount | integer | Aggregated outstanding balance on the basis selected by `basis`; practical projection of `outstanding_amount_excluding_tax` or `outstanding_amount_including_tax`. |
authorized_amount_excluding_tax | integer | Total credit granted (excluding tax). |
authorized_amount_including_tax | integer | Total credit granted (including tax). |
consumed_amount_excluding_tax | integer | Indicative consumed amount (excluding tax). Does not affect outstanding balance. |
consumed_amount_including_tax | integer | Indicative consumed amount (including tax). |
released_amount_excluding_tax | integer | Released portion (excluding tax). Reduces outstanding balance. |
released_amount_including_tax | integer | Released portion (including tax). |
settled_amount_excluding_tax | integer | Amount settled after payment (excluding tax). Reduces outstanding balance. |
settled_amount_including_tax | integer | Settled amount (including tax). |
cancelled_amount_excluding_tax | integer | Canceled amount (excluding tax). Reduces outstanding balance. |
cancelled_amount_including_tax | integer | Canceled amount (including tax). |
expired_amount_excluding_tax | integer | Expired amount (excluding tax). Reduces outstanding balance. |
expired_amount_including_tax | integer | Expired amount (including tax). |
outstanding_amount_excluding_tax | integer | Active outstanding balance (excluding tax). Computed field — see formula. |
outstanding_amount_including_tax | integer | Active outstanding balance (including tax). Computed field. |
movements | array | Immutable movement ledger (`cem_…` objects). See the Movements section. |
metadata | object | Flat map of `string | number | boolean` scalars, following the API metadata convention. |
created_at | datetime | Creation date. |
updated_at | datetime | Last update date. |
Amount counters
Exposure accumulates six pairs of counters (excluding tax + including tax). Each action on exposure increments one counter and may reduce active outstanding balance.
| Action API | Created movement | Affected counter | Effect on outstanding balance |
|---|---|---|---|
grant | credit_granted | authorized ↑ | outstanding ↑ |
consume | credit_consumed | consumed ↑ | unchanged |
release | credit_released | released ↑ | outstanding ↓ |
settle | credit_settled | settled ↑ | outstanding ↓ |
cancel | credit_cancelled | cancelled ↑ | outstanding ↓ |
expire | credit_expired | expired ↑ | outstanding ↓ |
Active outstanding balance (outstanding_amount_*) is calculated in real time:
outstanding = max(0, authorized − released − settled − cancelled − expired)
The credit_consumed movement is purely indicative — it records that authorized credit was used, for example that an invoice was issued, but it does not reduce outstanding. Only release,
settle, cancel and expire reduce active outstanding balance.
Each counter and the field outstanding exist on two bases (_excluding_tax and _including_tax). At least one basis must be provided for an action.
Movement ledger
The field movements is an append-only ledger — every action on exposure creates an immutable movement. It is the complete history of credit granted to this buyer.
| Movement field | Description |
|---|---|
id | Unique movement identifier (prefix cem_). |
type | Movement type: credit_granted, credit_consumed, credit_released, credit_settled, credit_cancelled, credit_expired. |
amount_excluding_tax | Movement amount excluding tax in cents. Optional depending on type. |
amount_including_tax | Movement amount including tax in cents. Optional depending on type. |
source_type | Type of source object for the movement, for example checkout_session, payment, or invoice. |
source_id | Identifier of the source object. |
reason | Free-form textual reason. Optional. |
metadata | Flat map of string | number | boolean scalars. Optional. |
created_at | Movement timestamp. |
Status
| Status | Meaning |
|---|---|
active | Exposure is open and can receive new movements. |
closed | Exposure is closed (outstanding = 0 or total cancellation). |
Interaction with the credit limit
The credit limit defines the authorized ceiling; exposure tracks what is actually committed. Available credit is the difference between the two.
available = credit_limit.effective_amount − credit_exposure.outstanding_amount
The nodes credit.evaluate_credit_availability and credit.check_credit_availability
automatically calculate this comparison and produce an object
credit_availability_check with the following fields:
{
"object": "credit_availability_check",
"decision": "approved",
"reason": "within_limit",
"basis": "excluding_tax",
"currency": "eur",
"limit_amount": 500000,
"used_amount": 416666,
"requested_amount": 50000,
"available_amount": 83334,
"projected_used_amount": 466666,
"projected_available_amount": 33334
}When decision is rejected, the reason is
insufficient_available_credit. The process then routes to a decline path or request for additional collateral.
Credit limit and exposure share the same key (buyer_id, merchant_id, currency).
The node credit.evaluate_credit_availability resolves both in one call.
In processes
Exposure is entirely driven by process nodes — there is no automatic update triggered by other objects.
| Node | Type | Description |
|---|---|---|
credit.evaluate_credit_availability | Routeur | Consolidated node: resolves the effective limit, retrieves current exposure, and decides whether the requested amount is available. Outputs: `effective_credit_limit`, `credit_exposure`, `credit_availability_check`. Routes: `approved` / `rejected`. |
credit.check_credit_availability | Routeur | Checks only capacity from already-loaded objects (`effective_credit_limit` + `credit_exposure` + `requested_amount`). Routes: `approved` / `rejected`. |
credit.grant_credit | Helper | Increases a company's authorized outstanding exposure (POST /grant). Accepts an optional `credit_availability_check` — fails when `decision=rejected`. |
credit.fetch_credit_exposure | Helper | Retrieves a company's current exposure (GET /current). Returns an empty exposure (`outstanding = 0`) when none exists yet. |
credit.consume_credit_exposure | Helper | Records an indicative consumption (POST /consume). Does not affect outstanding balance. |
credit.release_credit_exposure | Helper | Releases an unused portion (POST /release). Reduces outstanding exposure. |
credit.settle_credit_exposure | Helper | Settles a portion after payment (POST /settle). Reduces outstanding exposure. |
credit.cancel_credit_exposure | Helper | Cancels all or part of the remaining exposure (POST /cancel). When no amount is supplied, cancels the full amount. |
Typical flow: credit authorization
Here is the common shape of a credit-decision process during checkout:
credit.evaluate_credit_availability (company, requested amount) → approved → credit.grant_credit → create checkout session / order → rejected → notify buyer or request collateral
Typical flow: close after payment
payment.matched or psp_payment.succeeded → credit.fetch_credit_exposure (company) → credit.settle_credit_exposure (received amount) → [if outstanding = 0] credit.cancel_credit_exposure
Events
Every exposure action emits a distinct event. The payload includes the complete exposure state before and after the movement, plus the movement itself in latest_movement.
| Event | Trigger |
|---|---|
credit_exposure.granted | POST /grant — new outstanding exposure granted or existing exposure increased. |
credit_exposure.consumed | POST /:id/consume — indicative consumption recorded. |
credit_exposure.released | POST /:id/release — released portion. |
credit_exposure.settled | POST /:id/settle — settled portion. |
credit_exposure.cancelled | POST /:id/cancel — canceled portion. |
credit_exposure.expired | POST /:id/expire — expired portion. |
The event credit_exposure.granted is emitted both at creation (first action grant) and on every subsequent increase in authorized outstanding balance.