1 <?php
2 /**
3 * Copyright 2014 Klarna AB
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 * File containing the Connector class.
18 */
19
20 namespace Klarna\Rest\Transport;
21
22 use GuzzleHttp\Client;
23 use GuzzleHttp\ClientInterface;
24 use GuzzleHttp\Exception\RequestException;
25 use GuzzleHttp\Message\RequestInterface;
26 use GuzzleHttp\Message\ResponseInterface;
27 use Klarna\Rest\Transport\Exception\ConnectorException;
28
29 /**
30 * Transport connector used to authenticate and make HTTP requests against the
31 * Klarna APIs.
32 */
33 class Connector implements ConnectorInterface
34 {
35 /**
36 * HTTP transport client.
37 *
38 * @var ClientInterface
39 */
40 protected $client;
41
42 /**
43 * Merchant ID.
44 *
45 * @var string
46 */
47 protected $merchantId;
48
49 /**
50 * Shared secret.
51 *
52 * @var string
53 */
54 protected $sharedSecret;
55
56 /**
57 * HTTP user agent.
58 *
59 * @var UserAgent
60 */
61 protected $userAgent;
62
63 /**
64 * Constructs a connector instance.
65 *
66 * Example usage:
67 *
68 * $client = new \GuzzleHttp\Client(['base_url' => 'https://api.klarna.com']);
69 * $connector = new \Klarna\Transport\Connector($client, '0', 'sharedSecret');
70 *
71 *
72 * @param ClientInterface $client HTTP transport client
73 * @param string $merchantId Merchant ID
74 * @param string $sharedSecret Shared secret
75 * @param UserAgentInterface $userAgent HTTP user agent to identify the client
76 */
77 public function __construct(
78 ClientInterface $client,
79 $merchantId,
80 $sharedSecret,
81 UserAgentInterface $userAgent = null
82 ) {
83 $this->client = $client;
84 $this->merchantId = $merchantId;
85 $this->sharedSecret = $sharedSecret;
86
87 if ($userAgent === null) {
88 $userAgent = UserAgent::createDefault();
89 }
90 $this->userAgent = $userAgent;
91 }
92
93 /**
94 * Creates a request object.
95 *
96 * @param string $url URL
97 * @param string $method HTTP method
98 * @param array $options Request options
99 *
100 * @return RequestInterface
101 */
102 public function createRequest($url, $method = 'GET', array $options = [])
103 {
104 $options['auth'] = [$this->merchantId, $this->sharedSecret];
105 $options['headers']['User-Agent'] = strval($this->userAgent);
106
107 return $this->client->createRequest($method, $url, $options);
108 }
109
110 /**
111 * Sends the request.
112 *
113 * @param RequestInterface $request Request to send
114 *
115 * @throws ConnectorException If the API returned an error response
116 * @throws RequestException When an error is encountered
117 * @throws \LogicException When the adapter does not populate a response
118 *
119 * @return ResponseInterface
120 */
121 public function send(RequestInterface $request)
122 {
123 try {
124 return $this->client->send($request);
125 } catch (RequestException $e) {
126 if (!$e->hasResponse()) {
127 throw $e;
128 }
129
130 $response = $e->getResponse();
131
132 if ($response->getHeader('Content-Type') !== 'application/json') {
133 throw $e;
134 }
135
136 $data = $response->json();
137
138 if (!is_array($data) || !array_key_exists('error_code', $data)) {
139 throw $e;
140 }
141
142 throw new ConnectorException($data, $e);
143 }
144 }
145
146 /**
147 * Gets the HTTP transport client.
148 *
149 * @return ClientInterface
150 */
151 public function getClient()
152 {
153 return $this->client;
154 }
155
156 /**
157 * Gets the user agent.
158 *
159 * @return UserAgentInterface
160 */
161 public function getUserAgent()
162 {
163 return $this->userAgent;
164 }
165
166 /**
167 * Factory method to create a connector instance.
168 *
169 * @param string $merchantId Merchant ID
170 * @param string $sharedSecret Shared secret
171 * @param string $baseUrl Base URL for HTTP requests
172 * @param UserAgentInterface $userAgent HTTP user agent to identify the client
173 *
174 * @return self
175 */
176 public static function create(
177 $merchantId,
178 $sharedSecret,
179 $baseUrl = self::EU_BASE_URL,
180 UserAgentInterface $userAgent = null
181 ) {
182 $client = new Client(['base_url' => $baseUrl]);
183
184 return new static($client, $merchantId, $sharedSecret, $userAgent);
185 }
186 }
187