Completed
Push — master ( f889a9...4a0b03 )
by Raza
06:07 queued 04:05
created

ExpressCheckout::setShippingDiscount()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 8
rs 9.4285
cc 2
eloc 4
nc 2
nop 1
1
<?php
2
3
namespace Srmklive\PayPal\Services;
4
5
use Illuminate\Support\Collection;
6
use Srmklive\PayPal\Traits\PayPalRequest as PayPalAPIRequest;
7
use Srmklive\PayPal\Traits\PayPalTransactions;
8
use Srmklive\PayPal\Traits\RecurringProfiles;
9
10
class ExpressCheckout
11
{
12
    // Integrate PayPal Request trait
13
    use PayPalAPIRequest, PayPalTransactions, RecurringProfiles;
14
15
    /**
16
     * ExpressCheckout constructor.
17
     *
18
     * @param array $config
19
     *
20
     * @throws \Exception
21
     */
22
    public function __construct(array $config = [])
23
    {
24
        // Setting PayPal API Credentials
25
        $this->setConfig($config);
26
27
        $this->httpBodyParam = 'form_params';
28
29
        $this->options = [];
30
    }
31
32
    /**
33
     * Set ExpressCheckout API endpoints & options.
34
     *
35
     * @param array $credentials
36
     *
37
     * @return void
38
     */
39
    public function setExpressCheckoutOptions($credentials)
40
    {
41
        // Setting API Endpoints
42
        if ($this->mode === 'sandbox') {
43
            $this->config['api_url'] = !empty($this->config['secret']) ?
44
                'https://api-3t.sandbox.paypal.com/nvp' : 'https://api.sandbox.paypal.com/nvp';
45
46
            $this->config['gateway_url'] = 'https://www.sandbox.paypal.com';
47
        } else {
48
            $this->config['api_url'] = !empty($this->config['secret']) ?
49
                'https://api-3t.paypal.com/nvp' : 'https://api.paypal.com/nvp';
50
51
            $this->config['gateway_url'] = 'https://www.paypal.com';
52
        }
53
54
        // Adding params outside sandbox / live array
55
        $this->config['payment_action'] = $credentials['payment_action'];
56
        $this->config['notify_url'] = $credentials['notify_url'];
57
        $this->config['locale'] = $credentials['locale'];
58
    }
59
60
    /**
61
     * Set cart item details for PayPal.
62
     *
63
     * @param array $items
64
     *
65
     * @return \Illuminate\Support\Collection
66
     */
67
    protected function setCartItems($items)
68
    {
69
        return (new Collection($items))->map(function ($item, $num) {
70
            return [
71
                'L_PAYMENTREQUEST_0_NAME'.$num => $item['name'],
72
                'L_PAYMENTREQUEST_0_AMT'.$num  => $item['price'],
73
                'L_PAYMENTREQUEST_0_QTY'.$num  => isset($item['qty']) ? $item['qty'] : 1,
74
            ];
75
        })->flatMap(function ($value) {
76
            return $value;
77
        });
78
    }
79
80
    /**
81
     * Set Recurring payments details for SetExpressCheckout API call.
82
     *
83
     * @param array $data
84
     * @param bool  $subscription
85
     */
86
    protected function setExpressCheckoutRecurringPaymentConfig($data, $subscription = false)
87
    {
88
        $billingType = $this->billingType;
89
90
        // Overwrite billing type if $subscription flag is enabled
91
        if ($subscription) {
92
            $billingType = 'RecurringPayments';
93
        }
94
95
        // Send L_BILLINGTYPE0 and L_BILLINGAGREEMENTDESCRIPTION0 only if there is billing type
96
        if (isset($billingType)) {
97
            $this->post = $this->post->merge([
98
                'L_BILLINGTYPE0' => $billingType,
99
                'L_BILLINGAGREEMENTDESCRIPTION0' => !empty($data['subscription_desc']) ?
100
                    $data['subscription_desc'] : $data['invoice_description'],
101
            ]);
102
        }
103
    }
104
105
    /**
106
     * Set item subtotal if available.
107
     *
108
     * @param array $data
109
     */
110
    protected function setItemSubTotal($data)
111
    {
112
        $this->subtotal = isset($data['subtotal']) ? $data['subtotal'] : $data['total'];
113
    }
114
115
    /**
116
     * Set shipping amount if available.
117
     *
118
     * @param array $data
119
     */
120
    protected function setShippingAmount($data)
121
    {
122
        if (isset($data['shipping'])) {
123
            $this->post = $this->post->merge([
124
                'PAYMENTREQUEST_0_SHIPPINGAMT' => $data['shipping'],
125
            ]);
126
        }
127
    }
128
    
129
    /**
130
     * Set shipping discount if available.
131
     *
132
     * @param array $data
133
     */
134
    protected function setShippingDiscount($data)
135
    {
136
        if (isset($data['shipping_discount'])) {
137
            $this->post = $this->post->merge([
138
                'PAYMENTREQUEST_0_SHIPDISCAMT' => $data['shipping_discount'] * -1,
139
            ]);
140
        }
141
    }
142
143
    /**
144
     * Perform a SetExpressCheckout API call on PayPal.
145
     *
146
     * @param array $data
147
     * @param bool  $subscription
148
     *
149
     * @throws \Exception
150
     *
151
     * @return array|\Psr\Http\Message\StreamInterface
152
     */
153
    public function setExpressCheckout($data, $subscription = false)
154
    {
155
        $this->setItemSubTotal($data);
156
157
        $this->post = $this->setCartItems($data['items'])->merge([
158
            'PAYMENTREQUEST_0_ITEMAMT'       => $this->subtotal,
159
            'PAYMENTREQUEST_0_AMT'           => $data['total'],
160
            'PAYMENTREQUEST_0_PAYMENTACTION' => $this->paymentAction,
161
            'PAYMENTREQUEST_0_CURRENCYCODE'  => $this->currency,
162
            'PAYMENTREQUEST_0_DESC'          => $data['invoice_description'],
163
            'PAYMENTREQUEST_0_INVNUM'        => $data['invoice_id'],
164
            'NOSHIPPING'                     => 1,
165
            'RETURNURL'                      => $data['return_url'],
166
            'CANCELURL'                      => $data['cancel_url'],
167
            'LOCALE'                         => $this->locale,
168
        ]);
169
170
        $this->setShippingAmount($data);
171
        
172
        $this->setShippingDiscount($data);
173
174
        $this->setExpressCheckoutRecurringPaymentConfig($data, $subscription);
175
176
        $response = $this->doPayPalRequest('SetExpressCheckout');
177
178
        return collect($response)->merge([
179
            'paypal_link' => !empty($response['TOKEN']) ? $this->config['gateway_url'].'/webscr?cmd=_express-checkout&token='.$response['TOKEN'] : null,
180
        ])->toArray();
181
    }
182
183
    /**
184
     * Perform a GetExpressCheckoutDetails API call on PayPal.
185
     *
186
     * @param string $token
187
     *
188
     * @throws \Exception
189
     *
190
     * @return array|\Psr\Http\Message\StreamInterface
191
     */
192
    public function getExpressCheckoutDetails($token)
193
    {
194
        $this->setRequestData([
195
            'TOKEN' => $token,
196
        ]);
197
198
        return $this->doPayPalRequest('GetExpressCheckoutDetails');
199
    }
200
201
    /**
202
     * Perform DoExpressCheckoutPayment API call on PayPal.
203
     *
204
     * @param array  $data
205
     * @param string $token
206
     * @param string $payerid
207
     *
208
     * @throws \Exception
209
     *
210
     * @return array|\Psr\Http\Message\StreamInterface
211
     */
212
    public function doExpressCheckoutPayment($data, $token, $payerid)
213
    {
214
        $this->setItemSubTotal($data);
215
216
        $this->post = $this->setCartItems($data['items'])->merge([
217
            'TOKEN'                          => $token,
218
            'PAYERID'                        => $payerid,
219
            'PAYMENTREQUEST_0_ITEMAMT'       => $this->subtotal,
220
            'PAYMENTREQUEST_0_AMT'           => $data['total'],
221
            'PAYMENTREQUEST_0_PAYMENTACTION' => !empty($this->config['payment_action']) ? $this->config['payment_action'] : 'Sale',
222
            'PAYMENTREQUEST_0_CURRENCYCODE'  => $this->currency,
223
            'PAYMENTREQUEST_0_DESC'          => $data['invoice_description'],
224
            'PAYMENTREQUEST_0_INVNUM'        => $data['invoice_id'],
225
            'PAYMENTREQUEST_0_NOTIFYURL'     => $this->notifyUrl,
226
        ]);
227
228
        $this->setShippingAmount($data);
229
230
        return $this->doPayPalRequest('DoExpressCheckoutPayment');
231
    }
232
233
    /**
234
     * Perform a DoAuthorization API call on PayPal.
235
     *
236
     * @param string $authorization_id Transaction ID
237
     * @param float  $amount           Amount to capture
238
     * @param array  $data             Optional request fields
239
     *
240
     * @throws \Exception
241
     *
242
     * @return array|\Psr\Http\Message\StreamInterface
243
     */
244
    public function doAuthorization($authorization_id, $amount, $data = [])
245
    {
246
        $this->setRequestData(
247
            array_merge($data, [
248
                'AUTHORIZATIONID' => $authorization_id,
249
                'AMT'             => $amount,
250
            ])
251
        );
252
253
        return $this->doPayPalRequest('DoAuthorization');
254
    }
255
256
    /**
257
     * Perform a DoCapture API call on PayPal.
258
     *
259
     * @param string $authorization_id Transaction ID
260
     * @param float  $amount           Amount to capture
261
     * @param string $complete         Indicates whether or not this is the last capture.
262
     * @param array  $data             Optional request fields
263
     *
264
     * @throws \Exception
265
     *
266
     * @return array|\Psr\Http\Message\StreamInterface
267
     */
268
    public function doCapture($authorization_id, $amount, $complete = 'Complete', $data = [])
269
    {
270
        $this->setRequestData(
271
            array_merge($data, [
272
                'AUTHORIZATIONID' => $authorization_id,
273
                'AMT'             => $amount,
274
                'COMPLETETYPE'    => $complete,
275
                'CURRENCYCODE'    => $this->currency,
276
            ])
277
        );
278
279
        return $this->doPayPalRequest('DoCapture');
280
    }
281
282
    /**
283
     * Perform a DoReauthorization API call on PayPal to reauthorize an existing authorization transaction.
284
     *
285
     * @param string $authorization_id
286
     * @param float  $amount
287
     * @param array  $data
288
     *
289
     * @throws \Exception
290
     *
291
     * @return array|\Psr\Http\Message\StreamInterface
292
     */
293
    public function doReAuthorization($authorization_id, $amount, $data = [])
294
    {
295
        $this->setRequestData(
296
            array_merge($data, [
297
                'AUTHORIZATIONID' => $authorization_id,
298
                'AMOUNT'          => $amount,
299
            ])
300
        );
301
302
        return $this->doPayPalRequest('DoReauthorization');
303
    }
304
305
    /**
306
     * Perform a DoVoid API call on PayPal.
307
     *
308
     * @param string $authorization_id Transaction ID
309
     * @param array  $data             Optional request fields
310
     *
311
     * @throws \Exception
312
     *
313
     * @return array|\Psr\Http\Message\StreamInterface
314
     */
315
    public function doVoid($authorization_id, $data = [])
316
    {
317
        $this->setRequestData(
318
            array_merge($data, [
319
                'AUTHORIZATIONID' => $authorization_id,
320
            ])
321
        );
322
323
        return $this->doPayPalRequest('DoVoid');
324
    }
325
326
    /**
327
     * Perform a CreateBillingAgreement API call on PayPal.
328
     *
329
     * @param string $token
330
     *
331
     * @throws \Exception
332
     *
333
     * @return array|\Psr\Http\Message\StreamInterface
334
     */
335
    public function createBillingAgreement($token)
336
    {
337
        $this->setRequestData([
338
            'TOKEN' => $token,
339
        ]);
340
341
        return $this->doPayPalRequest('CreateBillingAgreement');
342
    }
343
344
    /**
345
     * Perform a CreateRecurringPaymentsProfile API call on PayPal.
346
     *
347
     * @param array  $data
348
     * @param string $token
349
     *
350
     * @throws \Exception
351
     *
352
     * @return array|\Psr\Http\Message\StreamInterface
353
     */
354
    public function createRecurringPaymentsProfile($data, $token)
355
    {
356
        $this->post = $this->setRequestData($data)->merge([
357
            'TOKEN' => $token,
358
        ]);
359
360
        return $this->doPayPalRequest('CreateRecurringPaymentsProfile');
361
    }
362
363
    /**
364
     * Perform a GetRecurringPaymentsProfileDetails API call on PayPal.
365
     *
366
     * @param string $id
367
     *
368
     * @throws \Exception
369
     *
370
     * @return array|\Psr\Http\Message\StreamInterface
371
     */
372
    public function getRecurringPaymentsProfileDetails($id)
373
    {
374
        $this->setRequestData([
375
            'PROFILEID' => $id,
376
        ]);
377
378
        return $this->doPayPalRequest('GetRecurringPaymentsProfileDetails');
379
    }
380
381
    /**
382
     * Perform a UpdateRecurringPaymentsProfile API call on PayPal.
383
     *
384
     * @param array  $data
385
     * @param string $id
386
     *
387
     * @throws \Exception
388
     *
389
     * @return array|\Psr\Http\Message\StreamInterface
390
     */
391
    public function updateRecurringPaymentsProfile($data, $id)
392
    {
393
        $this->post = $this->setRequestData($data)->merge([
394
            'PROFILEID' => $id,
395
        ]);
396
397
        return $this->doPayPalRequest('UpdateRecurringPaymentsProfile');
398
    }
399
400
    /**
401
     * Change Recurring payment profile status on PayPal.
402
     *
403
     * @param string $id
404
     * @param string $status
405
     *
406
     * @throws \Exception
407
     *
408
     * @return array|\Psr\Http\Message\StreamInterface
409
     */
410
    protected function manageRecurringPaymentsProfileStatus($id, $status)
411
    {
412
        $this->setRequestData([
413
            'PROFILEID' => $id,
414
            'ACTION'    => $status,
415
        ]);
416
417
        return $this->doPayPalRequest('ManageRecurringPaymentsProfileStatus');
418
    }
419
420
    /**
421
     * Perform a ManageRecurringPaymentsProfileStatus API call on PayPal to cancel a RecurringPaymentsProfile.
422
     *
423
     * @param string $id
424
     *
425
     * @throws \Exception
426
     *
427
     * @return array|\Psr\Http\Message\StreamInterface
428
     */
429
    public function cancelRecurringPaymentsProfile($id)
430
    {
431
        return $this->manageRecurringPaymentsProfileStatus($id, 'Cancel');
432
    }
433
434
    /**
435
     * Perform a ManageRecurringPaymentsProfileStatus API call on PayPal to suspend a RecurringPaymentsProfile.
436
     *
437
     * @param string $id
438
     *
439
     * @throws \Exception
440
     *
441
     * @return array|\Psr\Http\Message\StreamInterface
442
     */
443
    public function suspendRecurringPaymentsProfile($id)
444
    {
445
        return $this->manageRecurringPaymentsProfileStatus($id, 'Suspend');
446
    }
447
448
    /**
449
     * Perform a ManageRecurringPaymentsProfileStatus API call on PayPal to reactivate a RecurringPaymentsProfile.
450
     *
451
     * @param string $id
452
     *
453
     * @throws \Exception
454
     *
455
     * @return array|\Psr\Http\Message\StreamInterface
456
     */
457
    public function reactivateRecurringPaymentsProfile($id)
458
    {
459
        return $this->manageRecurringPaymentsProfileStatus($id, 'Reactivate');
460
    }
461
}
462