Completed
Push — master ( 374367...b950ab )
by Vladimir
09:30
created

Gateway::setUrl()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

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 3
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AcquiroPay;
6
7
use AcquiroPay\Gateway\Responses\InitResponse;
8
use AcquiroPay\Gateway\Responses\PaymentStatusByCfResponse;
9
use DOMDocument;
10
use DOMElement;
11
use GuzzleHttp\Client as Http;
12
use Illuminate\Support\Collection;
13
use Symfony\Component\Serializer\Encoder\XmlEncoder;
14
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
15
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
16
use Symfony\Component\Serializer\Serializer;
17
18
class Gateway
19
{
20
    private const LIVE_URL = 'https://gateway.acquiropay.com';
21
    private const TEST_URL = 'https://gateway.acqp.co';
22
23
    protected $http;
24
    protected $url;
25
26
    protected $merchantId;
27
    protected $secretWord;
28
29
    protected $request;
30
31
    public function __construct(
32
        Http $http,
33
        int $merchantId = null,
0 ignored issues
show
Unused Code introduced by
The parameter $merchantId 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...
34
        string $secretWord = null,
0 ignored issues
show
Unused Code introduced by
The parameter $secretWord 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...
35
        bool $live = false
0 ignored issues
show
Unused Code introduced by
The parameter $live 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...
36
    )
37
    {
38
        $this->http = $http;
39
    }
40
41
    public function setUrl(string $url): Gateway
42
    {
43
        $this->url = $url;
44
45
        return $this;
46
    }
47
48
    public function setMerchantId(int $merchantId): Gateway
49
    {
50
        $this->merchantId = $merchantId;
51
52
        return $this;
53
    }
54
55
    public function setSecretWord(string $secretWord): Gateway
56
    {
57
        $this->secretWord = $secretWord;
58
59
        return $this;
60
    }
61
62
    public function setLive(bool $live): Gateway
63
    {
64
        $this->url = $live ? self::LIVE_URL : self::TEST_URL;
65
66
        return $this;
67
    }
68
69
    /**
70
     * Init payment.
71
     *
72
     * @param int $productId
73
     * @param string $pan
74
     * @param string $cardHolder
75
     * @param int $expiryMonth
76
     * @param int $expiryYear
77
     * @param string $cvv
78
     * @param string $cf
79
     * @param float|string $amount
80
     * @param array $parameters
81
     *
82
     * @return InitResponse
83
     */
84
    public function init(
85
        int $productId,
86
        string $pan,
87
        string $cardHolder,
88
        int $expiryMonth,
89
        int $expiryYear,
90
        string $cvv,
91
        string $cf,
92
        float $amount,
93
        array $parameters = []
94
    ): InitResponse
95
    {
96
        $amount = $this->formatAmount($amount);
97
98
        $parameters = array_merge($parameters, [
99
            'opcode' => 0,
100
            'product_id' => $productId,
101
            'amount' => $amount,
102
            'cf' => $cf,
103
            'pan' => $pan,
104
            'cvv' => $cvv,
105
            'exp_month' => $expiryMonth,
106
            'exp_year' => $expiryYear,
107
            'cardholder' => $cardHolder,
108
            'token' => md5(
109
                $this->merchantId .
110
                $productId .
111
                $amount .
112
                $cf .
113
                array_get($parameters, 'cf2') .
114
                array_get($parameters, 'cf3') .
115
                $this->secretWord
116
            ),
117
        ]);
118
119
        $response = $this->send($parameters);
120
121
        return $this->deserialize($response, InitResponse::class);
122
    }
123
124
    /**
125
     * Get payment status using cf.
126
     *
127
     * @param int $productId
128
     * @param string $cf
129
     *
130
     * @return Collection|PaymentStatusByCfResponse[]
131
     */
132
    public function paymentStatusByCf(int $productId, string $cf)
133
    {
134
        $parameters = [
135
            'opcode' => 2,
136
            'product_id' => $productId,
137
            'cf' => $cf,
138
            'token' => md5($this->merchantId . $productId . $cf . $this->secretWord),
139
        ];
140
141
        $response = $this->send($parameters);
142
143
        $xml = new DOMDocument;
144
        $xml->formatOutput = true;
145
        $xml->loadXML($response);
146
147
        // один платеж
148
        if ($xml->getElementsByTagName('payments')->length === 0) {
149
            return collect([$this->deserialize($response, PaymentStatusByCfResponse::class)]);
150
        }
151
152
        $payments = collect();
153
        $elements = $xml->getElementsByTagName('payments')->item(0)->getElementsByTagName('payment');
154
155
        /** @var DOMElement $element */
156
        foreach ($elements as $element) {
157
            $payments->push($this->deserialize($xml->saveXML($element), PaymentStatusByCfResponse::class));
158
        }
159
160
        return $payments;
161
    }
162
163
    public function getRequest(): ?array
164
    {
165
        return $this->request;
166
    }
167
168
    private function send(array $parameters): string
169
    {
170
        $this->request = $parameters;
171
172
        $response = $this->http->post($this->url, ['form_params' => $parameters, 'verify' => false]);
173
174
        return (string)$response->getBody();
175
    }
176
177
    private function deserialize(string $data, string $class)
178
    {
179
        $normalizers = [new ObjectNormalizer(null, new CamelCaseToSnakeCaseNameConverter)];
180
        $encoders = [new XmlEncoder];
181
182
        return (new Serializer($normalizers, $encoders))->deserialize($data, $class, 'xml');
183
    }
184
185
    private function formatAmount(float $amount): string
186
    {
187
        return number_format($amount, 2, '.', '');
188
    }
189
}