Credit Cards API
This API manages revolving credit cards: a credit limit, billing cycles with a cut-off date, statements with a due date, configurable daily interest on unpaid balances, a minimum payment with a late fee, and purchase reversals.
It is a product line of its own, separate from DPA flows and debts — the only shared entity is the client. The CMS Base URL is used (see introduction).
No card number, no security code
The tail you see in responses is a display label derived from the account id
so support and the cardholder can name the same card. It is not a PAN and
cannot be used as a payment instrument — issuing and tokenization belong to a
card processor.
The Card Account Object
Attributes
| Attribute | Description | Type |
|---|---|---|
id | Card account id | UUID |
clientId | The client the card belongs to | UUID |
productId | Card product (plan) the terms were copied from | UUID |
referenceId | Partner's own id — creation idempotency key | String |
status | See Card Status | String |
creditLimit | Credit limit (cupo máximo), enforced on every purchase | Money |
outstanding | Total owed: unpaid billed statements + the open cycle's charges | Money |
creditBalance | Money in the cardholder's favor (overpayment / reversal excess) | Money |
availableCredit | creditLimit − outstanding + creditBalance — derived, never stored | Money |
expiresOn | Card validity date (openedOn + terms.validityYears) | Date |
currentStatementId | The single open statement (current cycle) | UUID |
terms | Frozen copy of the plan's terms — see Card Products | Object |
Card Status
| Status | Meaning |
|---|---|
pending | Created, not yet activated. No purchases, no payments. |
enabled | Operating: purchases and payments allowed. |
disabled | Purchases rejected; payments still accepted. Billing and interest continue. |
closed | Terminal. Requires a settled book (outstanding − creditBalance exactly zero). |
Billing Cycles
- The account always has exactly one open statement. Purchases land there and are never due mid-cycle — that is the grace period.
- At the cut-off (
closeDate, inclusive) the statement is billed: itsdueAmountandminDuefreeze, and the next cycle opens. Cycle dates always chain from the previous cut-off, so cycles stay contiguous even if a sweep runs late. - The due date is
closeDate + termDays. - Unpaid balances are not re-billed into later cycles: every statement keeps
its own
dueAmount/paidAmount. Interest and late fees charged against a statement post on the current open statement (they appear on the next bill, like a real card) and therefore never compound.
Statement Status
| Status | Meaning |
|---|---|
open | Current cycle, nothing due yet |
closed | Billed at cut-off, awaiting payment |
overdue | Past the due date with money still owing |
paid | Remaining due reached zero (or the cycle billed nothing) |
Money Rules
- Credit is revolving: a payment reduces
outstandingimmediately, so the available credit is restored in the same transaction — no waiting for the cut-off. - Payments apply oldest-unpaid-first across billed statements; the remainder
becomes
creditBalance. The payment records the split inapplications. - Purchases over the available credit are rejected with
422 insufficient_credit, checked under a row lock so concurrent purchases cannot jointly overrun the limit. - Interest is daily, from the day after a statement's due date on its unpaid balance, until it is paid. The base is the statement's own remaining due, so interest never accrues on interest.
- The late fee is one-shot per statement, charged only when payments through
the due date did not reach
minDue. Paying at or above the minimum avoids the fee; interest still accrues on the rest.
Idempotency
Every write is idempotent — a replay returns the existing record with 200
instead of creating a twin.
| Operation | Key |
|---|---|
| Open account | referenceId (optional) |
| Purchase / payment | referenceId (required) |
| Purchase reversal | one reversal per purchase |
| Interest / late fee | one per statement per day / one per statement |
The Idempotency-Key header is additionally honored on purchases, payments and
reversals.
Endpoints
Open a Card Account
Creates the account in pending with its first open statement.
Body:
| Field | Description | Type |
|---|---|---|
clientId | Client UUID or the partner's external id | String |
creditLimit | Credit limit | Money |
productId | Plan to use. Omitted ⇒ the tenant's default plan | UUID |
referenceId | Partner's id for the account (idempotency) | String |
termsOverride | Per-account overrides of the plan terms | Object |
openedOn | Backdates the account for historical imports (YYYY-MM-DD) | Date |
metadata | Free-form | Object |
Returns 201 with the Card Account; a replay of the same referenceId returns
200 with the existing one.
Get / List Card Accounts
Change the Credit Limit
Body: { "creditLimit": { "amount": "15000.00", "currency": "USD" } }.
Lowering it below the current usage is allowed — the available credit goes
negative and purchases are rejected until the cardholder pays down.
Activate, Suspend or Close
A suspended card still accepts payments. Closing requires a settled book.
Register a Purchase
| Field | Description | Type |
|---|---|---|
referenceId | Required idempotency key | String |
amount | Purchase amount | Money |
date | Business date. Omitted ⇒ today (YYYY-MM-DD) | Date |
metadata | description is shown on the statement | Object |
412 if the card is not enabled; 422 insufficient_credit if it exceeds the
available credit.
Reverse a Purchase
Body: optional amount (omit for a full reversal) and reason. Transactions are
immutable, so the reversal is a new compensating transaction — one per
purchase, full or partial:
- If the purchase's statement is still open, the reversal voids it inside the cycle and the purchase never gets billed.
- If the statement was already billed, the reversal applies against that
statement like a targeted payment (and can mark it
paid, stopping its daily interest). Any excess becomes credit balance.
Interest or late fees already charged for past days are not retro-reverted.
Register a Payment
Same body as a purchase. Applies oldest-unpaid-first; statements it zeroes become
paid, which stops their daily interest from that date. The response carries the
split:
(the remaining 100.00 became credit balance).
Account Summary
The cardholder's position right now: creditLimit, outstanding,
creditBalance, availableCredit, dueNow, minDueNow, oldestDueDate,
daysPastDue, cycleStartDate, nextCutoffDate, nextDueDate, cycleSpend
(this period's consumption) and expiresOn.
Statements and Transactions
Transaction types: purchase, payment, interest, penalty (late fee) and
reversal. Interest and late fees carry metadata.sourceStatementId pointing at
the cycle that owed the money; reversals carry metadata.sourceTransactionId.
Statement Document (estado de cuenta)
The composed statement of one cycle in a single payload — issuer, cardholder,
card, period, totals and the itemized lines — so a renderer never has to stitch
calls or re-derive money. .csv returns the same document as a downloadable
attachment (debits positive, credits negative, so summing the amount column
reconciles).
previousBalance is what the older cycles still owed as of this cut-off. It is
computed when the document is built (unpaid balances are never re-billed) and it
is informational — it is not part of this cycle's dueAmount.
Tax (VAT) on interest and late fees
When the plan sets interestTax (and optionally penaltyTax), every interest or
late-fee charge stores its own tax and the document breaks it out:
| Total | What it is |
|---|---|
interest / penalties | Gross: tax included, because that is what the cardholder owes and what dueAmount is built from |
interestTax / penaltyTax | The tax included in each of the two above |
taxes | interestTax + penaltyTax for the period |
Each interest/late-fee line also carries its own tax; a line's net charge is
amount − tax. Every other line (purchases, payments, reversals) carries a zero
tax.
Tax is rounded per charge
Interest accrues daily, so the tax is computed and rounded per charge (half-even). The period total is the sum of the lines — the way a line-level VAT invoice adds up. Re-applying the rate to the aggregate interest can differ by cents: the document reports the sum, not the recomputation.
The payment reference is still missing
The document does not yet include a payment reference or coupon. It is deliberately not derived: a number the API invents is registered with no collection network and cannot be paid. The shape will be an opaque per-account reference set by the partner, plus the tenant's configured payment instructions.
Permissions
| Permission | Grants |
|---|---|
card.account.read | accounts, summary, statements, transactions, statement document |
card.account.write | open an account, change the limit, enable/disable/close |
card.purchase.create | register purchases and reverse them |
card.payment.create | register payments |
Sending X-Test-Mode: true operates on the tenant's sandbox, fully partitioned
from production data.
Error Handling
| Status | When |
|---|---|
400 | Validation: missing referenceId, non-positive amount, currency mismatch, bad dates |
404 | Unknown account, statement or transaction |
412 | Wrong state: purchase on a non-enabled card, closing with debt, reversing a non-purchase |
422 insufficient_credit | The purchase exceeds the available credit |
200 on replay | A duplicate referenceId returns the existing record instead of failing |