Skip to content

Commit 7804e58

Browse files
committed
Support for paymentPage recurring payments.
1 parent 8d87875 commit 7804e58

13 files changed

+537
-39
lines changed

README.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Table of Contents
1616
* [Payment Page](#payment-page)
1717
* [Purchase (redirect)](#purchase-redirect)
1818
* [Payment Page Complete Payment](#payment-page-complete-payment)
19+
* [Payment Page Recurring Profiles](#payment-page-recurring-profiles)
1920
* [Notification Handler](#notification-handler)
2021

2122
# mPAY24 Driver for Omnipay v3
@@ -111,6 +112,12 @@ but could be carried forward through the session instead.
111112

112113
The `/pay` endpoint handles the actual payment.
113114

115+
The above form does not redirect the user to a payment page.
116+
Instead, it sends the card details to the gateway, with the token as a key.
117+
So in the next step, the gateway will already have the card details and the
118+
merchant site will just use the pre-generated token to reference them when
119+
completing the payment.
120+
114121
### Payment Using Token
115122

116123
```php
@@ -265,6 +272,54 @@ Alternatively a range of payment methods can be supplied as a JSON string:
265272

266273
The transaction is completed in exactly the same way as for the seamless payments.
267274

275+
### Payment Page Recurring Profiles
276+
277+
The gateway supports two types of profile: a single recurring payment profile for a customer,
278+
and up to 20 interactive profiles for each customer.
279+
The *Payment Page* API will support only ONE of these profile types at a time.
280+
This driver presently support ONLY recurrent payment profiles for *Payment Page*.
281+
282+
To create or update a customer's recurring payment profile, when making a purchase,
283+
set the `createCard` flag and provide a `customerId`:
284+
285+
'createCard' => true,
286+
'customerId' => 'cust-12345',
287+
288+
On completing the payment, you can check if the customer recurring profile was created
289+
or updated by checking the profile status:
290+
291+
$profileWasCreatedOrUpdates = $completeResult->isProfileChanged();
292+
293+
If this returns true, then it means the payment details for the current transaction
294+
have been saved against the customer ID.
295+
Use the customer ID as though it were a card reference when making a backend payment.
296+
297+
A customer ID can be used to make a recurring payment (an offline payment) liek this:
298+
299+
```php
300+
$gateway = Omnipay::create('Mpay24_Backend');
301+
302+
// Set the usual merchant ID and test mode flags.
303+
304+
$request = $gateway->purchase([
305+
'amount' => '9.99',
306+
'currency' => 'EUR',
307+
'transactionId' => 'new-transaction-id',
308+
'description' => 'Recurring Payment Description',
309+
'card' => [
310+
'name' => 'Customer Name',
311+
],
312+
'notifyUrl' => 'https://omnipay.acadweb.co.uk/mpay24/notify.php?foo=bar&fee=fah', // mandatory
313+
'language' => 'de',
314+
// Either
315+
'customerId' => 'cust-12345',
316+
// or
317+
'cardReference' => 'cust-12345',
318+
]);
319+
```
320+
321+
This will return the details of the successful payment, or error details if not successful.
322+
268323
## Notification Handler
269324

270325
The notification handler will accept notification server requests,

src/BackendGateway.php

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
namespace Omnipay\Mpay24;
4+
5+
use Omnipay\Mpay24\Messages\Backend\ListProfilesRequest;
6+
use Omnipay\Mpay24\Messages\Backend\DeleteProfileRequest;
7+
use Omnipay\Mpay24\Messages\FetchTransactionRequest;
8+
use Omnipay\Mpay24\Messages\Backend\PurchaseRequest;
9+
use Omnipay\Mpay24\Messages\AcceptNotification;
10+
11+
class BackendGateway extends PaymentPageGateway
12+
{
13+
/**
14+
* @param array $parameters
15+
* @return PurchaseRequest
16+
*/
17+
public function purchase(array $parameters = [])
18+
{
19+
return $this->createRequest(PurchaseRequest::class, $parameters);
20+
}
21+
22+
/**
23+
* @param array $parameters
24+
* @return PurchaseRequest
25+
*/
26+
public function authorize(array $parameters = [])
27+
{
28+
return $this->purchase($parameters);
29+
}
30+
31+
/**
32+
* @param array $parameters
33+
* @return ListProfilesRequest
34+
*/
35+
public function listProfiles(array $parameters = [])
36+
{
37+
return $this->createRequest(ListProfilesRequest::class, $parameters);
38+
}
39+
40+
/**
41+
* @param array $parameters
42+
* @return DeleteProfileRequest
43+
*/
44+
public function deleteProfile(array $parameters = [])
45+
{
46+
return $this->createRequest(DeleteProfileRequest::class, $parameters);
47+
}
48+
49+
/**
50+
* @param array $parameters
51+
* @return DeleteProfileRequest
52+
*/
53+
public function deleteCard(array $parameters = [])
54+
{
55+
return $this->deletePofile($parameters);
56+
}
57+
}

src/ConstantsInterface.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ interface ConstantsInterface
165165
const PTYPE_PAYOLUTION = 'PAYOLUTION';
166166
const PTYPE_SOFORT = 'SOFORT';
167167
const PTYPE_MASTERPASS = 'MASTERPASS';
168+
const PTYPE_PROFILE = 'PROFILE';
168169

169170
/**
170171
* Brands.
@@ -221,4 +222,15 @@ interface ConstantsInterface
221222
const CSS_NAME_WEB = 'WEB';
222223
const CSS_NAME_MOBILE = 'MOBILE';
223224
const CSS_NAME_MODERN = 'MODERN';
225+
226+
/**
227+
*
228+
*/
229+
230+
const PROFILE_STATUS_IGNORED = 'IGNORED';
231+
const PROFILE_STATUS_USED = 'USED';
232+
const PROFILE_STATUS_ERROR = 'ERROR';
233+
const PROFILE_STATUS_CREATED = 'CREATED';
234+
const PROFILE_STATUS_UPDATED = 'UPDATED';
235+
const PROFILE_STATUS_DELETED = 'DELETED';
224236
}

src/Messages/AbstractMpay24Request.php

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
use Omnipay\Mpay24\ConstantsInterface;
88
use Mpay24\Mpay24;
99
use Mpay24\Mpay24Config;
10+
use Money\Money;
11+
use Money\Number;
12+
//use Money\Currencies\ISOCurrencies;
13+
use Money\Currency;
14+
use Money\Parser\DecimalMoneyParser;
1015

1116
abstract class AbstractMpay24Request extends AbstractRequest implements ConstantsInterface
1217
{
@@ -135,9 +140,38 @@ protected function getShippingAddressData()
135140
}
136141

137142
/**
138-
* @return array
143+
* Return the items basket/cart as data with mPAY24 key names.
139144
*/
140-
protected function getShoppingCartData()
145+
public function getShoppingCartData(): array
141146
{
147+
$data = [];
148+
149+
if (! empty($this->getItems())) {
150+
$itemNumber = 0;
151+
152+
foreach ($this->getItems() as $item) {
153+
$itemNumber++;
154+
155+
$currencyCode = $this->getCurrency();
156+
$currency = new Currency($currencyCode);
157+
158+
$moneyParser = new DecimalMoneyParser($this->getCurrencies());
159+
160+
$number = Number::fromString($item->getPrice());
161+
162+
$money = $moneyParser->parse((string) $number, $currency);
163+
164+
$data[$itemNumber] = [
165+
'number' => $itemNumber,
166+
'productNr' => $item->getName(),
167+
'description' => $item->getDescription() ?: $item->getName(),
168+
'quantity' => $item->getQuantity(),
169+
'itemPrice' => $item->getPrice(), // Major units
170+
'amount' => $money->getAmount(), // Minor units
171+
];
172+
}
173+
}
174+
175+
return $data;
142176
}
143177
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
namespace Omnipay\Mpay24\Messages\Backend;
4+
5+
use Omnipay\Mpay24\Messages\AbstractMpay24Request;
6+
use Mpay24\Mpay24Order;
7+
8+
class DeleteProfileRequest extends AbstractMpay24Request
9+
{
10+
/**
11+
* The data key names are from the mPAY24 spec, but lower camelCase.
12+
*
13+
* @return array
14+
* @throws InvalidRequestException
15+
* @throws \Omnipay\Common\Exception\InvalidRequestException
16+
*/
17+
public function getData()
18+
{
19+
return [
20+
'customerId' => $this->getCustomerId() ?? $this->getCardReference(),
21+
'profileId' => $this->getProfileId(),
22+
];
23+
}
24+
25+
/**
26+
* @param array $data
27+
* @return ResponseInterface|ListProfilesResponse
28+
*/
29+
public function sendData($data)
30+
{
31+
$mpay24 = $this->getMpay();
32+
33+
$result = $mpay24->deleteProfile(
34+
$data['customerId'],
35+
$data['profileId']
36+
);
37+
38+
$resultData = [
39+
'operationStatus' => $result->getStatus(),
40+
'returnCode' => $result->getReturnCode(),
41+
];
42+
43+
return new Response($this, $resultData);
44+
}
45+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
namespace Omnipay\Mpay24\Messages\Backend;
4+
5+
use Omnipay\Mpay24\Messages\AbstractMpay24Request;
6+
use Mpay24\Mpay24Order;
7+
8+
class ListProfilesRequest extends AbstractMpay24Request
9+
{
10+
/**
11+
* The data key names are from the mPAY24 spec, but lower camelCase.
12+
*
13+
* @return array
14+
* @throws InvalidRequestException
15+
* @throws \Omnipay\Common\Exception\InvalidRequestException
16+
*/
17+
public function getData()
18+
{
19+
return [
20+
'customerId' => $this->getCustomerId() ?? $this->getCardReference(),
21+
'expiredBy' => $this->getExpiredBy(),
22+
'begin' => $this->getBegin(),
23+
'size' => $this->getSize(),
24+
];
25+
}
26+
27+
/**
28+
* @param array $data
29+
* @return ResponseInterface|ListProfilesResponse
30+
*/
31+
public function sendData($data)
32+
{
33+
$mpay24 = $this->getMpay();
34+
35+
$result = $mpay24->listCustomers(
36+
$data['customerId'],
37+
$data['expiredBy'],
38+
$data['begin'],
39+
$data['size']
40+
);
41+
42+
$resultData = [
43+
'operationStatus' => $result->getStatus(),
44+
'returnCode' => $result->getReturnCode(),
45+
'profiles' => $result->getProfiles(),
46+
];
47+
48+
return new ListProfilesResponse($this, $resultData);
49+
}
50+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace Omnipay\Mpay24\Messages\Backend;
4+
5+
/**
6+
* Lists matching profiles (customers).
7+
*/
8+
9+
use Omnipay\Mpay24\Messages\AbstractMpay24Response;
10+
use Omnipay\Mpay24\Messages\NotificationValuesTrait;
11+
12+
class ListProfilesResponse extends AbstractMpay24Response
13+
{
14+
use NotificationValuesTrait;
15+
16+
/**
17+
* Returns an array of arrays containing "customerID" and "updated" elements.
18+
*/
19+
public function getProfiles()
20+
{
21+
return $this->getDataItem('profiles');
22+
}
23+
}

0 commit comments

Comments
 (0)