Currency (Semantic Module)
The Currency semantic module manages monetary amounts, transactions, and product pricing across your application.
In traditional software development, storing money as standard floating-point numbers often introduces subtle rounding errors (e.g., 0.1 + 0.2 = 0.30000000000000004). The Currency semantic module prevents these issues by validating monetary inputs, enforcing ISO 4217 currency codes, and managing exact decimal precision.
Technical Specifications
Section titled “Technical Specifications”| Attribute | Specification |
|---|---|
| Scope | Property (Applied to a Number or String property) |
| Data Types | Number (for raw numeric amounts) or String (for combined amount + currency) |
| Default Currency | USD (ISO 4217 standard) |
| Default Precision | 2 decimal places |
| Negative Values | Disallowed by default (allowNegative: false) |
| Supported Storage | decimal, integer_cents, or complex_object |
Key Capabilities
Section titled “Key Capabilities”1. Flexible Input Handling (Numbers & Strings)
Section titled “1. Flexible Input Handling (Numbers & Strings)”The Serverless Engine accepts monetary amounts in two convenient ways:
- Numeric Input: Pass a standard number (e.g.,
19.99). The system assigns the configureddefaultCurrency(e.g.USD). - Formatted String with Currency: Pass the amount followed by an ISO currency code (e.g.,
"19.99 EUR"or"120.50 GBP"). The engine automatically parses the amount, extracts the currency code, and validates both.
2. Decimal Precision Enforcement (decimalPlaces)
Section titled “2. Decimal Precision Enforcement (decimalPlaces)”To avoid precision mismatch and fractional cent errors:
- Enforces the maximum allowed decimal places (default:
2). - If a client submits an amount with more decimal places than configured (such as
19.999), the engine immediately rejects the request with a validation error. - Can be configured with
0for zero-decimal currencies (likeJPYorKRW) or up to8for high-precision assets.
3. Multi-Currency Validation (allowedCurrencies)
Section titled “3. Multi-Currency Validation (allowedCurrencies)”When building international stores or multi-tenant platforms:
- Configure an allowlist of permitted ISO 4217 currency codes (e.g.,
['USD', 'EUR', 'GBP', 'CAD']). - Any transaction submitted with an unlisted currency code is rejected.
- If multiple currencies are permitted, clients must submit values with explicit currency codes (e.g.,
"25.00 EUR") to avoid ambiguous transactions.
4. Negative Values for Refunds & Discounts (allowNegative)
Section titled “4. Negative Values for Refunds & Discounts (allowNegative)”- By default, negative values are blocked to prevent erroneous negative pricing.
- For ledgers, credit notes, discount codes, or refund records, toggle
allowNegative: trueto permit negative balances.
Storage Formats
Section titled “Storage Formats”You can choose how monetary values are physically structured in the database:
decimal(Default): Stored as a high-precision decimal number. This is ideal for standard e-commerce where numerical calculations, sorting, and price range filters (such asprice[gte]=20.00) are common.integer_cents: Stored as whole integer units representing the smallest currency denomination (e.g.$19.99is stored as1999cents). This completely eliminates floating-point rounding bugs in financial calculation engines.complex_object: Stored as a composite object containing both amount and currency (e.g.{ "amount": 19.99, "currency": "USD" }). This is optimal for dynamic multi-currency catalogs where individual records can each use different currencies.
Configuration Options
Section titled “Configuration Options”When configuring the Currency semantic in the Domain Modeler, you can adjust the following parameters:
| Option | Type | Default | Description |
|---|---|---|---|
storageFormat | 'decimal' | 'integer_cents' | 'complex_object' | 'decimal' | How the monetary amount is stored in the database. |
defaultCurrency | string | 'USD' | Default ISO 4217 currency code applied when no currency is specified. |
allowedCurrencies | string[] | [] (all allowed) | Array of permitted ISO currency codes (e.g. ['USD', 'EUR']). |
decimalPlaces | number | 2 | Maximum decimal places permitted on inputs. |
allowNegative | boolean | false | Whether negative amounts are allowed (for discounts or refunds). |
validateCurrencyCode | boolean | true | Validates currency codes against official ISO 4217 standards. |
API Lifecycle Examples
Section titled “API Lifecycle Examples”1. Creating a Product with Default Currency
Section titled “1. Creating a Product with Default Currency”A client creates a product supplying a standard numeric value:
POST /productsContent-Type: application/json
{ "name": "Standard Subscription", "price": 49.99}Server Response (201 Created):
{ "data": { "id": "prod_101", "name": "Standard Subscription", "price": 49.99 }}2. Multi-Currency Input
Section titled “2. Multi-Currency Input”On an entity configured with multiple allowed currencies (['USD', 'EUR', 'GBP']), a client submits a string value:
POST /invoicesContent-Type: application/json
{ "invoiceNumber": "INV-2026-001", "total": "1250.00 EUR"}Server Response (201 Created):
{ "data": { "id": "inv_801", "invoiceNumber": "INV-2026-001", "total": "1250.00 EUR" }}3. Validation Failure (Negative Amount Disallowed)
Section titled “3. Validation Failure (Negative Amount Disallowed)”When allowNegative: false (default) and a client passes a negative number:
{ "price": -15.00}Server Response (422 Unprocessable Entity):
{ "type": "https://docs.apinow.app/errors/validation", "title": "Validation Error", "status": 422, "code": "E_VALIDATION_ERROR", "detail": "The field 'price' must not be negative."}Validation Rules & Modeling Guidelines
Section titled “Validation Rules & Modeling Guidelines”- Applicable Property Types: You can apply
Currencyto either a Number property (for purely numerical values) or a String property (for combined amount and currency text). - Multi-Currency Requirements: If
allowedCurrenciescontains more than one currency, incoming numbers without a currency string are rejected. This protects against currency confusion (e.g. charging 50 USD instead of 50 EUR).