PluginProbe
The Innovative Form Builder – IvyForms / 1.5.1
The Innovative Form Builder – IvyForms v1.5.1
1.5.1 1.5 1.4.1 1.4 trunk 0.1.2 0.2 0.2.1 0.3 0.3.1 0.4 0.5 0.6 0.6.1 0.6.1-backup 0.6.1.1 0.7 0.8 0.8.1 0.8.2 0.9 0.9.1 1.0 1.1 1.1.1 All 27 releases
ivyforms / backend / src / Services / Payment / MoneyMinorUnits.php

MoneyMinorUnits.php in The Innovative Form Builder – IvyForms 1.5.1, at backend/src/Services/Payment/MoneyMinorUnits.php

96 lines 2.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace IvyForms\Services\Payment;
4
5 /**
6 * Currency-aware conversion between major units and integer minor units.
7 *
8 * Do not use for parsing form money strings — that is MoneyParser's job.
9 */
10 final class MoneyMinorUnits
11 {
12 /**
13 * ISO currencies that use zero decimal places (amount already in minor units as whole numbers).
14 *
15 * @see https://docs.stripe.com/currencies#zero-decimal
16 *
17 * @var list<string>
18 */
19 private const ZERO_DECIMAL = [
20 'BIF', 'CLP', 'DJF', 'GNF', 'JPY', 'KMF', 'KRW', 'MGA',
21 'PYG', 'RWF', 'UGX', 'VND', 'VUV', 'XAF', 'XOF', 'XPF',
22 ];
23
24 /**
25 * PayPal rejects decimal `value` strings for these codes (JPY already in ZERO_DECIMAL).
26 *
27 * @see https://developer.paypal.com/api/rest/reference/currency-codes/
28 *
29 * @var list<string>
30 */
31 private const PAYPAL_ZERO_DECIMAL = ['HUF', 'TWD'];
32
33 /**
34 * Convert a major-unit amount to the integer minor units for the currency.
35 */
36 public static function toMinor(float $amount, string $currency): int
37 {
38 $code = strtoupper(trim($currency));
39
40 if (in_array($code, self::ZERO_DECIMAL, true)) {
41 return (int) round($amount);
42 }
43
44 return (int) round($amount * 100);
45 }
46
47 /**
48 * Convert integer minor units back to a major-unit float for persistence/display.
49 */
50 public static function fromMinor(int $minor, string $currency): float
51 {
52 $code = strtoupper(trim($currency));
53
54 if (in_array($code, self::ZERO_DECIMAL, true)) {
55 return (float) $minor;
56 }
57
58 return $minor / 100;
59 }
60
61 /**
62 * Format a major-unit amount for PayPal Orders (`value` string).
63 */
64 public static function formatMajor(float $amount, string $currency): string
65 {
66 $code = strtoupper(trim($currency));
67
68 if (
69 in_array($code, self::ZERO_DECIMAL, true)
70 || in_array($code, self::PAYPAL_ZERO_DECIMAL, true)
71 ) {
72 return (string) (int) round($amount);
73 }
74
75 return number_format($amount, 2, '.', '');
76 }
77
78 /**
79 * Lowest charge we will send to a processor (minor units).
80 *
81 * Matches the common card-network floor (~0.50 in two-decimal currencies)
82 * so $0.01 card-testing charges are rejected before they hit the gateway.
83 */
84 public static function minimumChargeMinor(string $currency): int
85 {
86 unset($currency);
87
88 return 50;
89 }
90
91 public static function isChargeable(float $amount, string $currency): bool
92 {
93 return self::toMinor($amount, $currency) >= self::minimumChargeMinor($currency);
94 }
95 }
96