Transactions & Fees
Card activity produces two distinct, non-overlapping datasets: Transactions (recorded in GET /cards/transactions) and Fees (recorded in GET /cards/fees). A third dataset covers Wallet-level movements (GET /wallets/transactions). Understanding how these three datasets relate — and that a single real-world event can generate records in more than one of them — is essential for correct reconciliation.
Three datasets, one complete picture
flowchart LR
EVT["Real-world event<br/>(e.g. foreign-currency purchase)"]
TXN["GET /cards/transactions<br/>— the spend event"]
FEE["GET /cards/fees<br/>— associated fees<br/>(e.g. FX fee)"]
WAL["GET /wallets/transactions<br/>— wallet-level movements<br/>(e.g. fund transfer in)"]
EVT --> TXN
EVT -.-> FEE
EVT -.-> WAL
style FEE stroke-dasharray: 5 5
style WAL stroke-dasharray: 5 5
Dashed lines indicate that a fee record and/or a wallet transaction record may or may not accompany a given card transaction — it depends on the event type. A domestic card purchase may produce only a transaction record; a cross-border purchase may produce a transaction record and one or more fee records; a wallet-to-card transfer produces only a wallet transaction record and no card transaction record.
To build a complete picture of all activity on a card and its associated wallets for any given period, query all three endpoints for overlapping date ranges and the same cardId/cardholderId. See Reconcile Transactions & Fees for the full reconciliation walkthrough.
Transactions (GET /cards/transactions)
GET /cards/transactions)The Transaction object
| Field | Type | Description |
|---|---|---|
cardId | integer | The card on which the transaction occurred |
transId | string | Unique transaction ID |
authRefNum | string | Authorization reference number |
amount | string | Transaction amount in the card's base currency — see amount type note and what amount reflects below |
description | string | Transaction description / narrative |
dateCreated | string | Date and time the transaction record was created |
dateSettled | string | Date and time the transaction was settled |
transType | integer | Transaction type — see note below |
transStatus | integer | Transaction status — see table below |
merchantName | string | Name of the merchant |
merchantCurrency | string | The currency of the transaction as presented by the merchant — see merchant currency note below |
merchantAmount | string | The amount in the merchant's presented currency — see merchant currency note below |
Amount type:
amountandmerchantAmountare typed as strings, unlike every other monetary field in this API, which uses decimal-implied integers (e.g.1000= $10.00). Check actual values returned in your environment to confirm the precise format before building any financial logic that depends on these fields.
What
amountreflects: theamountfield represents the full end-to-end cost of the transaction to the cardholder in the card's base currency — not just the face value of the purchase. It includes all embedded costs across the full transaction lifecycle: FX conversion (if applicable), card-network assessment fees, cross-border fees, the acquirer's merchant discount rate components that are passed through, and any other fees embedded by parties in the chain (acquirer, acquirer processor, merchant currency conversion). These costs are variable on a transaction-by-transaction basis and depend on factors outside the platform's control: transaction type, jurisdiction, currency pair, card network, merchant, acquirer, and acquirer processor.
merchantCurrencyandmerchantAmount— not always the merchant's currency. Depending on how a transaction is processed and at what stage currency conversion occurs,merchantCurrencyandmerchantAmountmay reflect the card program's base currency rather than the merchant's actual pricing currency — even on what was genuinely a foreign-currency transaction. This can happen when forced currency conversion is performed on the merchant or acquirer side (a form of Dynamic Currency Conversion — see Embedded FX & Cross-Border Fees) before the transaction reaches the issuer. In these cases,merchantAmountandamountmay be identical, andmerchantCurrencymay match the card's base currency. This is not within the platform's control and should be expected on a transaction-by-transaction basis.
Transaction status (transStatus)
transStatus)transStatus | Name | Lifecycle phase |
|---|---|---|
1 | Pending | Authorization hold placed — funds reserved, not yet cleared (see The Card Transaction Lifecycle) |
2 | Cleared | Transaction posted — authorization converted to a settled debit |
3 | Completion | Settlement complete |
4 | Declined | Authorization declined — no hold placed, no funds moved |
5 | Error | A processing error occurred |
stateDiagram-v2
[*] --> Pending: Authorization approved
[*] --> Declined: Authorization declined
Pending --> Cleared: Merchant batch cleared
Cleared --> Completion: Settlement complete
Pending --> Error
Cleared --> Error
Declined --> [*]
Completion --> [*]
Error --> [*]
transTypevalues: this field is an integer identifying the transaction type. See Pagination, Filtering & Rate Limits for how to filter on it.
Fees (GET /cards/fees)
GET /cards/fees)The Fee object
| Field | Type | Description |
|---|---|---|
cardId | integer | The card against which the fee was incurred |
feeId | string | Unique fee record ID |
authRefNum | string | Authorization reference number (links back to the associated transaction, if any) |
amount | string | Fee amount — same string-type caveat as Transaction amount |
description | string | Fee description / narrative |
dateCreated | string | Date and time the fee record was created |
dateSettled | string | Date and time the fee was settled |
feeType | integer | Fee type identifier |
transStatus | integer | Fee status — same 1–5 enum as Transaction transStatus above |
merchantName | string | Merchant name associated with the fee (for transaction-linked fees) |
merchantCurrency | string | Merchant currency (for transaction-linked fees) |
merchantAmount | string | Merchant amount (for transaction-linked fees) |
Linking fees to transactions: the
authRefNumfield on a fee record can be used to correlate it with the associated transaction inGET /cards/transactions. Use this to attribute fees to specific transactions during reconciliation.
Fee types in context
The following fee types may appear in this endpoint depending on how a Program is configured. All fees are set by the Tenant per Program in Account Management — see Platform fee structure below.
| Fee category | When it arises |
|---|---|
| Standard transaction fee | On any card transaction (domestic, card-present or CNP) |
| Foreign transaction / cross-border fee | When the merchant's country differs from the issuing country and/or a currency conversion occurs |
| Off-ramping fee | When a digital-asset deposit is converted to the card's base fiat currency |
| ATM withdrawal fee | On cash withdrawals at ATMs |
| ATM balance inquiry fee | On ATM balance enquiries (where applicable) |
| Card issuance / delivery fee | At issuance of a physical or virtual card (if configured) |
| Card re-activation fee | Where a closed or lapsed card is re-activated (if applicable per Program) |
| Card replacement fee | For replacing a lost, stolen, or damaged physical card |
| Deposit fee | On incoming bank-rail deposits (if configured) |
| Monthly / maintenance fee | Periodic charge (if configured) |
| Inactivity fee | After a defined period of no card activity (if configured) |
Platform fee structure
Who sets fees and how
All fee types, rates, and parameters are configured by the Tenant for each specific Program via Account Management. This includes the fee rate, the minimum amount, the billing trigger, and the fee-share split between the Tenant and the Program. Billing cycle and settlement currency/asset are also configurable per Tenant/Program.
Account Management is only available in the production environment — fee configuration for a Program cannot be tested in staging. Confirm fee structures with your Axys account team as part of program design, ahead of go-live.
Platform-enforced minimums
For certain fee types, Axys enforces a platform-level minimum that the Tenant cannot configure below. Where a platform minimum exists, it represents the floor — the Tenant may set a higher fee for their Program, but not a lower one. The fee-share model (below) applies only to the markup above the platform minimum, not to the minimum itself. Discuss applicable minimums for your fee structure with your Axys account team.
Fee sharing between Tenant and Program
For each fee type, the Tenant can configure a fee-share split between the Tenant itself and the Program. In a white-label or co-brand arrangement, the Tenant operating the Program on behalf of a client can use this mechanism to define the economics of that relationship — the Program's share flows to the client's settlement, the Tenant's share is retained. Specific rates and splits are commercial terms agreed between the Tenant and Program, configured via Account Management, rather than published platform figures.
Fee accumulation rules: conjunctive and disjunctive
Fees are conjunctive and accumulative by default — if multiple fee types apply to a single transaction, all of them are charged. However, there is one important exception:
| Rule | Fee types | Example |
|---|---|---|
| Conjunctive (both charged) | Foreign transaction fee + off-ramping fee | A cross-border transaction paid with crypto — both the foreign transaction fee and the off-ramping fee apply |
| Conjunctive (both charged) | Off-ramping fee + any other applicable fee | Any transaction where digital assets are converted |
| Disjunctive (one OR the other, not both) | Standard transaction fee vs foreign transaction fee | A foreign-currency transaction is charged the foreign transaction fee instead of the standard transaction fee, not in addition to it |
The practical implication: a cardholder making an online cross-border purchase using a crypto-funded card could be subject to a foreign transaction fee and an off-ramping fee simultaneously — but not a standard transaction fee on top of the foreign transaction fee.
flowchart TD
T["Transaction occurs"]
DOM{"Domestic<br/>transaction?"}
STF["Standard transaction fee"]
FTF{"Foreign / cross-border?"}
FTFEE["Foreign transaction fee<br/>(replaces standard txn fee)"]
ORA{"Digital asset<br/>deposit / off-ramp?"}
ORFEE["Off-ramping fee<br/>(conjunctive — added on top)"]
TOTAL["Total fee = applicable fees summed"]
T --> DOM
DOM -- "Yes" --> STF
DOM -- "No" --> FTF
FTF -- "Yes" --> FTFEE
STF --> ORA
FTFEE --> ORA
ORA -- "Yes" --> ORFEE
ORA -- "No" --> TOTAL
ORFEE --> TOTAL
STF --> TOTAL
T+0 settlement and dateSettled
dateSettledAxys's T+0 settlement model means dateSettled on Transaction and Fee records reflects same-day settlement rather than the multi-day lag typical of traditional card programs, and replaces the traditional multi-party interchange split described in Interchange & Platform Economics — with no explicit platform fee published, and commercial terms agreed directly between the Tenant and Program.
Wallet transactions (GET /wallets/transactions)
GET /wallets/transactions)Wallet-level movements (deposits into a Wallet, transfers from a Wallet to a Card or to another Wallet) are recorded in a separate dataset, not in GET /cards/transactions or GET /cards/fees.
Individual wallet transactions are retrievable by ID:
GET /wallets/transactions/{transactionId}
The full filtered list is available at:
GET /wallets/transactions
For filtering parameters on these endpoints, see Pagination, Filtering & Rate Limits.
Reconciliation approach
Because transactions, fees, and wallet movements are in three separate datasets and a single event can span more than one of them, a complete reconciliation requires:
flowchart TD
A["Define a reconciliation window<br/>(date range + cardId or cardholderId)"]
B["GET /cards/transactions (filtered)"]
C["GET /cards/fees (filtered)"]
D["GET /wallets/transactions (filtered)"]
E["Correlate fees to transactions<br/>via shared authRefNum"]
F["Combine all three datasets<br/>into unified ledger view"]
G["Cross-check: sum of debits/credits<br/>should reconcile to balance delta<br/>on GET /cards/{cardId}/balance"]
A --> B & C & D
B --> E
C --> E
E --> F
D --> F
F --> G
For the fully worked recipe with pagination and deduplication handling, see Reconcile Transactions & Fees and Daily Reconciliation Job.
