Skip to content

Commit 61e5a6f

Browse files
authored
Merge pull request #11 from superbrave/splits-transaction-status-to-complete-authorise-and-capture
Splits transaction status to complete authorise and capture
2 parents da7868d + ef6f3b1 commit 61e5a6f

28 files changed

+654
-87
lines changed

src/Gateway.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use DateTime;
66
use Omnipay\Common\AbstractGateway;
77
use Omnipay\Common\Message\RequestInterface;
8+
use Omnipay\IcepayPayments\Message\CompleteAuthoriseAndCaptureRequest;
89
use Omnipay\IcepayPayments\Message\CreateTransactionRequest;
910
use Omnipay\IcepayPayments\Message\RefundRequest;
1011
use Omnipay\IcepayPayments\Message\TransactionStatusRequest;
@@ -108,7 +109,7 @@ public function authorize(array $parameters = []): RequestInterface
108109
*/
109110
public function completeAuthorize(array $parameters = []): RequestInterface
110111
{
111-
return $this->fetchTransaction($parameters);
112+
return $this->createRequest(CompleteAuthoriseAndCaptureRequest::class, $parameters);
112113
}
113114

114115
/**
@@ -144,7 +145,7 @@ public function refund(array $parameters = []): RequestInterface
144145
*/
145146
public function capture(array $parameters = []): RequestInterface
146147
{
147-
return $this->fetchTransaction($parameters);
148+
return $this->createRequest(CompleteAuthoriseAndCaptureRequest::class, $parameters);
148149
}
149150

150151
/**

src/Message/AbstractResponse.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ abstract class AbstractResponse extends OmnipayAbstractResponse
9090
*/
9191
public function isSuccessful(): bool
9292
{
93-
return isset($this->data['contractId']);
93+
return isset($this->data['contractId']) && isset($this->data['transactionId']);
9494
}
9595

9696
/**
@@ -110,6 +110,6 @@ public function isCancelled(): bool
110110
*/
111111
public function getTransactionReference(): ?string
112112
{
113-
return $this->data['transactionId'] ?? ($this->data['providerTransactionId'] ?? null);
113+
return $this->data['transactionId'] ?? null;
114114
}
115115
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
namespace Omnipay\IcepayPayments\Message;
4+
5+
use Omnipay\Common\Message\ResponseInterface;
6+
use Symfony\Component\HttpFoundation\Request;
7+
8+
/**
9+
* The request for retrieving the payment transaction status when the CompleteAuthorise and Capture happens.
10+
* The payment transaction status can be different from what we get back as data from Icepay.
11+
*/
12+
class CompleteAuthoriseAndCaptureRequest extends AbstractRequest
13+
{
14+
/**
15+
* {@inheritdoc}
16+
*/
17+
public function getData(): array
18+
{
19+
$data = parent::getData();
20+
21+
$data['ContractProfileId'] = $this->getContractProfileId();
22+
23+
return $data;
24+
}
25+
26+
/**
27+
* {@inheritdoc}
28+
*/
29+
public function sendData($data): ResponseInterface
30+
{
31+
$this->sendRequest(
32+
Request::METHOD_POST,
33+
sprintf(
34+
'/transaction/%s',
35+
$this->getTransactionReference()
36+
),
37+
$data
38+
);
39+
40+
return new CompleteAuthoriseAndCaptureResponse(
41+
$this,
42+
$this->getResponseBody()
43+
);
44+
}
45+
46+
/**
47+
* Get the HttpRequest.
48+
* Note: this is not an API request.
49+
*
50+
* @see Omnipay\Common\Message\AbstractRequest::$httpRequest
51+
*
52+
* @return Request
53+
*/
54+
public function getHttpRequest(): Request
55+
{
56+
return $this->httpRequest;
57+
}
58+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
namespace Omnipay\IcepayPayments\Message;
4+
5+
/**
6+
* The response after complete authorise and capture request.
7+
* For this response, we explicitly check what the status is of the payment transaction at Icepay.
8+
*/
9+
class CompleteAuthoriseAndCaptureResponse extends AbstractResponse
10+
{
11+
/**
12+
* {@inheritdoc}
13+
*/
14+
public function isSuccessful(): bool
15+
{
16+
return isset($this->data['status']) && in_array($this->data['status'], [
17+
self::RESPONSE_STATUS_COMPLETED,
18+
self::RESPONSE_STATUS_SETTLED,
19+
]);
20+
}
21+
22+
/**
23+
* {@inheritdoc}
24+
*
25+
* In case there is no status 'cancelled' available in the response (yet), check if there is statusCode in the
26+
* queryString. Icepay calls a postback to the completeUrl with data of the payment transaction as queryString.
27+
*/
28+
public function isCancelled(): bool
29+
{
30+
return isset($this->data['status']) && $this->data['status'] === self::RESPONSE_STATUS_CANCELLED
31+
|| $this->request->getHttpRequest()->get('statusCode') === self::RESPONSE_STATUS_CANCELLED;
32+
}
33+
34+
/**
35+
* {@inheritdoc}
36+
*/
37+
public function getTransactionReference(): ?string
38+
{
39+
return $this->request->getTransactionReference();
40+
}
41+
}

src/Message/CreateTransactionRequest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public function getData(): array
5454
'TotalGrossAmountCents' => $this->getAmountInteger(),
5555
'TotalNetAmountCents' => $this->getAmountInteger(),
5656
],
57-
'Description' => $this->getTransactionId(),
57+
'Description' => $this->getDescription(),
5858
],
5959
];
6060

