PayController   A
last analyzed

Complexity

Total Complexity 22

Size/Duplication

Total Lines 169
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 9

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 22
lcom 2
cbo 9
dl 0
loc 169
ccs 0
cts 91
cp 0
rs 10
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A actions() 0 8 1
A getMerchantModule() 0 4 1
A beforeAction() 0 8 2
A actionCancel() 0 6 2
A actionReturn() 0 11 2
A actionCheckReturn() 0 20 4
A actionNotify() 0 11 3
A checkNotify() 0 4 1
A actionProxyNotification() 0 4 1
A actionDeposit() 0 16 4
A renderDeposit() 0 14 1
1
<?php
2
/**
3
 * Yii2 extension for payment processing with Omnipay, Payum and more later.
4
 *
5
 * @link      https://github.com/hiqdev/yii2-merchant
6
 * @package   yii2-merchant
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2015-2017, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hiqdev\yii2\merchant\controllers;
12
13
use hiqdev\yii2\merchant\actions\RequestAction;
14
use hiqdev\yii2\merchant\models\DepositForm;
15
use hiqdev\yii2\merchant\models\DepositRequest;
16
use hiqdev\yii2\merchant\Module;
17
use hiqdev\yii2\merchant\transactions\Transaction;
18
use Yii;
19
use yii\base\InvalidConfigException;
20
use yii\web\BadRequestHttpException;
21
use yii\web\NotFoundHttpException;
22
use yii\web\Response;
23
24
class PayController extends \yii\web\Controller
25
{
26
    public function actions()
27
    {
28
        return array_merge(parent::actions(), [
29
            'request' => [
30
                'class' => RequestAction::class
31
            ]
32
        ]);
33
    }
34
35
    /**
36
     * @return Module|\yii\base\Module
37
     */
38
    public function getMerchantModule()
39
    {
40
        return $this->module;
41
    }
42
43
    /**
44
     * Disable CSRF validation for POST requests we receive from outside
45
     * {@inheritdoc}
46
     */
47
    public function beforeAction($action)
48
    {
49
        if (in_array($this->action->id, ['notify', 'return', 'cancel', 'proxy-notification'], true)) {
50
            Yii::$app->controller->enableCsrfValidation = false;
51
        }
52
53
        return parent::beforeAction($action);
54
    }
55
56
    /**
57
     * @return Response
58
     */
59
    public function actionCancel()
60
    {
61
        Yii::$app->session->addFlash('error', Yii::t('merchant', 'Payment failed or cancelled'));
62
63
        return $this->redirect($this->getMerchantModule()->previousUrl() ?: ['deposit']);
64
    }
65
66
    /**
67
     * @param string|null $transactionId
68
     *
69
     * Parameters are NOT required because some merchants may NOT send them, or send in POST or JSON bode.
70
     * The main purpose of these parameters is handling of special routes using UrlManager
71
     *
72
     * @return string
73
     * @throws InvalidConfigException
74
     */
75
    public function actionReturn(string $transactionId = null)
76
    {
77
        $transaction = $this->checkNotify($transactionId);
78
        if ($transaction === null) {
79
            return $this->actionCancel();
80
        }
81
82
        return $this->render('return', [
83
            'transactionId' => $transaction->getId(),
84
        ]);
85
    }
86
87
    /**
88
     * @param string $transactionId
89
     * @throws BadRequestHttpException
90
     * @return array
91
     */
92
    public function actionCheckReturn($transactionId)
93
    {
94
        Yii::$app->response->format = Response::FORMAT_JSON;
95
        $transaction = $this->getMerchantModule()->findTransaction($transactionId);
96
97
        if ($transaction === null) {
98
            throw new NotFoundHttpException('Transaction does not exist');
99
        }
100
101
        if ($transaction->getParameter('username') !== $this->getMerchantModule()->getUsername()) {
102
            throw new BadRequestHttpException('Access denied', 403);
103
        }
104
105
        return [
106
            'status' => $transaction->getSuccess(),
107
            'url'    => $transaction->isConfirmed()
108
                ? $transaction->getParameter('finishUrl')
109
                : $transaction->getParameter('cancelUrl'),
110
        ];
111
    }
112
113
    /**
114
     * Action handles notifications from payment systems,
115
     * processes them and report success or error for the payment system.
116
     *
117
     * @param string|null $transactionId Parameters is NOT required because some merchants may NOT send it, or send in POST or JSON body.
118
     * The main purpose of these parameters is handling of special routes using UrlManager
119
     *
120
     * @return null|string
121
     * @throws InvalidConfigException
122
     */
123
    public function actionNotify(string $transactionId = null)
124
    {
125
        $transaction = $this->checkNotify($transactionId);
126
        if ($transaction === null) {
127
            return 'Unknown transaction';
128
        }
129
130
        Yii::$app->response->format = Response::FORMAT_RAW;
131
132
        return $transaction->isConfirmed() ? 'OK' : $transaction->getParameter('error');
133
    }
134
135
    /**
136
     * Check notifications.
137
     * TODO: implement actual request check and proper handling.
138
     *
139
     * @param string|null $transactionId Parameters is NOT required because some merchants may NOT send it, or send in POST or JSON body.
140
     * The main purpose of these parameters is handling of special routes using UrlManager
141
     *
142
     * @return Transaction|null
143
     * @throws InvalidConfigException
144
     */
145
    public function checkNotify(string $transactionId = null): ?Transaction
0 ignored issues
show
Unused Code introduced by
The parameter $transactionId is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
146
    {
147
        throw new InvalidConfigException('Method checkNotify must be implemented');
148
    }
149
150
    public function actionProxyNotification()
151
    {
152
        throw new InvalidConfigException('Method actionProxyNotification must be implemented');
153
    }
154
155
    public function actionDeposit()
156
    {
157
        $merchantModule = $this->getMerchantModule();
158
159
        $model   = Yii::createObject($merchantModule->depositFromClass);
160
        $request = Yii::$app->request;
161
        if ($model->load($request->isPost ? $request->post() : $request->get()) && $model->validate()) {
162
            return $this->renderDeposit($model);
163
        }
164
165
        return $this->render('deposit-form', [
166
            'model' => $model,
167
            'availableMerchants' => $this->getMerchantModule()->getPurchaseRequestCollection()->getItems(),
168
            'availableCurrencies' => $this->getMerchantModule()->getAvailableCurrenciesCollection()->getList(),
169
        ]);
170
    }
171
172
    /**
173
     * Renders depositing buttons for given request data.
174
     *
175
     * @param DepositForm $form request data
176
     * @return \yii\web\Response
177
     */
178
    public function renderDeposit($form)
179
    {
180
        $request = new DepositRequest();
181
        $request->amount = $form->amount;
0 ignored issues
show
Documentation Bug introduced by
The property $amount was declared of type string, but $form->amount is of type double. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
182
        $request->currency = $form->currency;
183
        $request->finishUrl = $form->finishUrl;
184
185
        $requests = $this->getMerchantModule()->getPurchaseRequestCollection($request)->getItems();
186
187
        return $this->render('deposit', [
188
            'requests' => $requests,
189
            'depositForm' => $form
190
        ]);
191
    }
192
}
193