@nice2dev/ui-money
v1.0.12
Published
Nice2Dev Money & Payments — Money / MoneyInput / CurrencySelector / CreditCardInput / PaymentForm + ISO 4217 catalog, Luhn validation, exchange-rate & payment-processor adapters
Maintainers
Readme
@nice2dev/ui-money
Money, currency, credit-card and payment React components for the Nice2Dev monorepo. First-class integrations: ISO 4217 catalog (60+ currencies + crypto), Luhn / brand detection, exchange-rate providers, payment-processor adapters.
npm install @nice2dev/ui-moneyComponents
| Component | Purpose |
| ----------------------- | --------------------------------------------------------------------------- |
| NiceMoney | Read-only formatted amount with optional FX preview. |
| NiceMoneyInput | Amount input + integrated currency selector + steppers + live preview. |
| NiceCurrencySelector | Searchable, optgroup-aware ISO-4217 picker with recents. |
| NiceCreditCardInput | Card number + expiry + CVC + holder + postal. Brand detection, Luhn. |
| NicePaymentForm | Composite checkout form driven by any PaymentProcessor adapter. |
| NicePriceTag | Price with strike-through, discount badge, period suffix (subscriptions). |
| NiceCurrencyConverter | Live source ↔ target conversion widget driven by an ExchangeRateProvider. |
Money domain
Amounts are always stored as integer minor units (cents, satoshi, …) — never floats:
import { toMoney, fromMoney, addMoney, formatMoney } from '@nice2dev/ui-money';
const price = toMoney(12.34, 'USD'); // { amount: 1234, currency: 'USD' }
const tax = toMoney(0.99, 'USD');
const total = addMoney(price, tax); // { amount: 1333, currency: 'USD' }
formatMoney(total, { locale: 'en-US' }); // "$13.33"
formatMoney(total, { locale: 'de-DE' }); // "13,33 $"JPY (0 decimals) and BHD (3 decimals) are handled automatically via the catalog.
Exchange-rate providers
Built-in adapters, all behind one ExchangeRateProvider interface:
import {
StaticExchangeRateProvider,
FrankfurterProvider, // free, ECB-derived, no key
ExchangeRateHostProvider, // free, aggregated, no key
OpenExchangeRatesProvider, // requires app id
convertMoney,
} from '@nice2dev/ui-money';
const fx = new FrankfurterProvider({ cacheTtl: 60_000 });
const eur = await convertMoney(toMoney(100, 'USD'), 'EUR', fx);Implement ExchangeRateProvider to plug in Fixer, CurrencyAPI, Wise, your own backend, etc.
Payment-processor adapters
Provider-agnostic PaymentProcessor interface with bundled scaffolds for:
- Stripe · PayPal · Adyen · Square · Mollie
- Braintree · Razorpay · Klarna
- PayU · Przelewy24 (Polish market: BLIK, Przelewy24)
- Coinbase Commerce (BTC, ETH, USDC, USDT)
MockPaymentProcessor(tests / demos)
Each adapter is a scaffold — pass an executor that calls the real SDK / REST API:
import { makeStripeAdapter } from '@nice2dev/ui-money';
const stripe = makeStripeAdapter({
authorize: async (req) => {
// call Stripe SDK / REST here, return PaymentResponse
},
capture: async (id, amount) => {
/* … */
},
cancel: async (id) => {
/* … */
},
refund: async (id, amount) => {
/* … */
},
});Usage
import { NicePaymentForm, toMoney, MockPaymentProcessor } from '@nice2dev/ui-money';
import '@nice2dev/ui-money/style.css';
export default function Checkout() {
return (
<NicePaymentForm
processor={new MockPaymentProcessor()}
amount={toMoney(49.99, 'USD')}
description="Pro plan, billed monthly"
onSuccess={(r) => console.log('paid!', r.id)}
/>
);
}Hooks
useNiceMoney(initial, locale?) // reactive Money + helpers
useNiceExchangeRate(source, target, fx) // live conversion subscription
useNicePayment(processor) // authorize / capture / refundWhy not just floats?
Floating-point arithmetic loses pennies (0.1 + 0.2 !== 0.3). Storing minor units as
integers makes every arithmetic op exact, every comparison stable, and every
serialization round-trip lossless. toMoney / fromMoney are the only places where a
decimal touches a number.
License
See repository LICENSE.
