Completed
Push — master ( 0c2f78...613e31 )
by Kazi Mainuddin
02:31
created

PaymentController::getFormDataArray()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 7
nc 3
nop 1
1
<?php
2
namespace Tzsk\Payu\Controllers;
3
4
use App\Http\Controllers\Controller;
5
use Illuminate\Http\Request;
6
use Illuminate\Support\Facades\Session;
7
use Illuminate\Support\Facades\Validator;
8
use Tzsk\Payu\Helpers\Config;
9
use Tzsk\Payu\Helpers\Storage;
10
use Tzsk\Payu\Model\PayuPayment;
11
use Tzsk\Payu\ProcessPayment;
12
13
class PaymentController extends Controller
14
{
15
    /**
16
     * @var Config
17
     */
18
    protected $config;
19
20
    /**
21
     * @var Storage
22
     */
23
    protected $storage;
24
25
    /**
26
     * PaymentController constructor.
27
     */
28
    public function __construct()
29
    {
30
        $this->config = new Config();
31
        $this->storage = new Storage();
32
    }
33
34
    /**
35
     * Got to payment.
36
     *
37
     * @param Request $request
38
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
39
     */
40
    public function index(Request $request)
41
    {
42
        $payment = $this->getPaymentFormInformation($request);
43
44
        return view('tzsk::payment_form', compact('payment'));
45
    }
46
47
    /**
48
     * After payment it will return here.
49
     *
50
     * @param Request $request
51
     * @return \Illuminate\Http\RedirectResponse
52
     */
53
    public function payment(Request $request)
54
    {
55
        $attributes = $request->only([
56
            'txnid', 'mihpayid', 'firstname', 'email', 'phone', 'amount', 'discount',
57
            'net_amount_debit', 'data', 'status', 'unmappedstatus', 'mode', 'bank_ref_num',
58
            'bankcode', 'cardnum', 'name_on_card', 'issuing_bank', 'card_type'
59
        ]);
60
        $attributes['data'] = json_encode($request->all());
61
        $process = new ProcessPayment($request);
62
        $attributes['status'] = $process->getStatus();
63
64
        $this->generatePaymentObject($attributes);
65
66
        return redirect()->to(base64_decode($request->callback));
67
    }
68
69
    /**
70
     * @param  Request $request
71
     * @return object
72
     * @throws \Exception
73
     */
74
    protected function getPaymentFormInformation(Request $request)
75
    {
76
        $form_fields = $this->getFormFields($request);
77
78
        $prefix = ($this->config->getEnv() == 'secure') ? 'secure' : 'test';
79
        $url = "https://{$prefix}.".$this->config->getEndpoint();
80
81
        $payment = (object) ['fields' => $form_fields, 'url' => $url];
82
83
        return $payment;
84
    }
85
86
    /**
87
     * @param Request $request
88
     * @return string
89
     */
90
    protected function getHashChecksum(Request $request)
91
    {
92
        $fields = array_merge($this->config->getRequiredFields(), $this->config->getOptionalFields());
93
94
        $hash_array = [];
95
        foreach (collect($fields)->flip()->except(['phone'])->flip() as $field) {
96
            $hash_array[] = $request->has($field) ? $request->get($field) : "";
97
        }
98
99
        $checksum_array = array_merge([$this->config->getKey()], $hash_array, [$this->config->getSalt()]);
100
101
        $hash = hash('sha512', implode('|', $checksum_array));
102
103
        return $hash;
104
    }
105
106
    /**
107
     * @param Request $request
108
     * @return array
109
     */
110
    protected function validateRequest(Request $request)
111
    {
112
        $validation = collect(array_flip($this->config->getRequiredFields()))->map(function () {
113
            return 'required';
114
        })->all();
115
116
        $data = $this->getFormDataArray($request);
117
118
        $validator = Validator::make($request->all(), $validation);
119
120
        if ($validator->fails()) {
121
            throw new \InvalidArgumentException($validator->errors()->first());
122
        }
123
124
        return $data;
125
    }
126
127
    /**
128
     * Generate the payment model Object for use.
129
     *
130
     * @param $attributes
131
     */
132
    protected function generatePaymentObject($attributes)
133
    {
134
        $model = $this->storage->getModel();
135
136
        if ($this->config->getDriver() == 'database') {
137
            $payment_instance = PayuPayment::create($attributes);
138
139
            if (!empty($model)) {
140
                $payment_instance->fill([
141
                    'payable_id' => $model['id'],
142
                    'payable_type' => $model['class']
143
                ])->save();
144
            }
145
146
            $payment = $payment_instance->id;
147
        } else {
148
            $payment = $attributes;
149
        }
150
151
        Session::put('tzsk_payu_data.payment', $payment);
152
    }
153
154
    /**
155
     * Get the form data array.
156
     *
157
     * @param Request $request
158
     * @return array
159
     */
160
    private function getFormDataArray(Request $request)
161
    {
162
        $data = [];
163
        $items = collect($this->config->getRequiredFields())->merge($this->config->getOptionalFields())
164
            ->merge($this->config->getAdditionalFields());
165
166
        foreach ($items as $item) {
167
            $request->has($item) ? $data[$item] = $request->get($item) : null;
168
        }
169
170
        return $data;
171
    }
172
173
    /**
174
     * Get Status url.
175
     *
176
     * @return string
177
     * @throws \Exception
178
     */
179
    private function getStatusUrl()
180
    {
181
        $status_url = $this->storage->getStatusUrl();
182
183
        if (empty($status_url)) {
184
            throw new \Exception("There is no Redirect URL specified.");
185
        }
186
187
        return urlencode(base64_encode($status_url));
188
    }
189
190
    /**
191
     * @param Request $request
192
     * @return array
193
     */
194
    protected function getFormFields(Request $request)
195
    {
196
        $data = $this->storage->getData();
197
        $status_url = $this->getStatusUrl();
198
199
        $request->replace($data);
200
        $validation = $this->validateRequest($request);
201
        $hash = $this->getHashChecksum($request);
202
203
        $redirect = collect($this->config->getRedirect())->map(function ($value) use ($request, $status_url) {
204
            $separator = str_contains($value, '?') ? '&' : '?';
205
            return url($value.$separator.'_token='.csrf_token().'&'.'callback='.$status_url);
206
        })->all();
207
208
        $form_fields = array_merge(['key' => $this->config->getKey(), 'hash' => $hash],
209
            array_merge($redirect, $validation));
210
211
        return $form_fields;
212
    }
213
}
214