# Money: 4.8-4.15

Behaviour the specs don't define (simulator choices). Back to the [index](README.md).

Load Card (4.8):
- `billingAmount` is what gets added to the balance. `loadAmount` must be
  a valid amount and `loadCurrency` 3 uppercase letters, but neither is used.
- Balances are whole units, so amounts may only have zero decimals (`30` or
  `30.00`); anything else → `11`. A missing `productInfo` → `11`.
- Locked (`L`) → `CRDLKD`; hot-listed (`HL`/`HS`/`HD`) → `CRDBLO`.
- No fees are charged, and balance and transaction limits aren't simulated,
  so `CBELIM` and the `LM*EX` limit codes are never returned.
- The response uses `cardBalance` with two decimals, as in the sample, not
  `balanceAmt` from the table. The sample's figure doesn't add up (12221 + 30
  is shown as `12261.00`); the simulator returns the real sum, `12251.00`.

Amount Refund (4.10):
- `amount` follows Load Card's rules: whole units, zero decimals allowed
  (the sample's `01.00` is 1). Anything else, or a `requestType` other than
  `REFUND`, → `11`.
- `balanceAmount` is the account's balance after the refund, with two
  decimals. The sample's figure (`12261.00` after refunding 1 from the
  seed card) doesn't follow from anything; the simulator returns `12220.00`.
- No fees are charged, so the refund fails only when `amount` is more than
  the balance (`EXEAMT`, the closest match to the spec's "refund amount +
  fee is greater than balance").
- Hot-listed cards can't be refunded, as with Load Card. To get money off a
  lost or stolen card, replace it (4.6) and refund the new one.

Account Closure (4.11):
- Accounts can be closed whatever the card's status, including locked and
  hot-listed, as long as the balance is zero. A replaced card's balances
  have moved to the new card, so it can always be closed.
- A missing `productCode` → `11`; one the card doesn't have → `INPDID`.
- The response echoes `productCode` as the table says. The sample shows `null`.
- A closed card (`C`) is refused by every endpoint that changes cards,
  with `CRDCLD` (closing it again included; the spec also lists `ALRCLD`).
  Update Customer by `customerId` skips the customer's closed cards.
- A closed product can't be added back with Account Addition (`ACTEXT`).

Get X Transactions (4.12):
- Dates are inclusive. `fromDate` after `toDate`, more than 90 days apart,
  `fromDate` more than six months ago, or a malformed date → `INVDAT`. With
  `count` `"**"`, the dates aren't checked at all, as the spec says they're
  ignored. Any other `count` outside 1–99 → `11`. The page number the spec
  mentions has no field in the table and isn't supported.
- No matching transactions → `17` ("No records found") rather than an empty list.
- The response uses the sample's field names (`transactionRefNumber`,
  `merchLocation`, `availableBalance`, `rrn`, ...) where they differ from
  the table. `transactionDate` includes the time, as in the sample.
- Every transaction is settled at once: `transStatus` `Approved`,
  `transSettleDate` the transaction's date, `exRate` `1.0000`, and transaction
  and billing amounts and currencies the same. Merchant, terminal and auth
  fields are `null`, as in the sample. `transRefNo` and `rrn` are a
  generated 16-digit number.
- `activateDate` is the day the card became active, through Purchase Card
  with `cardActivationFlag` `Y` or Card Activation. It's left out for the
  seed card and for cards not yet activated.
- Card Replacement's balance move isn't recorded, and the new card starts
  with no transactions; the old card keeps its history.
- History lives with the cards, so a restart or `/_sim/reset` clears it.

Debit/Credit the Account (4.13):
- An `amount` in another currency is converted at the saved rate for
  buying the account's currency with `currency`; with no such rate →
  `NOEXRT`. `currency` must still be 3 uppercase letters (`11`).
- The balance check and the transaction in 4.12 use the converted amount,
  in the account's currency.
- `amount` follows Load Card's rules (whole units, zero decimals allowed).
- `remarks` is mandatory but may be empty, as in the sample; a missing one → `11`.
  The 25-character limit isn't checked.
- A `type` other than `BAT`/`FEE` or a `flag` other than `D`/`C` → `11`.
- A debit larger than the balance → `LSSBAL` ("Available Card Balance is
  Less than the Amount"), so balances never go negative.
- `cardBalance` is a whole number with no decimals, as in the sample (`"0"`),
  not `cardBalnce` from the table.

Fund Transfer (4.14):
- Across currencies, the rate is the sent `exchangeRate` or else the saved
  rate for buying the destination currency with the source currency; with
  neither → `NOEXRT` ("Exchange Rate is not Defined"). The rate is picked
  from the request's `accountCcy` fields, which must match the accounts.
  `exchangeRate` must be a positive number of at most 12 characters if sent
  (`INVEXR`). Same-currency transfers ignore it and use `1.0000`.
- The response's `exchangeRate` is the rate used, with at least four
  decimals (`1.0000`, `3.6725`). `sourceAccount.amount` is what the source
  paid in its currency; `destAccount.amount` what the destination got.
- A converted cost that rounds to zero → `ZETRAM`, so nothing is ever free.
- 4.12 shows each side's transaction in its own currency, and `exRate`
  stays `1.0000` there.
- "Different card holders" means different `customerId`s. Cards with no
  `customerId` (such as the seed card) count as different holders. The same
  card on both sides, or two cards of one holder, → `NOTSAM`.
- Only active (`I`) cards qualify, as the spec says; inactive (`M`), locked
  and hot-listed cards → `SRCACC` / `DESACC`. A closed account on either side
  gets the same codes; a closed card → `CRDCLD`.
- A zero or negative amount → `ZETRAM`; any other amount that doesn't
  follow Load Card's rules → `11`. A missing `proxyNumber` → `INVFPD` /
  `INVTPD`; a missing `sourceAccount` or `destAccount` node → `11`.
- No fees, so both `feeAmount`s are `"0"` as in the sample. The response echoes `txnRefNo` and the destination's
  `productCode` (the sample shows `null` for both). The sample's
  `transRefNumber` isn't returned.

Exchange Rate (4.15):
- The request has no date, so a pair has one rate, set on the day it was
  last sent; a later request for the pair replaces it, as the spec says
  happens for a rate already set that day. Pairs are directional:
  `AED`/`USD` and `USD`/`AED` are separate rates.
- Currencies must be 3 uppercase letters (`BUYNOT` / `SELNOT` otherwise).
  There's no list of known currencies, so any such code is accepted. The
  same currency on both sides → `11`.
- `exRate` and `bankRate` must be positive decimal numbers of at most 12
  characters, such as the sample's `01.2551` (`INVEXR` otherwise). They're
  stored as sent.
- There's no endpoint to read rates back. They're lost on a restart or
  `/_sim/reset`.
