Completed
Push — master ( 10a953...06746b )
by Raza
01:55
created

PayPalRequest::setExpressCheckoutOptions()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 12
nc 4
nop 2
dl 0
loc 20
rs 9.2
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
A PayPalRequest::setCurrency() 0 13 2
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);
0 ignored issues
show
Bug introduced by
The method setAdaptivePaymentsOptions() cannot be called from this context as it is declared protected in class Srmklive\PayPal\Services\AdaptivePayments.

This check looks for access to methods that are not accessible from the current context.

If you need to make a method accessible to another context you can raise its visibility level in the defining class.

Loading history...
123
        } else {
124
            $this->setExpressCheckoutOptions($credentials, $mode);
0 ignored issues
show
Bug introduced by
It seems like setExpressCheckoutOptions() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
125
        }
126
127
        // Set default currency.
128
        $this->setCurrency($credentials['currency']);
129
130
        // Set default payment action.
131
        $this->paymentAction = !empty($this->config['payment_action']) ?
132
            $this->config['payment_action'] : 'Sale';
133
134
        // Set default locale.
135
        $this->locale = !empty($this->config['locale']) ?
136
            $this->config['locale'] : 'en_US';
137
138
        // Set PayPal IPN Notification URL
139
        $this->notifyUrl = $credentials['notify_url'];
140
    }
141
142
    /**
143
     * Setup request data to be sent to PayPal.
144
     *
145
     * @param array $data
146
     *
147
     * @return \Illuminate\Support\Collection
148
     */
149
    protected function setRequestData(array $data = [])
150
    {
151
        if (($this->post instanceof Collection) && ($this->post->isNotEmpty())) {
152
            unset($this->post);
153
        }
154
155
        $this->post = new Collection($data);
156
157
        return $this->post;
158
    }
159
160
    /**
161
     * Set other/override PayPal API parameters.
162
     *
163
     * @param array $options
164
     *
165
     * @return $this
166
     */
167
    public function addOptions(array $options)
168
    {
169
        $this->options = $options;
170
171
        return $this;
172
    }
173
174
    /**
175
     * Function to set currency.
176
     *
177
     * @param string $currency
178
     *
179
     * @throws \Exception
180
     *
181
     * @return $this
182
     */
183
    public function setCurrency($currency = 'USD')
184
    {
185
        $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'];
186
187
        // Check if provided currency is valid.
188
        if (!in_array($currency, $allowedCurrencies)) {
189
            throw new \Exception('Currency is not supported by PayPal.');
190
        }
191
192
        $this->currency = $currency;
193
194
        return $this;
195
    }
196
197
    /**
198
     * Retrieve PayPal IPN Response.
199
     *
200
     * @param array $post
201
     *
202
     * @return array
203
     */
204
    public function verifyIPN($post)
205
    {
206
        $this->setRequestData($post);
207
208
        return $this->doPayPalRequest('verifyipn');
209
    }
210
211
    /**
212
     * Refund PayPal Transaction.
213
     *
214
     * @param string $transaction
215
     *
216
     * @return array
217
     */
218
    public function refundTransaction($transaction)
219
    {
220
        $this->setRequestData([
221
            'TRANSACTIONID' => $transaction,
222
        ]);
223
224
        return $this->doPayPalRequest('RefundTransaction');
225
    }
226
227
    /**
228
     * Search Transactions On PayPal.
229
     *
230
     * @param array $post
231
     *
232
     * @return array
233
     */
234
    public function searchTransactions($post)
235
    {
236
        $this->setRequestData($post);
237
238
        return $this->doPayPalRequest('TransactionSearch');
239
    }
240
241
    /**
242
     * Function To Perform PayPal API Request.
243
     *
244
     * @param string $method
245
     *
246
     * @throws \Exception
247
     *
248
     * @return array|\Psr\Http\Message\StreamInterface
249
     */
250
    private function doPayPalRequest($method)
251
    {
252
        // Check configuration settings. Reset them if empty.
253
        if (empty($this->config)) {
254
            self::setConfig();
255
        }
256
257
        // Throw exception if configuration is still not set.
258
        if (empty($this->config)) {
259
            throw new \Exception('PayPal api settings not found.');
260
        }
261
262
        // Setting API Credentials, Version & Method
263
        $this->post->merge([
264
            'USER'      => $this->config['username'],
265
            'PWD'       => $this->config['password'],
266
            'SIGNATURE' => $this->config['signature'],
267
            'VERSION'   => 123,
268
            'METHOD'    => $method,
269
        ]);
270
271
        // Checking Whether The Request Is PayPal IPN Response
272
        if ($method == 'verifyipn') {
273
            $this->post = $this->post->filter(function ($value, $key) {
274
                if ($key !== 'METHOD') {
275
                    return $value;
276
                }
277
            });
278
279
            $post_url = $this->config['gateway_url'].'/cgi-bin/webscr';
280
        } else {
281
            $post_url = $this->config['api_url'];
282
        }
283
284
        // Merge $options array if set.
285
        if (!empty($this->options)) {
286
            $this->post->merge($this->options);
287
        }
288
289
        try {
290
            $request = $this->client->post($post_url, [
291
                'form_params' => $this->post->toArray(),
292
            ]);
293
294
            $response = $request->getBody(true);
295
296
            return ($method == 'verifyipn') ? $response : $this->retrieveData($response);
297
        } catch (HttpClientException $e) {
298
            throw new \Exception($e->getRequest().' '.$e->getResponse());
299
        } catch (HttpServerException $e) {
300
            throw new \Exception($e->getRequest().' '.$e->getResponse());
301
        } catch (HttpBadResponseException $e) {
302
            throw new \Exception($e->getRequest().' '.$e->getResponse());
303
        } catch (\Exception $e) {
304
            $message = $e->getMessage();
305
        }
306
307
        return [
308
            'type'      => 'error',
309
            'message'   => $message,
310
        ];
311
    }
312
313
    /**
314
     * Parse PayPal NVP Response.
315
     *
316
     * @param string $request
317
     * @param array  $response
318
     *
319
     * @return array
320
     */
321
    private function retrieveData($request, array $response = null)
322
    {
323
        parse_str($request, $response);
324
325
        return $response;
326
    }
327
}
328