Completed
Push — master ( 0d9221...5a40a7 )
by Iurii
01:31
created

Stripe::submitPayment()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

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