Passed
Push — main ( 70cf55...dfec68 )
by Michael
03:58
created

StripePaymentProvider::updatePaymentIntent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 1
eloc 7
c 3
b 0
f 0
nc 1
nop 4
dl 0
loc 14
ccs 6
cts 6
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace MichaelRubel\StripeIntegration\Providers;
6
7
use Illuminate\Database\Eloquent\Model;
8
use Illuminate\Support\Collection;
9
use Illuminate\Support\Traits\Macroable;
10
use Laravel\Cashier\Exceptions\IncompletePayment;
11
use Laravel\Cashier\Payment;
12
use Laravel\Cashier\PaymentMethod as CashierPaymentMethod;
13
use MichaelRubel\StripeIntegration\DataTransferObjects\OffsessionChargeData;
14
use MichaelRubel\StripeIntegration\DataTransferObjects\StripeChargeData;
15
use MichaelRubel\StripeIntegration\Decorators\StripePaymentAmount;
16
use MichaelRubel\StripeIntegration\Providers\Contracts\PaymentProviderContract;
17
use Money\Currency;
18
use Stripe\Customer;
19
use Stripe\Exception\ApiErrorException;
20
use Stripe\PaymentIntent;
21
use Stripe\PaymentMethod;
22
use Stripe\SetupIntent;
23
use Stripe\StripeClient;
24
25
class StripePaymentProvider implements PaymentProviderContract
26
{
27
    use Macroable;
0 ignored issues
show
Bug introduced by
The trait Illuminate\Support\Traits\Macroable requires the property $name which is not provided by MichaelRubel\StripeInteg...s\StripePaymentProvider.
Loading history...
28
29
    /**
30
     * @return void
31
     */
32 14
    public function __construct(
33
        protected StripeClient $stripeClient
34
    ) {
35
    }
36
37
    /**
38
     * Set the Cashier's currency.
39
     *
40
     * @param Currency $currency
41
     *
42
     * @return void
43
     */
44 1
    public function configureCashierCurrency(Currency $currency): void
45
    {
46 1
        config([
47 1
            'cashier.currency' => $currency->getCode(),
48
        ]);
49
    }
50
51
    /**
52
     * Create the Stripe setup intent.
53
     *
54
     * @param Model $model
55
     * @param array $options
56
     *
57
     * @return SetupIntent
58
     */
59 1
    public function setupIntentUsing(Model $model, array $options = []): SetupIntent
60
    {
61 1
        $options = collect([
0 ignored issues
show
Bug introduced by
array('usage' => 'off_session') of type array<string,string> is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $value of collect(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

61
        $options = collect(/** @scrutinizer ignore-type */ [
Loading history...
62
            'usage' => 'off_session',
63 1
        ])->merge($options)->toArray();
0 ignored issues
show
Bug introduced by
$options of type array is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $items of Illuminate\Support\Collection::merge(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

63
        ])->merge(/** @scrutinizer ignore-type */ $options)->toArray();
Loading history...
64
65 1
        return call($model)->createSetupIntent($options);
66
    }
67
68
    /**
69
     * Prepare the customer to work with the payment system.
70
     *
71
     * @param Model $model
72
     *
73
     * @return Customer
74
     */
75 3
    public function prepareCustomer(Model $model): Customer
76
    {
77 3
        return call($model)->createOrGetStripeCustomer();
78
    }
79
80
    /**
81
     * Update the default payment method for model.
82
     *
83
     * @param Model                $model
84
     * @param PaymentMethod|string $paymentMethod
85
     *
86
     * @return CashierPaymentMethod
87
     */
88 3
    public function updatePaymentMethod(Model $model, PaymentMethod|string $paymentMethod): CashierPaymentMethod
89
    {
90 3
        return call($model)->updateDefaultPaymentMethod($paymentMethod);
91
    }
92
93
    /**
94
     * Attach the payment method to the customer.
95
     *
96
     * @param PaymentMethod|CashierPaymentMethod $paymentMethod
97
     * @param Customer                           $customer
98
     * @param array                              $params
99
     * @param array                              $options
100
     *
101
     * @return PaymentMethod
102
     */
103 3
    public function attachPaymentMethodToCustomer(
104
        PaymentMethod|CashierPaymentMethod $paymentMethod,
105
        Customer $customer,
106
        array $params = [],
107
        array $options = []
108
    ): PaymentMethod {
109 3
        $params = collect([
0 ignored issues
show
Bug introduced by
array('customer' => $customer->id) of type array<string,string> is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $value of collect(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

109
        $params = collect(/** @scrutinizer ignore-type */ [
Loading history...
110 3
            'customer' => $customer->id,
111 3
        ])->merge($params)->toArray();
0 ignored issues
show
Bug introduced by
$params of type array is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $items of Illuminate\Support\Collection::merge(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

111
        ])->merge(/** @scrutinizer ignore-type */ $params)->toArray();
Loading history...
112
113 3
        return call($this->stripeClient->paymentMethods)->attach(
114 3
            $paymentMethod->id,
115
            $params,
116
            $options
117
        );
118
    }
119
120
    /**
121
     * Perform a simple charge.
122
     *
123
     * @param StripeChargeData $data
124
     *
125
     * @return Payment
126
     * @throws IncompletePayment
127
     */
128 1
    public function charge(StripeChargeData $data): Payment
129
    {
130 1
        return call($data->model)->charge(
131 1
            $data->payment_amount->getAmount(),
132 1
            $data->payment_method->id,
133 1
            $data->options
134
        );
135
    }
136
137
    /**
138
     * Create a payment intent.
139
     *
140
     * @param StripePaymentAmount $paymentAmount
141
     * @param Model               $model
142
     * @param array               $params
143
     * @param array               $options
144
     *
145
     * @return PaymentIntent
146
     */
147 2
    public function createPaymentIntent(
148
        StripePaymentAmount $paymentAmount,
149
        Model $model,
150
        array $params = [],
151
        array $options = []
152
    ): PaymentIntent {
153 2
        return call($this->stripeClient->paymentIntents)->create(
154 2
            collect([
0 ignored issues
show
Bug introduced by
array('amount' => $payme...ypes' => array('card')) of type array<string,array<integ...string>|integer|string> is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $value of collect(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

154
            collect(/** @scrutinizer ignore-type */ [
Loading history...
155 2
                'amount'               => $paymentAmount->getAmount(),
156 2
                'currency'             => $paymentAmount->getCurrency()->getCode(),
157
                'payment_method_types' => ['card'],
158
            ])
159 2
            ->when($model->stripeId(), fn ($params) => $params->merge([
160
                'customer' => $model->stripeId(),
161
            ]))
162 2
            ->merge($params)
0 ignored issues
show
Bug introduced by
$params of type array is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $items of Illuminate\Support\Collection::merge(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

162
            ->merge(/** @scrutinizer ignore-type */ $params)
Loading history...
163 2
            ->toArray(),
164
            $options
165
        );
166
    }
167
168
    /**
169
     * Update the payment intent.
170
     *
171
     * @param string $intentId
172
     * @param Model  $model
173
     * @param array  $params
174
     * @param array  $options
175
     *
176
     * @return PaymentIntent
177
     *
178
     */
179 1
    public function updatePaymentIntent(
180
        string $intentId,
181
        Model $model,
182
        array $params = [],
183
        array $options = []
184
    ): PaymentIntent {
185 1
        return call($this->stripeClient->paymentIntents)->update(
186
            $intentId,
187 1
            collect($params)
0 ignored issues
show
Bug introduced by
$params of type array is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $value of collect(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

187
            collect(/** @scrutinizer ignore-type */ $params)
Loading history...
188 1
                ->when($model->stripeId(), fn ($params) => $params->merge([
189 1
                    'customer' => $model->stripeId(),
190
                ]))
191 1
                ->toArray(),
192
            $options
193
        );
194
    }
195
196
    /**
197
     * Retrieve the payment intent.
198
     *
199
     * @param string $intent_id
200
     * @param array  $params
201
     * @param array  $options
202
     *
203
     * @return PaymentIntent
204
     *
205
     * @throws ApiErrorException
206
     */
207 1
    public function retrievePaymentIntent(string $intent_id, array $params = [], array $options = []): PaymentIntent
208
    {
209 1
        return call($this->stripeClient->paymentIntents)->retrieve(
210
            $intent_id,
211
            $params,
212
            $options
213
        );
214
    }
215
216
    /**
217
     * Confirm the payment intent.
218
     *
219
     * @param PaymentIntent $paymentIntent
220
     * @param array         $confirmation_params
221
     * @param array         $confirmation_options
222
     *
223
     * @return PaymentIntent
224
     */
225 2
    public function confirmPaymentIntent(
226
        PaymentIntent $paymentIntent,
227
        array $confirmation_params = [],
228
        array $confirmation_options = []
229
    ): PaymentIntent {
230 2
        return call($this->stripeClient->paymentIntents)->confirm(
231 2
            $paymentIntent->id,
232
            $confirmation_params,
233
            $confirmation_options
234
        );
235
    }
236
237
    /**
238
     * Perform an offsession charge.
239
     *
240
     * @param OffsessionChargeData $data
241
     *
242
     * @return PaymentIntent
243
     * @throws ApiErrorException
244
     */
245 1
    public function offsessionCharge(OffsessionChargeData $data): PaymentIntent
246
    {
247 1
        $paymentIntent = $this->createPaymentIntent(
248 1
            $data->payment_amount,
249 1
            $data->model
250
        );
251
252 1
        $confirmation_params = collect([
0 ignored issues
show
Bug introduced by
array('payment_method' =...ultPaymentMethod()->id) of type array is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $value of collect(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

252
        $confirmation_params = collect(/** @scrutinizer ignore-type */ [
Loading history...
253 1
            'payment_method' => call($data->model)->defaultPaymentMethod()->id,
254 1
        ])->merge($data->confirmation_params)->toArray();
0 ignored issues
show
Bug introduced by
$data->confirmation_params of type array is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $items of Illuminate\Support\Collection::merge(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

254
        ])->merge(/** @scrutinizer ignore-type */ $data->confirmation_params)->toArray();
Loading history...
255
256 1
        return $this->confirmPaymentIntent(
257
            $paymentIntent,
258
            $confirmation_params,
259 1
            $data->confirmation_options
260
        );
261
    }
262
}
263