Completed
Push — master ( 0e4826...915d32 )
by Raza
02:13
created

AdaptivePayments   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 256
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 14
Bugs 0 Features 0
Metric Value
c 14
b 0
f 0
dl 0
loc 256
rs 10
wmc 25
lcom 1
cbo 4

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A setAdaptivePaymentsOptions() 0 10 2
A setHeaders() 0 13 1
A setEnvelope() 0 9 1
B createPayRequest() 0 22 5
A setPaymentOptions() 0 11 1
A getPaymentOptions() 0 11 2
A getPaymentDetails() 0 4 1
A getRedirectUrl() 0 12 3
A setPaymentOptionsReceiverDetails() 0 18 1
A createRequestPayload() 0 6 1
A makeHttpRequest() 0 15 4
A doPayPalRequest() 0 18 2
1
<?php
2
3
namespace Srmklive\PayPal\Services;
4
5
use Srmklive\PayPal\Traits\PayPalRequest as PayPalAPIRequest;
6
7
class AdaptivePayments
8
{
9
    use PayPalAPIRequest;
10
11
    /**
12
     * PayPal Processor Constructor.
13
     */
14
    public function __construct()
15
    {
16
        // Setting PayPal API Credentials
17
        $this->setConfig();
18
    }
19
20
    /**
21
     * Set AdaptivePayments API endpoints & options.
22
     *
23
     * @return void
24
     */
25
    public function setAdaptivePaymentsOptions()
26
    {
27
        if ($this->mode == 'sandbox') {
28
            $this->config['api_url'] = 'https://svcs.sandbox.paypal.com/AdaptivePayments';
29
            $this->config['gateway_url'] = 'https://www.sandbox.paypal.com/cgi-bin/webscr';
30
        } else {
31
            $this->config['api_url'] = 'https://svcs.paypal.com/AdaptivePayments';
32
            $this->config['gateway_url'] = 'https://www.paypal.com/cgi-bin/webscr';
33
        }
34
    }
35
36
    /**
37
     * Set Adaptive Payments API request headers.
38
     *
39
     * @return array
40
     */
41
    private function setHeaders()
42
    {
43
        $headers = [
44
            'X-PAYPAL-SECURITY-USERID'      => $this->config['username'],
45
            'X-PAYPAL-SECURITY-PASSWORD'    => $this->config['password'],
46
            'X-PAYPAL-SECURITY-SIGNATURE'   => $this->config['signature'],
47
            'X-PAYPAL-REQUEST-DATA-FORMAT'  => 'JSON',
48
            'X-PAYPAL-RESPONSE-DATA-FORMAT' => 'JSON',
49
            'X-PAYPAL-APPLICATION-ID'       => $this->config['app_id'],
50
        ];
51
52
        return $headers;
53
    }
54
55
    /**
56
     * Set Adaptive Payments API request envelope.
57
     *
58
     * @return array
59
     */
60
    private function setEnvelope()
61
    {
62
        $envelope = [
63
            'errorLanguage' => 'en_US',
64
            'detailLevel'   => 'ReturnAll',
65
        ];
66
67
        return $envelope;
68
    }
69
70
    /**
71
     * Function to perform Adaptive Payments API's PAY operation.
72
     *
73
     * @param array $data
74
     *
75
     * @throws \Exception
76
     *
77
     * @return array
78
     */
79
    public function createPayRequest($data)
80
    {
81
        if (empty($data['return_url']) && empty($data['cancel_url'])) {
82
            throw new \Exception('Return & Cancel URL should be specified');
83
        }
84
85
        $this->setRequestData([
86
            'actionType'        => 'PAY',
87
            'currencyCode'      => $this->currency,
88
            'receiverList'      => [
89
                'receiver'      => $data['receivers'],
90
            ],
91
            'returnUrl'         => $data['return_url'],
92
            'cancelUrl'         => $data['cancel_url'],
93
            'requestEnvelope'   => $this->setEnvelope(),
94
            'feesPayer'         => $data['payer'],
95
        ])->filter(function ($value, $key) use ($data) {
96
            return (($key === 'feesPayer') && empty($value)) ?: $value;
97
        });
98
99
        return $this->doPayPalRequest('Pay');
100
    }
101
102
    /**
103
     * Function to perform Adaptive Payments API's SetPaymentOptions operation.
104
     *
105
     * @param string $payKey
106
     * @param array  $receivers
107
     *
108
     * @return array
109
     */
110
    public function setPaymentOptions($payKey, $receivers)
111
    {
112
        $this->post = $this->setRequestData([
113
            'requestEnvelope' => $this->setEnvelope(),
114
            'payKey'          => $payKey,
115
        ])->merge([
116
            'receiverOptions' => $this->setPaymentOptionsReceiverDetails($receivers),
117
        ]);
118
119
        return $this->doPayPalRequest('SetPaymentOptions');
120
    }
121
122
    /**
123
     * Function to perform Adaptive Payments API's GetPaymentOptions operation.
124
     *
125
     * @param string $payKey
126
     * @param bool   $details
127
     *
128
     * @return array
129
     */
130
    public function getPaymentOptions($payKey, $details = false)
131
    {
132
        $operation = ($details) ? 'PaymentDetails' : 'GetPaymentOptions';
133
134
        $this->setRequestData([
135
            'requestEnvelope' => $this->setEnvelope(),
136
            'payKey'          => $payKey,
137
        ]);
138
139
        return $this->doPayPalRequest($operation);
140
    }
141
142
    /**
143
     * Function to perform Adaptive Payments API's PaymentDetails operation.
144
     *
145
     * @param string $payKey
146
     *
147
     * @return array
148
     */
149
    public function getPaymentDetails($payKey)
150
    {
151
        return $this->getPaymentOptions($payKey, true);
152
    }
153
154
    /**
155
     * Get PayPal redirect url for processing payment.
156
     *
157
     * @param string $option
158
     * @param string $payKey
159
     *
160
     * @return string
161
     */
162
    public function getRedirectUrl($option, $payKey)
163
    {
164
        $url = $this->config['gateway_url'].'?cmd=';
165
166
        if ($option == 'approved') {
167
            $url .= '_ap-payment&paykey='.$payKey;
168
        } elseif ($option == 'pre-approved') {
169
            $url .= '_ap-preapproval&preapprovalkey='.$payKey;
170
        }
171
172
        return $url;
173
    }
174
175
    /**
176
     * Set receiver details for SetPaymentOptions.
177
     *
178
     * @param  array $receivers
179
     * @return array
180
     */
181
    private function setPaymentOptionsReceiverDetails($receivers)
182
    {
183
        return collect($receivers)->map(function ($receiver) {
184
            $item = [];
185
186
            $item['receiver'] = [
187
                'email' => $receiver['email'],
188
            ];
189
190
            $item['invoiceData']['item'] = collect($receiver['invoice_data'])->map(function ($invoice) {
191
                return $invoice;
192
            })->toArray();
193
194
            $item['description'] = $receiver['description'];
195
196
            return $item;
197
        })->toArray();
198
    }
199
200
    /**
201
     * Create request payload to be sent to PayPal.
202
     *
203
     * @param string $method
204
     */
205
    private function createRequestPayload($method)
206
    {
207
        $this->apiUrl = $this->config['api_url'].'/'.$method;
208
209
        $this->post = $this->post->merge($this->options);
210
    }
211
212
    /**
213
     * Perform PayPal API request & return response.
214
     *
215
     * @throws \Exception
216
     *
217
     * @return \Psr\Http\Message\StreamInterface
218
     */
219
    private function makeHttpRequest()
220
    {
221
        try {
222
            return $this->client->post($this->apiUrl, [
223
                'json'    => $this->post->toArray(),
224
                'headers' => $this->setHeaders(),
225
            ])->getBody();
226
        } catch (\GuzzleHttp\Exception\ClientException $e) {
227
            throw new \Exception(collect($e->getTrace())->implode('\n'));
228
        } catch (\GuzzleHttp\Exception\ServerException $e) {
229
            throw new \Exception(collect($e->getTrace())->implode('\n'));
230
        } catch (\GuzzleHttp\Exception\BadResponseException $e) {
231
            throw new \Exception(collect($e->getTrace())->implode('\n'));
232
        }
233
    }
234
235
    /**
236
     * Function To Perform PayPal API Request.
237
     *
238
     * @param string $method
239
     *
240
     * @throws \Exception
241
     *
242
     * @return array|mixed|\Psr\Http\Message\StreamInterface
243
     */
244
    private function doPayPalRequest($method)
245
    {
246
        // Setup PayPal API Request Payload
247
        $this->createRequestPayload($method);
248
249
        try {
250
            $response = $this->makeHttpRequest();
251
252
            return \GuzzleHttp\json_decode($response, true);
253
        } catch (\Exception $e) {
254
            $message = $e->getMessage();
255
        }
256
257
        return [
258
            'type'      => 'error',
259
            'message'   => $message,
260
        ];
261
    }
262
}
263