Passed
Push — main ( 67f80d...eb72a4 )
by Leith
05:54
created

AbstractRequest::createSignature()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 3
rs 10
1
<?php
2
3
namespace Omnipay\Worldline\Message;
4
5
use DateTime;
6
use DateTimeZone;
7
use Money\Currency;
8
use Money\Number;
9
use Money\Parser\DecimalMoneyParser;
10
use Omnipay\Common\Message\AbstractRequest as BaseAbstractRequest;
11
use Omnipay\Common\Exception\InvalidRequestException;
12
13
/**
14
 * Base request for Worldline
15
 *
16
 * @see https://docs.direct.worldline-solutions.com/en/integration/api-developer-guide/authentication
17
 */
18
abstract class AbstractRequest extends BaseAbstractRequest
19
{
20
    /** @var string */
21
    protected $liveEndpoint = 'https://payment.direct.worldline-solutions.com';
22
    /** @var string */
23
    protected $testEndpoint = 'https://payment.preprod.direct.worldline-solutions.com';
24
    /** @var string HTTP verb used to make the request */
25
    protected $requestMethod = 'GET';
26
27
    public function getApiKey()
28
    {
29
        return $this->getParameter('apiKey');
30
    }
31
32
    public function setApiKey($value)
33
    {
34
        return $this->setParameter('apiKey', $value);
35
    }
36
37
    public function getApiSecret()
38
    {
39
        return $this->getParameter('apiSecret');
40
    }
41
42
    public function setApiSecret($value)
43
    {
44
        return $this->setParameter('apiSecret', $value);
45
    }
46
47
    public function getMerchantId()
48
    {
49
        return $this->getParameter('merchantId');
50
    }
51
52
    public function setMerchantId($value)
53
    {
54
        return $this->setParameter('merchantId', $value);
55
    }
56
57
    public function getEndpoint()
58
    {
59
        return ($this->getTestMode() ? $this->testEndpoint : $this->liveEndpoint).$this->getAction();
60
    }
61
62
    public function sendData($data)
63
    {
64
        $contentType = $this->requestMethod == 'POST' ? 'application/json; charset=utf-8' : '';
65
        $now = new DateTime('now', new DateTimeZone('GMT'));
66
        $dateTime = $now->format("D, d M Y H:i:s T");
67
        $endpointAction = $this->getAction();
68
69
        $message = $this->requestMethod."\n".$contentType."\n".$dateTime."\n".$endpointAction."\n";
70
        $signature = $this->createSignature($message, $this->getApiSecret());
71
72
        $headers = [
73
            'Content-Type' => $contentType,
74
            'Authorization' => 'GCS v1HMAC:'.$this->getApiKey().':'.$signature,
75
            'Date' => $dateTime,
76
        ];
77
78
        $body = json_encode($data);
79
80
        $httpResponse = $this->httpClient->request(
81
            $this->requestMethod,
82
            $this->getEndpoint(),
83
            $headers,
84
            $body
85
        );
86
87
        return $this->createResponse($httpResponse->getBody()->getContents());
88
    }
89
90
    /**
91
     * @param mixed $data
92
     * @return AbstractResponse
0 ignored issues
show
Bug introduced by
The type Omnipay\Worldline\Message\AbstractResponse was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
93
     */
94
    abstract protected function createResponse($data);
95
96
    /**
97
     * @return string
98
     */
99
    abstract protected function getAction();
100
101
    /**
102
     * Create signature hash used to verify messages
103
     *
104
     * @param string $message  The message to encrypt
105
     * @param string $key      The base64-encoded key used to encrypt the message
106
     *
107
     * @return string Generated signature
108
     */
109
    protected function createSignature($message, $key)
110
    {
111
        return base64_encode(hash_hmac('sha256', $message, $key, true));
112
    }
113
114
    /**
115
     * Get integer version (sallest unit) of item price
116
     *
117
     * Copied from {@see BaseAbstractRequest::getAmountInteger()} & {@see BaseAbstractRequest::getMoney()}
118
     */
119
    protected function getItemPriceInteger($item)
120
    {
121
        $currencyCode = $this->getCurrency() ?: 'USD';
122
        $currency = new Currency($currencyCode);
123
        $amount = $item->getPrice();
124
125
        $moneyParser = new DecimalMoneyParser($this->getCurrencies());
126
        $number = Number::fromString($amount);
127
        // Check for rounding that may occur if too many significant decimal digits are supplied.
128
        $decimal_count = strlen($number->getFractionalPart());
129
        $subunit = $this->getCurrencies()->subunitFor($currency);
130
        if ($decimal_count > $subunit) {
131
            throw new InvalidRequestException('Amount precision is too high for currency.');
132
        }
133
        $money = $moneyParser->parse((string) $number, $currency);
134
135
        return (int) $money->getAmount();
136
    }
137
}
138