Issues (52)

src/Drivers/Bitpay/Bitpay.php (2 issues)

Labels
Severity
1
<?php
2
3
namespace Shetabit\Multipay\Drivers\Bitpay;
4
5
use Shetabit\Multipay\Abstracts\Driver;
6
use Shetabit\Multipay\Contracts\ReceiptInterface;
7
use Shetabit\Multipay\Exceptions\InvalidPaymentException;
8
use Shetabit\Multipay\Exceptions\PurchaseFailedException;
9
use Shetabit\Multipay\Invoice;
10
use Shetabit\Multipay\Receipt;
11
use Shetabit\Multipay\RedirectionForm;
12
use Shetabit\Multipay\Request;
13
14
class Bitpay 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
    public function __construct(Invoice $invoice, $settings)
31
    {
32
        $this->invoice($invoice);
33
        $this->settings = (object) $settings;
34
    }
35
36
    /**
37
     * Retrieve data from details using its name.
38
     *
39
     * @return string
40
     */
41
    private function extractDetails($name)
42
    {
43
        return empty($this->invoice->getDetails()[$name]) ? null : $this->invoice->getDetails()[$name];
44
    }
45
46
    /**
47
     * @return string
48
     *
49
     * @throws \Shetabit\Multipay\Exceptions\PurchaseFailedException
50
     */
51
    public function purchase()
52
    {
53
        $name = $this->extractDetails('name');
54
        $email = $this->extractDetails('email');
55
        $description = $this->extractDetails('description');
56
        $factorId = $this->extractDetails('factorId');
57
        $api = $this->settings->api_token;
58
        $amount = $this->invoice->getAmount() * ($this->settings->currency == 'T' ? 10 : 1); // convert to rial
59
        $redirect = $this->settings->callbackUrl;
60
61
        $ch = curl_init();
62
        curl_setopt($ch, CURLOPT_URL, $this->settings->apiPurchaseUrl);
63
        curl_setopt($ch, CURLOPT_POSTFIELDS, "api={$api}&amount={$amount}&redirect={$redirect}&factorId={$factorId}&name={$name}&email={$email}&description={$description}");
64
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
65
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
66
        $res = curl_exec($ch);
67
        curl_close($ch);
68
69
        if ($res > 0 && is_numeric($res)) {
70
            $this->invoice->transactionId($res);
71
72
            return $this->invoice->getTransactionId();
73
        }
74
75
        throw new PurchaseFailedException($this->purchaseTranslateStatus($res), $res);
0 ignored issues
show
$res of type string|true is incompatible with the type integer expected by parameter $code of Shetabit\Multipay\Except...xception::__construct(). ( Ignorable by Annotation )

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

75
        throw new PurchaseFailedException($this->purchaseTranslateStatus($res), /** @scrutinizer ignore-type */ $res);
Loading history...
76
    }
77
78
    /**
79
     * @return \Shetabit\Multipay\RedirectionForm
80
     */
81
    public function pay(): RedirectionForm
82
    {
83
        $url = str_replace('{id_get}', $this->invoice->getTransactionId(), $this->settings->apiPaymentUrl);
84
85
        return $this->redirectWithForm($url, [], 'GET');
86
    }
87
88
    /**
89
     * @return ReceiptInterface
90
     *
91
     * @throws \Shetabit\Multipay\Exceptions\InvalidPaymentException
92
     */
93
    public function verify(): ReceiptInterface
94
    {
95
        $trans_id = Request::get('trans_id');
96
        $id_get = Request::get('id_get');
97
        $api = $this->settings->api_token;
98
99
        $ch = curl_init();
100
        curl_setopt($ch, CURLOPT_URL, $this->settings->apiVerificationUrl);
101
        curl_setopt($ch, CURLOPT_POSTFIELDS, "api=$api&id_get=$id_get&trans_id=$trans_id&json=1");
102
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
103
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
104
        $res = curl_exec($ch);
105
        curl_close($ch);
106
107
        $parseDecode = json_decode($res);
0 ignored issues
show
It seems like $res 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

107
        $parseDecode = json_decode(/** @scrutinizer ignore-type */ $res);
Loading history...
108
        $statusCode = $parseDecode->status;
109
110
        if ($statusCode != 1) {
111
            throw new InvalidPaymentException($this->paymentTranslateStatus($statusCode), $statusCode);
112
        }
113
114
        $receipt = $this->createReceipt($trans_id);
115
116
        $receipt->detail([
117
            "amount" => $parseDecode->amount / ($this->settings->currency == 'T' ? 10 : 1), // convert to config currency
118
            "cardNum" => $parseDecode->cardNum,
119
            "factorId" => $parseDecode->factorId,
120
        ]);
121
122
        return $receipt;
123
    }
124
125
    /**
126
     * Generate the payment's receipt
127
     *
128
     * @param $referenceId
129
     *
130
     * @return Receipt
131
     */
132
    protected function createReceipt($referenceId)
133
    {
134
        $receipt = new Receipt('bitpay', $referenceId);
135
136
        return $receipt;
137
    }
138
139
    /**
140
     * Convert purchase status to a readable message.
141
     *
142
     * @param $status
143
     *
144
     * @return string
145
     */
146
    private function purchaseTranslateStatus($status)
147
    {
148
        $translations = [
149
            '-1' => 'Api ارسالی با نوع Api تعریف شده در bitpay سازگار نیست',
150
            '-2' => 'مقدار amount داده عددی نمی‌باشد و یا کمتر از ۱۰۰۰ ریال است',
151
            '-3' => 'مقدار redirect رشته null است',
152
            '-4' => 'درگاهی با اطلاعات ارسالی شما وجود ندارد و یا در حالت انتظار می‌باشد',
153
            '-5' => 'خطا در اتصال به درگاه، لطفا مجدد تلاش کنید',
154
        ];
155
156
        $unknownError = 'خطای ناشناخته رخ داده است. در صورت کسر مبلغ از حساب حداکثر پس از 72 ساعت به حسابتان برمیگردد';
157
158
        return array_key_exists($status, $translations) ? $translations[$status] : $unknownError;
159
    }
160
161
    /**
162
     * Convert payment status to a readable message.
163
     *
164
     * @param $status
165
     *
166
     * @return string
167
     */
168
    private function paymentTranslateStatus($status)
169
    {
170
        $translations = [
171
            '-1' => 'Api ارسالی با نوع Api تعریف شده در bitpay سازگار نیست',
172
            '-2' => 'tran_id ارسال شده، داده عددی نمی‌باشد',
173
            '-3' => 'id_get ارسال شده، داده عددی نمی‌باشد',
174
            '-4' => 'چنین تراکنشی در پایگاه داده وجود ندارد و یا موفقیت آمیز نبوده است',
175
            '11' => 'تراکنش از قبل وریفای شده است',
176
        ];
177
178
        $unknownError = 'خطای ناشناخته رخ داده است. در صورت کسر مبلغ از حساب حداکثر پس از 72 ساعت به حسابتان برمیگردد';
179
180
        return array_key_exists($status, $translations) ? $translations[$status] : $unknownError;
181
    }
182
}
183