Passed
Push — master ( 7688e5...ca97a2 )
by Samuel
08:01
created

Mpesa::saveResultParams()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 2
dl 0
loc 6
ccs 0
cts 4
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Samerior\MobileMoney\Mpesa\Repositories;
4
5
6
use Illuminate\Support\Arr;
7
use Illuminate\Support\Facades\Log;
8
use Samerior\MobileMoney\Mpesa\Database\Entities\MpesaB2cResultParameter;
9
use Samerior\MobileMoney\Mpesa\Database\Entities\MpesaBulkPaymentRequest;
10
use Samerior\MobileMoney\Mpesa\Database\Entities\MpesaBulkPaymentResponse;
11
use Samerior\MobileMoney\Mpesa\Database\Entities\MpesaC2bCallback;
12
use Samerior\MobileMoney\Mpesa\Database\Entities\MpesaStkCallback;
13
use Samerior\MobileMoney\Mpesa\Database\Entities\MpesaStkRequest;
14
use Samerior\MobileMoney\Mpesa\Events\B2cPaymentFailedEvent;
15
use Samerior\MobileMoney\Mpesa\Events\B2cPaymentSuccessEvent;
16
use Samerior\MobileMoney\Mpesa\Events\C2bConfirmationEvent;
17
use Samerior\MobileMoney\Mpesa\Events\StkPushPaymentFailedEvent;
18
use Samerior\MobileMoney\Mpesa\Events\StkPushPaymentSuccessEvent;
19
use Gahlawat\Slack\Facade\Slack;
20
use Illuminate\Support\Facades\Auth;
21
22
/**
23
 * Class Mpesa
24
 * @package Samerior\MobileMoney\Repositories
25
 */
