Skip to content

Commit ec61271

Browse files
authored
Authorize and capture separately (#7)
* wip * add PHP 8.1 to test suite * use setTransactionReference instead of setPaymentReference for CaptureRequest * update license * update readme and add comments * add badges * update readme * improve tests
1 parent 1073540 commit ec61271

File tree

7 files changed

+198
-12
lines changed

7 files changed

+198
-12
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ jobs:
2121
- "7.3"
2222
- "7.4"
2323
- "8.0"
24+
- "8.1"
2425
operating-system:
2526
- "ubuntu-latest"
2627

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright 2021 Swiftmade OÜ
1+
Copyright 2023 Swiftmade OÜ
22

33
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
44

README.md

Lines changed: 77 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,31 @@
1-
# Omnipay - EveryPay Gateway
1+
[![Latest Version on Packagist](https://img.shields.io/packagist/v/swiftmade/omnipay-everypay.svg?style=flat-square)](https://packagist.org/packages/swiftmade/omnipay-everypay)
2+
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md)
3+
[![Total Downloads](https://img.shields.io/packagist/dt/swiftmade/omnipay-everypay.svg?style=flat-square)](https://packagist.org/packages/swiftmade/omnipay-everypay)
24

3-
_Disclaimer: This package is **not** an official package by EveryPay AS nor by omnipay._
5+
# PHP EveryPay Client (for Omnipay)
46

5-
[EveryPay](https://every-pay.com/) is an Estonian payment provider, currently working with LHV and SEB banks.
7+
Use this package to integrate EveryPay into your PHP application using [Omnipay](http://omnipay.thephpleague.com).
68

7-
The package currently supports a limited set of essential features in EveryPay v4:
9+
EveryPay is a payment gateway currently used by:
10+
11+
- LHV
12+
- SEB
13+
- Swedbank
14+
15+
The package supports the following payment types:
816

917
- One-off payments
1018
- Requesting card tokens
11-
- One-click / CIT (Customer initiated Transactions) Payments
19+
- One-click / CIT (Customer Initiated Transactions) Payments
20+
- MIT (Merchant Initiated Transactions) Payments
1221

1322
## Usage
1423

15-
Require the package using composer:
24+
Install the package using composer
1625

17-
> composer require swiftmade/omnipay-everypay
26+
```bash
27+
composer require swiftmade/omnipay-everypay
28+
```
1829

1930
### Initialize the gateway
2031

@@ -39,7 +50,7 @@ $purchase = $gateway
3950
->setTransactionId($orderId) // unique order id for this purchase
4051
->setReturnUrl($customerUrl) // the url to redirect if the payment fails or gets cancelled
4152
->setClientIp($_SERVER['REMOTE_ADDR']) // optional, helps fraud detection
42-
->setEmail(''); // optional, helps fraud detection
53+
->setEmail(''); // optional, helps fraud detection
4354

4455
// Use this, if you want to make the payment using a previously stored card token
4556
// Only applicable for MIT and CIT payment types.
@@ -81,7 +92,7 @@ if ($response->isSuccessful()) {
8192
} else if($response->isRedirect()) {
8293
// 3DS Confirmation needed!
8394
// Redirect the user to 3DS Page.
84-
return $response->redirect();
95+
return $response->redirect();
8596
} else {
8697
// Something went wrong!
8798
// Check $response->getMessage();
@@ -97,8 +108,8 @@ You need to validate whether the payment went through.
97108
// Here, pass the payment array that we previously stored when creating the payment
98109
$response = $gateway->completePurchase()
99110
// These values are passed back to you by EveryPay
100-
->setTransactionId($_GET['payment_reference'])
101-
->setTransactionReference($_GET['order_reference'])
111+
->setTransactionId($_GET['order_reference'])
112+
->setTransactionReference($_GET['payment_reference'])
102113
->send();
103114

104115
if (!$response->isSuccessful()) {
@@ -115,3 +126,58 @@ if ($card = $response->getCardToken()) {
115126
}
116127
```
117128

129+
### Authorize & Capture Later
130+
131+
In EveryPay, when the payment will be captured is configured at the account level. If you want to authorize a payment without capturing it, then you need a Merchant Account configured accordingly.
132+
133+
To authorize a payment, simply substitue `purchase` and `completePurchase` methods with `authorize` and `completeAuthorize`. Then call `capture` to capture the funds.
134+
135+
```php
136+
// Here, pass the payment array that we previously stored when creating the payment
137+
$gateway->authorize([
138+
'amount' => $amount,
139+
'paymentType' => PaymentType::CIT,
140+
])
141+
->setCardReference('previously stored card token')
142+
// Set all the other parameters. See previous examples ...
143+
->send();
144+
145+
// Redirect the user to 3DS confirmation as necessary.
146+
147+
// When EveryPay redirects the user back, do this...
148+
// This won't capture the payment yet, but makes sure the authorization is successful.
149+
$authorizeResponse = $gateway->completeAuthorize()
150+
->setTransactionId($_GET['order_reference'])
151+
->setTransactionReference($_GET['payment_reference'])
152+
->send();
153+
154+
// Hold on to this.. You'll use this reference to capture the payment.
155+
$paymentReference = $authorizeResponse->getTransactionReference();
156+
157+
// When you're ready to capture, call:
158+
$response = $gateway->capture([
159+
'amount' => $amount, // You can capture partially, or the whole amount.
160+
'transactionReference' => $paymentReference,
161+
])->send();
162+
163+
if ($response->isSuccessful()) {
164+
// Payment captured!
165+
} else {
166+
// Something went wrong!
167+
// Check $response->getMessage();
168+
}
169+
```
170+
171+
---
172+
173+
### Security
174+
175+
If you discover any security related issues, please email hello@swiftmade.co instead of using the issue tracker.
176+
177+
### Disclaimer
178+
179+
This package is **not** an official package by EveryPay AS nor by Omnipay.
180+
181+
### License
182+
183+
The MIT License (MIT). Please see [License File](LICENSE) for more information.

src/Gateway.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Omnipay\Common\AbstractGateway;
66
use Omnipay\EveryPay\Enums\PaymentType;
77
use Omnipay\EveryPay\Support\SignedData;
8+
use Omnipay\EveryPay\Messages\CaptureRequest;
89
use Omnipay\EveryPay\Messages\CitPaymentRequest;
910
use Omnipay\EveryPay\Messages\MitPaymentRequest;
1011
use Omnipay\EveryPay\Messages\OneOffPaymentRequest;
@@ -53,4 +54,19 @@ public function completePurchase(array $options = [])
5354
{
5455
return $this->createRequest(CompletePurchaseRequest::class, $options);
5556
}
57+
58+
public function authorize(array $options = [])
59+
{
60+
return $this->purchase($options);
61+
}
62+
63+
public function completeAuthorize(array $options = [])
64+
{
65+
return $this->completePurchase($options);
66+
}
67+
68+
public function capture($options = [])
69+
{
70+
return $this->createRequest(CaptureRequest::class, $options);
71+
}
5672
}

src/Messages/CaptureRequest.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
namespace Omnipay\EveryPay\Messages;
4+
5+
use Omnipay\Common\Exception\InvalidResponseException;
6+
7+
class CaptureRequest extends AbstractRequest
8+
{
9+
public function getData()
10+
{
11+
$this->validate(
12+
'amount',
13+
'transactionReference'
14+
);
15+
16+
$baseData = $this->getBaseData();
17+
18+
return array_merge($baseData, [
19+
'amount' => $this->getAmount(),
20+
'payment_reference' => $this->getTransactionReference(),
21+
]);
22+
}
23+
24+
public function sendData($data): PurchaseResponse
25+
{
26+
try {
27+
$payment = $this->httpRequest(
28+
'POST',
29+
$this->getEndpoint() . '/payments/capture',
30+
$this->getHeaders(),
31+
$data
32+
);
33+
34+
return $this->response = new PurchaseResponse(
35+
$this,
36+
$payment
37+
);
38+
} catch (InvalidResponseException $e) {
39+
return $this->response = new PurchaseResponse(
40+
$this,
41+
[
42+
'error' => [
43+
'message' => $e->getMessage(),
44+
'code' => $e->getCode(),
45+
],
46+
]
47+
);
48+
}
49+
}
50+
}

src/Messages/PurchaseResponse.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,11 +124,17 @@ public function isCancelled(): bool
124124
return $this->getPaymentState() === PaymentState::ABANDONED;
125125
}
126126

127+
/**
128+
* This is usually he ID of the payment record in your database.
129+
*/
127130
public function getTransactionId()
128131
{
129132
return $this->data['order_reference'] ?? null;
130133
}
131134

135+
/**
136+
* This is the Payment Gateway’s reference to the transaction
137+
*/
132138
public function getTransactionReference()
133139
{
134140
return $this->data['payment_reference'] ?? null;

tests/RequestsTest.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
use Omnipay\Tests\TestCase;
4+
use Omnipay\EveryPay\Gateway;
5+
use Omnipay\EveryPay\Enums\PaymentType;
6+
use Omnipay\EveryPay\Messages\CaptureRequest;
7+
use Omnipay\EveryPay\Messages\CitPaymentRequest;
8+
use Omnipay\EveryPay\Messages\MitPaymentRequest;
9+
use Omnipay\EveryPay\Messages\OneOffPaymentRequest;
10+
use Omnipay\EveryPay\Messages\CompletePurchaseRequest;
11+
12+
class RequestsTest extends TestCase
13+
{
14+
public function testPurchaseRequest()
15+
{
16+
$gateway = new Gateway();
17+
18+
$this->assertInstanceOf(OneOffPaymentRequest::class, $gateway->purchase());
19+
20+
$this->assertInstanceOf(OneOffPaymentRequest::class, $gateway->purchase([
21+
'paymentType' => PaymentType::ONE_OFF,
22+
]));
23+
24+
$this->assertInstanceOf(CitPaymentRequest::class, $gateway->purchase([
25+
'paymentType' => PaymentType::CIT,
26+
]));
27+
28+
$this->assertInstanceOf(MitPaymentRequest::class, $gateway->purchase([
29+
'paymentType' => PaymentType::MIT,
30+
]));
31+
}
32+
33+
public function testCompletePurchaseRequest()
34+
{
35+
$gateway = new Gateway();
36+
37+
$this->assertInstanceOf(CompletePurchaseRequest::class, $gateway->completePurchase());
38+
$this->assertInstanceOf(CompletePurchaseRequest::class, $gateway->completeAuthorize());
39+
}
40+
41+
public function testCaptureRequest()
42+
{
43+
$gateway = new Gateway();
44+
45+
$this->assertInstanceOf(CaptureRequest::class, $gateway->capture());
46+
}
47+
}

0 commit comments

Comments
 (0)