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 Order class.
18 */
19
20 namespace Klarna\Rest\OrderManagement;
21
22 use GuzzleHttp\Exception\RequestException;
23 use Klarna\Rest\Resource;
24 use Klarna\Rest\Transport\Connector;
25 use Klarna\Rest\Transport\Exception\ConnectorException;
26
27 /**
28 * Order management resource.
29 *
30 * @example docs/examples/order/acknowledge_order.php
31 * @example docs/examples/order/cancel_order.php
32 * @example docs/examples/order/extend_authorization_time.php
33 * @example docs/examples/order/fetch_order.php
34 * @example docs/examples/order/fetch_capture.php
35 * @example docs/examples/order/refund_order.php
36 * @example docs/examples/order/release_remaining_authorization.php
37 * @example docs/examples/order/update_customer_details.php
38 * @example docs/examples/order/update_merchant_references.php
39 * @example docs/examples/order/update_order_lines.php
40 */
41 class Order extends Resource
42 {
43 /**
44 * {@inheritDoc}
45 */
46 const ID_FIELD = 'order_id';
47
48 /**
49 * {@inheritDoc}
50 */
51 public static $path = '/ordermanagement/v1/orders';
52
53 /**
54 * Constructs an order instance.
55 *
56 * @param Connector $connector HTTP transport connector
57 * @param string $orderId Order ID
58 */
59 public function __construct(Connector $connector, $orderId)
60 {
61 parent::__construct($connector);
62
63 $this->setLocation(self::$path . "/{$orderId}");
64 $this[static::ID_FIELD] = $orderId;
65 }
66
67 /**
68 * Fetches the order.
69 *
70 * @throws ConnectorException When the API replies with an error response
71 * @throws RequestException When an error is encountered
72 * @throws \RuntimeException On an unexpected API response
73 * @throws \RuntimeException If the response content type is not JSON
74 * @throws \InvalidArgumentException If the JSON cannot be parsed
75 * @throws \LogicException When Guzzle cannot populate the response
76 *
77 * @return self
78 */
79 public function fetch()
80 {
81 parent::fetch();
82
83 // Convert captures data to Capture[]
84
85 $captures = [];
86 foreach ($this['captures'] as $capture) {
87 $captureId = $capture[Capture::ID_FIELD];
88
89 $object = new Capture(
90 $this->connector,
91 $this->getLocation(),
92 $captureId
93 );
94 $object->exchangeArray($capture);
95
96 $captures[] = $object;
97 }
98
99 $this['captures'] = $captures;
100
101 return $this;
102 }
103
104 /**
105 * Acknowledges the order.
106 *
107 * @throws ConnectorException When the API replies with an error response
108 * @throws RequestException When an error is encountered
109 * @throws \RuntimeException If the API replies with an unexpected response
110 * @throws \LogicException When Guzzle cannot populate the response
111 *
112 * @return self
113 */
114 public function acknowledge()
115 {
116 $this->post($this->getLocation() . '/acknowledge')
117 ->status('204');
118
119 return $this;
120 }
121
122 /**
123 * Cancels this order.
124 *
125 * @throws ConnectorException When the API replies with an error response
126 * @throws RequestException When an error is encountered
127 * @throws \RuntimeException If the API replies with an unexpected response
128 * @throws \LogicException When Guzzle cannot populate the response
129 *
130 * @return self
131 */
132 public function cancel()
133 {
134 $this->post($this->getLocation() . '/cancel')
135 ->status('204');
136
137 return $this;
138 }
139
140 /**
141 * Updates the authorization data.
142 *
143 * @param array $data Authorization data
144 *
145 * @throws ConnectorException When the API replies with an error response
146 * @throws RequestException When an error is encountered
147 * @throws \RuntimeException If the API replies with an unexpected response
148 * @throws \LogicException When Guzzle cannot populate the response
149 *
150 * @return self
151 */
152 public function updateAuthorization(array $data)
153 {
154 $this->patch($this->getLocation() . '/authorization', $data)
155 ->status('204');
156
157 return $this;
158 }
159
160 /**
161 * Extends the authorization time.
162 *
163 * @throws ConnectorException When the API replies with an error response
164 * @throws RequestException When an error is encountered
165 * @throws \RuntimeException If the API replies with an unexpected response
166 * @throws \LogicException When Guzzle cannot populate the response
167 *
168 * @return self
169 */
170 public function extendAuthorizationTime()
171 {
172 $this->post($this->getLocation() . '/extend-authorization-time')
173 ->status('204');
174
175 return $this;
176 }
177
178 /**
179 * Update the merchant references.
180 *
181 * @param array $data Merchant references
182 *
183 * @throws ConnectorException When the API replies with an error response
184 * @throws RequestException When an error is encountered
185 * @throws \RuntimeException If the API replies with an unexpected response
186 * @throws \LogicException When Guzzle cannot populate the response
187 *
188 * @return self
189 */
190 public function updateMerchantReferences(array $data)
191 {
192 $this->patch($this->getLocation() . '/merchant-references', $data)
193 ->status('204');
194
195 return $this;
196 }
197
198 /**
199 * Updates the customer details.
200 *
201 * @param array $data Customer data
202 *
203 * @throws ConnectorException When the API replies with an error response
204 * @throws RequestException When an error is encountered
205 * @throws \RuntimeException If the API replies with an unexpected response
206 * @throws \LogicException When Guzzle cannot populate the response
207 *
208 * @return self
209 */
210 public function updateCustomerDetails(array $data)
211 {
212 $this->patch($this->getLocation() . '/customer-details', $data)
213 ->status('204');
214
215 return $this;
216 }
217
218 /**
219 * Refunds an amount of a captured order.
220 *
221 * @param array $data Refund data
222 *
223 * @throws ConnectorException When the API replies with an error response
224 * @throws RequestException When an error is encountered
225 * @throws \RuntimeException If the API replies with an unexpected response
226 * @throws \LogicException When Guzzle cannot populate the response
227 *
228 * @return self
229 */
230 public function refund(array $data)
231 {
232 $this->post($this->getLocation() . '/refunds', $data)
233 ->status(['201', '204']);
234
235 return $this;
236 }
237
238 /**
239 * Release the remaining authorization for an order.
240 *
241 * @throws ConnectorException When the API replies with an error response
242 * @throws RequestException When an error is encountered
243 * @throws \RuntimeException If the API replies with an unexpected response
244 * @throws \LogicException When Guzzle cannot populate the response
245 *
246 * @return self
247 */
248 public function releaseRemainingAuthorization()
249 {
250 $this->post($this->getLocation() . '/release-remaining-authorization')
251 ->status('204');
252
253 return $this;
254 }
255
256 /**
257 * Capture all or part of an order.
258 *
259 * @param array $data Capture data
260 *
261 * @see Capture::create() For more information on how to create a capture
262 *
263 * @throws ConnectorException When the API replies with an error response
264 * @throws RequestException When an error is encountered
265 * @throws \RuntimeException If the location header is missing
266 * @throws \RuntimeException If the API replies with an unexpected response
267 * @throws \LogicException When Guzzle cannot populate the response
268 *
269 * @return Capture
270 */
271 public function createCapture(array $data)
272 {
273 $capture = new Capture($this->connector, $this->getLocation());
274
275 $capture->create($data);
276
277 $this['captures'][] = $capture;
278
279 return $capture;
280 }
281
282 /**
283 * Fetches the specified capture.
284 *
285 * @param string $captureId Capture ID
286 *
287 * @see Capture::fetch() For more information on how to fetch a capture
288 *
289 * @throws ConnectorException When the API replies with an error response
290 * @throws RequestException When an error is encountered
291 * @throws \RuntimeException On an unexpected API response
292 * @throws \RuntimeException If the response content type is not JSON
293 * @throws \InvalidArgumentException If the JSON cannot be parsed
294 * @throws \LogicException When Guzzle cannot populate the response
295 *
296 * @return Capture
297 */
298 public function fetchCapture($captureId)
299 {
300 if ($this->offsetExists('captures')) {
301 foreach ($this['captures'] as $capture) {
302 if ($capture->getId() !== $captureId) {
303 continue;
304 }
305
306 return $capture->fetch();
307 }
308 }
309
310 $capture = new Capture($this->connector, $this->getLocation(), $captureId);
311 $capture->fetch();
312
313 $this['captures'][] = $capture;
314
315 return $capture;
316 }
317 }
318