Skip to content

Commit 7b9a9d9

Browse files
authored
v0.4.0 (#5)
* chore: update composer dependencies * chore: apply code style * chore: add github workflow * chore: support phpunit 8 * chore: remove unneeded dev dependency * chore: disable support for lowest deps * fix: add v4 endpoints * feat: modify backend purchase request * fix: rename accountId to accountName, update readme * wip: implement CIT payment request/response * wip: implement one-off payment * refactor: CitPaymentRequest and OneOffPaymentRequest * refactor: response class, simplify code * feat: handle complete purchase * refactor: cs * fix: handle missing card token * tests: add tests for purchase response * tests: improve purchase response test * feat: add mit payment support * docs: update readme * fix: trailing comma
1 parent 647271e commit 7b9a9d9

28 files changed

+1212
-515
lines changed

.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
EVERY_PAY_API_USERNAME=
22
EVERY_PAY_API_SECRET=
3-
EVERY_PAY_ACCOUNT_ID=
3+
EVERY_PAY_ACCOUNT_NAME=

.github/workflows/test.yml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: "PHPUnit tests"
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- "master"
8+
9+
jobs:
10+
phpunit:
11+
name: "PHPUnit tests"
12+
runs-on: ${{ matrix.operating-system }}
13+
14+
strategy:
15+
matrix:
16+
dependencies:
17+
# - "lowest"
18+
- "highest"
19+
php-version:
20+
- "7.2"
21+
- "7.3"
22+
- "7.4"
23+
- "8.0"
24+
operating-system:
25+
- "ubuntu-latest"
26+
27+
steps:
28+
- name: 📁 Checkout code
29+
uses: actions/checkout@v2
30+
31+
- name: "Install PHP"
32+
uses: "shivammathur/setup-php@v2"
33+
with:
34+
coverage: "pcov"
35+
php-version: "${{ matrix.php-version }}"
36+
ini-values: memory_limit=-1
37+
tools: composer:v2
38+
39+
- name: "Install lowest dependencies"
40+
if: ${{ matrix.dependencies == 'lowest' }}
41+
run: "composer update --prefer-lowest --no-interaction --no-progress --no-suggest"
42+
43+
- name: "Install highest dependencies"
44+
if: ${{ matrix.dependencies == 'highest' }}
45+
run: "composer update --no-interaction --no-progress --no-suggest"
46+
47+
- name: 🔨 Create .env file
48+
run: |
49+
cp .env.example .env
50+
51+
- name: 🧪 Run phpunit tests
52+
run: |
53+
php vendor/bin/phpunit

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
/vendor
2+
composer.lock
23

34
.env
45

5-
composer.lock
6+
.phpunit.result.cache
7+
.php-cs-fixer.cache
8+
9+
.idea

.php-cs-fixer.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
$finder = Symfony\Component\Finder\Finder::create()
4+
->notPath('vendor')
5+
->in([
6+
__DIR__ . '/src',
7+
__DIR__ . '/tests',
8+
])
9+
->name('*.php')
10+
->notName('*.blade.php')
11+
->ignoreDotFiles(true)
12+
->ignoreVCS(true);
13+
14+
$config = new PhpCsFixer\Config();
15+
16+
return $config->setRules([
17+
18+
'@PSR2' => true,
19+
'array_syntax' => ['syntax' => 'short'],
20+
'ordered_imports' => ['sort_algorithm' => 'length'],
21+
'no_unused_imports' => true,
22+
'not_operator_with_successor_space' => true,
23+
'trailing_comma_in_multiline' => true,
24+
'phpdoc_scalar' => true,
25+
'unary_operator_spaces' => true,
26+
'binary_operator_spaces' => true,
27+
'blank_line_before_statement' => [
28+
'statements' => ['break', 'continue', 'declare', 'return', 'throw', 'try'],
29+
],
30+
'phpdoc_single_line_var_spacing' => true,
31+
'phpdoc_var_without_name' => true,
32+
'class_attributes_separation' => [
33+
'elements' => [
34+
'method' => 'one',
35+
],
36+
],
37+
'method_argument_space' => [
38+
'on_multiline' => 'ensure_fully_multiline',
39+
'keep_multiple_spaces_after_comma' => true,
40+
],
41+
'single_trait_insert_per_statement' => true,
42+
])
43+
->setFinder($finder);

README.md

Lines changed: 56 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ _Disclaimer: This package is **not** an official package by EveryPay AS nor by o
44

55
[EveryPay](https://every-pay.com/) is an Estonian payment provider, currently working with LHV and SEB banks.
66

7-
The package currently supports a limited set of essential features:
7+
The package currently supports a limited set of essential features in EveryPay v4:
88

9-
- Charge cards through the Gateway API (redirect)
10-
- Requesting card tokens (Gateway API only)
11-
- Token payments using Backend API
9+
- One-off payments
10+
- Requesting card tokens
11+
- One-click / CIT (Customer initiated Transactions) Payments
1212

1313
## Usage
1414

@@ -22,28 +22,32 @@ Require the package using composer:
2222
$gateway = Omnipay::create('EveryPay')->initialize([
2323
'username' => '', // EveryPay api username
2424
'secret' => '', // EveryPay api secret
25-
'accountId' => '', // merchant account ID
25+
'accountName' => '', // merchant account ID
2626
'testMode' => true, // set to false for production!
2727
'locale' => 'en', // et=Estonian, see integration guide for more options.
2828
]);
2929
```
3030

31-
### Process a purchase (Gateway)
31+
### One-off Purchase
3232

3333
```php
3434
$purchase = $gateway
35-
->purchase(['amount' => $amount])
36-
->setTransactionId(uniqid()) // unique order id for this purchase
35+
->purchase([
36+
'amount' => $amount,
37+
'paymentType' => PaymentType::ONE_OFF,
38+
])
39+
->setTransactionId($orderId) // unique order id for this purchase
40+
->setReturnUrl($customerUrl) // the url to redirect if the payment fails or gets cancelled
3741
->setClientIp($_SERVER['REMOTE_ADDR']) // optional, helps fraud detection
38-
->setEmail('') // optional, helps fraud detection
39-
->setCallbackUrl($callbackUrl) // payment callback where payment result will be sent (with PUT)
40-
->setCustomerUrl($callbackUrl); // the url to redirect if the payment fails or gets cancelled
42+
->setEmail(''); // optional, helps fraud detection
4143

42-
// Uncomment if you want to make the payment using a previously stored card token
43-
// $purchase->setCardReference($token);
44+
// Use this, if you want to make the payment using a previously stored card token
45+
// Only applicable for MIT and CIT payment types.
46+
$purchase->setCardReference($token);
4447

4548
// Uncomment if you want to store the card as a token after the payment
46-
// $purchase->setSaveCard(true);
49+
// (Only supported with One-off payment type)
50+
$purchase->setSaveCard(true);
4751

4852
$response = $purchase->send();
4953

@@ -53,14 +57,49 @@ $payment = $response->getData();
5357
return $response->redirect(); // this will return a self-submitting html form to EveryPay Gateway API
5458
```
5559

60+
### Customer Initiated Transaction (One-click payment)
61+
62+
```php
63+
$purchase = $gateway
64+
->purchase([
65+
'amount' => $amount,
66+
'paymentType' => PaymentType::CIT,
67+
])
68+
->setTransactionId($orderId) // unique order id for this purchase
69+
->setCardReference('previously stored card token')
70+
->setReturnUrl($customerUrl)
71+
->setClientIp($_SERVER['REMOTE_ADDR']) // optional, helps fraud detection
72+
->setEmail(''); // optional, helps fraud detection
73+
74+
$response = $purchase->send();
75+
76+
// Store the payment response data if you wish.
77+
$payment = $response->getData();
78+
79+
if ($response->isSuccessful()) {
80+
// Payment done!
81+
} else if($response->isRedirect()) {
82+
// 3DS Confirmation needed!
83+
// Redirect the user to 3DS Page.
84+
return $response->redirect();
85+
} else {
86+
// Something went wrong!
87+
// Check $response->getMessage();
88+
}
89+
```
90+
5691
### Complete Payment (handle Gateway redirect from EveryPay)
5792

58-
EveryPay will return to your callback url with a `PUT` request once the payment is finalized.
59-
You need to validate this response and check if the payment succeeded.
93+
EveryPay will redirect the user to the `returnUrl` once the payment is finalized.
94+
You need to validate whether the payment went through.
6095

6196
```php
6297
// Here, pass the payment array that we previously stored when creating the payment
63-
$response = $gateway->completePurchase(['payment' => $payment])->send();
98+
$response = $gateway->completePurchase()
99+
// These values are passed back to you by EveryPay
100+
->setTransactionId($_GET['payment_reference'])
101+
->setTransactionReference($_GET['order_reference'])
102+
->send();
64103

65104
if (!$response->isSuccessful()) {
66105
// Payment failed!
@@ -76,26 +115,3 @@ if ($card = $response->getCardToken()) {
76115
}
77116
```
78117

79-
### Make a token payment (Backend)
80-
81-
```php
82-
$purchase = $gateway
83-
->purchase(['amount' => $amount, 'backend' => true])
84-
->setClientIp($_SERVER['REMOTE_ADDR']) // optional, helps fraud detection
85-
->setEmail(''); // optional, helps fraud detection
86-
87-
// Pass a valid card token here
88-
$purchase->setCardReference($token);
89-
90-
$response = $purchase->send();
91-
92-
// Store the payment response data if you wish.
93-
$payment = $response->getData();
94-
95-
if ($response->isSuccessful()) {
96-
// Payment done!
97-
} else {
98-
// Something went wrong!
99-
// Check $response->getMessage();
100-
}
101-
```

composer.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@
1111
],
1212
"minimum-stability": "stable",
1313
"require": {
14-
"php": ">=7.0.0",
14+
"php": "^7.2|^8",
15+
"ext-json": "*",
1516
"league/omnipay": "^3"
1617
},
1718
"require-dev": {
18-
"phpunit/phpunit": "^6.0",
19-
"php-vcr/php-vcr": "^1.4",
20-
"omnipay/tests": "^3.1"
19+
"phpunit/phpunit": "^8.5|^9",
20+
"omnipay/tests": "^4.1",
21+
"friendsofphp/php-cs-fixer": "^3.2"
2122
},
2223
"autoload": {
2324
"psr-4": {

src/Common/CardToken.php

Lines changed: 0 additions & 43 deletions
This file was deleted.

src/Common/TokenizedCard.php

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
namespace Omnipay\EveryPay\Common;
3+
4+
use Omnipay\Common\CreditCard;
5+
6+
class TokenizedCard extends CreditCard
7+
{
8+
protected $token;
9+
10+
/**
11+
*
12+
* @see https://support.every-pay.com/downloads/everypay_apiv4_integration_documentation.pdf
13+
* Page 35
14+
*
15+
* @param array $payload cc_details
16+
* @return TokenizedCard
17+
*/
18+
public static function make(array $payload)
19+
{
20+
// Card type. Possible values are ‘visa’ or ‘master_card’.
21+
$brands = [
22+
'visa' => self::BRAND_VISA,
23+
'master_card' => self::BRAND_MASTERCARD,
24+
];
25+
26+
$brand = $brands[$payload['type']] ?? null;
27+
28+
$card = new TokenizedCard([
29+
'brand' => $brand,
30+
'name' => $payload['holder_name'] ?? null,
31+
'number' => $payload['last_four_digits'] ?? null,
32+
'expiryYear' => (int) $payload['year'],
33+
'expiryMonth' => (int) $payload['month'],
34+
]);
35+
36+
$card->setToken($payload['token']);
37+
38+
return $card;
39+
}
40+
41+
public function setBrand($brand)
42+
{
43+
return $this->setParameter('brand', $brand);
44+
}
45+
46+
public function getBrand()
47+
{
48+
return $this->getParameter('brand');
49+
}
50+
51+
public function setToken($token)
52+
{
53+
$this->token = $token;
54+
}
55+
56+
public function getToken()
57+
{
58+
return $this->token;
59+
}
60+
}

0 commit comments

Comments
 (0)