src/Message/CreateTransactionResponse.php

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,7 @@ class CreateTransactionResponse extends AbstractResponse
1313
public function isSuccessful(): bool
1414
{
1515
return parent::isSuccessful()
16-
&& ($this->getTransactionReference() !== null)
17-
&& in_array($this->data['transactionStatusCode'], [
18-
self::RESPONSE_STATUS_STARTED,
19-
]);
16+
&& (isset($this->data['transactionStatusCode']) && $this->data['transactionStatusCode'] === self::RESPONSE_STATUS_STARTED);
2017
}
2118

2219
/**
@@ -32,6 +29,6 @@ public function isRedirect(): bool
3229
*/
3330
public function getRedirectUrl(): string
3431
{
35-
return $this->data['acquirerRequestUri'];
32+
return $this->data['acquirerRequestUri'] ?? '';
3633
}
3734
}

src/Message/TransactionStatusRequest.php

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,10 @@ public function sendData($data): ResponseInterface
3636
$data
3737
);
3838

39-
$response = array_merge(
40-
$this->getResponseBody(),
41-
[
42-
'statusCode' => $this->getResponse()->getStatusCode(),
43-
]
44-
);
45-
4639
return new TransactionStatusResponse(
4740
$this,
48-
$response
41+
$this->getResponseBody(),
42+
$this->getResponse()->getStatusCode()
4943
);
5044
}
5145
}

src/Message/TransactionStatusResponse.php

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,47 @@
22

33
namespace Omnipay\IcepayPayments\Message;
44

