Passed
Push — main ( 4a71ae...5b4805 )
by Michael
11:45 queued 08:20
created

StripePaymentProvider::confirmPaymentIntent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 4
ccs 3
cts 3
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\Traits\Macroable;
9
use Laravel\Cashier\Exceptions\IncompletePayment;
10
use Laravel\Cashier\Payment;
11
use Laravel\Cashier\PaymentMethod as CashierPaymentMethod;
12
use MichaelRubel\StripeIntegration\DataTransferObjects\OffsessionChargeData;
13
use MichaelRubel\StripeIntegration\DataTransferObjects\PaymentIntentData;
14
use MichaelRubel\StripeIntegration\DataTransferObjects\PaymentMethodAttachmentData;
15
use MichaelRubel\StripeIntegration\DataTransferObjects\StripeChargeData;
16
use MichaelRubel\StripeIntegration\Providers\Contracts\PaymentProviderContract;
17
use Money\Currency;
18
use Spatie\DataTransferObject\Exceptions\UnknownProperties;
19
use Stripe\Customer;
20
use Stripe\Exception\ApiErrorException;
21
use Stripe\PaymentIntent;
22
use Stripe\PaymentMethod;
23
use Stripe\SetupIntent;
24
use Stripe\StripeClient;
25
26
class StripePaymentProvider implements PaymentProviderContract
27
{
28
    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...
29
30
    /**
31
     * @return void
32
     */
33 14
    public function __construct(
34
        protected StripeClient $stripeClient
35
    ) {
36
    }
37
38
    /**
39
     * Set the Cashier's currency.
40
     *
41
     * @param  Currency  $currency
42
     *
43
     * @return void
44
     */
45 1
    public function setCashierCurrency(Currency $currency): void
46
    {
47 1
        config([
48 1
            'cashier.currency' => $currency->getCode(),
49
        ]);
50
    }
51
52
    /**
53
     * Create the Stripe setup intent.
54
     *
55
     * @param  Model  $model
56
     * @param  array  $options
57
     *
58
     * @return SetupIntent
59
     */
60 1
    public function setupIntentUsing(Model $model, array $options = []): SetupIntent
61
    {
62 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

62
        $options = collect(/** @scrutinizer ignore-type */ [
Loading history...
63
            'usage' => 'off_session',
64 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

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

103
        $params = collect(/** @scrutinizer ignore-type */ ['customer' => $data->customer->id])
Loading history...
104 3
            ->merge($data->params)
0 ignored issues
show
Bug introduced by
$data->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

104
            ->merge(/** @scrutinizer ignore-type */ $data->params)
Loading history...
105 3
            ->toArray();
106
107 3
        return call($this->stripeClient->paymentMethods)->attach(
108 3
            $data->paymentMethod->id, $params, $data->options
109
        );
110
    }
111
112
    /**
113
     * Perform a simple charge.
114
     *
115
     * @param  StripeChargeData  $data
116
     *
117
     * @return Payment
118
     * @throws IncompletePayment
119
     */
120 1
    public function charge(StripeChargeData $data): Payment
121
    {
122 1
        return call($data->model)->charge(
123 1
            $data->payment_amount->getAmount(),
124 1
            $data->payment_method->id,
125 1
            $data->options
126
        );
127
    }
128
129
    /**
130
     * Create a payment intent.
131
     *
132
     * @param  PaymentIntentData  $data
133
     *
134
     * @return PaymentIntent
135
     */
136 2
    public function createPaymentIntent(PaymentIntentData $data): PaymentIntent
137
    {
138 2
        $makeIntentParams = collect([
0 ignored issues
show
Bug introduced by
array('amount' => $data-...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

138
        $makeIntentParams = collect(/** @scrutinizer ignore-type */ [
Loading history...
139 2
            'amount' => $data->paymentAmount?->getAmount(),
140 2
            'currency' => $data->paymentAmount?->getCurrency()->getCode(),
141
            'payment_method_types' => ['card'],
142
        ])
143 2
        ->when($data->model?->stripeId(), fn ($params) => $params->merge([
144 1
            'customer' => $data->model?->stripeId(),
145
        ]))
146 2
        ->merge($data->params)
0 ignored issues
show
Bug introduced by
$data->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

146
        ->merge(/** @scrutinizer ignore-type */ $data->params)
Loading history...
147 2
        ->toArray();
148
149 2
        return call($this->stripeClient->paymentIntents)->create($makeIntentParams, $data->options);
150
    }
151
152
    /**
153
     * Update the payment intent.
154
     *
155
     * @param  PaymentIntentData  $data
156
     *
157
     * @return PaymentIntent
158
     */
159 1
    public function updatePaymentIntent(PaymentIntentData $data): PaymentIntent
160
    {
161 1
        $updateIntentParams = collect($data->params)
0 ignored issues
show
Bug introduced by
$data->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

161
        $updateIntentParams = collect(/** @scrutinizer ignore-type */ $data->params)
Loading history...
162 1
            ->when($data->model?->stripeId(), fn ($params) => $params->merge([
163 1
                'customer' => $data->model?->stripeId(),
164
            ]))
165 1
            ->toArray();
166
167 1
        return call($this->stripeClient->paymentIntents)->update(
168 1
            $data->intentId, $updateIntentParams, $data->options
169
        );
170
    }
171
172
    /**
173
     * Retrieve the payment intent.
174
     *
175
     * @param  PaymentIntentData  $data
176
     *
177
     * @return PaymentIntent
178
     */
179 1
    public function retrievePaymentIntent(PaymentIntentData $data): PaymentIntent
180
    {
181 1
        return call($this->stripeClient->paymentIntents)->retrieve(
182 1
            $data->intentId, $data->params, $data->options
183
        );
184
    }
185
186
    /**
187
     * Confirm the payment intent.
188
     *
189
     * @param  PaymentIntentData  $data
190
     *
191
     * @return PaymentIntent
192
     */
193 2
    public function confirmPaymentIntent(PaymentIntentData $data): PaymentIntent
194
    {
195 2
        return call($this->stripeClient->paymentIntents)->confirm(
196 2
            $data->paymentIntent?->id, $data->params, $data->options
197
        );
198
    }
199
200
    /**
201
     * Perform an offsession charge.
202
     *
203
     * @param  OffsessionChargeData  $data
204
     *
205
     * @return PaymentIntent
206
     * @throws ApiErrorException|UnknownProperties
207
     */
208 1
    public function offsessionCharge(OffsessionChargeData $data): PaymentIntent
209
    {
210 1
        $paymentIntent = $this->createPaymentIntent(new PaymentIntentData(
211 1
            paymentAmount: $data->payment_amount,
212 1
            model: $data->model,
213
        ));
214
215 1
        $confirmation_params = collect(['payment_method' => call($data->model)->defaultPaymentMethod()->id])
216 1
            ->merge($data->confirmation_params)
217 1
            ->toArray();
218
219 1
        return $this->confirmPaymentIntent(new PaymentIntentData(
220
            paymentIntent: $paymentIntent,
221
            params: $confirmation_params,
222 1
            options: $data->confirmation_options,
223
        ));
224
    }
225
}
226