Skip to content

Commit 4733ab8

Browse files
committed
Additional documentation; support for opaque data.
1 parent cfc633b commit 4733ab8

File tree

3 files changed

+273
-11
lines changed

3 files changed

+273
-11
lines changed

README.md

Lines changed: 180 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,36 @@
55
[![Latest Unstable Version](https://poser.pugx.org/academe/omnipay-authorizenetapi/v/unstable)](https://packagist.org/packages/academe/omnipay-authorizenetapi)
66
[![License](https://poser.pugx.org/academe/omnipay-authorizenetapi/license)](https://packagist.org/packages/academe/omnipay-authorizenetapi)
77

8+
Table of Contents
9+
=================
10+
11+
* [Omnipay-AuthorizeNetApi](#omnipay-authorizenetapi)
12+
* [Authorize.Net API](#authorizenet-api)
13+
* [API Authorize/Purchase (Credit Card)](#api-authorizepurchase-credit-car d)
14+
* [API Capture](#api-capture)
15+
* [API Authorize/Purchase (Opaque Data)](#api-authorizepurchase-opaque-dat a)
16+
* [API Void](#api-void)
17+
* [API Refund](#api-refund)
18+
* [API Fetch Transaction](#api-fetch-transaction)
19+
* [Hosted Payment Page](#hosted-payment-page)
20+
* [Hosted Payment Page Authorize/Purchase](#hosted-payment-page-authorizep urchase)
21+
822
# Omnipay-AuthorizeNetApi
923

1024
Omnipay 3.x implementation of Authorize.Net API
1125

12-
# Development Example
26+
# Authorize.Net API
27+
28+
The *Authorize.Net API* driver handles server-to-server requests.
29+
It is used both for direct card payment (though check PCI requirements)
30+
and for creating transactions using a card token.
1331

14-
This is under development, but is usable within limitations.
32+
## API Authorize/Purchase (Credit Card)
1533

16-
The following example is a simple authorize with known card details.
17-
You would normally avoid this particular method for PCI compliance reasons,
18-
supplying a tokenised card reference instead.
34+
The following example is a simple authorize with supplied card details.
35+
You would normally avoid allowing card details near your merchanet site
36+
back end for PCI compliance reasons,
37+
supplying a tokenised card reference instead (see later section for this).
1938

2039
```php
2140
<?php
@@ -62,7 +81,9 @@ var_dump($response->getTransactionReference());
6281
// string(11) "60103474871"
6382
```
6483

65-
If authorized, the amount can be captured:
84+
## API Capture
85+
86+
Once authorized, the amount can be captured:
6687

6788
```php
6889
// Captured from the authorization response.
@@ -75,6 +96,142 @@ $response = $gateway->capture([
7596
])->send();
7697
```
7798

99+
## API Authorize/Purchase (Opaque Data)
100+
101+
The "Opaque Data" here is a tokenised credit or debit card.
102+
Authorize.Net can tokenise cards in a number of ways, once of which
103+
is through the `accept.js` package on the front end. It works like this:
104+
105+
You build a payment form in your page.
106+
As well as hard-coding it as shown below, the gateway provides a method
107+
to generate it dynamically too.
108+
109+
```html
110+
<form id="paymentForm"
111+
method="POST"
112+
action="https://example.com/authorize">
113+
<input type="text" name="cardNumber" id="cardNumber" placeholder="cardNumber"/>
114+
<input type="text" name="expMonth" id="expMonth" placeholder="expMonth"/>
115+
<input type="text" name="expYear" id="expYear" placeholder="expYear"/>
116+
<input type="text" name="cardCode" id="cardCode" placeholder="cardCode"/>
117+
<input type="hidden" name="dataValue" id="dataValue" />
118+
<input type="hidden" name="dataDescriptor" id="dataDescriptor" />
119+
<button>Pay Now</button>
120+
</form>
121+
```
122+
123+
Note the card detail elements do not have names, so will not be submitted
124+
to your site.
125+
Two hidden fields are defined to carry the opaquer data to your site.
126+
You can include any many other fields as you like in the same form,
127+
which may include names and an address.
128+
129+
After the payment form, you will need the `accept.js` JavaScript:
130+
131+
```javascript
132+
<script type="text/javascript"
133+
src="https://jstest.authorize.net/v1/Accept.js"
134+
charset="utf-8">\
135+
</script>
136+
```
137+
138+
Or use `https://js.authorize.net/v1/Accept.js` for production.
139+
140+
You need to catch the "Pay Now" submission and send it to a function to
141+
process the card details. Either an `onclick` attribute or a jQuery event
142+
will work. For example:
143+
144+
<button type="button" onclick="sendPaymentDataToAnet()">Pay</button>
145+
146+
The `sendPaymentDataToAnet` function handles the tokenisation.
147+
148+
```
149+
<script type="text/javascript">
150+
function sendPaymentDataToAnet() {
151+
// Set up authorisation to access the gateway.
152+
var authData = {};
153+
authData.clientKey = "YOUR PUBLIC CLIENT KEY";
154+
authData.apiLoginID = "YOUR API LOGIN ID";
155+
156+
// Capture the card details from the payment form.
157+
// The cardCode is the CVV.
158+
// You can include fullName and zip fields too, for added security.
159+
// You can pick up bank account fields in a similar way, if using
160+
// that payment method.
161+
var cardData = {};
162+
cardData.cardNumber = document.getElementById("cardNumber").value;
163+
cardData.month = document.getElementById("expMonth").value;
164+
cardData.year = document.getElementById("expYear").value;
165+
cardData.cardCode = document.getElementById("cardCode").value;
166+
167+
// Now send the card data to the gateway for tokenisation.
168+
// The responseHandler function will handle the response.
169+
var secureData = {};
170+
secureData.authData = authData;
171+
secureData.cardData = cardData;
172+
Accept.dispatchData(secureData, responseHandler);
173+
}
174+
</script>
175+
```
176+
177+
The response handler is able to provide errors that may have been
178+
generated while trying to tokenise the card.
179+
But if all is well, it updates the payment form with the opaque data
180+
(another function `paymentFormUpdate`):
181+
182+
```javascript
183+
function responseHandler(response) {
184+
if (response.messages.resultCode === "Error") {
185+
var i = 0;
186+
while (i < response.messages.message.length) {
187+
console.log(
188+
response.messages.message[i].code + ": " +
189+
response.messages.message[i].text
190+
);
191+
i = i + 1;
192+
}
193+
} else {
194+
paymentFormUpdate(response.opaqueData);
195+
}
196+
}
197+
```
198+
199+
Populate the opaque data hidden form items, then submit the form again:
200+
201+
```javascript
202+
function paymentFormUpdate(opaqueData) {
203+
document.getElementById("dataDescriptor").value = opaqueData.dataDescriptor;
204+
document.getElementById("dataValue").value = opaqueData.dataValue;
205+
document.getElementById("paymentForm").submit();
206+
}
207+
```
208+
209+
Back at the server, you will have two opaque data fields to capture:
210+
211+
* dataDescriptor
212+
* dataValue
213+
214+
Initiate an `authorize()` or `purchase()` at the backend, as described in
215+
the previous section. In the `creditCard` object, leave the card details
216+
blank, not set. Instead, send the opaque data:
217+
218+
```php
219+
$gateway->authorize([
220+
...
221+
'opaqueDataDescriptor' => $opaqueDataDescriptor,
222+
'opaqueDataValue' => $opaqueDataValue,
223+
]);
224+
```
225+
226+
The authorizatiob or purchase should then go ahead as though the card
227+
details were provided directly. In the result, the last four digits
228+
of the card will be made available in case a refund needs to be performed.
229+
230+
Further details can be
231+
[fouund in the officual documentation](https://developer.authorize.net/api/reference/features/acceptjs.html).
232+
233+
## API Void
234+
78235
An authorized transaction can be voided:
79236

80237
```php
@@ -86,6 +243,8 @@ $response = $gateway->void([
86243
])->send();
87244
```
88245

246+
## API Refund
247+
89248
A cleared credit card payment can be refunded, given the original
90249
transaction reference, the original amount, and the last four digits
91250
of the credit card:
@@ -99,6 +258,8 @@ $response = $gateway->refund([
99258
])->send();
100259
```
101260

261+
## API Fetch Transaction
262+
102263
An existing transaction can be fetched from the gateway given
103264
its `transactionReference`:
104265

@@ -111,14 +272,20 @@ $response = $gateway->fetchTransaction([
111272
The Hosted Payment Page will host the payment form on the gateway.
112273
The form can be presented to the user as a full page redirect or in an iframe.
113274

275+
# Hosted Payment Page
276+
114277
The Hosted Payment Page is a different gateway:
115278

116279
```php
117280
$gateway = Omnipay\Omnipay::create('AuthorizeNetApi_HostedPage');
118281
```
119282

120-
The gateway is configured the same way, and the authorize/purchase
121-
requests are created in the same way, except for the return and cancel URLs:
283+
The gateway is configured the same way as the direct API gateway,
284+
and the authorize/purchase
285+
requests are created in the same way, except for the addition of
286+
`return` and `cancel` URLs:
287+
288+
## Hosted Payment Page Authorize/Purchase
122289

123290
```php
124291
$request = $gateway->authorize([
@@ -194,7 +361,7 @@ So the above set of options are supported by the following parameters:
194361
You can set these in the `authorize()` stage:
195362

196363
```php
197-
$gateway->authorize([
364+
$request = $gateway->authorize([
198365
...
199366
// Hide the bank account form but show the credit card form.
200367
'paymentOptionsShowCreditCard' => true,
@@ -204,4 +371,7 @@ $gateway->authorize([
204371
]);
205372
```
206373

207-
or use the `set*()` form to do the same thing.
374+
or use the `set*()` form to do the same thing:
375+
376+
$request->setPaymentOptionsShowBankAccount(false);
377+

src/HostedPageGateway.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
use Omnipay\AuthorizeNetApi\Traits\HasHostedPageGatewayParams;
1212
use Omnipay\AuthorizeNetApi\Message\HostedPage\AuthorizeRequest;
1313
use Omnipay\AuthorizeNetApi\Message\HostedPage\PurchaseRequest;
14+
use Omnipay\AuthorizeNetApi\Message\VoidRequest;
15+
use Omnipay\AuthorizeNetApi\Message\RefundRequest;
16+
use Omnipay\AuthorizeNetApi\Message\FetchTransactionRequest;
1417

1518
class HostedPageGateway extends AbstractGateway
1619
{
@@ -45,4 +48,37 @@ public function purchase(array $parameters = array())
4548
$parameters
4649
);
4750
}
51+
52+
/**
53+
* Void an authorized transaction.
54+
*/
55+
public function void(array $parameters = [])
56+
{
57+
return $this->createRequest(
58+
VoidRequest::class,
59+
$parameters
60+
);
61+
}
62+
63+
/**
64+
* Refund a captured transaction (before it is cleared).
65+
*/
66+
public function refund(array $parameters = [])
67+
{
68+
return $this->createRequest(
69+
RefundRequest::class,
70+
$parameters
71+
);
72+
}
73+
74+
/**
75+
* Fetch an existing transaction details.
76+
*/
77+
public function fetchTransaction(array $parameters = [])
78+
{
79+
return $this->createRequest(
80+
FetchTransactionRequest::class,
81+
$parameters
82+
);
83+
}
4884
}

src/Message/AuthorizeRequest.php

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Academe\AuthorizeNet\AmountInterface;
1818
use Academe\AuthorizeNet\Payment\Track1;
1919
use Academe\AuthorizeNet\Payment\Track2;
20+
use Academe\AuthorizeNet\Payment\OpaqueData;
2021
use Academe\AuthorizeNet\Request\Collections\LineItems;
2122
use Academe\AuthorizeNet\Request\Model\LineItem;
2223
use Academe\AuthorizeNet\Request\Model\CardholderAuthentication;
@@ -115,7 +116,16 @@ public function getData()
115116
}
116117
} // credit card
117118

118-
// TODO: allow "Accept JS" nonce (in two parts) instead of card (aka OpaqueData).
119+
// Allow "Accept JS" nonce (in two parts) instead of card (aka OpaqueData).
120+
121+
$descriptor = $this->getOpaqueDataDescriptor();
122+
$value = $this->getOpaqueDataValue();
123+
124+
if ($descriptor && $value) {
125+
$transaction = $transaction->withPayment(
126+
new OpaqueData($descriptor, $value)
127+
);
128+
}
119129

120130
if ($this->getClientIp()) {
121131
$transaction = $transaction->withCustomerIp($this->getClientIp());
@@ -257,4 +267,50 @@ public function getMarketType()
257267
{
258268
return $this->getParameter('marketType');
259269
}
270+
271+
/**
272+
* @param string $value Example: 'COMMON.ACCEPT.INAPP.PAYMENT'.
273+
* @return $this
274+
*/
275+
public function setOpaqueDataDescriptor($value)
276+
{
277+
return $this->setParameter('opaqueDataDescriptor', $value);
278+
}
279+
280+
/**
281+
* @return string
282+
*/
283+
public function getOpaqueDataDescriptor()
284+
{
285+
return $this->getParameter('opaqueDataDescriptor');
286+
}
287+
288+
/**
289+
* @param string $value Long text token usually 216 bytes long.
290+
* @return $this
291+
*/
292+
public function setOpaqueDataValue($value)
293+
{
294+
return $this->setParameter('opaqueDataValue', $value);
295+
}
296+
297+
/**
298+
* @return string
299+
*/
300+
public function getOpaqueDataValue()
301+
{
302+
return $this->getParameter('opaqueDataValue');
303+
}
304+
305+
/**
306+
* @param string $descriptor
307+
* @param string $value
308+
* @return $this
309+
*/
310+
public function setOpaqueData($descriptor, $value)
311+
{
312+
$this->setOpaqueDataValue($value);
313+
$this->setOpaqueDataDataDescriptor($descriptor);
314+
return $this;
315+
}
260316
}

0 commit comments

Comments
 (0)