Skip to content

Commit 1321de3

Browse files
committed
Add saved card support
1 parent eb72a41 commit 1321de3

File tree

7 files changed

+73
-2
lines changed

7 files changed

+73
-2
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
},
4444
"extra": {
4545
"branch-alias": {
46-
"dev-main": "3.1.x-dev"
46+
"dev-main": "3.2.x-dev"
4747
}
4848
},
4949
"prefer-stable": true,

src/Message/AbstractRequest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,16 @@ public function setMerchantId($value)
5454
return $this->setParameter('merchantId', $value);
5555
}
5656

57+
public function getCreateToken()
58+
{
59+
return $this->getParameter('createToken');
60+
}
61+
62+
public function setCreateToken($value)
63+
{
64+
return $this->setParameter('createToken', $value);
65+
}
66+
5767
public function getEndpoint()
5868
{
5969
return ($this->getTestMode() ? $this->testEndpoint : $this->liveEndpoint).$this->getAction();

src/Message/CompletePurchaseResponse.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,14 @@ public function getMessage()
3838
{
3939
return $this->data->createdPaymentOutput->payment->status;
4040
}
41+
42+
/**
43+
* Get the card reference (payment token) if available
44+
*
45+
* @return null|string
46+
*/
47+
public function getCardReference()
48+
{
49+
return $this->data->createdPaymentOutput->payment->paymentOutput->cardPaymentMethodSpecificOutput->token ?? null;
50+
}
4151
}

src/Message/PurchaseRequest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ public function getData()
114114
$data = [
115115
'cardPaymentMethodSpecificInput' => [
116116
'authorizationMode' => $this->authorizationMode ?? 'SALE',
117+
'tokenize' => (bool) $this->getCreateToken(),
117118
'transactionChannel' => $this->getTransactionChannel() ?? 'ECOMMERCE',
118119
],
119120
'hostedCheckoutSpecificInput' => [
@@ -163,6 +164,10 @@ public function getData()
163164
$data['hostedCheckoutSpecificInput']['sessionTimeout'] = (int) $this->getSessionTimeout();
164165
}
165166

167+
if ($this->getToken() !== null || $this->getCardReference() !== null) {
168+
$data['cardPaymentMethodSpecificInput']['token'] = $this->getToken() ?? $this->getCardReference();
169+
}
170+
166171
if ($this->getNotifyUrl() !== null) {
167172
$data['feedbacks'] = [
168173
'webhookUrl' => $this->getNotifyUrl(),

tests/GatewayTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ public function testCompletePurchaseSuccess()
5757
$this->assertFalse($response->isRedirect());
5858
$this->assertSame('1234567890_0', $response->getTransactionReference());
5959
$this->assertSame('PENDING_CAPTURE', $response->getMessage());
60+
$this->assertSame('12345678-90ab-cdef-1234-567890abcdef', $response->getCardReference());
6061
}
6162

6263
public function testCompletePurchaseFailure()
@@ -71,6 +72,7 @@ public function testCompletePurchaseFailure()
7172
$this->assertFalse($response->isRedirect());
7273
$this->assertSame('1234567890_0', $response->getTransactionReference());
7374
$this->assertSame('CANCELLED', $response->getMessage());
75+
$this->assertNull($response->getCardReference());
7476
}
7577

7678
public function testRefundSuccess()

tests/Message/PurchaseRequestTest.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ public function testGetData()
106106
$this->assertArrayHasKey("cardPaymentMethodSpecificInput", $data);
107107
$this->assertArrayHasKey("authorizationMode", $data["cardPaymentMethodSpecificInput"]);
108108
$this->assertSame("SALE", $data["cardPaymentMethodSpecificInput"]['authorizationMode']);
109+
$this->assertArrayHasKey("tokenize", $data["cardPaymentMethodSpecificInput"]);
110+
$this->assertFalse($data["cardPaymentMethodSpecificInput"]['tokenize']);
109111
$this->assertArrayHasKey("transactionChannel", $data["cardPaymentMethodSpecificInput"]);
110112
$this->assertSame("ECOMMERCE", $data["cardPaymentMethodSpecificInput"]['transactionChannel']);
111113
$this->assertArrayHasKey("hostedCheckoutSpecificInput", $data);
@@ -157,6 +159,48 @@ public function testGetItemPriceIntegerWithBadItemPrice()
157159
$data = $request->getData();
158160
}
159161

