Completed
Push — v1.0 ( cbceb3...668b92 )
by Raza
02:19
created

PayPalRequest   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 410
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 31
lcom 1
cbo 4
dl 0
loc 410
rs 9.92
c 0
b 0
f 0

14 Methods

Rating   Name   Duplication   Size   Complexity  
A setApiCredentials() 0 17 1
A addOptions() 0 6 1
A setCurrency() 0 13 2
A setBillingType() 0 12 3
A verifyIPN() 0 8 1
A setFraudnetId() 0 6 1
A setRequestData() 0 10 3
A setConfig() 0 13 3
A setDefaultValues() 0 17 4
A setApiEnvironment() 0 8 3
A setApiProviderConfiguration() 0 21 2
A setApiProvider() 0 12 3
A createRequestPayload() 0 15 2
A retrieveData() 0 10 2
1
<?php
2
3
namespace Srmklive\PayPal\Traits;
4
5
use Exception;
6
use GuzzleHttp\Client as HttpClient;
7
use Illuminate\Support\Collection;
8
use Psr\Http\Message\StreamInterface;
9
use RuntimeException;
10
use Srmklive\PayPal\Services\AdaptivePayments;
11
use Srmklive\PayPal\Services\ExpressCheckout;
12
13
trait PayPalRequest
14
{
15
    use PayPalHttpClient;
16
17
    /**
18
     * Http Client class object.
19
     *
20
     * @var HttpClient
21
     */
22
    private $client;
23
24
    /**
25
     * Http Client configuration.
26
     *
27
     * @var array
28
     */
29
    private $httpClientConfig;
30
31
    /**
32
     * PayPal API Certificate data for authentication.
33
     *
34
     * @var string
35
     */
36
    private $certificate;
37
38
    /**
39
     * PayPal API mode to be used.
40
     *
41
     * @var string
42
     */
43
    public $mode;
44
45
    /**
46
     * Request data to be sent to PayPal.
47
     *
48
     * @var Collection
49
     */
50
    protected $post;
51
52
    /**
53
     * PayPal API configuration.
54
     *
55
     * @var array
56
     */
57
    private $config;
58
59
    /**
60
     * Item subtotal.
61
     *
62
     * @var float
63
     */
64
    private $subtotal;
65
66
    /**
67
     * Default currency for PayPal.
68
     *
69
     * @var string
70
     */
71
    private $currency;
72
73
    /**
74
     * Default billing type for PayPal reference transactions.
75
     *
76
     * @var string
77
     */
78
    private $billingType;
79
80
    /**
81
     * Additional options for PayPal API request.
82
     *
83
     * @var array
84
     */
85
    private $options;
86
87
    /**
88
     * Default payment action for PayPal.
89
     *
90
     * @var string
91
     */
92
    private $paymentAction;
93
94
    /**
95
     * Default locale for PayPal.
96
     *
97
     * @var string
98
     */
99
    private $locale;
100
101
    /**
102
     * PayPal API Endpoint.
103
     *
104
     * @var string
105
     */
106
    private $apiUrl;
107
108
    /**
109
     * IPN notification url for PayPal.
110
     *
111
     * @var string
112
     */
113
    private $notifyUrl;
114
115
    /**
116
     * Http Client request body parameter name.
117
     *
118
     * @var string
119
     */
120
    private $httpBodyParam;
121
122
    /**
123
     * Validate SSL details when creating HTTP client.
124
     *
125
     * @var bool
126
     */
127
    private $validateSSL;
128
129
    /**
130
     * Fraudnet Header Id.
131
     *
132
     * @var string
133
     */
134
    private $fraudnetId;
135
136
    /**
137
     * Set PayPal API Credentials.
138
     *
139
     * @param array $credentials
140
     *
141
     * @throws Exception
142
     *
143
     * @return void
144
     */
145
    public function setApiCredentials($credentials)
146
    {
147
        // Setting Default PayPal Mode If not set
148
        $this->setApiEnvironment($credentials);
149
150
        // Set API configuration for the PayPal provider
151
        $this->setApiProviderConfiguration($credentials);
152
153
        // Set default currency.
154
        $this->setCurrency($credentials['currency']);
155
156
        // Set default billing type
157
        $this->setBillingType($credentials['billing_type']);
158
159
        // Set Http Client configuration.
160
        $this->setHttpClientConfiguration();
161
    }
162
163
    /**
164
     * Set other/override PayPal API parameters.
165
     *
166
     * @param array $options
167
     *
168
     * @return $this
169
     */
170
    public function addOptions(array $options)
171
    {
172
        $this->options = $options;
173
174
        return $this;
175
    }
176
177
    /**
178
     * Function to set currency.
179
     *
180
     * @param string $currency
181
     *
182
     * @throws Exception
183
     *
184
     * @return $this
185
     */
186
    public function setCurrency($currency = 'USD')
187
    {
188
        $allowedCurrencies = ['AUD', 'BRL', 'CAD', 'CZK', 'DKK', 'EUR', 'HKD', 'HUF', 'ILS', 'INR', 'JPY', 'MYR', 'MXN', 'NOK', 'NZD', 'PHP', 'PLN', 'GBP', 'SGD', 'SEK', 'CHF', 'TWD', 'THB', 'USD', 'RUB'];
189
190
        // Check if provided currency is valid.
191
        if (!in_array($currency, $allowedCurrencies, true)) {
192
            throw new Exception('Currency is not supported by PayPal.');
193
        }
194
195
        $this->currency = $currency;
196
197
        return $this;
198
    }
199
200
    /**
201
     * Function to set billing type.
202
     *
203
     * @param string $billingType
204
     *
205
     * @throws Exception
206
     *
207
     * @return $this
208
     */
209
    public function setBillingType($billingType = 'MerchantInitiatedBilling')
210
    {
211
        $allowedBillingTypes = ['MerchantInitiatedBilling', 'MerchantInitiatedBillingSingleAgreement', 'RecurringPayments'];
212
213
        if ($billingType !== null && !in_array($billingType, $allowedBillingTypes, true)) {
214
            throw new RuntimeException('Billing type is not supported by PayPal.');
215
        }
216
217
        $this->billingType = $billingType;
218
219
        return $this;
220
    }
221
222
    /**
223
     * Retrieve PayPal IPN Response.
224
     *
225
     * @param array $post
226
     *
227
     * @throws Exception
228
     *
229
     * @return array
230
     */
231
    public function verifyIPN($post)
232
    {
233
        $this->setRequestData($post);
234
235
        $this->apiUrl = $this->config['ipn_url'];
236
237
        return $this->doPayPalRequest('verifyipn');
238
    }
239
240
    /**
241
     * Function to set fraudnet id.
242
     *
243
     * @param string $fraudnetId
244
     *
245
     * @return $this
246
     */
247
    public function setFraudnetId($fraudnetId)
248
    {
249
        $this->fraudnetId = $fraudnetId;
250
        
251
        return $this;
252
    }
253
254
    /**
255
     * Setup request data to be sent to PayPal.
256
     *
257
     * @param array $data
258
     *
259
     * @return Collection
260
     */
261
    protected function setRequestData(array $data = [])
262
    {
263
        if (($this->post instanceof Collection) && (!$this->post->isEmpty())) {
264
            unset($this->post);
265
        }
266
267
        $this->post = new Collection($data);
268
269
        return $this->post;
270
    }
271
272
    /**
273
     * Function To Set PayPal API Configuration.
274
     *
275
     * @param array $config
276
     *
277
     * @throws Exception
278
     */
279
    private function setConfig(array $config = [])
280
    {
281
        // Set Api Credentials
282
        if (function_exists('config')) {
283
            $this->setApiCredentials(
284
                config('paypal')
285
            );
286
        } elseif (!empty($config)) {
287
            $this->setApiCredentials($config);
288
        }
289
290
        $this->setRequestData();
291
    }
292
293
    /**
294
     * Set default values for configuration.
295
     *
296
     * @return void
297
     */
298
    private function setDefaultValues()
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
299
    {
300
        // Set default payment action.
301
        if (empty($this->paymentAction)) {
302
            $this->paymentAction = 'Sale';
303
        }
304
305
        // Set default locale.
306
        if (empty($this->locale)) {
307
            $this->locale = 'en_US';
308
        }
309
310
        // Set default value for SSL validation.
311
        if (empty($this->validateSSL)) {
312
            $this->validateSSL = false;
313
        }
314
    }
315
316
    /**
317
     * Set API environment to be used by PayPal.
318
     *
319
     * @param array $credentials
320
     *
321
     * @return void
322
     */
323
    private function setApiEnvironment($credentials)
324
    {
325
        if (empty($credentials['mode']) || !in_array($credentials['mode'], ['sandbox', 'live'])) {
326
            $this->mode = 'live';
327
        } else {
328
            $this->mode = $credentials['mode'];
329
        }
330
    }
331
332
    /**
333
     * Set configuration details for the provider.
334
     *
335
     * @param array $credentials
336
     *
337
     * @throws Exception
338
     *
339
     * @return void
340
     */
341
    private function setApiProviderConfiguration($credentials)
342
    {
343
        // Setting PayPal API Credentials
344
        collect($credentials[$this->mode])->map(function ($value, $key) {
345
            $this->config[$key] = $value;
346
        });
347
348
        // Setup PayPal API Signature value to use.
349
        $this->config['signature'] = empty($this->config['certificate']) ?
350
        $this->config['secret'] : $this->config['certificate'];
351
352
        $this->paymentAction = $credentials['payment_action'];
353
354
        $this->locale = $credentials['locale'];
355
356
        $this->certificate = $this->config['certificate'];
357
358
        $this->validateSSL = $credentials['validate_ssl'];
359
360
        $this->setApiProvider($credentials);
361
    }
362
363
    /**
364
     * Determines which API provider should be used.
365
     *
366
     * @param array $credentials
367
     *
368
     * @throws Exception
369
     */
370
    private function setApiProvider($credentials)
371
    {
372
        if ($this instanceof AdaptivePayments) {
373
            return $this->setAdaptivePaymentsOptions();
374
        }
375
376
        if ($this instanceof ExpressCheckout) {
377
            return $this->setExpressCheckoutOptions($credentials);
378
        }
379
380
        throw new RuntimeException('Invalid api credentials provided for PayPal!. Please provide the right api credentials.');
381
    }
382
383
    /**
384
     * Create request payload to be sent to PayPal.
385
     *
386
     * @param string $method
387
     */
388
    private function createRequestPayload($method)
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
389
    {
390
        $config = array_merge([
391
            'USER'      => $this->config['username'],
392
            'PWD'       => $this->config['password'],
393
            'SIGNATURE' => $this->config['signature'],
394
            'VERSION'   => 123,
395
            'METHOD'    => $method,
396
        ], $this->options);
397
398
        $this->post = $this->post->merge($config);
399
        if ($method === 'verifyipn') {
400
            $this->post->forget('METHOD');
401
        }
402
    }
403
404
    /**
405
     * Parse PayPal NVP Response.
406
     *
407
     * @param string                $method
408
     * @param array|StreamInterface $response
409
     *
410
     * @return array
411
     */
412
    private function retrieveData($method, $response)
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
413
    {
414
        if ($method === 'verifyipn') {
415
            return $response;
416
        }
417
418
        parse_str($response, $output);
419
420
        return $output;
421
    }
422
}
423