5+
use Omnipay\Common\Message\RequestInterface;
6+
57
/**
68
* The response after getting the transaction status at Icepay.
9+
* For this response, we check the response (statusCode) of the payment transaction at Icepay.
710
*/
811
class TransactionStatusResponse extends AbstractResponse
912
{
13+
/**
14+
* @var int
15+
*/
16+
private $statusCode;
17+
18+
/**
19+
* TransactionStatusResponse constructor.
20+
*
21+
* @param RequestInterface $request
22+
* @param mixed $data
23+
* @param int $statusCode
24+
*/
25+
public function __construct(RequestInterface $request, $data, int $statusCode)
26+
{
27+
parent::__construct($request, $data);
28+
29+
$this->statusCode = $statusCode;
30+
}
31+
1032
/**
1133
* {@inheritdoc}
1234
*/
1335
public function isSuccessful(): bool
1436
{
15-
return (isset($this->data['status']) && in_array($this->data['status'], [
16-
self::RESPONSE_STATUS_COMPLETED,
17-
self::RESPONSE_STATUS_SETTLED,
18-
])) && (isset($this->data['statusCode']) && $this->data['statusCode'] === 200);
37+
return $this->statusCode === 200;
1938
}
2039

2140
/**
2241
* {@inheritdoc}
2342
*/
2443
public function isCancelled(): bool
2544
{
26-
return parent::isCancelled() || $this->data['statusCode'] === self::RESPONSE_STATUS_CANCELLED;
45+
return isset($this->data['status']) && $this->data['status'] === self::RESPONSE_STATUS_CANCELLED;
2746
}
2847

2948
/**

tests/GatewayTest.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Omnipay\Common\GatewayInterface;
66
use Omnipay\IcepayPayments\Gateway;
7+
use Omnipay\IcepayPayments\Message\CompleteAuthoriseAndCaptureRequest;
78
use Omnipay\IcepayPayments\Message\CreateTransactionRequest;
89
use Omnipay\IcepayPayments\Message\RefundRequest;
910
use Omnipay\IcepayPayments\Message\TransactionStatusRequest;
@@ -92,7 +93,7 @@ public function testCompleteAuthorize(): void
9293
{
9394
$request = $this->gateway->completeAuthorize($this->options);
9495

95-
$this->assertInstanceOf(TransactionStatusRequest::class, $request);
96+
$this->assertInstanceOf(CompleteAuthoriseAndCaptureRequest::class, $request);
9697
}
9798

9899
/**
@@ -102,7 +103,7 @@ public function testCapture(): void
102103
{
103104
$request = $this->gateway->capture($this->options);
104105

105-
$this->assertInstanceOf(TransactionStatusRequest::class, $request);
106+
$this->assertInstanceOf(CompleteAuthoriseAndCaptureRequest::class, $request);
106107
}
107108

108109
/**
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?php
2+
3+
namespace Omnipay\IcepayPayments\Tests\Message;
4+
5+
use GuzzleHttp\Psr7\Request;
6+
use Omnipay\IcepayPayments\Message\CompleteAuthoriseAndCaptureRequest;
7+
use Omnipay\IcepayPayments\Message\CompleteAuthoriseAndCaptureResponse;
8+
use Omnipay\IcepayPayments\Tests\AbstractTestCase;
9+
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
10+
11+
/**
12+
* Class CompleteAuthoriseAndCaptureRequestTest.
13+
*/
14+
class CompleteAuthoriseAndCaptureRequestTest extends AbstractTestCase
15+
{
16+
/**
17+
* @var CompleteAuthoriseAndCaptureRequest
18+
*/
19+
protected $request;
20+
21+
/**
22+
* Creates a new CompleteAuthoriseAndCaptureRequestTest instance.
23+
*/
24+
protected function setUp(): void
25+
{
26+
parent::setUp();
27+
28+
$this->request = new CompleteAuthoriseAndCaptureRequest($this->httpClient, $this->httpRequest);
29+
$this->request->setBaseUrl('https://www.superbrave.nl');
30+
$this->request->setSecretKey('NjRlYjM3MTctOGI1ZC00MDg4LTgxMDgtOTMyMjQ2NzVlNTM4');
31+
$this->request->setContractProfileId('64eb3717-8b5d-4088-8108-93224675e538');
32+
$this->request->setTransactionReference('e7ca29c8-f1f4-4a4c-a968-0f9667d0519d');
33+
}
34+
35+
/**
36+
* Tests if CompleteAuthoriseAndCaptureRequest::getData validates the basic keys and returns an array of data.
37+
*/
38+
public function testGetData(): void
39+
{
40+
$expectedData = [
41+
'ContractProfileId' => '64eb3717-8b5d-4088-8108-93224675e538',
42+
];
43+
$this->assertEquals($expectedData, $this->request->getData());
44+
}
45+
46+
/**
47+
* Tests if CompleteAuthoriseAndCaptureRequest::sendData returns a CompleteAuthoriseAndCaptureResponse.
48+
*/
49+
public function testSendData(): void
50+
{
51+
$data = [
52+
'AmountInCents' => 1337,
53+
'CurrencyCode' => 'EUR',
54+
'Reference' => '2fad9b1b-a2d3-455c-bc29-b79516fd3257',
55+
'Timestamp' => '2019-03-09T12:00:00Z',
56+
];
57+
$response = $this->request->sendData($data);
58+
59+
$this->assertInstanceOf(CompleteAuthoriseAndCaptureResponse::class, $response);
60+
61+
$expectedRequest = new Request(
62+
SymfonyRequest::METHOD_POST,
63+
'https://www.superbrave.nl/transaction/e7ca29c8-f1f4-4a4c-a968-0f9667d0519d'
64+
);
65+
66+
$this->assertEquals($expectedRequest->getMethod(), $this->clientMock->getLastRequest()->getMethod());
67+
$this->assertEquals($expectedRequest->getUri(), $this->clientMock->getLastRequest()->getUri());
68+
}
69+
70+
/**
71+
* Tests if CompleteAuthoriseAndCaptureRequest getRequest function will return a Symfony HttpRequest object.
72+
*/
73+
public function testGetHttpRequest(): void
74+
{
75+
$this->assertSame($this->httpRequest, $this->request->getHttpRequest());
76+
$this->assertInstanceOf(SymfonyRequest::class, $this->request->getHttpRequest());
77+
}
78+
}

0 commit comments

Comments
 (0)