162+
public function testCardReference()
163+
{
164+
$params = $this->allParams;
165+
$params['cardReference'] = '12345678-90ab-cdef-1234-567890abcdef';
166+
$request = new PurchaseRequest($this->getHttpClient(), $this->getHttpRequest());
167+
$request->initialize($params);
168+
169+
$data = $request->getData();
170+
171+
$this->assertArrayHasKey("cardPaymentMethodSpecificInput", $data);
172+
$this->assertArrayHasKey("token", $data["cardPaymentMethodSpecificInput"]);
173+
$this->assertSame('12345678-90ab-cdef-1234-567890abcdef', $data["cardPaymentMethodSpecificInput"]['token']);
174+
}
175+
176+
public function testToken()
177+
{
178+
$params = $this->allParams;
179+
$params['token'] = '12345678-90ab-cdef-1234-567890abcdef';
180+
$request = new PurchaseRequest($this->getHttpClient(), $this->getHttpRequest());
181+
$request->initialize($params);
182+
183+
$data = $request->getData();
184+
185+
$this->assertArrayHasKey("cardPaymentMethodSpecificInput", $data);
186+
$this->assertArrayHasKey("token", $data["cardPaymentMethodSpecificInput"]);
187+
$this->assertSame('12345678-90ab-cdef-1234-567890abcdef', $data["cardPaymentMethodSpecificInput"]['token']);
188+
}
189+
190+
public function testCreateToken()
191+
{
192+
$params = $this->allParams;
193+
$params['createToken'] = true;
194+
$request = new PurchaseRequest($this->getHttpClient(), $this->getHttpRequest());
195+
$request->initialize($params);
196+
197+
$data = $request->getData();
198+
199+
$this->assertArrayHasKey("cardPaymentMethodSpecificInput", $data);
200+
$this->assertArrayHasKey("tokenize", $data["cardPaymentMethodSpecificInput"]);
201+
$this->assertTrue($data["cardPaymentMethodSpecificInput"]['tokenize']);
202+
}
203+
160204
public function testMotoTransactionChannel()
161205
{
162206
$params = $this->allParams;

tests/Mock/HostedCompletePurchaseSuccess.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ Correlation-Id: 11111111-2222-3333-4444-abcdefabcdef
66
Api_Auth: true
77
Strict-Transport-Security: max-age=16000000; includeSubDomains; preload;
88

9-
{"createdPaymentOutput":{"payment":{"hostedCheckoutSpecificOutput":{"hostedCheckoutId":"0000000001"},"paymentOutput":{"amountOfMoney":{"amount":145,"currencyCode":"EUR"},"references":{"merchantReference":"123abc"},"acquiredAmount":{"amount":145,"currencyCode":"EUR"},"customer":{"device":{"ipAddressCountryCode":"99"}},"cardPaymentMethodSpecificOutput":{"paymentProductId":1,"authorisationCode":"123456","card":{"cardNumber":"************1111","expiryDate":"1230","bin":"411111","countryCode":"99"},"fraudResults":{"fraudServiceResult":"no-advice","avsResult":"U","cvvResult":"M"},"schemeReferenceData":"123456789012","paymentAccountReference":"0123456789ABCDEFGHIJKLMNOPQRS","threeDSecureResults":{"version":"2.2.0","flow":"frictionless","cavv":"AAABBBCCCDDDEEEFFFZZAAAAAAA=","eci":"5","schemeEci":"05","authenticationStatus":"Y","acsTransactionId":"ABCDEF01-2345-6789-0ABC-DEF123456789","dsTransactionId":"ABCDEF01-2345-6789-0ABC-DEF012345678","xid":"ZYXWVUTSRQP000==","liability":"issuer"},"acquirerInformation":{"name":"ACQUIRER"}},"paymentMethod":"card"},"status":"PENDING_CAPTURE","statusOutput":{"isCancellable":true,"statusCategory":"PENDING_MERCHANT","statusCode":5,"isAuthorized":true,"isRefundable":false},"id":"1234567890_0"},"paymentStatusCategory":"SUCCESSFUL"},"status":"PAYMENT_CREATED"}
9+
{"createdPaymentOutput":{"payment":{"hostedCheckoutSpecificOutput":{"hostedCheckoutId":"0000000001"},"paymentOutput":{"amountOfMoney":{"amount":145,"currencyCode":"EUR"},"references":{"merchantReference":"123abc"},"acquiredAmount":{"amount":145,"currencyCode":"EUR"},"customer":{"device":{"ipAddressCountryCode":"99"}},"cardPaymentMethodSpecificOutput":{"paymentProductId":1,"authorisationCode":"123456","card":{"cardNumber":"************1111","expiryDate":"1230","bin":"411111","countryCode":"99"},"fraudResults":{"fraudServiceResult":"no-advice","avsResult":"U","cvvResult":"M"},"schemeReferenceData":"123456789012","paymentAccountReference":"0123456789ABCDEFGHIJKLMNOPQRS","threeDSecureResults":{"version":"2.2.0","flow":"frictionless","cavv":"AAABBBCCCDDDEEEFFFZZAAAAAAA=","eci":"5","schemeEci":"05","authenticationStatus":"Y","acsTransactionId":"ABCDEF01-2345-6789-0ABC-DEF123456789","dsTransactionId":"ABCDEF01-2345-6789-0ABC-DEF012345678","xid":"ZYXWVUTSRQP000==","liability":"issuer"},"token":"12345678-90ab-cdef-1234-567890abcdef","acquirerInformation":{"name":"ACQUIRER"}},"paymentMethod":"card"},"status":"PENDING_CAPTURE","statusOutput":{"isCancellable":true,"statusCategory":"PENDING_MERCHANT","statusCode":5,"isAuthorized":true,"isRefundable":false},"id":"1234567890_0"},"paymentStatusCategory":"SUCCESSFUL"},"status":"PAYMENT_CREATED"}

0 commit comments

Comments
 (0)