Passed
Push — master ( 5ba3e9...ebce2f )
by mahdi
04:13
created

Paypal::createReceipt()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
namespace Shetabit\Payment\Drivers\Paypal;
4
5
use Shetabit\Payment\Abstracts\Driver;
6
use Shetabit\Payment\Exceptions\InvalidPaymentException;
7
use Shetabit\Payment\Exceptions\PurchaseFailedException;
8
use Shetabit\Payment\Contracts\ReceiptInterface;
9
use Shetabit\Payment\Invoice;
10
use Shetabit\Payment\Receipt;
11
12
class Paypal extends Driver
13
{
14
    /**
15
     * Invoice
16
     *
17
     * @var Invoice
18
     */
19
    protected $invoice;
20
21
    /**
22
     * Driver settings
23
     *
24
     * @var object
25
     */
26
    protected $settings;
27
28
    /**
29
     * Paypal constructor.
30
     * Construct the class with the relevant settings.
31
     *
32
     * @param Invoice $invoice
33
     * @param $settings
34
     */
35
    public function __construct(Invoice $invoice, $settings)
36
    {
37
        $this->invoice($invoice);
38
        $this->settings = (object) $settings;
39
    }
40
41
    /**
42
     * Purchase Invoice.
43
     *
44
     * @return string
45
     *
46
     * @throws PurchaseFailedException
47
     * @throws \SoapFault
48
     */
49
    public function purchase()
50
    {
51
        if (!empty($this->invoice->getDetails()['description'])) {
52
            $description = $this->invoice->getDetails()['description'];
53
        } else {
54
            $description = $this->settings->description;
55
        }
56
57
        $data = array(
58
            'MerchantID' => $this->settings->merchantId,
59
            'Amount' => $this->invoice->getAmount(),
60
            'CallbackURL' => $this->settings->callbackUrl,
61
            'Description' => $description,
62
            'AdditionalData' => $this->invoice->getDetails()
63
        );
64
65
        $client = new \SoapClient($this->getPurchaseUrl(), ['encoding' => 'UTF-8']);
66
        $result = $client->PaymentRequest($data);
67
68
        if ($result->Status != 100 || empty($result->Authority)) {
69
            // some error has happened
70
            $message = $this->translateStatus($result->Status);
71
            throw new PurchaseFailedException($message);
72
        }
73
74
        $this->invoice->transactionId($result->Authority);
75
76
        // return the transaction's id
77
        return $this->invoice->getTransactionId();
78
    }
79
80
    /**
81
     * Pay the Invoice
82
     *
83
     * @return \Illuminate\Http\RedirectResponse|mixed
84
     */
85
    public function pay()
86
    {
87
        $transactionId = $this->invoice->getTransactionId();
88
        $paymentUrl = $this->getPaymentUrl();
89
90
        if (strtolower($this->getMode()) == 'zaringate') {
91
            $payUrl = str_replace(':authority', $transactionId, $paymentUrl);
92
        } else {
93
            $payUrl = $paymentUrl.$transactionId;
94
        }
95
96
        // redirect using laravel logic
97
        return redirect()->to($payUrl);
98
    }
99
100
    /**
101
     * Verify payment
102
     *
103
     * @return ReceiptInterface
104
     *
105
     * @throws InvalidPaymentException
106
     * @throws \SoapFault
107
     */
108
    public function verify() : ReceiptInterface
109
    {
110
        $authority = $this->invoice->getTransactionId() ?? request()->get('Authority');
111
        $status = request()->get('Status');
112
113
        $data = [
114
            'MerchantID' => $this->settings->merchantId,
115
            'Authority' => $authority,
116
            'Amount' => $this->invoice->getAmount(),
117
        ];
118
119
        if ($status != 'OK') {
120
            throw new InvalidPaymentException('عملیات پرداخت توسط کاربر لغو شد.');
121
        }
122
123
        $client = new \SoapClient($this->getVerificationUrl(), ['encoding' => 'UTF-8']);
124
        $result = $client->PaymentVerification($data);
125
126
        if ($result->Status != 100) {
127
            $message = $this->translateStatus($result->Status);
128
            throw new InvalidPaymentException($message);
129
        }
130
131
        return $this->createReceipt($result->RefID);
132
    }
133
134
    /**
135
     * Generate the payment's receipt
136
     *
137
     * @param $referenceId
138
     *
139
     * @return Receipt
140
     */
141
    public function createReceipt($referenceId)
142
    {
143
        return new Receipt('zarinpal', $referenceId);
144
    }
145
146
    /**
147
     * Convert status to a readable message.
148
     *
149
     * @param $status
150
     *
151
     * @return mixed|string
152
     */
153
    private function translateStatus($status)
154
    {
155
        $translations = array(
156
            "-1" => "اطلاعات ارسال شده ناقص است.",
157
            "-2" => "IP و يا مرچنت كد پذيرنده صحيح نيست",
158
            "-3" => "با توجه به محدوديت هاي شاپرك امكان پرداخت با رقم درخواست شده ميسر نمي باشد",
159
            "-4" => "سطح تاييد پذيرنده پايين تر از سطح نقره اي است.",
160
            "-11" => "درخواست مورد نظر يافت نشد.",
161
            "-12" => "امكان ويرايش درخواست ميسر نمي باشد.",
162
            "-21" => "هيچ نوع عمليات مالي براي اين تراكنش يافت نشد",
163
            "-22" => "تراكنش نا موفق ميباشد",
164
            "-33" => "رقم تراكنش با رقم پرداخت شده مطابقت ندارد",
165
            "-34" => "سقف تقسيم تراكنش از لحاظ تعداد يا رقم عبور نموده است",
166
            "-40" => "اجازه دسترسي به متد مربوطه وجود ندارد.",
167
            "-41" => "اطلاعات ارسال شده مربوط به AdditionalData غيرمعتبر ميباشد.",
168
            "-42" => "مدت زمان معتبر طول عمر شناسه پرداخت بايد بين 30 دقيه تا 45 روز مي باشد.",
169
            "-54" => "درخواست مورد نظر آرشيو شده است",
170
            "101" => "عمليات پرداخت موفق بوده و قبلا PaymentVerification تراكنش انجام شده است.",
171
        );
172
173
        $unknownError = 'خطای ناشناخته رخ داده است.';
174
175
        return array_key_exists($status, $translations) ? $translations[$status] : $unknownError;
176
    }
177
178
    /**
179
     * Retrieve purchase url
180
     *
181
     * @return string
182
     */
183
    protected function getPurchaseUrl() : string
184
    {
185
        $mode = $this->getMode();
186
187
        switch ($mode) {
188
            case 'sandbox':
189
                $url = $this->settings->sandboxApiPurchaseUrl;
190
                break;
191
            case 'zaringate':
192
                $url = $this->settings->zaringateApiPurchaseUrl;
193
                break;
194
            default: // default: normal
195
                $url = $this->settings->apiPurchaseUrl;
196
                break;
197
        }
198
199
        return $url;
200
    }
201
202
    /**
203
     * Retrieve Payment url
204
     *
205
     * @return string
206
     */
207
    protected function getPaymentUrl() : string
208
    {
209
        $mode = $this->getMode();
210
211
        switch ($mode) {
212
            case 'sandbox':
213
                $url = $this->settings->sandboxApiPaymentUrl;
214
                break;
215
            case 'zaringate':
216
                $url = $this->settings->zaringateApiPaymentUrl;
217
                break;
218
            default: // default: normal
219
                $url = $this->settings->apiPaymentUrl;
220
                break;
221
        }
222
223
        return $url;
224
    }
225
226
    /**
227
     * Retrieve verification url
228
     *
229
     * @return string
230
     */
231
    protected function getVerificationUrl() : string
232
    {
233
        $mode = $this->getMode();
234
235
        switch ($mode) {
236
            case 'sandbox':
237
                $url = $this->settings->sandboxApiVerificationUrl;
238
                break;
239
            case 'zaringate':
240
                $url = $this->settings->zaringateApiVerificationUrl;
241
                break;
242
            default: // default: normal
243
                $url = $this->settings->apiVerificationUrl;
244
                break;
245
        }
246
247
        return $url;
248
    }
249
250
    /**
251
     * Retrieve payment mode.
252
     *
253
     * @return string
254
     */
255
    protected function getMode() : string
256
    {
257
        return strtolower($this->settings->mode);
258
    }
259
}
260