Skip to content

Commit 3f014a3

Browse files
PHPSDK-191: Create method to know if 'Manual Capture' is supported (#402)
1 parent a83adfa commit 3f014a3

2 files changed

Lines changed: 206 additions & 0 deletions

File tree

src/Api/PaymentMethods/PaymentMethod.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class PaymentMethod
4040
public const PAYMENT_COMPONENT_KEY = 'payment_components';
4141
public const PAYMENT_COMPONENT_HAS_FIELDS_KEY = 'has_fields';
4242
public const PAYMENT_COMPONENT_QR_KEY = 'qr';
43+
public const MANUAL_CAPTURE_KEY = 'manual_capture';
4344
public const FAST_CHECKOUT_KEY = 'fastcheckout';
4445
public const RECURRING_MODEL_CARD_ON_FILE_KEY = 'cardonfile';
4546
public const RECURRING_MODEL_SUBSCRIPTION_KEY = 'subscription';
@@ -114,6 +115,11 @@ class PaymentMethod
114115
*/
115116
private $requiredCustomerData;
116117

118+
/**
119+
* @var array
120+
*/
121+
private $manualCapture;
122+
117123
/**
118124
* Transaction constructor.
119125
* @param array $data
@@ -135,6 +141,7 @@ public function __construct(array $data)
135141
$this->allowedCountries = $data[self::ALLOWED_COUNTRIES_KEY] ?? null;
136142
$this->iconUrls = $data[self::ICON_URLS_KEY] ?? '';
137143
$this->requiredCustomerData = $data[self::REQUIRED_CUSTOMER_DATA_KEY] ?? null;
144+
$this->manualCapture = $data[self::MANUAL_CAPTURE_KEY] ?? [];
138145
}
139146

140147
/**
@@ -293,6 +300,16 @@ public function supportsQr(): bool
293300
$this->apps[self::PAYMENT_COMPONENT_KEY][self::PAYMENT_COMPONENT_QR_KEY][self::SUPPORTED_KEY];
294301
}
295302

303+
/**
304+
* @return bool
305+
*/
306+
public function supportsManualCapture(): bool
307+
{
308+
return isset($this->manualCapture[self::IS_ENABLED_KEY], $this->manualCapture[self::SUPPORTED_KEY]) &&
309+
$this->manualCapture[self::IS_ENABLED_KEY] &&
310+
$this->manualCapture[self::SUPPORTED_KEY];
311+
}
312+
296313
/**
297314
* @return bool
298315
*/
@@ -384,6 +401,10 @@ public function getData(): array
384401
self::RECURRING_MODEL_UNSCHEDULED_KEY => $this->tokenization[self::TOKENIZATION_MODELS_KEY][self::RECURRING_MODEL_UNSCHEDULED_KEY] ?? false,
385402
],
386403
],
404+
self::MANUAL_CAPTURE_KEY => [
405+
self::IS_ENABLED_KEY => $this->manualCapture[self::IS_ENABLED_KEY] ?? false,
406+
self::SUPPORTED_KEY => $this->manualCapture[self::SUPPORTED_KEY] ?? false,
407+
],
387408
self::SHOPPING_CART_REQUIRED_KEY => $this->shoppingCartRequired,
388409
self::PREFERRED_COUNTRIES_KEY => $this->preferredCountries,
389410
self::ICON_URLS_KEY => [
@@ -464,6 +485,22 @@ private function validate(array $data): void
464485
throw new InvalidDataInitializationException('No Payment Component has "qr" field ' . $data[self::ID_KEY]);
465486
}
466487

488+
if (isset($data[self::MANUAL_CAPTURE_KEY])) {
489+
$manualCapture = $data[self::MANUAL_CAPTURE_KEY];
490+
491+
if (!is_array($manualCapture)) {
492+
throw new InvalidDataInitializationException('Manual capture is not an array ' . $data[self::ID_KEY]);
493+
}
494+
495+
if (!isset($manualCapture[self::IS_ENABLED_KEY])) {
496+
throw new InvalidDataInitializationException('No Manual Capture has "is_enabled" field ' . $data[self::ID_KEY]);
497+
}
498+
499+
if (!isset($manualCapture[self::SUPPORTED_KEY])) {
500+
throw new InvalidDataInitializationException('No Manual Capture has "supported" field ' . $data[self::ID_KEY]);
501+
}
502+
}
503+
467504
if (!isset($data[self::ICON_URLS_KEY]) || !is_array($data[self::ICON_URLS_KEY])) {
468505
throw new InvalidDataInitializationException('Icon urls is not an array ' . $data[self::ID_KEY]);
469506
}

tests/Unit/Api/PaymentMethods/PaymentMethodTest.php

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,85 @@ public function testImproperInitialization()
7373
new PaymentMethod($this->getWrongData());
7474
}
7575

76+
/**
77+
* Test support manual capture from current API format
78+
*/
79+
public function testSupportsManualCaptureFromRootLevelData()
80+
{
81+
$data = $this->getValidData();
82+
$data[PaymentMethod::MANUAL_CAPTURE_KEY] = [
83+
PaymentMethod::IS_ENABLED_KEY => true,
84+
PaymentMethod::SUPPORTED_KEY => true,
85+
];
86+
87+
$paymentMethod = new PaymentMethod($data);
88+
89+
$this->assertTrue($paymentMethod->supportsManualCapture());
90+
}
91+
92+
/**
93+
* Test manual capture defaults to false when field is missing
94+
*/
95+
public function testSupportsManualCaptureReturnsFalseWithoutManualCapture()
96+
{
97+
$paymentMethod = new PaymentMethod($this->getValidData());
98+
99+
$this->assertFalse($paymentMethod->supportsManualCapture());
100+
}
101+
102+
/**
103+
* Test manual capture is false when one of required flags is false
104+
*
105+
* @dataProvider getManualCaptureFalseValues
106+
*/
107+
public function testSupportsManualCaptureReturnsFalseWithFalseValues(array $manualCapture)
108+
{
109+
$data = $this->getValidData();
110+
$data[PaymentMethod::MANUAL_CAPTURE_KEY] = $manualCapture;
111+
112+
$paymentMethod = new PaymentMethod($data);
113+
114+
$this->assertFalse($paymentMethod->supportsManualCapture());
115+
}
116+
117+
/**
118+
* Test invalid manual capture payload fails initialization
119+
*
120+
* @dataProvider getWrongManualCaptureData
121+
*/
122+
public function testImproperInitializationWithInvalidManualCapture($manualCapture, string $expectedErrorMessage)
123+
{
124+
$this->expectException(InvalidDataInitializationException::class);
125+
$this->expectExceptionMessage($expectedErrorMessage);
126+
127+
$data = $this->getValidData();
128+
$data[PaymentMethod::MANUAL_CAPTURE_KEY] = $manualCapture;
129+
130+
new PaymentMethod($data);
131+
}
132+
133+
/**
134+
* Test getData includes manual_capture structure when enabled
135+
*/
136+
public function testGetDataIncludesManualCaptureWhenEnabled()
137+
{
138+
$data = $this->getValidData();
139+
$data[PaymentMethod::MANUAL_CAPTURE_KEY] = [
140+
PaymentMethod::IS_ENABLED_KEY => true,
141+
PaymentMethod::SUPPORTED_KEY => true,
142+
];
143+
144+
$paymentMethod = new PaymentMethod($data);
145+
$result = $paymentMethod->getData();
146+
147+
$this->assertArrayHasKey(PaymentMethod::MANUAL_CAPTURE_KEY, $result);
148+
$this->assertIsArray($result[PaymentMethod::MANUAL_CAPTURE_KEY]);
149+
$this->assertArrayHasKey(PaymentMethod::IS_ENABLED_KEY, $result[PaymentMethod::MANUAL_CAPTURE_KEY]);
150+
$this->assertArrayHasKey(PaymentMethod::SUPPORTED_KEY, $result[PaymentMethod::MANUAL_CAPTURE_KEY]);
151+
$this->assertTrue($result[PaymentMethod::MANUAL_CAPTURE_KEY][PaymentMethod::IS_ENABLED_KEY]);
152+
$this->assertTrue($result[PaymentMethod::MANUAL_CAPTURE_KEY][PaymentMethod::SUPPORTED_KEY]);
153+
}
154+
76155
/**
77156
* @return array
78157
*/
@@ -81,4 +160,94 @@ private function getWrongData(): array
81160
$this->wrongData['id'] = '';
82161
return $this->wrongData;
83162
}
163+
164+
/**
165+
* @return array
166+
*/
167+
private function getValidData(): array
168+
{
169+
return [
170+
PaymentMethod::ID_KEY => 'VISA',
171+
PaymentMethod::NAME_KEY => 'Visa',
172+
PaymentMethod::TYPE_KEY => PaymentMethod::PAYMENT_METHOD_TYPE,
173+
PaymentMethod::ALLOWED_AMOUNT_KEY => [
174+
PaymentMethod::ALLOWED_MIN_AMOUNT_KEY => 0,
175+
PaymentMethod::ALLOWED_MAX_AMOUNT_KEY => null,
176+
],
177+
PaymentMethod::ALLOWED_COUNTRIES_KEY => [],
178+
PaymentMethod::BRANDS_KEY => [],
179+
PaymentMethod::PREFERRED_COUNTRIES_KEY => [],
180+
PaymentMethod::REQUIRED_CUSTOMER_DATA_KEY => [],
181+
PaymentMethod::SHOPPING_CART_REQUIRED_KEY => false,
182+
PaymentMethod::TOKENIZATION_KEY => [
183+
PaymentMethod::IS_ENABLED_KEY => true,
184+
PaymentMethod::TOKENIZATION_MODELS_KEY => [
185+
PaymentMethod::RECURRING_MODEL_CARD_ON_FILE_KEY => true,
186+
PaymentMethod::RECURRING_MODEL_SUBSCRIPTION_KEY => true,
187+
PaymentMethod::RECURRING_MODEL_UNSCHEDULED_KEY => true,
188+
],
189+
],
190+
PaymentMethod::APPS_KEY => [
191+
PaymentMethod::PAYMENT_COMPONENT_KEY => [
192+
PaymentMethod::PAYMENT_COMPONENT_HAS_FIELDS_KEY => true,
193+
PaymentMethod::IS_ENABLED_KEY => true,
194+
PaymentMethod::PAYMENT_COMPONENT_QR_KEY => [
195+
PaymentMethod::SUPPORTED_KEY => false,
196+
],
197+
],
198+
PaymentMethod::FAST_CHECKOUT_KEY => [
199+
PaymentMethod::IS_ENABLED_KEY => true,
200+
],
201+
],
202+
PaymentMethod::ICON_URLS_KEY => [
203+
PaymentMethod::ICON_URLS_LARGE_KEY => 'https://example.com/visa-large.png',
204+
PaymentMethod::ICON_URLS_MEDIUM_KEY => 'https://example.com/visa-medium.png',
205+
PaymentMethod::ICON_URLS_VECTOR_KEY => 'https://example.com/visa.svg',
206+
],
207+
PaymentMethod::ALLOWED_CURRENCIES_KEY => ['EUR'],
208+
];
209+
}
210+
211+
/**
212+
* @return array
213+
*/
214+
public function getManualCaptureFalseValues(): array
215+
{
216+
return [
217+
[[
218+
PaymentMethod::IS_ENABLED_KEY => false,
219+
PaymentMethod::SUPPORTED_KEY => true,
220+
]],
221+
[[
222+
PaymentMethod::IS_ENABLED_KEY => true,
223+
PaymentMethod::SUPPORTED_KEY => false,
224+
]],
225+
[[
226+
PaymentMethod::IS_ENABLED_KEY => false,
227+
PaymentMethod::SUPPORTED_KEY => false,
228+
]],
229+
];
230+
}
231+
232+
/**
233+
* @return array
234+
*/
235+
public function getWrongManualCaptureData(): array
236+
{
237+
return [
238+
['', 'Manual capture is not an array'],
239+
[
240+
[
241+
PaymentMethod::SUPPORTED_KEY => true,
242+
],
243+
'No Manual Capture has "is_enabled" field',
244+
],
245+
[
246+
[
247+
PaymentMethod::IS_ENABLED_KEY => true,
248+
],
249+
'No Manual Capture has "supported" field',
250+
],
251+
];
252+
}
84253
}

0 commit comments

Comments
 (0)