Completed
Push — master ( 80d841...fb8f6f )
by Joachim
01:55
created

PaymentController::getPaymentFromId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
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\Payload\CaptureReservation as CaptureReservationPayload;
6
use Loevgaard\AltaPay\Payload\RefundCapturedReservation as RefundCapturedReservationPayload;
7
use Loevgaard\AltaPay\Payload\OrderLine as OrderLinePayload;
8
use Loevgaard\AltaPay\Payload\PaymentRequest as PaymentRequestPayload;
9
use Loevgaard\AltaPay\Payload\PaymentRequest\Config as ConfigPayload;
10
use Loevgaard\AltaPay\Payload\PaymentRequest\CustomerInfo as CustomerInfoPayload;
11
use Loevgaard\Dandomain\Pay\Handler;
12
use Loevgaard\DandomainAltapayBundle\Annotation\LogHttpTransaction;
13
use Loevgaard\DandomainAltapayBundle\Entity\Payment;
14
use Loevgaard\DandomainAltapayBundle\Exception\AltapayPaymentRequestException;
15
use Loevgaard\DandomainAltapayBundle\Exception\ChecksumMismatchException;
16
use Loevgaard\DandomainAltapayBundle\Exception\PaymentException;
17
use Loevgaard\DandomainAltapayBundle\Exception\TerminalNotFoundException;
18
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
19
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
20
use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory;
21
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
22
use Symfony\Component\HttpFoundation\RedirectResponse;
23
use Symfony\Component\HttpFoundation\Request;
24
use Symfony\Component\HttpFoundation\Response;
25
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
26
27
/**
28
 * @Route("/payment")
29
 */
