Completed
Push — master ( 246ea7...c4d68b )
by Joachim
02:13
created

CallbackController::getSiteSettings()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 1
1
<?php
2
3
namespace Loevgaard\DandomainAltapayBundle\Controller;
4
5
use Loevgaard\AltaPay\Callback\Xml as XmlCallback;
6
use Loevgaard\AltaPay\Entity\Transaction;
7
use Loevgaard\DandomainAltapayBundle\Annotation\LogHttpTransaction;
8
use Loevgaard\DandomainAltapayBundle\Entity\Payment;
9
use Loevgaard\DandomainAltapayBundle\Entity\PaymentRepository;
10
use Loevgaard\DandomainAltapayBundle\Entity\SiteSetting;
11
use Loevgaard\DandomainAltapayBundle\Exception\CallbackException;
12
use Loevgaard\DandomainAltapayBundle\Exception\NotAllowedIpException;
13
use Loevgaard\DandomainAltapayBundle\Exception\PaymentException;
14
use Loevgaard\DandomainAltapayBundle\PsrHttpMessage\DiactorosTrait;
15
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
16
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
17
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
18
use Symfony\Component\HttpFoundation\RedirectResponse;
19
use Symfony\Component\HttpFoundation\Request;
20
use Symfony\Component\HttpFoundation\Response;
21
22
/**
23
 * @Route("/callback")
24
 */
