Passed
Push — master ( 28508a...00e36d )
by mahdi
01:52
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
     * Payment Driver Name.
27
     *
28
     * @var string
29
     */
30
    protected $driver;
31
32
    /**
33
     * Payment Driver Instance.
34
     *
35
     * @var object
36
     */
37
    protected $driverInstance;
38
39
    /**
40
     * @var Invoice
41
     */
42
    protected $invoice;
43
44
    /**
45
     * PaymentManager constructor.
46
     *
47
     * @param $config
48
     * @throws \Exception
49
     */
50
    public function __construct($config)
51
    {
52
        $this->config = $config;
53
        $this->invoice(new Invoice());
54
        $this->via($this->config['default']);
55
    }
56
57
    /**
58
     * Set payment amount.
59
     *
60
     * @param $amount
61
     * @return $this
62
     * @throws \Exception
63
     */
64
    public function amount($amount)
65
    {
66
        $this->invoice->amount($amount);
67
68
        return $this;
69
    }
70
71
    /**
72
     * Set a piece of data to the details.
73
     *
74
     * @param $key
75
     * @param $value|null
76
     * @return $this
77
     */
78
    public function detail($key, $value = null)
79
    {
80
        $this->invoice->detail($key, $value);
81
82
        return $this;
83
    }
84
85
    /**
86
     * Set transaction's id
87
     *
88
     * @param $id
89
     * @return $this
90
     */
91
    public function transactionId($id)
92
    {
93
        $this->invoice->transactionId($id);
94
95
        return $this;
96
    }
97
98
    /**
99
     * Change the driver on the fly.
100
     *
101
     * @param $driver
102
     * @return $this
103
     * @throws \Exception
104
     */
105
    public function via($driver)
106
    {
107
        $this->driver = $driver;
108
        $this->validateDriver();
109
        $this->invoice->via($driver);
110
        $this->settings = $this->config['drivers'][$driver];
111
112
        return $this;
113
    }
114
115
    /**
116
     * Purchase the invoice
117
     *
118
     * @param Invoice $invoice|null
119
     * @param $initializeCallback|null
120
     * @param $finalizeCallback|null
121
     * @return $this
122
     * @throws \Exception
123
     */
124
    public function purchase(Invoice $invoice = null, $initializeCallback = null, $finalizeCallback = null)
125
    {
126
        if ($invoice) { // create new invoice
127
            $this->invoice($invoice);
128
        }
129
130
        $this->driverInstance = $this->getFreshDriverInstance();
131
        if (!empty($initializeCallback)) {
132
            call_user_func($initializeCallback, $this->driverInstance);
133
        }
134
135
        //purchase the invoice
136
        $body = $this->driverInstance->purchase();
137
        if ($finalizeCallback) {
138
            call_user_func_array($finalizeCallback, [$this->driverInstance, $body]);
139
        }
140
141
        return $this;
142
    }
143
144
    /**
145
     * Pay the purchased invoice.
146
     *
147
     * @param $initializeCallback|null
148
     * @return mixed
149
     * @throws \Exception
150
     */
151
    public function pay($initializeCallback = null)
152
    {
153
        $this->driverInstance = $this->getDriverInstance();
154
        if ($initializeCallback) {
155
            call_user_func($initializeCallback, $this->driverInstance);
156
        }
157
        $this->validateInvoice();
158
159
        return $this->driverInstance->pay();
160
    }
161
162
    /**
163
     * Verifies the payment
164
     *
165
     * @param $initializeCallback|null
166
     * @param $finalizeCallback|null
167
     * @return $this
168
     * @throws InvoiceNotFoundException
169
     */
170
    public function verify($initializeCallback = null, $finalizeCallback = null)
171
    {
172
        $this->driverInstance = $this->getDriverInstance();
173
        if (!empty($initializeCallback)) {
174
            call_user_func($initializeCallback, $this->driverInstance);
175
        }
176
        $this->validateInvoice();
177
        $this->driverInstance->verify();
178
        if (!empty($finalizeCallback)) {
179
            call_user_func($finalizeCallback, $this->driverInstance);
180
        }
181
182
        return $this;
183
    }
184
185
    /**
186
     * @param Invoice $invoice
187
     * @return self
188
     */
189
    protected function invoice(Invoice $invoice)
190
    {
191
        $this->invoice = $invoice;
192
193
        return $this;
194
    }
195
196
    /**
197
     * Retrieve current driver instance or generate new one.
198
     *
199
     * @return mixed
200
     * @throws \Exception
201
     */
202
    protected function getDriverInstance()
203
    {
204
        if (!empty($this->driverInstance)) {
205
            return $this->driverInstance;
206
        }
207
208
        return $this->getFreshDriverInstance();
209
    }
210
211
    /**
212
     * Get new driver instance
213
     *
214
     * @return mixed
215
     * @throws \Exception
216
     */
217
    protected function getFreshDriverInstance()
218
    {
219
        $this->validateDriver();
220
        $class = $this->config['map'][$this->driver];
221
222
        return new $class($this->invoice, $this->settings);
223
    }
224
225
    /**
226
     * Validate Invoice.
227
     *
228
     * @throws InvoiceNotFoundException
229
     */
230
    protected function validateInvoice()
231
    {
232
        if (empty($this->invoice)) {
233
            throw new InvoiceNotFoundException('Invoice not selected or does not exist.');
234
        }
235
    }
236
237
    /**
238
     * Validate driver.
239
     *
240
     * @throws \Exception
241
     */
242
    protected function validateDriver()
243
    {
244
        if (empty($this->driver)) {
245
            throw new DriverNotFoundException('Driver not selected or default driver does not exist.');
246
        }
247
248
        if (empty($this->config['drivers'][$this->driver]) || empty($this->config['map'][$this->driver])) {
249
            throw new DriverNotFoundException('Driver not found in config file. Try updating the package.');
250
        }
251
252
        if (!class_exists($this->config['map'][$this->driver])) {
253
            throw new DriverNotFoundException('Driver source not found. Please update the package.');
254
        }
255
256
        $reflect = new \ReflectionClass($this->config['map'][$this->driver]);
257
258
        if (!$reflect->implementsInterface(Contracts\DriverInterface::class)) {
259
            throw new \Exception("Driver must be an instance of Contracts\DriverInterface.");
260
        }
261
    }
262
}
263