30
class PaymentController extends Controller
31
{
32
    /**
33
     * @Method("GET")
34
     * @Route("", name="loevgaard_dandomain_altapay_payment_index")
35
     *
36
     * @param Request $request
37
     *
38
     * @return Response
39
     */
40
    public function indexAction(Request $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request 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...
41
    {
42
        $paymentManager = $this->container->get('loevgaard_dandomain_altapay.payment_manager');
43
44
        /** @var Payment[] $payments */
45
        $payments = $paymentManager->getRepository()->findAll();
46
47
        return $this->render('@LoevgaardDandomainAltapay/payment/index.html.twig', [
48
            'payments' => $payments,
49
        ]);
50
    }
51
52
    /**
53
     * Payment flow
54
     * 1. The Dandomain payment API POSTs to this page with the terminal slug in the URL
55
     * 2. After validating all input, we create a payment request to the Altapay API
56
     * 3. Finally we redirect the user to the URL given by the Altapay API.
57
     *
58
     * @Method("POST")
59
     * @Route("/{terminal}", name="loevgaard_dandomain_altapay_payment_new")
60
     *
61
     * @LogHttpTransaction()
62
     *
63
     * @param $terminal
64
     * @param Request $request
65
     *
66
     * @return RedirectResponse
67
     *
68
     * @throws PaymentException
69
     */
70
    public function newAction($terminal, Request $request)
71
    {
72
        $terminalManager = $this->container->get('loevgaard_dandomain_altapay.terminal_manager');
73
        $paymentManager = $this->container->get('loevgaard_dandomain_altapay.payment_manager');
74
75
        // convert symfony request to PSR7 request
76
        $psr7Factory = new DiactorosFactory();
77
        $psrRequest = $psr7Factory->createRequest($request);
78
79
        $handler = new Handler(
80
            $psrRequest,
81
            $this->container->getParameter('loevgaard_dandomain_altapay.shared_key_1'),
82
            $this->container->getParameter('loevgaard_dandomain_altapay.shared_key_2')
83
        );
84
85
        $dandomainPaymentRequest = $handler->getPaymentRequest();
86
87
        $paymentEntity = $paymentManager->createPaymentFromDandomainPaymentRequest($dandomainPaymentRequest);
88
        $paymentManager->update($paymentEntity);
89
90
        $terminalEntity = $terminalManager->findTerminalBySlug($terminal, true);
91
        if (!$terminalEntity) {
92
            // @todo fix translation
93
            throw TerminalNotFoundException::create('Terminal `'.$terminal.'` does not exist', $request, $paymentEntity);
94
        }
95
96
        if (!$handler->checksumMatches()) {
97
            // @todo fix translation
98
            throw ChecksumMismatchException::create('Checksum mismatch. Try again', $request, $paymentEntity);
99
        }
100
101
        $paymentRequestPayload = new PaymentRequestPayload(
102
            $terminalEntity->getTitle(),
103
            $dandomainPaymentRequest->getOrderId(),
104
            $dandomainPaymentRequest->getTotalAmount(),
105
            $dandomainPaymentRequest->getCurrencySymbol()
106
        );
107
108
        foreach ($dandomainPaymentRequest->getPaymentLines() as $paymentLine) {
109
            $orderLinePayload = new OrderLinePayload(
110
                $paymentLine->getName(),
111
                $paymentLine->getProductNumber(),
112
                $paymentLine->getQuantity(),
113
                $paymentLine->getPrice()
114
            );
115
            $orderLinePayload->setTaxPercent($paymentLine->getVat());
116
117
            $paymentRequestPayload->addOrderLine($orderLinePayload);
118
        }
119
120
        $customerInfoPayload = new CustomerInfoPayload();
121
        $customerNames = explode(' ', $dandomainPaymentRequest->getCustomerName(), 2);
122
        $shippingNames = explode(' ', $dandomainPaymentRequest->getDeliveryName(), 2);
123
        $customerInfoPayload
124
            ->setBillingFirstName($customerNames[0] ?? '')
125
            ->setBillingLastName($customerNames[1] ?? '')
126
            ->setBillingAddress(
127
                $dandomainPaymentRequest->getCustomerAddress().
128
                ($dandomainPaymentRequest->getCustomerAddress2() ? "\r\n".$dandomainPaymentRequest->getCustomerAddress2() : '')
129
            )
130
            ->setBillingPostal($dandomainPaymentRequest->getCustomerZipCode())
131
            ->setBillingCity($dandomainPaymentRequest->getCustomerCity())
132
            ->setBillingCountry($dandomainPaymentRequest->getCustomerCountry())
133
            ->setShippingFirstName($shippingNames[0] ?? '')
134
            ->setShippingLastName($shippingNames[1] ?? '')
135
            ->setShippingAddress(
136
                $dandomainPaymentRequest->getDeliveryAddress().
137
                ($dandomainPaymentRequest->getDeliveryAddress2() ? "\r\n".$dandomainPaymentRequest->getDeliveryAddress2() : '')
138
            )
139
            ->setShippingPostal($dandomainPaymentRequest->getDeliveryZipCode())
140
            ->setShippingCity($dandomainPaymentRequest->getDeliveryCity())
141
            ->setShippingCountry($dandomainPaymentRequest->getDeliveryCountry())
142
        ;
143
        $paymentRequestPayload->setCustomerInfo($customerInfoPayload);
144
145
        $configPayload = new ConfigPayload();
146
        $configPayload
147
            ->setCallbackForm($this->generateUrl('loevgaard_dandomain_altapay_callback_form', [], UrlGeneratorInterface::ABSOLUTE_URL))
148
            ->setCallbackOk($this->generateUrl('loevgaard_dandomain_altapay_callback_ok', [], UrlGeneratorInterface::ABSOLUTE_URL))
149
            ->setCallbackFail($this->generateUrl('loevgaard_dandomain_altapay_callback_fail', [], UrlGeneratorInterface::ABSOLUTE_URL))
150
            ->setCallbackRedirect($this->generateUrl('loevgaard_dandomain_altapay_callback_redirect', [], UrlGeneratorInterface::ABSOLUTE_URL))
151
            ->setCallbackOpen($this->generateUrl('loevgaard_dandomain_altapay_callback_open', [], UrlGeneratorInterface::ABSOLUTE_URL))
152
            ->setCallbackNotification($this->generateUrl('loevgaard_dandomain_altapay_callback_notification', [], UrlGeneratorInterface::ABSOLUTE_URL))
153
        ;
154
        $paymentRequestPayload->setConfig($configPayload);
155
156
        $paymentRequestPayload
157
            ->setCookiePart($this->getParameter('loevgaard_dandomain_altapay.cookie_payment_id'), $paymentEntity->getId())
158
            ->setCookiePart($this->getParameter('loevgaard_dandomain_altapay.cookie_checksum_complete'), $handler->getChecksum2())
159
        ;
160
161
        $altapay = $this->container->get('loevgaard_dandomain_altapay.altapay_client');
162
        $response = $altapay->createPaymentRequest($paymentRequestPayload);
163
164
        if (!$response->isSuccessful()) {
165
            // @todo fix translation
166
            throw AltapayPaymentRequestException::create('An error occured during payment request. Try again. Message from gateway: '.$response->getErrorMessage(), $request, $paymentEntity);
167
        }
168
169
        return new RedirectResponse($response->getUrl());
170
    }
171
172
    /**
173
     * @Method("GET")
174
     * @Route("/{paymentId}/capture", name="loevgaard_dandomain_altapay_payment_capture")
175
     *
176
     * @param int     $paymentId
177
     * @param Request $request
178
     *
179
     * @return RedirectResponse
180
     */
181
    public function captureAction(int $paymentId, Request $request)
182
    {
183
        $payment = $this->getPaymentFromId($paymentId);
184
185
        if ($payment) {
186
            $altapayClient = $this->get('loevgaard_dandomain_altapay.altapay_client');
187
188
            $payload = new CaptureReservationPayload($payment->getAltapayId());
189
            $res = $altapayClient->captureReservation($payload);
190
191
            if ($res->isSuccessful()) {
192
                $this->addFlash('success', 'The payment for order '.$payment->getOrderId().' was captured.'); // @todo fix translation
193
            } else {
194
                $this->addFlash('danger', 'An error occurred during capture of the payment: '.$res->getErrorMessage()); // @todo fix translation
195
            }
196
        }
197
198
        $redirect = $request->headers->get('referer') ? $request->headers->get('referer') : $this->generateUrl('loevgaard_dandomain_altapay_payment_index');
199
200
        return $this->redirect($redirect);
0 ignored issues
show
Bug introduced by
It seems like $redirect defined by $request->headers->get('...altapay_payment_index') on line 198 can also be of type array; however, Symfony\Bundle\Framework...rollerTrait::redirect() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
201
    }
202
203
    /**
204
     * @Method({"POST", "GET"})
205
     * @Route("/{paymentId}/refund", name="loevgaard_dandomain_altapay_payment_refund")
206
     *
207
     * @param int     $paymentId
208
     * @param Request $request
209
     *
210
     * @return RedirectResponse
211
     */
212
    public function refundAction(int $paymentId, Request $request)
213
    {
214
        $payment = $this->getPaymentFromId($paymentId);
215
216
        if ($payment) {
217
            $altapayClient = $this->get('loevgaard_dandomain_altapay.altapay_client');
218
219
            $payload = new RefundCapturedReservationPayload($payment->getAltapayId());
220
            $res = $altapayClient->refundCapturedReservation($payload);
221
222
            if ($res->isSuccessful()) {
223
                $this->addFlash('success', 'The payment for order '.$payment->getOrderId().' was refunded.'); // @todo fix translation
224
            } else {
225
                $this->addFlash('danger', 'An error occurred during refund of the payment: '.$res->getErrorMessage()); // @todo fix translation
226
            }
227
        }
228
229
        $redirect = $request->headers->get('referer') ? $request->headers->get('referer') : $this->generateUrl('loevgaard_dandomain_altapay_payment_index');
230
231
        return $this->redirect($redirect);
0 ignored issues
show
Bug introduced by
It seems like $redirect defined by $request->headers->get('...altapay_payment_index') on line 229 can also be of type array; however, Symfony\Bundle\Framework...rollerTrait::redirect() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
232
    }
233
234
    /**
235
     * @param int $paymentId
236
     * @return Payment|null
237
     */
238
    private function getPaymentFromId(int $paymentId) : ?Payment
239
    {
240
        $paymentManager = $this->get('loevgaard_dandomain_altapay.payment_manager');
241
242
        /** @var Payment $payment */
243
        $payment = $paymentManager->getRepository()->find($paymentId);
244
245
        return $payment;
246
    }
247
}
248