Completed
Push — master ( 915d32...5ba690 )
by Raza
02:05
created

AdaptivePayments::createPayRequest()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 0 Features 0
Metric Value
cc 3
eloc 5
nc 2
nop 1
dl 0
loc 10
rs 9.4285
c 5
b 0
f 0
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
     * Set request details for Pay API operation.
72
     *
73
     * @param array $data
74
     *
75
     * @return void
76
     */
77
    private function setPayRequestDetails($data)
78
    {
79
        $this->post = $this->setRequestData([
80
            'actionType'        => 'PAY',
81
            'currencyCode'      => $this->currency,
82
            'receiverList'      => [
83
                'receiver'      => $data['receivers'],
84
            ],
85
            'returnUrl'         => $data['return_url'],
86
            'cancelUrl'         => $data['cancel_url'],
87
            'requestEnvelope'   => $this->setEnvelope(),
88
            'feesPayer'         => $data['payer'],
89
        ])->filter(function ($value, $key) use ($data) {
90
            return (($key === 'feesPayer') && empty($value)) ?: $value;
91
        });
92
    }
93
94
    /**
95
     * Function to perform Adaptive Payments API's PAY operation.
96
     *
97
     * @param array $data
98
     *
99
     * @throws \Exception
100
     *
101
     * @return array
102
     */
103
    public function createPayRequest($data)
104
    {
105
        if (empty($data['return_url']) && empty($data['cancel_url'])) {
106
            throw new \Exception('Return & Cancel URL should be specified');
107
        }
108
109
        $this->setPayRequestDetails($data);
110
111
        return $this->doPayPalRequest('Pay');
112
    }
113
114
    /**
115
     * Function to perform Adaptive Payments API's SetPaymentOptions operation.
116
     *
117
     * @param string $payKey
118
     * @param array  $receivers
119
     *
120
     * @return array
121
     */
122
    public function setPaymentOptions($payKey, $receivers)
123
    {
124
        $this->post = $this->setRequestData([
125
            'requestEnvelope' => $this->setEnvelope(),
126
            'payKey'          => $payKey,
127
        ])->merge([
128
            'receiverOptions' => $this->setPaymentOptionsReceiverDetails($receivers),
129
        ]);
130
131
        return $this->doPayPalRequest('SetPaymentOptions');
132
    }
133
134
    /**
135
     * Function to perform Adaptive Payments API's GetPaymentOptions operation.
136
     *
137
     * @param string $payKey
138
     * @param bool   $details
139
     *
140
     * @return array
141
     */
142
    public function getPaymentOptions($payKey, $details = false)
143
    {
144
        $operation = ($details) ? 'PaymentDetails' : 'GetPaymentOptions';
145
146
        $this->setRequestData([
147
            'requestEnvelope' => $this->setEnvelope(),
148
            'payKey'          => $payKey,
149
        ]);
150
151
        return $this->doPayPalRequest($operation);
152
    }
153
154
    /**
155
     * Function to perform Adaptive Payments API's PaymentDetails operation.
156
     *
157
     * @param string $payKey
158
     *
159
     * @return array
160
     */
161
    public function getPaymentDetails($payKey)
162
    {
163
        return $this->getPaymentOptions($payKey, true);
164
    }
165
166
    /**
167
     * Get PayPal redirect url for processing payment.
168
     *
169
     * @param string $option
170
     * @param string $payKey
171
     *
172
     * @return string
173
     */
174
    public function getRedirectUrl($option, $payKey)
175
    {
176
        $url = $this->config['gateway_url'].'?cmd=';
177
178
        if ($option == 'approved') {
179
            $url .= '_ap-payment&paykey='.$payKey;
180
        } elseif ($option == 'pre-approved') {
181
            $url .= '_ap-preapproval&preapprovalkey='.$payKey;
182
        }
183
184
        return $url;
185
    }
186
187
    /**
188
     * Set receiver details for SetPaymentOptions.
189
     *
190
     * @param  array $receivers
191
     *
192
     * @return array
193
     */
194
    private function setPaymentOptionsReceiverDetails($receivers)
195
    {
196
        return collect($receivers)->map(function ($receiver) {
197
            $item = [];
198
199
            $item['receiver'] = [
200
                'email' => $receiver['email'],
201
            ];
202
203
            $item['invoiceData']['item'] = collect($receiver['invoice_data'])->map(function ($invoice) {
204
                return $invoice;
205
            })->toArray();
206
207
            $item['description'] = $receiver['description'];
208
209
            return $item;
210
        })->toArray();
211
    }
212
213
    /**
214
     * Create request payload to be sent to PayPal.
215
     *
216
     * @param string $method
217
     */
218
    private function createRequestPayload($method)
219
    {
220
        $this->apiUrl = $this->config['api_url'].'/'.$method;
221
222
        $this->post = $this->post->merge($this->options);
223
    }
224
225
    /**
226
     * Perform PayPal API request & return response.
227
     *
228
     * @throws \Exception
229
     *
230
     * @return \Psr\Http\Message\StreamInterface
231
     */
232
    private function makeHttpRequest()
233
    {
234
        try {
235
            return $this->client->post($this->apiUrl, [
236
                'json'    => $this->post->toArray(),
237
                'headers' => $this->setHeaders(),
238
            ])->getBody();
239
        } catch (\GuzzleHttp\Exception\ClientException $e) {
240
            throw new \Exception(collect($e->getTrace())->implode('\n'));
241
        } catch (\GuzzleHttp\Exception\ServerException $e) {
242
            throw new \Exception(collect($e->getTrace())->implode('\n'));
243
        } catch (\GuzzleHttp\Exception\BadResponseException $e) {
244
            throw new \Exception(collect($e->getTrace())->implode('\n'));
245
        }
246
    }
247
248
    /**
249
     * Function To Perform PayPal API Request.
250
     *
251
     * @param string $method
252
     *
253
     * @throws \Exception
254
     *
255
     * @return array|mixed|\Psr\Http\Message\StreamInterface
256
     */
257
    private function doPayPalRequest($method)
258
    {
259
        // Setup PayPal API Request Payload
260
        $this->createRequestPayload($method);
261
262
        try {
263
            $response = $this->makeHttpRequest();
264
265
            return \GuzzleHttp\json_decode($response, true);
266
        } catch (\Exception $e) {
267
            $message = $e->getMessage();
268
        }
269
270
        return [
271
            'type'      => 'error',
272
            'message'   => $message,
273
        ];
274
    }
275
}
276