Completed
Pull Request — v1.0 (#438)
by
unknown
01:27
created

PayPalRequest   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 409
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 31
lcom 1
cbo 4
dl 0
loc 409
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 5 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
        return $this;
251
    }
252
253
    /**
254
     * Setup request data to be sent to PayPal.
255
     *
256
     * @param array $data
257
     *
258
     * @return Collection
259
     */
260
    protected function setRequestData(array $data = [])
261
    {
262
        if (($this->post instanceof Collection) && (!$this->post->isEmpty())) {
263
            unset($this->post);
264
        }
265
266
        $this->post = new Collection($data);
267
268
        return $this->post;
269
    }
270
271
    /**
272
     * Function To Set PayPal API Configuration.
273
     *
274
     * @param array $config
275
     *
276
     * @throws Exception
277
     */
278
    private function setConfig(array $config = [])
279
    {
280
        // Set Api Credentials
281
        if (function_exists('config')) {
282
            $this->setApiCredentials(
283
                config('paypal')
284
            );
285
        } elseif (!empty($config)) {
286
            $this->setApiCredentials($config);
287
        }
288
289
        $this->setRequestData();
290
    }
291
292
    /**
293
     * Set default values for configuration.
294
     *
295
     * @return void
296
     */
297
    private function setDefaultValues()
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
298
    {
299
        // Set default payment action.
300
        if (empty($this->paymentAction)) {
301
            $this->paymentAction = 'Sale';
302
        }
303
304
        // Set default locale.
305
        if (empty($this->locale)) {
306
            $this->locale = 'en_US';
307
        }
308
309
        // Set default value for SSL validation.
310
        if (empty($this->validateSSL)) {
311
            $this->validateSSL = false;
312
        }
313
    }
314
315
    /**
316
     * Set API environment to be used by PayPal.
317
     *
318
     * @param array $credentials
319
     *
320
     * @return void
321
     */
322
    private function setApiEnvironment($credentials)
323
    {
324
        if (empty($credentials['mode']) || !in_array($credentials['mode'], ['sandbox', 'live'])) {
325
            $this->mode = 'live';
326
        } else {
327
            $this->mode = $credentials['mode'];
328
        }
329
    }
330
331
    /**
332
     * Set configuration details for the provider.
333
     *
334
     * @param array $credentials
335
     *
336
     * @throws Exception
337
     *
338
     * @return void
339
     */
340
    private function setApiProviderConfiguration($credentials)
341
    {
342
        // Setting PayPal API Credentials
343
        collect($credentials[$this->mode])->map(function ($value, $key) {
344
            $this->config[$key] = $value;
345
        });
346
347
        // Setup PayPal API Signature value to use.
348
        $this->config['signature'] = empty($this->config['certificate']) ?
349
        $this->config['secret'] : $this->config['certificate'];
350
351
        $this->paymentAction = $credentials['payment_action'];
352
353
        $this->locale = $credentials['locale'];
354
355
        $this->certificate = $this->config['certificate'];
356
357
        $this->validateSSL = $credentials['validate_ssl'];
358
359
        $this->setApiProvider($credentials);
360
    }
361
362
    /**
363
     * Determines which API provider should be used.
364
     *
365
     * @param array $credentials
366
     *
367
     * @throws Exception
368
     */
369
    private function setApiProvider($credentials)
370
    {
371
        if ($this instanceof AdaptivePayments) {
372
            return $this->setAdaptivePaymentsOptions();
373
        }
374
375
        if ($this instanceof ExpressCheckout) {
376
            return $this->setExpressCheckoutOptions($credentials);
377
        }
378
379
        throw new RuntimeException('Invalid api credentials provided for PayPal!. Please provide the right api credentials.');
380
    }
381
382
    /**
383
     * Create request payload to be sent to PayPal.
384
     *
385
     * @param string $method
386
     */
387
    private function createRequestPayload($method)
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
388
    {
389
        $config = array_merge([
390
            'USER'      => $this->config['username'],
391
            'PWD'       => $this->config['password'],
392
            'SIGNATURE' => $this->config['signature'],
393
            'VERSION'   => 123,
394
            'METHOD'    => $method,
395
        ], $this->options);
396
397
        $this->post = $this->post->merge($config);
398
        if ($method === 'verifyipn') {
399
            $this->post->forget('METHOD');
400
        }
401
    }
402
403
    /**
404
     * Parse PayPal NVP Response.
405
     *
406
     * @param string                $method
407
     * @param array|StreamInterface $response
408
     *
409
     * @return array
410
     */
411
    private function retrieveData($method, $response)
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
412
    {
413
        if ($method === 'verifyipn') {
414
            return $response;
415
        }
416
417
        parse_str($response, $output);
418
419
        return $output;
420
    }
421
}
422