• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mlocati / PayWay / 5276115637

pending completion
5276115637

push

github

web-flow
Force checking response signature (#6)

8 of 8 new or added lines in 1 file covered. (100.0%)

1603 of 2145 relevant lines covered (74.73%)

1.53 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

72.37
/src/Client.php
1
<?php
2

3
namespace MLocati\PayWay;
4

5
use RuntimeException;
6

7
class Client
8
{
9
    /**
10
     * @var string always ending with a slash
11
     */
12
    protected $servicesUrlPrefix;
13

14
    /**
15
     * @var string
16
     */
17
    protected $signatureKey;
18

19
    /**
20
     * @var \MLocati\PayWay\Http\Driver
21
     */
22
    protected $driver;
23

24
    /**
25
     * @var callable[]
26
     */
27
    protected $listeners = [];
28

29
    /**
30
     * @var \MLocati\PayWay\Init\Request\Serializer|null
31
     */
32
    private $initSerializer;
33

34
    /**
35
     * @var \MLocati\PayWay\Init\Response\Unserializer|null
36
     */
37
    private $initUnserializer;
38

39
    /**
40
     * @var \MLocati\PayWay\Verify\Request\Serializer|null
41
     */
42
    private $verifySerializer;
43

44
    /**
45
     * @var \MLocati\PayWay\Verify\Response\Unserializer|null
46
     */
47
    private $verifyUnserializer;
48

49
    /**
50
     * @param string|object|mixed $servicesUrl
51
     */
52
    public function __construct($servicesUrl, $signatureKey, Http\Driver $driver = null)
53
    {
54
        $servicesUrlPrefix = static::normalizeServicesUrl($servicesUrl);
9✔
55
        if ($servicesUrlPrefix === '') {
9✔
56
            throw new RuntimeException("'{$servicesUrl}' is not a valid base URL of the web services");
5✔
57
        }
58
        $this->servicesUrlPrefix = $servicesUrlPrefix;
4✔
59
        $this->signatureKey = is_string($signatureKey) ? $signatureKey : '';
4✔
60
        if ($this->signatureKey === '') {
4✔
61
            throw new RuntimeException('Missing the signature key');
1✔
62
        }
63
        $this->driver = $driver === null ? static::buildDefaultDriver() : $driver;
3✔
64
    }
65

66
    /**
67
     * Normalize the value of the services URL.
68
     *
69
     * @param string|object|mixed $value
70
     *
71
     * @return string empty string in case of errors
72
     */
73
    public static function normalizeServicesUrl($value)
74
    {
75
        switch (gettype($value)) {
24✔
76
            case 'string':
24✔
77
                break;
21✔
78
            case 'object':
3✔
79
                if (!method_exists($value, '__toString')) {
1✔
80
                    return '';
×
81
                }
82
                $value = (string) $value;
1✔
83
                break;
1✔
84
            default:
85
                return '';
2✔
86
        }
87
        $value = trim($value);
22✔
88
        if ($value === '' || strpos($value, '?') !== false || strpos($value, '#') !== false) {
22✔
89
            return '';
5✔
90
        }
91
        if (!filter_var($value, FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED)) {
17✔
92
            return '';
10✔
93
        }
94

95
        return rtrim($value, '/') . '/';
7✔
96
    }
97

98
    /**
99
     * @return \MLocati\PayWay\Init\Response
100
     */
101
    public function init(Init\Request $request)
102
    {
103
        $xml = $this->getInitSerializer()->serialize($request, $this->signatureKey);
3✔
104
        $rawResponse = $this->postSoapRequest('PaymentInitGatewayPort', $xml);
3✔
105
        if (!$rawResponse->is2xx()) {
3✔
106
            throw new Exception\InvalidHttpResponseCode($rawResponse);
1✔
107
        }
108
        $response = $this->getInitUnserializer()->unserialize($rawResponse->getBody());
2✔
109
        if (!$response->isError() || $response->getSignature() !== '') {
×
110
            $response->checkSignature($this->signatureKey);
×
111
        }
112

113
        return $response;
×
114
    }
115

116
    /**
117
     * @return \MLocati\PayWay\Verify\Response
118
     */
119
    public function verify(Verify\Request $request)
120
    {
121
        $xml = $this->getVerifySerializer()->serialize($request, $this->signatureKey);
×
122
        $rawResponse = $this->postSoapRequest('PaymentInitGatewayPort', $xml);
×
123
        if (!$rawResponse->is2xx()) {
×
124
            throw new Exception\InvalidHttpResponseCode($rawResponse);
×
125
        }
126
        $response = $this->getVerifyUnserializer()->unserialize($rawResponse->getBody());
×
127
        if (!$response->isError() || $response->getSignature() !== '') {
×
128
            $response->checkSignature($this->signatureKey);
×
129
        }
130

131
        return $response;
×
132
    }
133

134
    /**
135
     * @return $this
136
     */
137
    public function addListener(callable $value)
138
    {
139
        $this->listeners[] = $value;
1✔
140

141
        return $this;
1✔
142
    }
143

144
    /**
145
     * @return $this
146
     */
147
    public function removeListener(callable $value)
148
    {
149
        $this->listeners = array_filter($this->listeners, static function (callable $item) use ($value) {
1✔
150
            return $item !== $value;
1✔
151
        });
1✔
152

153
        return $this;
1✔
154
    }
155

156
    /**
157
     * @return \MLocati\PayWay\Http\Driver
158
     */
159
    protected static function buildDefaultDriver()
160
    {
161
        if (extension_loaded('curl')) {
×
162
            return new Http\Driver\Curl();
×
163
        }
164

165
        throw new RuntimeException("The cURL extension is required if you don't provide your own HTTP driver");
×
166
    }
167

168
    /**
169
     * @return \MLocati\PayWay\Init\Request\Serializer
170
     */
171
    protected function getInitSerializer()
172
    {
173
        if ($this->initSerializer === null) {
3✔
174
            $this->initSerializer = new Init\Request\Serializer();
3✔
175
        }
176

177
        return $this->initSerializer;
3✔
178
    }
179

180
    /**
181
     * @return \MLocati\PayWay\Init\Response\Unserializer
182
     */
183
    protected function getInitUnserializer()
184
    {
185
        if ($this->initUnserializer === null) {
2✔
186
            $this->initUnserializer = new Init\Response\Unserializer();
2✔
187
        }
188

189
        return $this->initUnserializer;
2✔
190
    }
191

192
    /**
193
     * @return \MLocati\PayWay\Verify\Request\Serializer
194
     */
195
    protected function getVerifySerializer()
196
    {
197
        if ($this->verifySerializer === null) {
×
198
            $this->verifySerializer = new Verify\Request\Serializer();
×
199
        }
200

201
        return $this->verifySerializer;
×
202
    }
203

204
    /**
205
     * @return \MLocati\PayWay\Verify\Response\Unserializer
206
     */
207
    protected function getVerifyUnserializer()
208
    {
209
        if ($this->verifyUnserializer === null) {
×
210
            $this->verifyUnserializer = new Verify\Response\Unserializer();
×
211
        }
212

213
        return $this->verifyUnserializer;
×
214
    }
215

216
    /**
217
     * @param string $path
218
     * @param string $xml
219
     *
220
     * @return \MLocati\PayWay\Http\Response
221
     */
222
    private function postSoapRequest($path, $xml)
223
    {
224
        $url = $this->servicesUrlPrefix . $path;
3✔
225
        $response = $this->driver->send(
3✔
226
            $url,
3✔
227
            'POST',
3✔
228
            [
3✔
229
                'Content-Type' => 'text/xml; charset=utf-8',
3✔
230
                'SOAPAction' => '',
3✔
231
                'Content-Length: ' . strlen($xml),
3✔
232
            ],
3✔
233
            $xml
3✔
234
        );
3✔
235
        if ($this->listeners !== []) {
3✔
236
            $event = new Http\Event($url, 'POST', $xml, $response);
1✔
237
            foreach ($this->listeners as $listener) {
1✔
238
                $listener($event);
1✔
239
            }
240
        }
241

242
        return $response;
3✔
243
    }
244
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc