Passed
Branch master (9ba99c)
by mahdi
03:23 queued 01:28
created

PaymentManager::transactionId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Shetabit\Payment;
4
5
use Shetabit\Payment\Contracts\DriverInterface;
6
use Shetabit\Payment\Exceptions\DriverNotFoundException;
7
use Shetabit\Payment\Exceptions\InvoiceNotFoundException;
8
9
class PaymentManager
10
{
11
    /**
12
     * Payment Configuration.
13
     *
14
     * @var array
15
     */
16
    protected $config;
17
18
    /**
19
     * Payment Driver Settings.
20
     *
21
     * @var array
22
     */
23
    protected $settings;
24
25
    /**
26
     * callbackUrl
27
     *
28
     * @var string
29
     */
30
    protected $callbackUrl;
31
32
    /**
33
     * Payment Driver Name.
34
     *
35
     * @var string
36
     */
37
    protected $driver;
38
39
    /**
40
     * Payment Driver Instance.
41
     *
42
     * @var object
43
     */
44
    protected $driverInstance;
45
46
    /**
47
     * @var Invoice
48
     */
49
    protected $invoice;
50
51
    /**
52
     * PaymentManager constructor.
53
     *
54
     * @param $config
55
     * @throws \Exception
56
     */
57
    public function __construct($config)
58
    {
59
        $this->config = $config;
60
        $this->invoice(new Invoice());
61
        $this->via($this->config['default']);
62
    }
63
64
    /**
65
     * Set callbackUrl.
66
     *
67
     * @param $url|null
68
     * @return $this
69
     */
70
    public function callbackUrl($url = null)
71
    {
72
        $this->callbackUrl = $url;
73
74
        return $this;
75
    }
76
77
    /**
78
     * Reset the callbackUrl to its original that exists in configs.
79
     *
80
     * @return $this
81
     */
82
    public function resetCallbackUrl()
83
    {
84
        $this->callbackUrl();
85
86
        return $this;
87
    }
88
89
    /**
90
     * Set payment amount.
91
     *
92
     * @param $amount
93
     * @return $this
94
     * @throws \Exception
95
     */
96
    public function amount($amount)
97
    {
98
        $this->invoice->amount($amount);
99
100
        return $this;
101
    }
102
103
    /**
104
     * Set a piece of data to the details.
105
     *
106
     * @param $key
107
     * @param $value|null
108
     * @return $this
109
     */
110
    public function detail($key, $value = null)
111
    {
112
        $this->invoice->detail($key, $value);
113
114
        return $this;
115
    }
116
117
    /**
118
     * Set transaction's id
119
     *
120
     * @param $id
121
     * @return $this
122
     */
123
    public function transactionId($id)
124
    {
125
        $this->invoice->transactionId($id);
126
127
        return $this;
128
    }
129
130
    /**
131
     * Change the driver on the fly.
132
     *
133
     * @param $driver
134
     * @return $this
135
     * @throws \Exception
136
     */
137
    public function via($driver)
138
    {
139
        $this->driver = $driver;
140
        $this->validateDriver();
141
        $this->invoice->via($driver);
142
        $this->settings = $this->config['drivers'][$driver];
143
144
        return $this;
145
    }
146
147
    /**
148
     * Purchase the invoice
149
     *
150
     * @param Invoice $invoice|null
151
     * @param $finalizeCallback|null
152
     * @return $this
153
     * @throws \Exception
154
     */
155
    public function purchase(Invoice $invoice = null, $finalizeCallback = null)
156
    {
157
        if ($invoice) { // create new invoice
158
            $this->invoice($invoice);
159
        }
160
161
        $this->driverInstance = $this->getFreshDriverInstance();
162
163
        //purchase the invoice
164
        $body = $this->driverInstance->purchase();
165
        if ($finalizeCallback) {
166
            call_user_func_array($finalizeCallback, [$this->driverInstance, $body]);
167
        }
168
169
        return $this;
170
    }
171
172
    /**
173
     * Pay the purchased invoice.
174
     *
175
     * @param $initializeCallback|null
176
     * @return mixed
177
     * @throws \Exception
178
     */
179
    public function pay($initializeCallback = null)
180
    {
181
        $this->driverInstance = $this->getDriverInstance();
182
183
        if ($initializeCallback) {
184
            call_user_func($initializeCallback, $this->driverInstance);
185
        }
186
187
        $this->validateInvoice();
188
189
        return $this->driverInstance->pay();
190
    }
191
192
    /**
193
     * Verifies the payment
194
     *
195
     * @param $finalizeCallback|null
196
     * @return $this
197
     * @throws InvoiceNotFoundException
198
     */
199
    public function verify($finalizeCallback = null)
200
    {
201
        $this->driverInstance = $this->getDriverInstance();
202
        $this->validateInvoice();
203
        $this->driverInstance->verify();
204
205
        if (!empty($finalizeCallback)) {
206
            call_user_func($finalizeCallback, $this->driverInstance);
207
        }
208
209
        return $this;
210
    }
211
212
    /**
213
     * @param Invoice $invoice
214
     * @return self
215
     */
216
    protected function invoice(Invoice $invoice)
217
    {
218
        $this->invoice = $invoice;
219
220
        return $this;
221
    }
222
223
    /**
224
     * Retrieve current driver instance or generate new one.
225
     *
226
     * @return mixed
227
     * @throws \Exception
228
     */
229
    protected function getDriverInstance()
230
    {
231
        if (!empty($this->driverInstance)) {
232
            return $this->driverInstance;
233
        }
234
235
        return $this->getFreshDriverInstance();
236
    }
237
238
    /**
239
     * Get new driver instance
240
     *
241
     * @return mixed
242
     * @throws \Exception
243
     */
244
    protected function getFreshDriverInstance()
245
    {
246
        $this->validateDriver();
247
        $class = $this->config['map'][$this->driver];
248
249
        if (!empty($this->callbackUrl)) { // use custom callbackUrl if exists
250
            $this->settings['callbackUrl'] = $this->callbackUrl;
251
        }
252
253
        return new $class($this->invoice, $this->settings);
254
    }
255
256
    /**
257
     * Validate Invoice.
258
     *
259
     * @throws InvoiceNotFoundException
260
     */
261
    protected function validateInvoice()
262
    {
263
        if (empty($this->invoice)) {
264
            throw new InvoiceNotFoundException('Invoice not selected or does not exist.');
265
        }
266
    }
267
268
    /**
269
     * Validate driver.
270
     *
271
     * @throws \Exception
272
     */
273
    protected function validateDriver()
274
    {
275
        if (empty($this->driver)) {
276
            throw new DriverNotFoundException('Driver not selected or default driver does not exist.');
277
        }
278
279
        if (empty($this->config['drivers'][$this->driver]) || empty($this->config['map'][$this->driver])) {
280
            throw new DriverNotFoundException('Driver not found in config file. Try updating the package.');
281
        }
282
283
        if (!class_exists($this->config['map'][$this->driver])) {
284
            throw new DriverNotFoundException('Driver source not found. Please update the package.');
285
        }
286
287
        $reflect = new \ReflectionClass($this->config['map'][$this->driver]);
288
289
        if (!$reflect->implementsInterface(Contracts\DriverInterface::class)) {
290
            throw new \Exception("Driver must be an instance of Contracts\DriverInterface.");
291
        }
292
    }
293
}
294