Paypal   A
last analyzed

Complexity

Total Complexity 23

Size/Duplication

Total Lines 245
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 99
c 1
b 0
f 0
dl 0
loc 245
rs 10
wmc 23

10 Methods

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