Completed
Push — master ( e65131...330da9 )
by Raza
02:04
created

PayPalRequest::setRequestData()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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