26
class Mpesa
27
{
28
    /**
29
     * @param string $json
30
     * @return $this|array|\Illuminate\Database\Eloquent\Model
31
     */
32
    public function processStkPushCallback($json)
33
    {
34
        $object = json_decode($json);
35
        $data = $object->stkCallback;
36
        $real_data = [
37
            'MerchantRequestID' => $data->MerchantRequestID,
38
            'CheckoutRequestID' => $data->CheckoutRequestID,
39
            'ResultCode' => $data->ResultCode,
40
            'ResultDesc' => $data->ResultDesc,
41
        ];
42
        if ($data->ResultCode == 0) {
43
            $_payload = $data->CallbackMetadata->Item;
44
            foreach ($_payload as $callback) {
45
                $real_data[$callback->Name] = @$callback->Value;
46
            }
47
            $callback = MpesaStkCallback::create($real_data);
48
        } else {
49
            $callback = MpesaStkCallback::create($real_data);
50
        }
51
        $this->fireStkEvent($callback, get_object_vars($data));
52
        return $callback;
53
    }
54
55
    /**
56
     * @param $response
57
     * @param array $body
58
     * @return MpesaBulkPaymentRequest|\Illuminate\Database\Eloquent\Model
59
     */
60
    public function saveB2cRequest($response, $body = [])
61
    {
62
        return MpesaBulkPaymentRequest::create([
63
            'conversation_id' => $response->ConversationID,
64
            'originator_conversation_id' => $response->OriginatorConversationID,
65
            'amount' => $body['Amount'],
66
            'phone' => $body['PartyB'],
67
            'remarks' => $body['Remarks'],
68
            'CommandID' => $body['CommandID'],
69
            'user_id' => Auth::id(),
70
        ]);
71
    }
72
73
    /**
74
     * @param string $json
75
     * @return $this|\Illuminate\Database\Eloquent\Model
76
     */
77
    public function processConfirmation($json)
78
    {
79
        $data = json_decode($json, true);
80
        $callback = MpesaC2bCallback::create($data);
81
        event(new C2bConfirmationEvent($callback, $data));
82
        return $callback;
83
    }
84
85
    /**
86
     * @return MpesaBulkPaymentResponse|\Illuminate\Database\Eloquent\Model
87
     */
88
    private function handleB2cResult()
89
    {
90
        $data = request('Result');
91
92
        //check if data is an array
93
        if (!is_array($data)) {
94
            $data->toArray();
95
        }
96
97
        $common = [
98
            'ResultType', 'ResultCode', 'ResultDesc', 'OriginatorConversationID', 'ConversationID', 'TransactionID'
99
        ];
100
        $seek = ['OriginatorConversationID' => $data['OriginatorConversationID']];
101
        /** @var MpesaBulkPaymentResponse $response */
102
        $response = null;
0 ignored issues
show
Unused Code introduced by
$response is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
103
        if ($data['ResultCode'] !== 0) {
104
            $response = MpesaBulkPaymentResponse::updateOrCreate($seek, Arr::only($data, $common));
105
            event(new B2cPaymentFailedEvent($response, $data));
106
            return $response;
107
        }
108
        $resultParameter = $data['ResultParameters'];
109
110
        $data['ResultParameters'] = json_encode($resultParameter);
111
        $response = MpesaBulkPaymentResponse::updateOrCreate($seek, Arr::except($data, ['ReferenceData']));
112
        $this->saveResultParams($resultParameter, $response);
113
        event(new B2cPaymentSuccessEvent($response, $data));
114
        return $response;
115
    }
116
117
    private function saveResultParams(array $params, MpesaBulkPaymentResponse $response): \Illuminate\Database\Eloquent\Model
118
    {
119
        $params_payload = $params['ResultParameter'];
120
        $new_params = Arr::pluck($params_payload, 'Value', 'Key');
121
        return $response->data()->create($new_params);
122
    }
123
124
    /**
125
     * @param string|null $initiator
126
     * @return MpesaBulkPaymentResponse|void
127
     */
128
    public function handleResult($initiator = null)
129
    {
130
        if ($initiator === 'b2c') {
131
            return $this->handleB2cResult();
132
        }
133
        return;
134
    }
135
136
    /**
137
     * @param $title
138
     * @param bool $important
139
     */
140
    public function notification($title, $important = false): void
141
    {
142
        $slack = \config('samerior.mpesa.notifications.slack_web_hook');
143
        if (!$important && empty($slack) && \config('samerior.mpesa.notifications.only_important')) {
144
            return;
145
        }
146
        \config([
147
            'slack.incoming-webhook' => \config('samerior.mpesa.notifications.slack_web_hook'),
148
            'slack.default_username' => 'MPESA',
149
            'slack.default_emoji' => ':mailbox_with_mail:',]);
150
        Slack::send($title);
151
        Slack::send('```' . json_encode(request()->all(), JSON_PRETTY_PRINT) . '```');
152
    }
153
154
    /**
155
     * @return array
156
     */
157
    public function queryStkStatus(): array
158
    {
159
        /** @var MpesaStkRequest[] $stk */
160
        $stk = MpesaStkRequest::whereDoesntHave('response')->get();
161
        $success = $errors = [];
162
        foreach ($stk as $item) {
163
            try {
164
                $status = mpesa_stk_status($item->id);
165
                if (isset($status->errorMessage)) {
166
                    $errors[$item->CheckoutRequestID] = $status->errorMessage;
167
                    continue;
168
                }
169
                $attributes = [
170
                    'MerchantRequestID' => $status->MerchantRequestID,
171
                    'CheckoutRequestID' => $status->CheckoutRequestID,
172
                    'ResultCode' => $status->ResultCode,
173
                    'ResultDesc' => $status->ResultDesc,
174
                    'Amount' => $item->amount,
175
                ];
176
                $errors[$item->CheckoutRequestID] = $status->ResultDesc;
177
                $callback = MpesaStkCallback::create($attributes);
178
                $this->fireStkEvent($callback, get_object_vars($status));
179
            } catch (\Exception $e) {
180
                $errors[$item->CheckoutRequestID] = $e->getMessage();
181
            }
182
        }
183
        return ['successful' => $success, 'errors' => $errors];
184
    }
185
186
    /**
187
     * @param MpesaStkCallback $stkCallback
188
     * @param array $response
189
     * @return MpesaStkCallback
190
     */
191
    private function fireStkEvent(MpesaStkCallback $stkCallback, $response): MpesaStkCallback
192
    {
193
        if ($stkCallback->ResultCode == 0) {
194
            event(new StkPushPaymentSuccessEvent($stkCallback, $response));
195
        } else {
196
            event(new StkPushPaymentFailedEvent($stkCallback, $response));
197
        }
198
        return $stkCallback;
199
    }
200
}
201