-
Notifications
You must be signed in to change notification settings - Fork 8
/
Method.php
174 lines (166 loc) · 6.82 KB
/
Method.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
<?php
namespace Dfe\Stripe;
use Df\Payment\Token;
use Df\StripeClone\Facade\Customer as fCustomer;
use Dfe\Stripe\Facade\Card;
use Dfe\Stripe\Facade\Token as fToken;
use Magento\Sales\Model\Order\Payment\Transaction as T;
use \Throwable as Th; # 2023-08-02 "Treat `\Throwable` similar to `\Exception`": https://github.com/mage2pro/core/issues/311
/**
* 2020-01-22
* «Class Stripe\Error\Base does not exist»: https://github.com/mage2pro/stripe/issues/86
* https://github.com/stripe/stripe-php/blob/v5.3.0/lib/Error/Base.php
* The \Stripe\Error\Base class has been deleted from `stripe/stripe-php` since 7.0.0.
*/
use Stripe\Exception\ApiErrorException as lException;
/** @method Settings s() */
final class Method extends \Df\StripeClone\Method {
/**
* 2016-03-08
* @override
* @see \Df\Payment\Method::canCapturePartial()
*/
function canCapturePartial():bool {return true;}
/**
* 2017-10-12 It will be null for non-card payments (such payments are not implemented yet).
* @used-by \Dfe\Stripe\Currency::_iso3()
* @return string|null
*/
function cardType() {return dfc($this, function() {/** @var string $r */
if (
!($r = $this->iia(self::$II_CARD_TYPE))
&& ($token = Token::get($this->ii(), false))
&& fToken::isCard($token)
&& ($customerId = df_ci_get($this))
) {
/**
* 2017-10-12
* A payment with a previously used card case.
* In this case we can detect the type of the previously used card
* by an additional Stripe API request:
* https://stripe.com/docs/api#retrieve_customer
* @see \Dfe\Stripe\Facade\Customer::cardsData()
* $token will be `null` in the non-payment scenarios.
* 2017-11-12
* The Stripe's API does not have a simple retrieve() method for a card like for a source.
* So our retrieval code is more complex.
* @var string|null $token
*/
$fc = fCustomer::s($this); /** @var FCustomer $fc */
$this->s()->init();
if ($customer = $fc->get($customerId) /** @var object|null $customer */) {
/** @var Card|null $card */
if ($card = df_find(function(Card $card) use($token) {return
$token === $card->id()
;}, $fc->cards($customer))) {
$r = $card->brand();
}
}
}
return $r;
});}
/**
* 2016-11-13
* https://stripe.com/docs/api/php#create_charge-amount
* https://support.stripe.com/questions/which-zero-decimal-currencies-does-stripe-support
* @override
* @see \Df\Payment\Method::amountFactorTable()
* @used-by \Df\Payment\Method::amountFactor()
* @return array(int => string)
*/
protected function amountFactorTable():array {return [
1 => 'BIF,CLP,DJF,GNF,JPY,KMF,KRW,MGA,PYG,RWF,VND,VUV,XAF,XOF,XPF'
];}
/**
* 2017-02-08
* @override
* The result should be in the basic monetary unit (like dollars), not in fractions (like cents).
*
* [Stripe] What are the minimum and maximum amount limitations on a single payment?
* https://mage2.pro/t/2689
*
* 1) «What is the minimum amount I can charge with Stripe?»
* https://support.stripe.com/questions/what-is-the-minimum-amount-i-can-charge-with-stripe
*
* 2) «What is the maximum amount I can charge with Stripe?»
* https://support.stripe.com/questions/what-is-the-maximum-amount-i-can-charge-with-stripe
* «Regardless of the currency, there is a technical limitation of 8 digits
* (e.g. $999,999.99, or ¥99,999,999), though we don’t impose any other limitations atop that.»
* @see \Df\Payment\Method::amountLimits()
* @used-by \Df\Payment\Method::isAvailable()
*/
protected function amountLimits():\Closure {return function($c) {return [
$this->minimumAmount($c), $this->amountParse(99999999)
];};}
/**
* 2016-12-28
* @override
* @see \Df\Payment\Method::convertException()
* @used-by \Df\Payment\Method::action()
* @param Th|lException $th
*/
protected function convertException(Th $th):Th {return $th instanceof lException ? new Exception($th) : $th;}
/**
* 2017-10-12
* @override
* @see \Df\StripeClone\Method::iiaKeys()
* @used-by \Df\Payment\Method::assignData()
* @return string[]
*/
protected function iiaKeys():array {return array_merge(parent::iiaKeys(), [self::$II_CARD_TYPE]);}
/**
* 2016-12-26
* Хотя Stripe использует для страниц транзакций адреса вида
* https://dashboard.stripe.com/test/payments/<id>
* адрес без части «test» также успешно работает (даже в тестовом режиме).
* Использую именно такие адреса, потому что я не знаю,
* какова часть вместо «test» в промышленном режиме.
* @override
* @see \Df\StripeClone\Method::transUrlBase()
* @used-by \Df\StripeClone\Method::transUrl()
*/
protected function transUrlBase(T $t):string {return 'https://dashboard.stripe.com/' . (
fToken::isPreviouslyUsedOrTrimmedSource($t->getTxnId()) ? 'sources' : 'payments'
);}
/**
* 2017-02-08
* The result should be in the basic monetary unit (like dollars), not in fractions (like cents).
* «If your business is based in the United States and only processes payments in US dollars,
* then it’s pretty straightforward.
* In order to make sure each charge covers the necessary fees
* and you don’t end up losing money on the transaction,
* we require a minimum of $0.50 for each charge.
*
* If your business is based in the United States and you process payments in other currencies,
* then the minimum will be the equivalent of $0.50 after the charge is converted to US dollars.»
* https://support.stripe.com/questions/what-is-the-minimum-amount-i-can-charge-with-stripe#businesses-in-the-united-states
*
* «For businesses that are not based in the United States,
* the minimum charge depends on the currency for your bank account.
*
* Charges that are made in the same currency as your bank account
* will have the minimum shown in the list below.
* Charges that are made in other currencies will have the equivalent minimum
* after the charge is converted to your bank account’s currency.»
*
* https://support.stripe.com/questions/what-is-the-minimum-amount-i-can-charge-with-stripe#but-what-if-my-business-isnt-based-in-the-united-states
*
* 2017-04-15
* The «USD» currency could be not set up in the store,
* so use @uses df_currency_convert_safe() to get rid from a failure like «Undefined rate from "AUD-USD"».
*
* @used-by self::amountLimits()
*/
private function minimumAmount(string $c):float {return
$this->s()->isMerchantInUS() ? df_currency_convert_safe(.5, 'USD', $c) : dfa([
'AUD' => .5, 'CAD' => .5, 'CHF' => .5, 'DKK' => 2.5, 'EUR' => .5, 'GBP' => .3
,'HKD' => 4, 'JPY' => 50, 'MXN' => 10, 'NOK' => 3, 'SEK' => 3, 'SGD' => .5, 'USD' => .5
], $c, .5)
;}
/**
* 2017-10-12
* @used-by self::cardType()
* @used-by self::iiaKeys()
*/
private static $II_CARD_TYPE = 'cardType';
}