Skip to content

Commit 6e7fd9a

Browse files
committed
Add support for hosted purchases being in 'pending' state
Also adds CHANGELOG.md
1 parent ee1a50f commit 6e7fd9a

File tree

5 files changed

+95
-3
lines changed

5 files changed

+95
-3
lines changed

CHANGELOG.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [3.3.0] - 2025-11-14
9+
10+
### Added
11+
12+
- Support for hosted purchases being in 'pending' state (notably for 3DS state webhook callbacks)
13+
- Changelog!
14+
15+
## [3.2.0] - 2025-08-08
16+
17+
### Added
18+
19+
- Saved card support
20+
21+
## [3.1.0] - 2025-07-28
22+
23+
### Added
24+
25+
- `refund() support, including pending refunds
26+
- `fetchTransaction()` support
27+
- support for MOTO transactions
28+
29+
### Changed
30+
31+
- Complete purchase requests validate necessary URL parameters
32+
- Use a common, local `AbstractRequest`
33+
34+
## [3.0.1] - 2025-05-02
35+
36+
### Changed
37+
38+
- Explicitly mark as e-commerce transactions
39+
- Request method changed to class property
40+
41+
### Fixed
42+
43+
- Purchase should include authorisation and capture
44+
45+
## [3.0.0] - 2025-05-01
46+
47+
Initial version
48+
49+
[3.3.0]: https://github.com/Patronbase/omnipay-worldline/compare/v3.2.0...v3.3.0
50+
[3.2.0]: https://github.com/Patronbase/omnipay-worldline/compare/v3.1.0...v3.2.0
51+
[3.1.0]: https://github.com/Patronbase/omnipay-worldline/compare/v3.0.1...v3.1.0
52+
[3.0.1]: https://github.com/Patronbase/omnipay-worldline/compare/v3.0.0...v3.0.1
53+
[3.0.0]: https://github.com/Patronbase/omnipay-worldline/tree/v3.0.0

composer.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929
},
3030
"require": {
3131
"php": "^7.2|^8.0",
32-
"omnipay/common": "^3.1"
32+
"omnipay/common": "^3.1",
33+
"symfony/http-client": "^6.4"
3334
},
3435
"require-dev": {
3536
"omnipay/tests": "^4.1",
@@ -43,7 +44,7 @@
4344
},
4445
"extra": {
4546
"branch-alias": {
46-
"dev-main": "3.2.x-dev"
47+
"dev-main": "3.3.x-dev"
4748
}
4849
},
4950
"prefer-stable": true,

src/Message/CompletePurchaseResponse.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@
99
*/
1010
class CompletePurchaseResponse extends AbstractResponse
1111
{
12+
/**
13+
* Is the response pending?
14+
*
15+
* @return boolean
16+
*/
17+
public function isPending()
18+
{
19+
return $this->data->createdPaymentOutput->payment->statusOutput->statusCategory == 'PENDING_PAYMENT';
20+
}
21+
1222
/**
1323
* Is the response successful?
1424
*
@@ -46,6 +56,7 @@ public function getMessage()
4656
*/
4757
public function getCardReference()
4858
{
49-
return $this->data->createdPaymentOutput->payment->paymentOutput->cardPaymentMethodSpecificOutput->token ?? null;
59+
return $this->data->createdPaymentOutput->payment->paymentOutput->cardPaymentMethodSpecificOutput->token
60+
?? null;
5061
}
5162
}

tests/GatewayTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,30 @@ public function testCompletePurchaseSuccess()
5353

5454
$response = $this->gateway->completePurchase($options)->send();
5555

56+
$this->assertFalse($response->isPending());
5657
$this->assertTrue($response->isSuccessful());
5758
$this->assertFalse($response->isRedirect());
5859
$this->assertSame('1234567890_0', $response->getTransactionReference());
5960
$this->assertSame('PENDING_CAPTURE', $response->getMessage());
6061
$this->assertSame('12345678-90ab-cdef-1234-567890abcdef', $response->getCardReference());
6162
}
6263

64+
public function testCompletePurchasePending()
65+
{
66+
$this->setMockHttpResponse('HostedCompletePurchasePending.txt');
67+
68+
$options = array_merge($this->options, ['hostedCheckoutId' => '0000000001']);
69+
70+
$response = $this->gateway->completePurchase($options)->send();
71+
72+
$this->assertTrue($response->isPending());
73+
$this->assertFalse($response->isSuccessful());
74+
$this->assertFalse($response->isRedirect());
75+
$this->assertSame('1234567890', $response->getTransactionReference());
76+
$this->assertSame('REDIRECTED', $response->getMessage());
77+
$this->assertNull($response->getCardReference());
78+
}
79+
6380
public function testCompletePurchaseFailure()
6481
{
6582
$this->setMockHttpResponse('HostedCompletePurchaseFailure.txt');
@@ -68,6 +85,7 @@ public function testCompletePurchaseFailure()
6885

6986
$response = $this->gateway->completePurchase($options)->send();
7087

88+
$this->assertFalse($response->isPending());
7189
$this->assertFalse($response->isSuccessful());
7290
$this->assertFalse($response->isRedirect());
7391
$this->assertSame('1234567890_0', $response->getTransactionReference());
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
HTTP/1.1 200 OK
2+
Date: Thu, 14 Nov 2025 12:34:56 GMT
3+
Content-Length: 1302
4+
Content-Type: application/json; charset=utf-8
5+
Correlation-Id: 11111111-2222-3333-4444-abcdefabcdef
6+
Api_Auth: true
7+
Strict-Transport-Security: max-age=16000000; includeSubDomains; preload;
8+
9+
{"createdPaymentOutput":{"payment":{"hostedCheckoutSpecificOutput":{"hostedCheckoutId":"0000000001"},"paymentOutput":{"amountOfMoney":{"amount":145,"currencyCode":"EUR"},"references":{"merchantReference":"123abc"},"acquiredAmount":{"amount":0,"currencyCode":"EUR"},"customer":{"device":{"ipAddressCountryCode":"99"}},"cardPaymentMethodSpecificOutput":{"paymentProductId":1,"card":{"cardNumber":"************1111","expiryDate":"1234","bin":"411111","countryCode":"NZ","cardType":"Credit","cardCorporateIndicator":false,"cardEffectiveDateIndicator":"1","cardEffectiveDate":"2013-11-15","cardPanType":"pan","cardProductCode":"F","cardProductName":"Visa Classic","cardProductUsageLabel":"credit","cardScheme":"Visa","issuerRegionCode":"c","issuingCountryCode":"NZ","panLuhnCheck":"1","panLengthMax":"16","panLengthMin":"16"},"fraudResults":{"fraudServiceResult":"no-advice","cvvResult":"P"},"threeDSecureResults":{"version":"2.2.0","flow":"frictionless","eci":"7","xid":"ZYXWVUTSRQP000=="},"acquirerInformation":{"name":"ACQUIRER"},"cobrandSelectionIndicator":"alternative"},"paymentMethod":"card"},"status":"REDIRECTED","statusOutput":{"isCancellable":false,"statusCategory":"PENDING_PAYMENT","statusCode":46,"isAuthorized":false,"isRefundable":false},"id":"1234567890"},"paymentStatusCategory":"STATUS_UNKNOWN"},"status":"PAYMENT_CREATED"}

0 commit comments

Comments
 (0)