Skip to main content

Modelling Example: Revolving Credit (Credit Card)

This document shows how to map a revolving credit product — credit card, overdraft, line of credit — onto the platform. The client described here ("FlexiCard") is fictional. Companion examples: BNPL, Personal Loan, Recurring Invoices, Debt Buyer.

Revolving credit is the case that stresses the question "what is a claim?" hardest. There is no schedule of instalments to point at: the balance fluctuates with spending, interest, and payments; the contractual obligation each month is only a minimum payment; and the debt has no natural end date until the issuer terminates the line.

The modelling decision: rolling claim vs claim-per-statement

Two viable shapes, with a clear recommendation:

  1. One rolling claim per card (recommended once placed): a single claim whose balance is maintained with debit_claims (interest, fees, new spend if the line is still open) and credit_claims (payments made to the issuer). The claim is the card balance.
  2. One claim per statement cycle: each month's overdue amount becomes its own claim. This mirrors the BNPL Phase-1 shape, but revolving balances make it misleading — statements overlap (each includes the previous unpaid balance), so claims would double-count unless the client sends only the increment, which few card systems can produce cleanly.

The debit/credit endpoints are what make the rolling claim workable — their semantics (from the API spec) map directly onto card ledger events:

  • debit_claims increases amount and/or fees. Fees sent as a named array are merged by name: an existing fee with the same name is incremented, an unknown name creates a new fee entry. So monthly interest posts as { "name": "interest", "amount": ... } and accumulates in one bucket.
  • credit_claims decreases the claim; fees credited by name reduce the matching bucket (credits against a fee name that doesn't exist are ignored). When the claim amount reaches zero, the claim auto-resolves — a payoff closes the case with no extra call.
  • Debits after a payoff (payment reversal, late-posted interest) must carry options: { "forceAmountCheck": true }: without it the debit restores the balance but leaves the claim RESOLVED, invisible to collections. With the flag, one call restores the balance AND reactivates the claim.
  • resolve_claims changes state only, never the balance — and its reason enum matters for cards: FRAUDULENT (fraud write-off), CLAIM_DISCHARGED (insolvency), CLAIM_SOLD (portfolio sale — see the debt-buyer example), CLAIM_PAID, CLAIM_DISCARDED, CLAIM_INVALIDATED.

Entity mapping

Card conceptPlatform entity / mechanism
CardholderAccount
Card / credit lineProduct (type: "CREDIT_CARD", meta: limit, APR, open date)
Charged-off balanceClaim (one rolling claim per card)
Principal vs interest vs feesamount (principal) + named fees buckets
Interest/fee postingdebit_claims (merge-by-name)
Payment to the issuercredit_claims (auto-resolve at zero)
Fraud write-offresolve_claims reason FRAUDULENT
Hardship payoff planReceive Instalment Plan (freezes the revolving dynamics)

Fictional client: "FlexiCard"

Assumed policies:

  • Consumer credit cards, limits €1,000–€10,000, minimum payment 3% of balance.
  • Missed minimums trigger internal dunning; after 3 missed cycles the card is blocked; after 6 the account is charged off and placed in collection.
  • At charge-off the balance is fixed: principal separated from accrued interest and fees. Default interest continues to accrue monthly on principal (contractual).
  • Fraud cases can surface after placement and must be written off cleanly.

Worked example: Sofia's card

Sofia has a €3,000 limit, runs a €2,400 balance, stops paying. After 6 missed cycles FlexiCard charges off and places the debt.

  • Account = Sofia. Product = the card: productReference: "FC-CARD-5521", type: "CREDIT_CARD", meta: limit, APR, open date, charge-off date.

Placement — one rolling claim, decomposed:

// POST /v1/{clientId}/create_claims
{
"FC-CARD-5521-CO": {
"amount": 240000, // cents — principal at charge-off
"currency": "EUR",
"originalDueDate": "2026-01-20", // first missed minimum
"currentDueDate": "2026-07-20", // charge-off/placement
"productReference": "FC-CARD-5521",
"fees": [
{ "name": "interest", "amount": 21500 },
{ "name": "lateFees", "amount": 9000 },
],
"primaryDebtor": {
/* Sofia */
},
},
}

As with the personal loan: originalDueDate carries the real delinquency age, and the principal/cost split lives in amount vs named fees.

Monthly default interest — a debit, not a claim update. Merge-by-name keeps one bucket:

// POST /v1/{clientId}/debit_claims — each month
{
"FC-CARD-5521-CO": {
"amount": 0, // fees-only debit
"fees": [{ "name": "defaultInterest", "amount": 2400 }],
},
}

(Contrast with the personal-loan example, which used update_claims to replace the fee list. Both work; debits are incremental and append-friendly, updates are absolute and idempotent. Pick per the client's integration style — event-driven card ledgers fit debits, batch recomputations fit updates.)

Sofia pays €500 to FlexiCard directly:

// POST /v1/{clientId}/credit_claims
{
"FC-CARD-5521-CO": { "amount": 50000, "fees": 0 },
}

If a later credit takes the claim to zero, it resolves automatically.

Fraud discovered on part of the balance: FlexiCard's investigation attributes €600 of the balance to a fraudulent merchant. credit_claims removes the €600 (with the fraud case reference in the request meta); if instead the entire claim turns out to be fraud, resolve_claims with reason FRAUDULENT closes it — remembering that resolution does not zero the balance, so reporting on "collected vs written off" should key on the resolution reason.

Hardship treatment: the strategy offers a Receive Instalment Plan over the frozen balance — same mechanics as every other example. Freeze defaultInterest debits while a plan is active; a plan over a still-growing balance will not reconcile.

Discovery questions for a real revolving-credit client

  1. Placed at charge-off only, or earlier? Pre-charge-off placement of a live revolving line means new spend/interest keeps flowing — confirm the client can emit incremental debits, or keep servicing internal until charge-off (recommended).
  2. Incremental or absolute integration? Card ledgers that emit events → debit_claims / credit_claims. Systems that recompute balances in batch → update_claims. Mixing both on one claim is how balances drift.
  3. What is the fee taxonomy? Agree the named buckets (interest, defaultInterest, lateFees, overlimitFees...) up front — merge-by-name means renames fragment history.
  4. How is fraud handled contractually? Partial fraud → credit; full fraud → resolve FRAUDULENT. The distinction drives recovery reporting.
  5. Does default interest freeze on hardship plans or insolvency? Same question as the personal loan, sharper here because accrual is the norm for cards.

This example focuses on what to model; the step-by-step mechanics of each API call are covered by the generic use cases: