Issues (52)

src/Drivers/Sepehr/Sepehr.php (3 issues)

1
<?php
2
3
namespace Shetabit\Multipay\Drivers\Sepehr;
4
5
use Shetabit\Multipay\Abstracts\Driver;
6
use Shetabit\Multipay\Exceptions\InvalidPaymentException;
7
use Shetabit\Multipay\Exceptions\PurchaseFailedException;
8
use Shetabit\Multipay\Contracts\ReceiptInterface;
9
use Shetabit\Multipay\Invoice;
10
use Shetabit\Multipay\Receipt;
11
use Shetabit\Multipay\RedirectionForm;
12
use Shetabit\Multipay\Request;
13
14
class Sepehr extends Driver
15
{
16
    /**
17
     * Invoice
18
     *
19
     * @var Invoice
20
     */
21
    protected $invoice;
22
23
    /**
24
     * Driver settings
25
     *
26
     * @var object
27
     */
28
    protected $settings;
29
30
    /**
31
     * Sepehr constructor.
32
     * Construct the class with the relevant settings.
33
     *
34
     * @param Invoice $invoice
35
     * @param $settings
36
     */
37
    public function __construct(Invoice $invoice, $settings)
38
    {
39
        $this->invoice($invoice);
40
        $this->settings = (object)$settings;
41
    }
42
43
    /**
44
     * Purchase Invoice.
45
     *
46
     * @return string
47
     *
48
     * @throws PurchaseFailedException
49
     */
50
    public function purchase()
51
    {
52
        $amount = $this->invoice->getAmount() * ($this->settings->currency == 'T' ? 10 : 1); // convert to rial
53
54
        $mobile = '';
55
        //set CellNumber for get user cards
56
        if (!empty($this->invoice->getDetails()['mobile'])) {
57
            $mobile = '&CellNumber=' . $this->invoice->getDetails()['mobile'];
58
        }
59
60
        $data_query = 'Amount=' . $this->test_input($amount) . '&callbackURL=' . $this->test_input($this->settings->callbackUrl) . '&InvoiceID=' . $this->test_input($this->invoice->getUuid()) . '&TerminalID=' . $this->test_input($this->settings->terminalId) . '&Payload=' . $this->test_input("") . $mobile;
61
        $address_service_token = $this->settings->apiGetToken;
62
63
        $token_array = $this->makeHttpChargeRequest('POST', $data_query, $address_service_token);
64
65
        if ($token_array === false) {
66
            throw new PurchaseFailedException('درگاه مورد نظر پاسخگو نمی‌باشد، لطفا لحظاتی بعد امتحان کنید.');
67
        }
68
69
        $decode_token_array = json_decode($token_array);
0 ignored issues
show
It seems like $token_array can also be of type true; however, parameter $json of json_decode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

69
        $decode_token_array = json_decode(/** @scrutinizer ignore-type */ $token_array);
Loading history...
70
71
        $status = $decode_token_array->Status;
72
        $access_token = $decode_token_array->Accesstoken;
73
74
        if (empty($access_token) && $status != 0) {
75
            $this->purchaseFailed($status);
76
        }
77
78
        $this->invoice->transactionId($access_token);
79
        // return the transaction's id
80
        return $this->invoice->getTransactionId();
81
    }
82
83
    /**
84
     * Pay the Invoice
85
     *
86
     * @return RedirectionForm
87
     */
88
    public function pay(): RedirectionForm
89
    {
90
        return $this->redirectWithForm($this->settings->apiPaymentUrl, [
91
            'token' => $this->invoice->getTransactionId(),
92
            'terminalID' => $this->settings->terminalId
93
        ], 'POST');
94
    }
95
96
    /**
97
     * Verify payment
98
     *
99
     * @return ReceiptInterface
100
     *
101
     * @throws InvalidPaymentException
102
     *
103
     */
104
    public function verify(): ReceiptInterface
105
    {
106
        $responseCode = Request::input('respcode');
107
        $amount = $this->invoice->getAmount() * ($this->settings->currency == 'T' ? 10 : 1); // convert to rial
108
109
        if ($responseCode != 0) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $responseCode of type mixed|null to 0; this is ambiguous as not only 0 == 0 is true, but null == 0 is true, too. Consider using a strict comparison ===.
Loading history...
110
            $this->notVerified($responseCode);
111
        }
112
113
        $data_query = 'digitalreceipt=' . Request::input('digitalreceipt') . '&Tid=' . $this->settings->terminalId;
114
        $advice_array = $this->makeHttpChargeRequest('POST', $data_query, $this->settings->apiVerificationUrl);
115
        $decode_advice_array = json_decode($advice_array);
0 ignored issues
show
It seems like $advice_array can also be of type true; however, parameter $json of json_decode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

115
        $decode_advice_array = json_decode(/** @scrutinizer ignore-type */ $advice_array);
Loading history...
116
117
        $status = $decode_advice_array->Status;
118
        $return_id = $decode_advice_array->ReturnId;
119
120
        if ($status == "Ok") {
121
            if ($return_id != $amount) {
122
                throw new InvalidPaymentException('مبلغ واریز با قیمت محصول برابر نیست');
123
            }
124
            return $this->createReceipt(Request::input('rrn'));
125
        } else {
126
            $message = 'تراکنش نا موفق بود در صورت کسر مبلغ از حساب شما حداکثر پس از 72 ساعت مبلغ به حسابتان برمیگردد.';
127
            throw new InvalidPaymentException($message);
128
        }
129
    }
130
131
    /**
132
     * Generate the payment's receipt
133
     *
134
     * @param $referenceId
135
     *
136
     * @return Receipt
137
     */
138
    protected function createReceipt($referenceId)
139
    {
140
        $receipt = new Receipt('sepehr', $referenceId);
141
142
        return $receipt;
143
    }
144
145
    /**
146
     * Trigger an exception
147
     *
148
     * @param $status
149
     *
150
     * @throws PurchaseFailedException
151
     */
152
    protected function purchaseFailed($status)
153
    {
154
        $translations = array(
155
            -1 => 'تراکنش پیدا نشد.',
156
            -2 => 'عدم تطابق ip و یا بسته بودن port 8081',
157
            -3 => '‫ها‬ ‫‪Exception‬‬ ‫خطای‬ ‫–‬ ‫عمومی‬ ‫خطای‬ ‫‪Total‬‬ ‫‪Error‬‬',
158
            -4 => 'امکان انجام درخواست برای این تراکنش وجود ندارد.',
159
            -5 => 'آدرس ip نامعتبر می‌باشد.',
160
            -6 => 'عدم فعال بودن سرویس برگشت تراکنش برای پذیرنده',
161
        );
162
163
        if (array_key_exists($status, $translations)) {
164
            throw new PurchaseFailedException($translations[$status]);
165
        } else {
166
            throw new PurchaseFailedException('خطای ناشناخته ای رخ داده است.');
167
        }
168
    }
169
170
    /**
171
     * Trigger an exception
172
     *
173
     * @param $status
174
     *
175
     * @throws InvalidPaymentException
176
     */
177
    private function notVerified($status)
178
    {
179
        $translations = array(
180
            -1 => ' تراکنش توسط خریدار کنسل شده است.',
181
            -2 => 'زمان انجام تراکنش برای کاربر به پایان رسیده است.',
182
            -3 => '‫ها‬ ‫‪Exception‬‬ ‫خطای‬ ‫–‬ ‫عمومی‬ ‫خطای‬ ‫‪Total‬‬ ‫‪Error‬‬',
183
            -4 => 'امکان انجام درخواست برای این تراکنش وجود ندارد.',
184
            -5 => 'آدرس ip نامعتبر می‌باشد.',
185
            -6 => 'عدم فعال بودن سرویس برگشت تراکنش برای پذیرنده',
186
        );
187
188
        if (array_key_exists($status, $translations)) {
189
            throw new InvalidPaymentException($translations[$status], (int)$status);
190
        } else {
191
            throw new InvalidPaymentException('خطای ناشناخته ای رخ داده است.', (int)$status);
192
        }
193
    }
194
195
    private function test_input($data)
196
    {
197
        $data = trim($data);
198
        $data = stripslashes($data);
199
        $data = htmlspecialchars($data);
200
        return $data;
201
    }
202
203
    private function makeHttpChargeRequest($_Method, $_Data, $_Address)
204
    {
205
        $curl = curl_init();
206
        curl_setopt($curl, CURLOPT_URL, $_Address);
207
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $_Method);
208
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
209
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
210
        curl_setopt($curl, CURLOPT_POSTFIELDS, $_Data);
211
        $result = curl_exec($curl);
212
        curl_close($curl);
213
        return $result;
214
    }
215
}
216