Passed
Push — master ( 99d0e8...9e7049 )
by Ondra
03:35
created

ResponseProvider   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 98
Duplicated Lines 0 %

Test Coverage

Coverage 97.3%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 32
c 1
b 0
f 0
dl 0
loc 98
ccs 36
cts 37
cp 0.973
rs 10
wmc 14

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A provide() 0 23 4
A addOnError() 0 5 1
A verifyPaymentResponse() 0 11 2
A onError() 0 8 3
A addOnSuccess() 0 5 1
A onSuccess() 0 4 2
1
<?php
2
3
/**
4
 * This file is part of the Pixidos package.
5
 *
6
 *  (c) Ondra Votava <[email protected]>
7
 *
8
 *  For the full copyright and license information, please view the LICENSE
9
 *  file that was distributed with this source code.
10
 *
11
 */
12
13
declare(strict_types=1);
14
15
namespace Pixidos\GPWebPay;
16
17
use Closure;
18
use Pixidos\GPWebPay\Config\PaymentConfigProvider;
19
use Pixidos\GPWebPay\Data\ResponseInterface;
20
use Pixidos\GPWebPay\Enum\Param;
21
use Pixidos\GPWebPay\Exceptions\GPWebPayException;
22
use Pixidos\GPWebPay\Exceptions\GPWebPayResultException;
23
use Pixidos\GPWebPay\Exceptions\SignerException;
24
use Pixidos\GPWebPay\Signer\SignerProviderInterface;
25
26
class ResponseProvider implements ResponseProviderInterface
27
{
28
    /**
29
     * @var array<callable>
30
     */
31
    private array $onSuccess = [];
32
33
    /**
34
     * @var array<callable>
35
     */
36
    private array $onError = [];
37
38
39 11
    public function __construct(
40
        private readonly PaymentConfigProvider $configProvider,
41
        private readonly SignerProviderInterface $signerProvider
42
    ) {
43 11
    }
44
45
46 8
    public function provide(ResponseInterface $response): ResponseInterface
47
    {
48
        try {
49 8
            if (!$this->verifyPaymentResponse($response)) {
50
                throw new SignerException('Digest or Digest1 is incorrect!');
51
            }
52
53
            // verify PRCODE and SRCODE
54 8
            if ($response->hasError()) {
55 3
                throw new GPWebPayResultException(
56 3
                    'Response has an error.',
57 3
                    $response->getPrcode(),
58 3
                    $response->getSrcode(),
59 3
                    $response->getResultText()
60 3
                );
61
            }
62
63 5
            $this->onSuccess($response);
64 3
        } catch (GPWebPayException $exception) {
65 3
            $this->onError($exception, $response);
66
        }
67
68 6
        return $response;
69
    }
70
71
    /**
72
     * @param ResponseInterface $response
73
     *
74
     * @return bool
75
     * @throws GPWebPayException
76
     * @throws GPWebPayResultException
77
     */
78 11
    public function verifyPaymentResponse(ResponseInterface $response): bool
79
    {
80
        // verify digest & digest1
81 11
        $signer = $this->signerProvider->get($response->getGatewayKey());
82
83 11
        $params = $response->getParams();
84 11
        $verify = $signer->verify($params, $response->getDigest());
85 11
        $params[Param::MERCHANTNUMBER] = $this->configProvider->getMerchantNumber($response->getGatewayKey());
86 11
        $verify1 = $signer->verify($params, $response->getDigest1());
87
88 11
        return !(false === $verify || false === $verify1);
89
    }
90
91 1
    public function addOnSuccess(Closure $closure): ResponseProviderInterface
92
    {
93 1
        $this->onSuccess[] = $closure;
94
95 1
        return $this;
96
    }
97
98 1
    public function addOnError(Closure $closure): ResponseProviderInterface
99
    {
100 1
        $this->onError[] = $closure;
101
102 1
        return $this;
103
    }
104
105 5
    private function onSuccess(ResponseInterface $response): void
106
    {
107 5
        foreach ($this->onSuccess as $callback) {
108 1
            $callback($response);
109
        }
110
    }
111
112
    /**
113
     * @param GPWebPayException $exception
114
     * @param ResponseInterface $response
115
     */
116 3
    private function onError(GPWebPayException $exception, ResponseInterface $response): void
117
    {
118 3
        if (0 === count($this->onError)) {
119 2
            throw $exception;
120
        }
121
122 1
        foreach ($this->onError as $callback) {
123 1
            $callback($exception, $response);
124
        }
125
    }
126
}
127