Completed
Push — master ( 28a427...82bb37 )
by Iurii
01:15
created

Authorize::submitPurchase()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 18
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 18
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 12
nc 3
nop 0
1
<?php
2
3
/**
4
 * @package Authorize.Net
5
 * @author Iurii Makukh <[email protected]>
6
 * @copyright Copyright (c) 2017, Iurii Makukh <[email protected]>
7
 * @license https://www.gnu.org/licenses/gpl-3.0.en.html GNU General Public License 3.0
8
 */
9
10
namespace gplcart\modules\authorize;
11
12
use gplcart\core\Module;
13
14
/**
15
 * Main class for Authorize.Net module
16
 */
17
class Authorize extends Module
18
{
19
20
    /**
21
     * The current order
22
     * @var array
23
     */
24
    protected $data_order;
25
26
    /**
27
     * Omnipay response instance
28
     * @var object
29
     */
30
    protected $response;
31
32
    /**
33
     * Frontend controller instance
34
     * @var \gplcart\core\controllers\frontend\Controller $controller
35
     */
36
    protected $controller;
37
38
    /**
39
     * Order model instance
40
     * @var \gplcart\core\models\Order $order
41
     */
42
    protected $order;
43
44
    /**
45
     * Constructor
46
     */
47
    public function __construct()
48
    {
49
        parent::__construct();
50
    }
51
52
    /**
53
     * Implements hook "route.list"
54
     * @param array $routes
55
     */
56
    public function hookRouteList(array &$routes)
57
    {
58
        $routes['admin/module/settings/authorize'] = array(
59
            'access' => 'module_edit',
60
            'handlers' => array(
61
                'controller' => array('gplcart\\modules\\authorize\\controllers\\Settings', 'editSettings')
62
            )
63
        );
64
    }
65
66
    /**
67
     * Implements hook "module.enable.before"
68
     * @param mixed $result
69
     */
70
    public function hookModuleEnableBefore(&$result)
71
    {
72
        try {
73
            $this->getGatewayInstance();
74
        } catch (\InvalidArgumentException $ex) {
75
            $result = $ex->getMessage();
76
        }
77
    }
78
79
    /**
80
     * Implements hook "module.install.before"
81
     * @param mixed $result
82
     */
83
    public function hookModuleInstallBefore(&$result)
84
    {
85
        try {
86
            $this->getGatewayInstance();
87
        } catch (\InvalidArgumentException $ex) {
88
            $result = $ex->getMessage();
89
        }
90
    }
91
92
    /**
93
     * Get gateway instance
94
     * @return object
95
     * @throws \InvalidArgumentException
96
     */
97
    protected function getGatewayInstance()
98
    {
99
        /* @var $module \gplcart\modules\omnipay_library\OmnipayLibrary */
100
        $module = $this->getInstance('omnipay_library');
101
        $instance = $module->getGatewayInstance('AuthorizeNet_SIM');
102
103
        if (!$instance instanceof \Omnipay\AuthorizeNet\SIMGateway) {
0 ignored issues
show
Bug introduced by
The class Omnipay\AuthorizeNet\SIMGateway does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
104
            throw new \InvalidArgumentException('Object is not instance of Omnipay\AuthorizeNet\SIMGateway');
105
        }
106
107
        return $instance;
108
    }
109
110
    /**
111
     * Implements hook "payment.methods"
112
     * @param array $methods
113
     */
114
    public function hookPaymentMethods(array &$methods)
115
    {
116
        $language = $this->getLanguage();
117
118
        $methods['authorize_sim'] = array(
119
            'module' => 'authorize',
120
            'image' => 'image/icon.png',
121
            'status' => $this->getStatus(),
122
            'title' => $language->text('Authorize.Net'),
123
            'template' => array('complete' => 'pay')
124
        );
125
    }
126
127
    /**
128
     * Returns the current status for the payment method
129
     * @return bool
130
     */
131
    protected function getStatus()
132
    {
133
        return $this->setting('status')//
134
                && $this->setting('apiLoginId')//
135
                && $this->setting('hashSecret')//
136
                && $this->setting('transactionKey');
137
    }
138
139
    /**
140
     * Returns a module setting
141
     * @param string $name
142
     * @param mixed $default
143
     * @return mixed
144
     */
145
    protected function setting($name, $default = null)
146
    {
147
        return $this->config->module('authorize', $name, $default);
148
    }
149
150
    /**
151
     * Implements hook "order.add.before"
152
     * @param array $order
153
     * @param \gplcart\core\models\Order $model
154
     */
155
    public function hookOrderAddBefore(array &$order, $model)
156
    {
157
        // Adjust order status before creation
158
        // We want to get payment in advance, so assign "awaiting payment" status
159
        if ($order['payment'] === 'authorize_sim') {
160
            $order['status'] = $model->getStatusAwaitingPayment();
161
        }
162
    }
163
164
    /**
165
     * Implements hook "order.checkout.complete"
166
     * @param string $message
167
     * @param array $order
168
     */
169
    public function hookOrderCompleteMessage(&$message, $order)
170
    {
171
        if ($order['payment'] === 'authorize_sim') {
172
            $message = ''; // Hide default message
173
        }
174
    }
175
176
    /**
177
     * Implements hook "order.complete.page"
178
     * @param array $order
179
     * @param \gplcart\core\models\Order $model
180
     * @param \gplcart\core\controllers\frontend\Controller $controller
181
     */
182
    public function hookOrderCompletePage(array $order, $model, $controller)
183
    {
184
        if ($order['payment'] === 'authorize_sim') {
185
186
            $this->order = $model;
187
            $this->data_order = $order;
188
            $this->controller = $controller;
189
190
            $this->processPurchase();
191
        }
192
    }
193
194
    /**
195
     * Process payment
196
     */
197
    protected function processPurchase()
198
    {
199
        if ($this->controller->isPosted('pay')) {
200
            $this->submitPurchase();
201
        } else if ($this->controller->isQuery('authorize_return')) {
202
203
            $gateway = $this->getGatewayInstance();
204
            $this->response = $gateway->completePurchase($this->getPurchaseParams())->send();
205
206
            if ($this->controller->isQuery('cancel')) {
207
                $this->cancelPurchase();
208
            } else {
209
                $this->finishPurchase();
210
            }
211
        }
212
    }
213
214
    /**
215
     * Performs actions when a payment is canceled
216
     */
217
    protected function cancelPurchase()
218
    {
219
        $message = $this->controller->text('Payment has been canceled');
220
        $this->controller->setMessage($message, 'warning');
221
222
        $gateway_message = $this->response->getMessage();
223
224
        if (!empty($gateway_message)) {
225
            $this->controller->setMessage($gateway_message, 'warning');
226
        }
227
    }
228
229
    /**
230
     * Handles submitted payment
231
     */
232
    protected function submitPurchase()
233
    {
234
        $gateway = $this->getGatewayInstance();
235
236
        $gateway->setApiLoginId($this->setting('apiLoginId'));
237
        $gateway->setHashSecret($this->setting('hashSecret'));
238
        $gateway->setTestMode((bool) $this->setting('testMode'));
239
        $gateway->setDeveloperMode((bool) $this->setting('testMode'));
240
        $gateway->setTransactionKey($this->setting('transactionKey'));
241
242
        $this->response = $gateway->purchase($this->getPurchaseParams())->send();
243
244
        if ($this->response->isRedirect()) {
245
            $this->response->redirect();
246
        } else if (!$this->response->isSuccessful()) {
247
            $this->redirectError();
248
        }
249
    }
250
251
    /**
252
     * Returns an array of purchase parameters
253
     * @return array
254
     */
255
    protected function getPurchaseParams()
256
    {
257
        return array(
258
            'currency' => $this->data_order['currency'],
259
            'amount' => $this->data_order['total_formatted_number'],
260
            'cancelUrl' => $this->controller->url("checkout/complete/{$this->data_order['order_id']}", array('authorize_return' => true, 'cancel' => true), true),
261
            'returnUrl' => $this->controller->url("checkout/complete/{$this->data_order['order_id']}", array('authorize_return' => true), true)
262
        );
263
    }
264
265
    /**
266
     * Performs final actions on success payment
267
     */
268
    protected function finishPurchase()
269
    {
270
        if ($this->response->isSuccessful()) {
271
            $this->updateOrderStatus();
272
            $this->addTransaction();
273
            $this->redirectSuccess();
274
        } else if ($this->response->isRedirect()) {
275
            $this->response->redirect();
276
        } else {
277
            $this->redirectError();
278
        }
279
    }
280
281
    /**
282
     * Redirect on error payment
283
     */
284
    protected function redirectError()
285
    {
286
        $this->controller->redirect('', $this->response->getMessage(), 'warning', true);
287
    }
288
289
    /**
290
     * Redirect on successful payment
291
     */
292
    protected function redirectSuccess()
293
    {
294
        $vars = array(
295
            '@num' => $this->data_order['order_id'],
296
            '@status' => $this->order->getStatusName($this->data_order['status'])
297
        );
298
299
        $message = $this->controller->text('Thank you! Payment has been made. Order #@num, status: @status', $vars);
300
        $this->controller->redirect('/', $message, 'success', true);
301
    }
302
303
    /**
304
     * Update order status after successful transaction
305
     */
306
    protected function updateOrderStatus()
307
    {
308
        $data = array('status' => $this->setting('order_status_success'));
309
        $this->order->update($this->data_order['order_id'], $data);
310
        $this->data_order = $this->order->get($this->data_order['order_id']);
311
    }
312
313
    /**
314
     * Adds a transaction
315
     */
316
    protected function addTransaction()
317
    {
318
        $transaction = array(
319
            'total' => $this->data_order['total'],
320
            'order_id' => $this->data_order['order_id'],
321
            'currency' => $this->data_order['currency'],
322
            'payment_method' => $this->data_order['payment'],
323
            'gateway_transaction_id' => $this->response->getTransactionReference()
324
        );
325
326
        /* @var $object \gplcart\core\models\Transaction */
327
        $object = $this->getModel('Transaction');
328
        return $object->add($transaction);
329
    }
330
331
}
332