Completed
Push — master ( d694ed...da5df0 )
by Raza
02:05
created

PayPalRequest::retrieveData()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
nc 1
nop 2
dl 0
loc 6
rs 9.4285
c 1
b 0
f 0
1
<?php
2
3
namespace Srmklive\PayPal\Traits;
4
5
use GuzzleHttp\Client as HttpClient;
6
use GuzzleHttp\Exception\BadResponseException as HttpBadResponseException;
7
use GuzzleHttp\Exception\ClientException as HttpClientException;
8
use GuzzleHttp\Exception\ServerException as HttpServerException;
9
use Illuminate\Support\Collection;
10
11
trait PayPalRequest
12
{
13
    /**
14
     * Http Client class object.
15
     *
16
     * @var HttpClient
17
     */
18
    private $client;
19
20
    /**
21
     * Request data to be sent to PayPal.
22
     *
23
     * @var \Illuminate\Support\Collection
24
     */
25
    protected $post;
26
27
    /**
28
     * PayPal API configuration.
29
     *
30
     * @var array
31
     */
32
    private $config;
33
34
    /**
35
     * Default currency for PayPal.
36
     *
37
     * @var string
38
     */
39
    private $currency;
40
41
    /**
42
     * Additional options for PayPal API request.
43
     *
44
     * @var array
45
     */
46
    private $options;
47
48
    /**
49
     * Default payment action for PayPal.
50
     *
51
     * @var string
52
     */
53
    private $paymentAction;
54
55
    /**
56
     * Default locale for PayPal.
57
     *
58
     * @var string
59
     */
60
    private $locale;
61
62
    /**
63
     * PayPal API Endpoint.
64
     *
65
     * @var string
66
     */
67
    private $apiUrl;
68
69
    /**
70
     * IPN notification url for PayPal.
71
     *
72
     * @var string
73
     */
74
    private $notifyUrl;
75
76
    /**
77
     * Http Client request body parameter name.
78
     *
79
     * @var string
80
     */
81
    private $httpBodyParam;
82
83
    /**
84
     * Function To Set PayPal API Configuration.
85
     *
86
     * @param array $config
87
     *
88
     * @return void
89
     */
90
    private function setConfig(array $config = [])
91
    {
92
        // Setting Http Client
93
        $this->client = $this->setClient();
94
95
        // Set Api Credentials
96
        if (function_exists('config')) {
97
            $this->setApiCredentials(
98
                config('paypal')
99
            );
100
        } elseif (!empty($config)) {
101
            $this->setApiCredentials($config);
102
        }
103
104
        // Set options to be empty.
105
        $this->options = [];
106
107
        $this->setRequestData();
108
    }
109
110
    /**
111
     * Function to initialize Http Client.
112
     *
113
     * @return HttpClient
114
     */
115
    protected function setClient()
116
    {
117
        return new HttpClient([
118
            'curl' => [
119
                CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_2,
120
            ],
121
        ]);
122
    }
123
124
    /**
125
     * Set PayPal API Credentials.
126
     *
127
     * @param array  $credentials
128
     * @param string $mode
129
     *
130
     * @throws \Exception
131
     *
132
     * @return void
133
     */
134
    public function setApiCredentials($credentials, $mode = '')
135
    {
136
        // Setting Default PayPal Mode If not set
137
        if (empty($credentials['mode']) ||
138
            (!in_array($credentials['mode'], ['sandbox', 'live']))
139
        ) {
140
            $credentials['mode'] = 'live';
141
        }
142
143
        // Setting default mode.
144
        if (empty($mode)) {
145
            $mode = $credentials['mode'];
146
        }
147
148
        // Setting PayPal API Credentials
149
        foreach ($credentials[$mode] as $key => $value) {
150
            $this->config[$key] = $value;
151
        }
152
153
        // Setup PayPal API Signature value to use.
154
        if (!empty($this->config['secret'])) {
155
            $this->config['signature'] = $this->config['secret'];
156
        } else {
157
            $this->config['signature'] = file_get_contents($this->config['certificate']);
158
        }
159
160
        if ($this instanceof \Srmklive\PayPal\Services\AdaptivePayments) {
161
            $this->setAdaptivePaymentsOptions($mode);
162
        } elseif ($this instanceof \Srmklive\PayPal\Services\ExpressCheckout) {
163
            $this->setExpressCheckoutOptions($credentials, $mode);
164
        } else {
165
            throw new \Exception('Invalid api credentials provided for PayPal!. Please provide the right api credentials.');
166
        }
167
168
        // Set default currency.
169
        $this->setCurrency($credentials['currency']);
170
171
        // Set default payment action.
172
        $this->paymentAction = !empty($this->config['payment_action']) ?
173
            $this->config['payment_action'] : 'Sale';
174
175
        // Set default locale.
176
        $this->locale = !empty($this->config['locale']) ?
177
            $this->config['locale'] : 'en_US';
178
179
        // Set PayPal API Endpoint.
180
        $this->apiUrl = $this->config['api_url'];
181
182
        // Set PayPal IPN Notification URL
183
        $this->notifyUrl = $credentials['notify_url'];
184
    }
185
186
    /**
187
     * Setup request data to be sent to PayPal.
188
     *
189
     * @param array $data
190
     *
191
     * @return \Illuminate\Support\Collection
192
     */
193
    protected function setRequestData(array $data = [])
194
    {
195
        if (($this->post instanceof Collection) && ($this->post->isNotEmpty())) {
196
            unset($this->post);
197
        }
198
199
        $this->post = new Collection($data);
200
201
        return $this->post;
202
    }
203
204
    /**
205
     * Set other/override PayPal API parameters.
206
     *
207
     * @param array $options
208
     *
209
     * @return $this
210
     */
211
    public function addOptions(array $options)
212
    {
213
        $this->options = $options;
214
215
        return $this;
216
    }
217
218
    /**
219
     * Function to set currency.
220
     *
221
     * @param string $currency
222
     *
223
     * @throws \Exception
224
     *
225
     * @return $this
226
     */
227
    public function setCurrency($currency = 'USD')
228
    {
229
        $allowedCurrencies = ['AUD', 'BRL', 'CAD', 'CZK', 'DKK', 'EUR', 'HKD', 'HUF', 'ILS', 'JPY', 'MYR', 'MXN', 'NOK', 'NZD', 'PHP', 'PLN', 'GBP', 'SGD', 'SEK', 'CHF', 'TWD', 'THB', 'USD', 'RUB'];
230
231
        // Check if provided currency is valid.
232
        if (!in_array($currency, $allowedCurrencies)) {
233
            throw new \Exception('Currency is not supported by PayPal.');
234
        }
235
236
        $this->currency = $currency;
237
238
        return $this;
239
    }
240
241
    /**
242
     * Retrieve PayPal IPN Response.
243
     *
244
     * @param array $post
245
     *
246
     * @return array
247
     */
248
    public function verifyIPN($post)
249
    {
250
        $this->setRequestData($post);
251
252
        $this->apiUrl = $this->config['gateway_url'].'/cgi-bin/webscr';
253
254
        return $this->doPayPalRequest('verifyipn');
255
    }
256
257
    /**
258
     * Refund PayPal Transaction.
259
     *
260
     * @param string $transaction
261
     * @param float  $amount
262
     *
263
     * @return array
264
     */
265
    public function refundTransaction($transaction, $amount = 0.00)
266
    {
267
        $this->setRequestData([
268
            'TRANSACTIONID' => $transaction,
269
        ]);
270
271
        if ($amount > 0) {
272
            $this->post->merge([
273
                'REFUNDTYPE' => 'Partial',
274
                'AMT'        => $amount,
275
            ]);
276
        }
277
278
        return $this->doPayPalRequest('RefundTransaction');
279
    }
280
281
    /**
282
     * Search Transactions On PayPal.
283
     *
284
     * @param array $post
285
     *
286
     * @return array
287
     */
288
    public function searchTransactions($post)
289
    {
290
        $this->setRequestData($post);
291
292
        return $this->doPayPalRequest('TransactionSearch');
293
    }
294
295
    /**
296
     * Create request payload to be sent to PayPal.
297
     *
298
     * @param string $method
299
     */
300
    private function createRequestPayload($method)
301
    {
302
        $config = array_merge([
303
            'USER'      => $this->config['username'],
304
            'PWD'       => $this->config['password'],
305
            'SIGNATURE' => $this->config['signature'],
306
            'VERSION'   => 123,
307
            'METHOD'    => $method,
308
        ], $this->options);
309
310
        $this->post = $this->post->merge($config)
311
            ->filter(function ($value, $key) use($method) {
312
                return (($method === 'verifyipn') && ($key === 'METHOD')) ?: $value;
313
            });
314
    }
315
316
    /**
317
     * Function To Perform PayPal API Request.
318
     *
319
     * @param string $method
320
     *
321
     * @throws \Exception
322
     *
323
     * @return array|\Psr\Http\Message\StreamInterface
324
     */
325
    private function doPayPalRequest($method)
326
    {
327
        // Setting API Credentials, Version & Method
328
        $this->createRequestPayload($method);
329
330
        try {
331
            $request = $this->client->post($this->apiUrl, [
332
                $this->httpBodyParam => $this->post->toArray(),
333
            ]);
334
335
            $response = $request->getBody();
336
337
            return ($method == 'verifyipn') ? $response : $this->retrieveData($response);
338
        } catch (HttpClientException $e) {
339
            throw new \Exception($e->getRequest().' '.$e->getResponse());
340
        } catch (HttpServerException $e) {
341
            throw new \Exception($e->getRequest().' '.$e->getResponse());
342
        } catch (HttpBadResponseException $e) {
343
            throw new \Exception($e->getRequest().' '.$e->getResponse());
344
        } catch (\Exception $e) {
345
            $message = $e->getMessage();
346
        }
347
348
        return [
349
            'type'      => 'error',
350
            'message'   => $message,
351
        ];
352
    }
353
354
    /**
355
     * Parse PayPal NVP Response.
356
     *
357
     * @param string $request
358
     * @param array  $response
359
     *
360
     * @return array
361
     */
362
    private function retrieveData($request, array $response = null)
363
    {
364
        parse_str($request, $response);
365
366
        return $response;
367
    }
368
}
369