Passed
Push — master ( 015cf1...83dbe9 )
by Brian
14:23
created

Disbursement::transfer()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 32
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 4.001

Importance

Changes 0
Metric Value
cc 4
eloc 21
c 0
b 0
f 0
nc 4
nop 5
dl 0
loc 32
ccs 24
cts 25
cp 0.96
crap 4.001
rs 9.584
1
<?php
2
3
/**
4
 * Disbursement service/product.
5
 */
6
7
namespace Bmatovu\MtnMomo\Products;
8
9
use Bmatovu\MtnMomo\Exceptions\DisbursementRequestException;
10
use GuzzleHttp\ClientInterface;
11
use GuzzleHttp\Exception\RequestException;
12
use Illuminate\Container\Container;
13
use Illuminate\Contracts\Config\Repository;
14
use Ramsey\Uuid\Uuid;
15
16
/**
17
 * Class Disbursement.
18
 */
19
class Disbursement extends Product
20
{
21
    /**
22
     * Product.
23
     *
24
     * @var string
25
     */
26
    const PRODUCT = 'disbursement';
27
28
    /**
29
     * Transact URI.
30
     *
31
     * @var string
32
     */
33
    protected $transactionUri;
34
35
    /**
36
     * Transaction status URI.
37
     *
38
     * @var string
39
     */
40
    protected $transactionStatusUri;
41
42
    /**
43
     * Account status URI.
44
     *
45
     * @var string
46
     */
47
    protected $accountStatusUri;
48
49
    /**
50
     * Account balance URI.
51
     *
52
     * @var string
53
     */
54
    protected $accountBalanceUri;
55
56
    /**
57
     * Account holder basic info URI.
58
     *
59
     * @var string
60
     */
61
    protected $accountHolderInfoUri;
62
63
    /**
64
     * @return string
65
     */
66
    public function getTransactionUri()
67
    {
68
        return $this->transactionUri;
69
    }
70
71
    /**
72
     * @param string $transactionUri
73
     */
74
    public function setTransactionUri($transactionUri)
75
    {
76
        $this->transactionUri = $transactionUri;
77
    }
78
79
    /**
80
     * @return string
81
     */
82
    public function getTransactionStatusUri()
83
    {
84
        return $this->transactionStatusUri;
85
    }
86
87
    /**
88
     * @param string $transactionStatusUri
89
     */
90
    public function setTransactionStatusUri($transactionStatusUri)
91
    {
92
        $this->transactionStatusUri = $transactionStatusUri;
93
    }
94
95
    /**
96
     * @return string
97
     */
98
    public function getAccountStatusUri()
99
    {
100
        return $this->accountStatusUri;
101
    }
102
103
    /**
104
     * @param string $accountStatusUri
105
     */
106
    public function setAccountStatusUri($accountStatusUri)
107
    {
108
        $this->accountStatusUri = $accountStatusUri;
109
    }
110
111
    /**
112
     * @return string
113
     */
114
    public function getAccountBalanceUri()
115
    {
116
        return $this->accountBalanceUri;
117
    }
118
119
    /**
120
     * @param string $accountBalanceUri
121
     */
122
    public function setAccountBalanceUri($accountBalanceUri)
123
    {
124
        $this->accountBalanceUri = $accountBalanceUri;
125
    }
126
127
    /**
128
     * @return string
129
     */
130
    public function getAccountHolderInfoUri()
131
    {
132
        return $this->accountHolderInfoUri;
133
    }
134
135
    /**
136
     * @param string $accountHolderInfoUri
137
     */
138
    public function setAccountHolderInfoUri($accountHolderInfoUri)
139
    {
140
        $this->accountHolderInfoUri = $accountHolderInfoUri;
141
    }
142
143
    /**
144
     * Disbursement constructor.
145
     *
146
     * @param array $headers
147
     * @param array $middleware
148
     * @param \GuzzleHttp\ClientInterface $client
149
     *
150
     * @uses \Illuminate\Contracts\Config\Repository
151
     *
152
     * @throws \Exception
153
     */
154 8
    public function __construct(array $headers = [], array $middleware = [], ClientInterface $client = null)
155
    {
156 8
        $config = Container::getInstance()->make(Repository::class);
157
158 8
        $this->subscriptionKey = $config->get('mtn-momo.products.disbursement.key');
159 8
        $this->clientId = $config->get('mtn-momo.products.disbursement.id');
160 8
        $this->clientSecret = $config->get('mtn-momo.products.disbursement.secret');
161 8
        $this->clientCallbackUri = $config->get('mtn-momo.products.disbursement.callback_uri');
162
163 8
        $this->tokenUri = $config->get('mtn-momo.products.disbursement.token_uri');
164 8
        $this->transactionUri = $config->get('mtn-momo.products.disbursement.transaction_uri');
165 8
        $this->transactionStatusUri = $config->get('mtn-momo.products.disbursement.transaction_status_uri');
166 8
        $this->accountStatusUri = $config->get('mtn-momo.products.disbursement.account_status_uri');
167 8
        $this->accountBalanceUri = $config->get('mtn-momo.products.disbursement.account_balance_uri');
168 8
        $this->accountHolderInfoUri = $config->get('mtn-momo.products.disbursement.account_holder_info_uri');
169 8
        $this->partyIdType = $config->get('mtn-momo.products.disbursement.party_id_type');
170
171 8
        parent::__construct($headers, $middleware, $client);
172
    }
173
174
    /**
175
     * Request disbursement access token.
176
     *
177
     * @see https://momodeveloper.mtn.com/docs/services/disbursement/operations/token-POST Documentation
178
     *
179
     * @throws \GuzzleHttp\Exception\GuzzleException
180
     *
181
     * @return array
182
     */
183 1
    public function getToken()
184
    {
185
        try {
186 1
            $response = $this->client->request('POST', $this->tokenUri, [
187 1
                'headers' => [
188 1
                    'Authorization' => 'Basic '.base64_encode($this->clientId.':'.$this->clientSecret),
189 1
                ],
190 1
                'json' => [
191 1
                    'grant_type' => 'client_credentials',
192 1
                ],
193 1
            ]);
194
195 1
            return json_decode($response->getBody(), true);
196
        } catch (RequestException $ex) {
197
            throw new DisbursementRequestException('Unable to get token.', 0, $ex);
198
        }
199
    }
200
201
    /**
202
     * Transfer an amount to a payee account.
203
     *
204
     * @see https://momodeveloper.mtn.com/docs/services/disbursement/operations/transfer-POST Documentation
205
     *
206
     * @param  string $transactionId Transaction reference ID.
207
     * @param  string $partyId Account holder. Usually phone number if type is MSISDN.
208
     * @param  int $amount How much to transfer to payee account.
209
     * @param  string $payerMessage Payer transaction history message.
210
     * @param  string $payeeNote Payee transaction history message.
211
     *
212
     * @throws \Bmatovu\MtnMomo\Exceptions\DisbursementRequestException
213
     * @throws \GuzzleHttp\Exception\GuzzleException
214
     * @throws \Exception
215
     *
216
     * @return string $momoTransactionId                Auto generated payment reference. Format: UUID
217
     */
218 2
    public function transfer($transactionId, $partyId, $amount, $payerMessage = '', $payeeNote = '')
219
    {
220 2
        $momoTransactionId = Uuid::uuid4()->toString();
221
222 2
        $headers = [
223 2
            'X-Reference-Id' => $momoTransactionId,
224 2
            'X-Target-Environment' => $this->environment,
225 2
        ];
226
227 2
        if ($this->environment != 'sandbox' && $this->clientCallbackUri) {
228
            $headers['X-Callback-Url'] = $this->clientCallbackUri;
229
        }
230
231
        try {
232 2
            $this->client->request('POST', $this->transactionUri, [
233 2
                'headers' => $headers,
234 2
                'json' => [
235 2
                    'amount' => $amount,
236 2
                    'currency' => $this->currency,
237 2
                    'externalId' => $transactionId,
238 2
                    'payee' => [
239 2
                        'partyIdType' => $this->partyIdType,
240 2
                        'partyId' => $partyId,
241 2
                    ],
242 2
                    'payerMessage' => alphanumeric($payerMessage),
243 2
                    'payeeNote' => alphanumeric($payeeNote),
244 2
                ],
245 2
            ]);
246
247 1
            return $momoTransactionId;
248 1
        } catch (RequestException $ex) {
249 1
            throw new DisbursementRequestException('Request to transfer transaction - unsuccessful.', 0, $ex);
250
        }
251
    }
252
253
    /**
254
     * Get transaction status.
255
     *
256
     * @see https://momodeveloper.mtn.com/docs/services/disbursement/operations/transfer-referenceId-GET Documentation
257
     *
258
     * @param  string $momoTransactionId That was returned by transfer (transferAmount)
259
     *
260
     * @throws \Bmatovu\MtnMomo\Exceptions\DisbursementRequestException
261
     * @throws \GuzzleHttp\Exception\GuzzleException
262
     *
263
     * @return array
264
     */
265 1
    public function getTransactionStatus($momoTransactionId)
266
    {
267 1
        $transaction_status_uri = str_replace('{momoTransactionId}', $momoTransactionId, $this->transactionStatusUri);
268
269
        try {
270 1
            $response = $this->client->request('GET', $transaction_status_uri, [
271 1
                'headers' => [
272 1
                    'X-Target-Environment' => $this->environment,
273 1
                ],
274 1
            ]);
275
276 1
            return json_decode($response->getBody(), true);
277
        } catch (RequestException $ex) {
278
            throw new DisbursementRequestException('Unable to get transaction status.', 0, $ex);
279
        }
280
    }
281
282
    /**
283
     * Get account balance.
284
     *
285
     * @see https://momodeveloper.mtn.com/docs/services/disbursement/operations/get-v1_0-account-balance Documentation
286
     *
287
     * @throws \Bmatovu\MtnMomo\Exceptions\DisbursementRequestException
288
     * @throws \GuzzleHttp\Exception\GuzzleException
289
     *
290
     * @return array Account balance.
291
     */
292 1
    public function getAccountBalance()
293
    {
294
        try {
295 1
            $response = $this->client->request('GET', $this->accountBalanceUri, [
296 1
                'headers' => [
297 1
                    'X-Target-Environment' => $this->environment,
298 1
                ],
299 1
            ]);
300
301 1
            return json_decode($response->getBody(), true);
302
        } catch (RequestException $ex) {
303
            throw new DisbursementRequestException('Unable to get account balance.', 0, $ex);
304
        }
305
    }
306
307
    /**
308
     * Determine if an account holder is registered and active.
309
     *
310
     * @see https://momodeveloper.mtn.com/docs/services/disbursement/operations/get-v1_0-accountholder-accountholderidtype-accountholderid-active Documentation
311
     *
312
     * @param  string $partyId Party number - MSISDN, email, or code - UUID.
313
     * @param  string $partyIdType Specifies the type of the account ID. Allowed values [msisdn, email, party_code].
314
     *
315
     * @throws \Bmatovu\MtnMomo\Exceptions\DisbursementRequestException
316
     * @throws \GuzzleHttp\Exception\GuzzleException
317
     *
318
     * @return bool True if account holder is registered and active, false if the account holder is not active or not found
319
     */
320 1
    public function isActive($partyId, $partyIdType = null)
321
    {
322 1
        if (is_null($partyIdType)) {
323 1
            $partyIdType = $this->partyIdType;
324
        }
325
326 1
        $patterns = $replacements = [];
327
328 1
        $patterns[] = '/(\{\bpartyIdType\b\})/';
329 1
        $replacements[] = strtolower($partyIdType);
330
331 1
        $patterns[] = '/(\{\bpartyId\b\})/';
332 1
        $replacements[] = urlencode($partyId);
333
334 1
        $accountStatusUri = preg_replace($patterns, $replacements, $this->accountStatusUri);
335
336
        try {
337 1
            $response = $this->client->request('GET', $accountStatusUri, [
338 1
                'headers' => [
339 1
                    'X-Target-Environment' => $this->environment,
340 1
                ],
341 1
            ]);
342
343 1
            $body = json_decode($response->getBody(), true);
344
345 1
            return (bool) $body['result'];
346
        } catch (RequestException $ex) {
347
            throw new DisbursementRequestException('Unable to get user account information.', 0, $ex);
348
        }
349
    }
350
351
    /**
352
     * Get basic info of an account holder.
353
     *
354
     * @see https://momodeveloper.mtn.com/docs/services/disbursement/operations/basicuserInfo-GET Documentation
355
     *
356
     * @param  string $partyId Party number - MSISDN.
357
     *
358
     * @throws \Bmatovu\MtnMomo\Exceptions\DisbursementRequestException
359
     * @throws \GuzzleHttp\Exception\GuzzleException
360
     *
361
     * @return array account basic info
362
     */
363 1
    public function getAccountHolderBasicInfo($partyId)
364
    {
365 1
        $patterns = $replacements = [];
366
367 1
        $patterns[] = '/(\{\bpartyId\b\})/';
368 1
        $replacements[] = urlencode($partyId);
369
370 1
        $accountHolderInfoUri = preg_replace($patterns, $replacements, $this->accountHolderInfoUri);
371
372
        try {
373 1
            $response = $this->client->request('GET', $accountHolderInfoUri, [
374 1
                'headers' => [
375 1
                    'X-Target-Environment' => $this->environment,
376 1
                ],
377 1
            ]);
378
379 1
            return json_decode($response->getBody(), true);
380
        } catch (RequestException $ex) {
381
            throw new DisbursementRequestException('Unable to get user account information.', 0, $ex);
382
        }
383
    }
384
}
385