25
class CallbackController extends Controller
26
{
27
    use DiactorosTrait;
28
29
    /**
30
     * @Method("POST")
31
     * @Route("/form", name="loevgaard_dandomain_altapay_callback_form")
32
     *
33
     * @LogHttpTransaction()
34
     *
35
     * @param Request $request
36
     * @throws CallbackException
37
     * @throws PaymentException
38
     *
39
     * @return Response
40
     */
41 View Code Duplication
    public function formAction(Request $request)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
42
    {
43
        $payment = $this->handleCallback($request);
44
        $siteSettings = $this->getSiteSettings($payment);
45
46
        return $this->render('@LoevgaardDandomainAltapay/callback/form.html.twig', [
47
            'payment' => $payment,
48
            'siteSettings' => $siteSettings,
49
        ]);
50
    }
51
52
    /**
53
     * @Method("POST")
54
     * @Route("/ok", name="loevgaard_dandomain_altapay_callback_ok")
55
     *
56
     * @LogHttpTransaction()
57
     *
58
     * @param Request $request
59
     * @throws CallbackException
60
     * @throws PaymentException
61
     * @return RedirectResponse
62
     */
63
    public function okAction(Request $request)
64
    {
65
        $payment = $this->handleCallback($request);
66
67
        $url = $payment->getFullCallBackOkUrl()
68
            .'&PayApiCompleteOrderChecksum='.$request->cookies->getAlnum(
69
                $this->getParameter('loevgaard_dandomain_altapay.cookie_checksum_complete')
70
            );
71
72
        return $this->redirect($url);
73
    }
74
75
    /**
76
     * @Method("POST")
77
     * @Route("/fail", name="loevgaard_dandomain_altapay_callback_fail")
78
     *
79
     * @LogHttpTransaction()
80
     *
81
     * @param Request $request
82
     * @throws CallbackException
83
     * @throws PaymentException
84
     * @return Response
85
     */
86 View Code Duplication
    public function failAction(Request $request)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
87
    {
88
        $payment = $this->handleCallback($request);
89
        $siteSettings = $this->getSiteSettings($payment);
90
91
        return $this->render('@LoevgaardDandomainAltapay/callback/fail.html.twig', [
92
            'payment' => $payment,
93
            'siteSettings' => $siteSettings,
94
        ]);
95
    }
96
97
    /**
98
     * @Method("POST")
99
     * @Route("/redirect", name="loevgaard_dandomain_altapay_callback_redirect")
100
     *
101
     * @LogHttpTransaction()
102
     *
103
     * @param Request $request
104
     * @throws CallbackException
105
     * @throws PaymentException
106
     * @return Response
107
     */
108 View Code Duplication
    public function redirectAction(Request $request)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
109
    {
110
        $payment = $this->handleCallback($request);
111
        $siteSettings = $this->getSiteSettings($payment);
112
113
        return $this->render('@LoevgaardDandomainAltapay/callback/redirect.html.twig', [
114
            'payment' => $payment,
115
            'siteSettings' => $siteSettings,
116
        ]);
117
    }
118
119
    /**
120
     * @Method("POST")
121
     * @Route("/open", name="loevgaard_dandomain_altapay_callback_open")
122
     *
123
     * @LogHttpTransaction()
124
     *
125
     * @param Request $request
126
     * @throws CallbackException
127
     * @throws PaymentException
128
     * @return Response
129
     */
130 View Code Duplication
    public function openAction(Request $request)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
131
    {
132
        $payment = $this->handleCallback($request);
133
        $siteSettings = $this->getSiteSettings($payment);
134
135
        return $this->render('@LoevgaardDandomainAltapay/callback/open.html.twig', [
136
            'payment' => $payment,
137
            'siteSettings' => $siteSettings,
138
        ]);
139
    }
140
141
    /**
142
     * @Method("POST")
143
     * @Route("/notification", name="loevgaard_dandomain_altapay_callback_notification")
144
     *
145
     * @LogHttpTransaction()
146
     *
147
     * @param Request $request
148
     * @throws CallbackException
149
     * @throws PaymentException
150
     * @return Response
151
     */
152
    public function notificationAction(Request $request)
153
    {
154
        $this->handleCallback($request);
155
156
        return new Response('OK');
157
    }
158
159
    /**
160
     * @Method("POST")
161
     * @Route("/verify-order", name="loevgaard_dandomain_altapay_callback_verify_order")
162
     *
163
     * @LogHttpTransaction()
164
     *
165
     * @param Request $request
166
     * @throws CallbackException
167
     * @throws PaymentException
168
     * @return Response
169
     */
170
    public function verifyOrderAction(Request $request)
171
    {
172
        $this->handleCallback($request);
173
174
        return new Response('OK');
175
    }
176
177
    /**
178
     * @param Request $request
179
     *
180
     * @return Payment
181
     *
182
     * @throws CallbackException
183
     * @throws PaymentException
184
     */
185
    protected function handleCallback(Request $request)
186
    {
187
        $payment = $this->getPaymentFromRequest($request);
188
        $callbackFactory = $this->get('loevgaard_dandomain_altapay.altapay_callback_factory');
189
190
        $psrRequest = $this->createPsrRequest($request);
191
        $callback = $callbackFactory->create($psrRequest);
192
193
        if ($callback instanceof XmlCallback) {
194
            $transactions = $callback->getTransactions();
195
            if (isset($transactions[0])) {
196
                /** @var Transaction $transaction */
197
                $transaction = $transactions[0];
198
199
                $paymentRepository = $this->getPaymentRepository();
200
201
                $payment
202
                    ->setAltapayId($transaction->getPaymentId())
203
                    ->setCardStatus($transaction->getCardStatus())
204
                    ->setCreditCardToken($transaction->getCreditCardToken())
205
                    ->setCreditCardMaskedPan($transaction->getCreditCardMaskedPan())
206
                    ->setThreeDSecureResult($transaction->getThreeDSecureResult())
207
                    ->setLiableForChargeback($transaction->getLiableForChargeback())
208
                    ->setBlacklistToken($transaction->getBlacklistToken())
209
                    ->setShop($transaction->getShop())
210
                    ->setTerminal($transaction->getTerminal())
211
                    ->setTransactionStatus($transaction->getTransactionStatus())
212
                    ->setReasonCode($transaction->getReasonCode())
213
                    ->setMerchantCurrency($transaction->getMerchantCurrency())
214
                    ->setMerchantCurrencyAlpha($transaction->getMerchantCurrencyAlpha())
215
                    ->setCardHolderCurrency($transaction->getCardHolderCurrency())
216
                    ->setCardHolderCurrencyAlpha($transaction->getCardHolderCurrencyAlpha())
217
                    ->setReservedAmount($transaction->getReservedAmount())
0 ignored issues
show
Bug introduced by
It seems like $transaction->getReservedAmount() can be null; however, setReservedAmount() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
218
                    ->setCapturedAmount($transaction->getCapturedAmount())
0 ignored issues
show
Bug introduced by
It seems like $transaction->getCapturedAmount() can be null; however, setCapturedAmount() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
219
                    ->setRefundedAmount($transaction->getRefundedAmount())
0 ignored issues
show
Bug introduced by
It seems like $transaction->getRefundedAmount() can be null; however, setRefundedAmount() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
220
                    ->setRecurringDefaultAmount($transaction->getRecurringDefaultAmount())
0 ignored issues
show
Bug introduced by
It seems like $transaction->getRecurringDefaultAmount() can be null; however, setRecurringDefaultAmount() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
221
                    ->setCreatedDate($transaction->getCreatedDate())
222
                    ->setUpdatedDate($transaction->getUpdatedDate())
223
                    ->setPaymentNature($transaction->getPaymentNature())
224
                    ->setSupportsRefunds($transaction->getPaymentNatureService()->isSupportsRefunds())
225
                    ->setSupportsRelease($transaction->getPaymentNatureService()->isSupportsRelease())
226
                    ->setSupportsMultipleCaptures($transaction->getPaymentNatureService()->isSupportsMultipleCaptures())
227
                    ->setSupportsMultipleRefunds($transaction->getPaymentNatureService()->isSupportsMultipleRefunds())
228
                    ->setFraudRiskScore($transaction->getFraudRiskScore())
229
                    ->setFraudExplanation($transaction->getFraudExplanation())
230
                ;
231
232
                $paymentRepository->persist($payment);
233
                $paymentRepository->flush();
234
            }
235
        }
236
237
        $allowedIps = $this->container->getParameter('loevgaard_dandomain_altapay.altapay_ips');
238
        if ('prod' === $this->container->get('kernel')->getEnvironment() && !in_array($request->getClientIp(), $allowedIps)) {
239
            throw NotAllowedIpException::create('IP `'.$request->getClientIp().'` is not an allowed IP.', $request, $payment);
240
        }
241
242
        return $payment;
243
    }
244
245
    /**
246
     * @param Request $request
247
     *
248
     * @return Payment
249
     *
250
     * @throws CallbackException
251
     */
252
    protected function getPaymentFromRequest(Request $request)
253
    {
254
        $paymentId = $request->cookies->getInt($this->getParameter('loevgaard_dandomain_altapay.cookie_payment_id'));
255
        $paymentRepository = $this->getPaymentRepository();
256
257
        /** @var Payment $payment */
258
        $payment = $paymentRepository->find($paymentId);
259
260
        if (!$payment) {
261
            throw new CallbackException('Payment '.$paymentId.' does not exist');
262
        }
263
264
        return $payment;
265
    }
266
267
    /**
268
     * @return PaymentRepository
269
     */
270
    protected function getPaymentRepository()
271
    {
272
        return $this->container->get('loevgaard_dandomain_altapay.payment_repository');
273
    }
274
275
    /**
276
     * @param Payment $payment
277
     * @return SiteSetting[]
278
     */
279
    protected function getSiteSettings(Payment $payment) : array
280
    {
281
        return $this
282
            ->get('loevgaard_dandomain_altapay.site_settings_provider')
283
            ->findBySiteIdIndexedBySetting($payment->getLanguageId());
284
    }
285
}
286