Completed
Push — master ( 7362e4...edacb2 )
by Iurii
01:36
created

Stripe::redirectSuccess()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 6
nc 1
nop 0
1
<?php
2
3
/**
4
 * @package Stripe
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\stripe;
11
12
use gplcart\core\Module;
13
14
/**
15
 * Main class for Stripe module
16
 */
17
class Stripe extends Module
18
{
19
20
    /**
21
     * The current order
22
     * @var array
23
     */
24
    protected $data_order;
25
26
    /**
27
     * Stripe token
28
     * @var string
29
     */
30
    protected $data_token;
31
32
    /**
33
     * Omnipay response instance
34
     * @var object
35
     */
36
    protected $response;
37
38
    /**
39
     * Frontend controller instance
40
     * @var \gplcart\core\controllers\frontend\Controller $controller
41
     */
42
    protected $controller;
43
44
    /**
45
     * Order model instance
46
     * @var \gplcart\core\models\Order $order
47
     */
48
    protected $order;
49
50
    /**
51
     * Constructor
52
     */
53
    public function __construct()
54
    {
55
        parent::__construct();
56
    }
57
58
    /**
59
     * Returns Stripe gateway object
60
     * @return object
61
     * @throws \InvalidArgumentException
62
     */
63
    protected function getGatewayInstance()
64
    {
65
        /* @var $model \gplcart\modules\omnipay_library\OmnipayLibrary */
66
        $model = $this->getInstance('omnipay_library');
67
68
        $instance = $model->getGatewayInstance('Stripe');
69
70
        if (!$instance instanceof \Omnipay\Stripe\Gateway) {
0 ignored issues
show
Bug introduced by
The class Omnipay\Stripe\Gateway 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...
71
            throw new \InvalidArgumentException('Object is not instance of Omnipay\Stripe\Gateway');
72
        }
73
74
        return $instance;
75
    }
76
77
    /**
78
     * Implements hook "module.enable.before"
79
     * @param mixed $result
80
     */
81
    public function hookModuleEnableBefore(&$result)
82
    {
83
        try {
84
            $this->getGatewayInstance();
85
        } catch (\InvalidArgumentException $ex) {
86
            $result = $ex->getMessage();
87
        }
88
    }
89
90
    /**
91
     * Implements hook "module.install.before"
92
     * @param mixed $result
93
     */
94
    public function hookModuleInstallBefore(&$result)
95
    {
96
        try {
97
            $this->getGatewayInstance();
98
        } catch (\InvalidArgumentException $ex) {
99
            $result = $ex->getMessage();
100
        }
101
    }
102
103
    /**
104
     * Implements hook "route.list"
105
     * @param array $routes
106
     */
107
    public function hookRouteList(array &$routes)
108
    {
109
        $routes['admin/module/settings/stripe'] = array(
110
            'access' => 'module_edit',
111
            'handlers' => array(
112
                'controller' => array('gplcart\\modules\\stripe\\controllers\\Settings', 'editSettings')
113
            )
114
        );
115
    }
116
117
    /**
118
     * Implements hook "payment.methods"
119
     * @param array $methods
120
     */
121
    public function hookPaymentMethods(array &$methods)
122
    {
123
        $methods['stripe'] = array(
124
            'module' => 'stripe',
125
            'image' => 'image/icon.png',
126
            'status' => $this->getStatus(),
127
            'title' => 'Stripe',
128
            'template' => array('complete' => 'pay')
129
        );
130
    }
131
132
    /**
133
     * Returns a module setting
134
     * @param string $name
135
     * @param mixed $default
136
     * @return mixed
137
     */
138
    protected function setting($name, $default = null)
139
    {
140
        return $this->config->module('stripe', $name, $default);
141
    }
142
143
    /**
144
     * Returns the current status of the payment method
145
     */
146
    protected function getStatus()
147
    {
148
        if (!$this->setting('status')) {
149
            return false;
150
        }
151
152
        if ($this->setting('test')) {
153
            return $this->setting('test_key') && $this->setting('test_public_key');
154
        }
155
156
        return $this->setting('live_key') && $this->setting('live_public_key');
157
    }
158
159
    /**
160
     * Returns a public API key
161
     * @return string
162
     */
163
    protected function getPublicKey()
164
    {
165
        $key = $this->setting('test') ? 'test_public_key' : 'live_public_key';
166
        return $this->setting($key);
167
    }
168
169
    /**
170
     * Returns a secret API key
171
     * @return string
172
     */
173
    protected function getSecretKey()
174
    {
175
        $key = $this->setting('test') ? 'test_key' : 'live_key';
176
        return $this->setting($key);
177
    }
178
179
    /**
180
     * Implements hook "order.add.before"
181
     * @param array $order
182
     * @param \gplcart\core\models\Order $model
183
     */
184
    public function hookOrderAddBefore(array &$order, $model)
185
    {
186
        // Adjust order status before creation
187
        // We want to get payment in advance, so assign "awaiting payment" status
188
        if ($order['payment'] === 'stripe') {
189
            $order['status'] = $model->getStatusAwaitingPayment();
190
        }
191
    }
192
193
    /**
194
     * Implements hook "order.checkout.complete"
195
     * @param string $message
196
     * @param array $order
197
     */
198
    public function hookOrderCompleteMessage(&$message, $order)
199
    {
200
        if ($order['payment'] === 'stripe') {
201
            $message = ''; // Hide default message
202
        }
203
    }
204
205
    /**
206
     * Implements hook "order.complete.page"
207
     * @param array $order
208
     * @param \gplcart\core\models\Order $model
209
     * @param \gplcart\core\controllers\frontend\Controller $controller
210
     */
211
    public function hookOrderCompletePage(array $order, $model, $controller)
212
    {
213
        if ($order['payment'] === 'stripe') {
214
215
            $this->order = $model;
216
            $this->data_order = $order;
217
            $this->controller = $controller;
218
219
            $this->submit();
220
221
            $controller->setJs('https://js.stripe.com/v2');
222
            $controller->setJs('system/modules/stripe/js/common.js');
223
            $controller->setJsSettings('stripe', array('key' => $this->getPublicKey()));
224
        }
225
    }
226
227
    /**
228
     * Handles submitted payment
229
     */
230
    protected function submit()
231
    {
232
        $this->data_token = $this->controller->getPosted('stripeToken', '', true, 'string');
233
234
        if (!empty($this->data_token)) {
235
236
            $params = array(
237
                'token' => $this->data_token,
238
                'currency' => $this->data_order['currency'],
239
                'amount' => $this->data_order['total_formatted_number']
240
            );
241
242
            $gateway = $this->getGatewayInstance();
243
            $gateway->setApiKey($this->getSecretKey());
244
            $this->response = $gateway->purchase($params)->send();
245
            $this->processResponse();
246
        }
247
    }
248
249
    /**
250
     * Processes gateway response
251
     */
252
    protected function processResponse()
253
    {
254
        if ($this->response->isSuccessful()) {
255
            $this->updateOrderStatus();
256
            $this->addTransaction();
257
            $this->redirectSuccess();
258
        } else if ($this->response->isRedirect()) {
259
            $this->response->redirect();
260
        } else {
261
            $message = $this->response->getMessage();
262
            $this->controller->redirect('', $message, 'warning', true);
263
        }
264
    }
265
266
    /**
267
     * Redirect on successful transaction
268
     */
269
    protected function redirectSuccess()
270
    {
271
        $vars = array(
272
            '@num' => $this->data_order['order_id'],
273
            '@status' => $this->order->getStatusName($this->data_order['status'])
274
        );
275
276
        $message = $this->controller->text('Thank you! Payment has been made. Order #@num, status: @status', $vars);
277
        $this->controller->redirect('/', $message, 'success', true);
278
    }
279
280
    /**
281
     * Update order status after successful transaction
282
     */
283
    protected function updateOrderStatus()
284
    {
285
        $data = array('status' => $this->setting('order_status_success'));
286
        $this->order->update($this->data_order['order_id'], $data);
287
        $this->data_order = $this->order->get($this->data_order['order_id']);
288
    }
289
290
    /**
291
     * Adds a transaction
292
     * @return integer
293
     */
294
    protected function addTransaction()
295
    {
296
        $transaction = array(
297
            'total' => $this->data_order['total'],
298
            'order_id' => $this->data_order['order_id'],
299
            'currency' => $this->data_order['currency'],
300
            'payment_method' => $this->data_order['payment'],
301
            'gateway_transaction_id' => $this->response->getTransactionReference()
302
        );
303
304
        /* @var $object \gplcart\core\models\Transaction */
305
        $object = $this->getModel('Transaction');
306
        return $object->add($transaction);
307
    }
308
309
}
310