Documentation
¶
Index ¶
- Variables
- type Cents
- type Type
- func (t Type) Amount(c Cents) money.Amount
- func (t Type) Code() string
- func (t Type) Decimals() int32
- func (t Type) FitsCents() bool
- func (t Type) FromMinimalUnits(b *big.Int) Cents
- func (t Type) IsCrypto() bool
- func (t Type) IsZeroDecimal() bool
- func (t Type) Label() string
- func (t Type) MinimalUnitFactor() *big.Int
- func (t Type) Money() money.Currency
- func (t Type) Parse(s string) (Cents, error)
- func (t Type) ParseAmount(s string) (money.Amount, error)
- func (t Type) Symbol() string
- func (t Type) ToMinimalUnits(c Cents) *big.Int
- func (t Type) ToString(c Cents) string
- func (t Type) ToStringNoSymbol(c Cents) string
Constants ¶
This section is empty.
Variables ¶
var Types = []Type{}/* 139 elements not displayed */
Functions ¶
This section is empty.
Types ¶
type Cents ¶
type Cents int64
Cents is an amount in a currency's minor units — despite the name it is minor units, not cents: for a zero-decimal currency (see Type.IsZeroDecimal) one Cents is one whole unit.
There is deliberately no parser here. Converting a decimal string of MAJOR units ("19.99") into minor units is one fact, and its home is money.ParseCents in github.com/hanzoai/money — which commerce already depends on. Call that and convert the int64 it returns.
func (Cents) BasisPoints ¶ added in v1.49.49
BasisPoints returns bps basis points of c, rounded half away from zero — the shape promotion application methods store a percentage in (1500 means 15.00%).
func (Cents) Percent ¶ added in v1.49.49
Percent returns pct percent of c, rounded half away from zero — the shape coupons and discount rules store a percentage in (10 means 10%, not 0.10).
func (Cents) Scale ¶ added in v1.49.49
Scale returns c scaled by an exact rate — a discount, a commission, a tax — rounded to a whole minor unit HALF AWAY FROM ZERO. It is the one way to take a percentage of an amount in this codebase; the arithmetic itself is money.ScaleMinor, for the same reason the parser above is money.ParseCents.
The rule is rounding, not truncation, and it is the rule everywhere rather than one rule for discounts and another for fees. 10% off $19.99 is $1.999: truncating gives $1.99 and keeps the tenth of a cent, rounding gives $2.00 and gives it away. Either is defensible once; what is not defensible is that the fraction always fell the same way, so a price book's worth of orders each quietly withheld a fraction of a cent from the customer and the sum was never zero.
Half away from zero also means a negative scales like the positive it reverses, so a refunded discount is the discount back — which math.Floor, rounding toward negative infinity, does not give.
PANICS if the result does not fit an int64. Cents is an int64, so the only inputs that can do this are an amount already near the type's limit scaled up by a rate above 1 — no order reaches $46 quadrillion, and a discount rate is at most 1 anyway. Returning a wrapped number instead would report money nobody owes, and returning zero would report a free order; this follows money.Amount.Cmp, which panics across currencies on the same reasoning: it is a bug in the caller, not a runtime condition to branch on.
func (Cents) ScaleCeil ¶ added in v1.49.51
ScaleCeil and ScaleFloor are Scale for the amounts whose DIRECTION is the policy rather than an artifact: the platform fee this codebase has always rounded up, the affiliate commission it has always rounded down and kept the remainder of. Scale's half away from zero is right for an amount that only has to be correct, and wrong for one somebody decided always falls the same way — so those keep their direction, and only stop being computed on a float.
They round toward +infinity and toward -infinity, not away from and toward zero. A fee reversed on a refund is negative, and there the two readings differ.
The float spellings they replace, math.Ceil(float64(c)*rate) and math.Floor, do not round the product — they round the FLOAT, which is a different number and wrong in the direction each caller cares about most. 0.07 is held a hair high, so 700 cents at 7% is 49.000000000000007 and ceilings to 50: a cent charged on an amount that was exactly 49. 0.29 is held a hair low, so 100 cents at 29% is 28.999999999999996 and floors to 28: a cent taken out of a commission that was exactly 29. money.ScaleMinorCeil/Floor form the product exactly, so a whole product survives rounding in either direction untouched.
PANICS on overflow, for the reason Scale does.
type Type ¶
type Type string
const ( USD Type = "usd" AUD Type = "aud" CAD Type = "cad" EUR Type = "eur" GBP Type = "gbp" HKD Type = "hkd" JPY Type = "jpy" NZD Type = "nzd" SGD Type = "sgd" AED Type = "aed" // United Arab Emirates Dirham AFN Type = "afn" // Afghan Afghani* ALL Type = "all" // Albanian Lek AMD Type = "amd" // Armenian Dram ANG Type = "ang" // Netherlands Antillean Gulden AOA Type = "aoa" // Angolan Kwanza* ARS Type = "ars" // Argentine Peso* AWG Type = "awg" // Aruban Florin AZN Type = "azn" // Azerbaijani Manat BAM Type = "bam" // Bosnia & Herzegovina Convertible Mark BBD Type = "bbd" // Barbadian Dollar BDT Type = "bdt" // Bangladeshi Taka BGN Type = "bgn" // Bulgarian Lev BIF Type = "bif" // Burundian Franc BMD Type = "bmd" // Bermudian Dollar BND Type = "bnd" // Brunei Dollar BOB Type = "bob" // Bolivian Boliviano* BRL Type = "brl" // Brazilian Real* BSD Type = "bsd" // Bahamian Dollar BWP Type = "bwp" // Botswana Pula BZD Type = "bzd" // Belize Dollar CDF Type = "cdf" // Congolese Franc CHF Type = "chf" // Swiss Franc CLP Type = "clp" // Chilean Peso* CNY Type = "cny" // Chinese Renminbi Yuan COP Type = "cop" // Colombian Peso* CRC Type = "crc" // Costa Rican Colón* CVE Type = "cve" // Cape Verdean Escudo* CZK Type = "czk" // Czech Koruna* DJF Type = "djf" // Djiboutian Franc* DKK Type = "dkk" // Danish Krone DOP Type = "dop" // Dominican Peso DZD Type = "dzd" // Algerian Dinar EEK Type = "eek" // Estonian Kroon* EGP Type = "egp" // Egyptian Pound ETB Type = "etb" // Ethiopian Birr FJD Type = "fjd" // Fijian Dollar FKP Type = "fkp" // Falkland Islands Pound* GEL Type = "gel" // Georgian Lari GIP Type = "gip" // Gibraltar Pound GMD Type = "gmd" // Gambian Dalasi GNF Type = "gnf" // Guinean Franc* GTQ Type = "gtq" // Guatemalan Quetzal* GYD Type = "gyd" // Guyanese Dollar HNL Type = "hnl" // Honduran Lempira* HRK Type = "hrk" // Croatian Kuna HTG Type = "htg" // Haitian Gourde HUF Type = "huf" // Hungarian Forint* IDR Type = "idr" // Indonesian Rupiah ILS Type = "ils" // Israeli New Sheqel INR Type = "inr" // Indian Rupee* ISK Type = "isk" // Icelandic Króna JMD Type = "jmd" // Jamaican Dollar KES Type = "kes" // Kenyan Shilling KGS Type = "kgs" // Kyrgyzstani Som KHR Type = "khr" // Cambodian Riel KMF Type = "kmf" // Comorian Franc KRW Type = "krw" // South Korean Won KYD Type = "kyd" // Cayman Islands Dollar KZT Type = "kzt" // Kazakhstani Tenge LAK Type = "lak" // Lao Kip* LBP Type = "lbp" // Lebanese Pound LKR Type = "lkr" // Sri Lankan Rupee LRD Type = "lrd" // Liberian Dollar LSL Type = "lsl" // Lesotho Loti LTL Type = "ltl" // Lithuanian Litas LVL Type = "lvl" // Latvian Lats MAD Type = "mad" // Moroccan Dirham MDL Type = "mdl" // Moldovan Leu MGA Type = "mga" // Malagasy Ariary MKD Type = "mkd" // Macedonian Denar MNT Type = "mnt" // Mongolian Tögrög MOP Type = "mop" // Macanese Pataca MRO Type = "mro" // Mauritanian Ouguiya MUR Type = "mur" // Mauritian Rupee* MVR Type = "mvr" // Maldivian Rufiyaa MWK Type = "mwk" // Malawian Kwacha MXN Type = "mxn" // Mexican Peso* MYR Type = "myr" // Malaysian Ringgit MZN Type = "mzn" // Mozambican Metical NAD Type = "nad" // Namibian Dollar NGN Type = "ngn" // Nigerian Naira NIO Type = "nio" // Nicaraguan Córdoba* NOK Type = "nok" // Norwegian Krone NPR Type = "npr" // Nepalese Rupee PAB Type = "pab" // Panamanian Balboa* PEN Type = "pen" // Peruvian Nuevo Sol* PGK Type = "pgk" // Papua New Guinean Kina PHP Type = "php" // Philippine Peso PKR Type = "pkr" // Pakistani Rupee PLN Type = "pln" // Polish Złoty PYG Type = "pyg" // Paraguayan Guaraní* QAR Type = "qar" // Qatari Riyal RON Type = "ron" // Romanian Leu RSD Type = "rsd" // Serbian Dinar RUB Type = "rub" // Russian Ruble RWF Type = "rwf" // Rwandan Franc SAR Type = "sar" // Saudi Riyal SBD Type = "sbd" // Solomon Islands Dollar SCR Type = "scr" // Seychellois Rupee SEK Type = "sek" // Swedish Krona SHP Type = "shp" // Saint Helenian Pound* SLL Type = "sll" // Sierra Leonean Leone SOS Type = "sos" // Somali Shilling SRD Type = "srd" // Surinamese Dollar* STD Type = "std" // São Tomé and Príncipe Dobra SVC Type = "svc" // Salvadoran Colón* SZL Type = "szl" // Swazi Lilangeni THB Type = "thb" // Thai Baht TJS Type = "tjs" // Tajikistani Somoni TOP Type = "top" // Tongan Paʻanga TRY Type = "try" // Turkish Lira TTD Type = "ttd" // Trinidad and Tobago Dollar TWD Type = "twd" // New Taiwan Dollar TZS Type = "tzs" // Tanzanian Shilling UAH Type = "uah" // Ukrainian Hryvnia UGX Type = "ugx" // Ugandan Shilling UYU Type = "uyu" // Uruguayan Peso* UZS Type = "uzs" // Uzbekistani Som VND Type = "vnd" // Vietnamese Đồng VUV Type = "vuv" // Vanuatu Vat UWT Type = "uwt" // Samoan Tala XAF Type = "xaf" // Central African Cfa Franc XCD Type = "xcd" // East Caribbean Dollar XOF Type = "xof" // West African Cfa Franc* XPF Type = "xpf" // Cfp Franc* YER Type = "yer" // Yemeni Rial ZAR Type = "zar" // South African Rand ZMW Type = "zmw" // Zambian Kwacha // Three-decimal fiat (ISO 4217). These are real decimal places, not a // rounding convention: one Kuwaiti dinar is 1000 fils. BHD Type = "bhd" // Bahraini Dinar IQD Type = "iqd" // Iraqi Dinar JOD Type = "jod" // Jordanian Dinar KWD Type = "kwd" // Kuwaiti Dinar LYD Type = "lyd" // Libyan Dinar OMR Type = "omr" // Omani Rial TND Type = "tnd" // Tunisian Dinar // Crypto. The minor unit is the chain's own smallest indivisible unit — // satoshi, wei, lamport, nanoton — not a two-decimal fiat convention. BTC Type = "btc" // Bitcoin, 8 (satoshi) XBT Type = "xbt" // Bitcoin, ISO-style code BCH Type = "bch" // Bitcoin Cash, 8 LTC Type = "ltc" // Litecoin, 8 DOGE Type = "doge" // Dogecoin, 8 SOL Type = "sol" // Solana, 9 (lamport) TON Type = "ton" // Toncoin, 9 (nanoton) XRP Type = "xrp" // XRP, 6 (drop) USDC Type = "usdc" // USD Coin, 6 USDT Type = "usdt" // Tether, 6 ETH Type = "eth" // Ethereum, 18 (wei) MATIC Type = "matic" // Polygon, 18 AVAX Type = "avax" // Avalanche, 18 SHIB Type = "shib" // Shiba Inu, 18 // Own chains. EVM-native, so 18 like any other EVM gas token. LUX Type = "lux" // Lux C-Chain, 18 (X/P-Chain LUX is 9 — see decimals) ZOO Type = "zoo" // Zoo, 18 AI Type = "ai" // Hanzo native gas, 18 HANZO Type = "hanzo" // Hanzo, alias of AI SPC Type = "spc" // Sparkle Pony, 18 PARS Type = "pars" // Pars Network, 18 HUSD Type = "husd" // Hanzo USD, 18 PNT Type = "points" // points, 0 — a point is indivisible )
func (Type) Amount ¶ added in v1.49.48
Amount lifts a minor-unit amount in this currency into an exact money.Amount.
This is the ONE conversion out of Cents, and every rendering hangs off it: .MajorString() for a decimal string on the wire, .Display() for a human, .AsMajorUnits() for the last inch of a third-party API whose schema demands a JSON number. commerce owns no arithmetic of its own here — money does, on a big.Int, so no rendering can lose a cent or invent one.
func (Type) Decimals ¶ added in v1.49.48
Decimals is how many fractional digits the currency's minor unit has. This is the ONE place that scale is decided; nothing else may hardcode a 100.
func (Type) FitsCents ¶ added in v1.49.59
FitsCents reports whether this currency's minor units fit the int64 that Cents is. They do not for an 18-decimal token: one ETH is 1e18 wei and an int64 tops out at 9.2e18, so Cents cannot hold ten of them. Those amounts have to travel as money.Amount, which is arbitrary-precision.
func (Type) IsZeroDecimal ¶
Does the currency not have a decimal convention such as Japanese Yen (¥100) instead of USD ($1.00)
func (Type) MinimalUnitFactor ¶
Since pricing things in a crypto minimal denomination exceed int64 and the minimal domination is worth so little, we generally use a larger denomination of the currency by convention that can capture the minimal relatable values.
This returns the ratio of convention denomination to minimal denomination
func (Type) Money ¶ added in v1.49.48
Money lifts this currency into github.com/hanzoai/money — the ONE bridge between commerce's currency table and the package that owns exact money.
func (Type) Parse ¶ added in v1.49.52
Parse is the inverse of ToStringNoSymbol: it reads a decimal string in this currency's major unit and returns exact minor units.
It exists so an amount that arrives as a DECIMAL never has to pass through a float64 to become Cents. "19.99" has no exact binary representation, so Cents(f*100) on a parsed float yields 1998 — a cent lost, on money that was already captured. The scale comes from this package's own currency table rather than money's registry, which knows 29 of the 142 currencies here.
func (Type) ParseAmount ¶ added in v1.49.59
ParseAmount reads a decimal string of MAJOR units into an exact amount at this currency's own scale, with no int64 anywhere on the path.
This is the conversion to reach for when the currency might be an 18-decimal token: one ETH is 1e18 wei, so Parse (which returns Cents, an int64) can only carry nine of them before it overflows. money.Amount is arbitrary-precision — a big.Int underneath — so it holds a wei and a whale balance alike.
func (Type) ToStringNoSymbol ¶
ToStringNoSymbol renders the amount as a plain fixed-scale decimal string ("10.99", "500" for a zero-decimal currency, "-19.99" for a refund).