Skip to content

Commit 25f19fc

Browse files
committed
Merge pull request thephpleague#13 from anushr/master
Consolidate common functionality between AIM and CIM
2 parents f4fc378 + e82a5e0 commit 25f19fc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+803
-674
lines changed

src/AIMGateway.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,16 @@ public function setDeveloperEndpoint($value)
8787
return $this->setParameter('developerEndpoint', $value);
8888
}
8989

90+
public function getDuplicateWindow()
91+
{
92+
return $this->getParameter('duplicateWindow');
93+
}
94+
95+
public function setDuplicateWindow($value)
96+
{
97+
return $this->setParameter('duplicateWindow', $value);
98+
}
99+
90100
/**
91101
* @param array $parameters
92102
* @return AIMAuthorizeRequest

src/CIMGateway.php

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,6 @@
99
*/
1010
class CIMGateway extends AIMGateway
1111
{
12-
public function getDefaultParameters()
13-
{
14-
$params = parent::getDefaultParameters();
15-
$params['forceCardUpdate'] = false;
16-
$params['defaultBillTo'] = array(array());
17-
return $params;
18-
}
19-
2012
public function getName()
2113
{
2214
return 'Authorize.Net CIM';

src/Message/AIMAbstractRequest.php

Lines changed: 107 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace Omnipay\AuthorizeNet\Message;
44

5+
use Omnipay\AuthorizeNet\Model\CardReference;
6+
use Omnipay\AuthorizeNet\Model\TransactionReference;
57
use Omnipay\Common\CreditCard;
68
use Omnipay\Common\Exception\InvalidRequestException;
79
use Omnipay\Common\Message\AbstractRequest;
@@ -11,6 +13,7 @@
1113
*/
1214
abstract class AIMAbstractRequest extends AbstractRequest
1315
{
16+
protected $requestType = 'createTransactionRequest';
1417
protected $action = null;
1518

1619
public function getApiLoginId()
@@ -69,19 +72,87 @@ public function setDuplicateWindow($value)
6972

7073
private function getDuplicateWindow()
7174
{
72-
return $this->getParameter('duplicateWindow'); // Maps x_duplicate_window
75+
return $this->getParameter('duplicateWindow');
7376
}
7477

75-
protected function addExtraOptions(\SimpleXMLElement $data)
78+
public function getLiveEndpoint()
7679
{
77-
if (!is_null($this->getDuplicateWindow())) {
78-
$extraOptions = $data->addChild('extraOptions');
79-
$node = dom_import_simplexml($extraOptions);
80-
$nodeOwner = $node->ownerDocument;
81-
$duplicateWindowStr = sprintf("x_duplicate_window=%s", $this->getDuplicateWindow());
82-
$node->appendChild($nodeOwner->createCDATASection($duplicateWindowStr));
80+
return $this->getParameter('liveEndpoint');
81+
}
82+
83+
public function setLiveEndpoint($value)
84+
{
85+
return $this->setParameter('liveEndpoint', $value);
86+
}
87+
88+
public function getDeveloperEndpoint()
89+
{
90+
return $this->getParameter('developerEndpoint');
91+
}
92+
93+
public function setDeveloperEndpoint($value)
94+
{
95+
return $this->setParameter('developerEndpoint', $value);
96+
}
97+
98+
public function getEndpoint()
99+
{
100+
return $this->getDeveloperMode() ? $this->getDeveloperEndpoint() : $this->getLiveEndpoint();
101+
}
102+
103+
/**
104+
* @return TransactionReference
105+
*/
106+
public function getTransactionReference()
107+
{
108+
return $this->getParameter('transactionReference');
109+
}
110+
111+
public function setTransactionReference($value)
112+
{
113+
if (substr($value, 0, 1) === '{') {
114+
// Value is a complex key containing the transaction ID and other properties
115+
$transactionRef = new TransactionReference($value);
116+
} else {
117+
// Value just contains the transaction ID
118+
$transactionRef = new TransactionReference();
119+
$transactionRef->setTransId($value);
83120
}
84-
return $data;
121+
return $this->setParameter('transactionReference', $transactionRef);
122+
}
123+
124+
/**
125+
* @param string|CardReference $value
126+
* @return AbstractRequest
127+
*/
128+
public function setCardReference($value)
129+
{
130+
if (!($value instanceof CardReference)) {
131+
$value = new CardReference($value);
132+
}
133+
return parent::setCardReference($value);
134+
}
135+
136+
/**
137+
* @param bool $serialize Determines whether the return value will be a string or object
138+
* @return string|CardReference
139+
*/
140+
public function getCardReference($serialize = true)
141+
{
142+
$value = parent::getCardReference();
143+
if ($serialize) {
144+
$value = (string)$value;
145+
}
146+
return $value;
147+
}
148+
149+
public function sendData($data)
150+
{
151+
$headers = array('Content-Type' => 'text/xml; charset=utf-8');
152+
$data = $data->saveXml();
153+
$httpResponse = $this->httpClient->post($this->getEndpoint(), $headers, $data)->send();
154+
155+
return $this->response = new AIMResponse($this, $httpResponse->getBody());
85156
}
86157

87158
/**
@@ -90,27 +161,35 @@ protected function addExtraOptions(\SimpleXMLElement $data)
90161
*/
91162
public function getBaseData()
92163
{
93-
$data = new \SimpleXMLElement('<createTransactionRequest/>');
164+
$data = new \SimpleXMLElement('<' . $this->requestType . '/>');
94165
$data->addAttribute('xmlns', 'AnetApi/xml/v1/schema/AnetApiSchema.xsd');
166+
$this->addAuthentication($data);
167+
$this->addReferenceId($data);
168+
$this->addTransactionType($data);
169+
return $data;
170+
}
95171

96-
// Credentials
172+
protected function addAuthentication(\SimpleXMLElement $data)
173+
{
97174
$data->merchantAuthentication->name = $this->getApiLoginId();
98175
$data->merchantAuthentication->transactionKey = $this->getTransactionKey();
176+
}
99177

100-
// User-assigned transaction ID
178+
protected function addReferenceId(\SimpleXMLElement $data)
179+
{
101180
$txnId = $this->getTransactionId();
102181
if (!empty($txnId)) {
103182
$data->refId = $this->getTransactionId();
104183
}
184+
}
105185

106-
// Transaction type
186+
protected function addTransactionType(\SimpleXMLElement $data)
187+
{
107188
if (!$this->action) {
108189
// The extending class probably hasn't specified an "action"
109190
throw new InvalidRequestException();
110191
}
111192
$data->transactionRequest->transactionType = $this->action;
112-
113-
return $data;
114193
}
115194

116195
/**
@@ -156,46 +235,22 @@ protected function addBillingData(\SimpleXMLElement $data)
156235
return $data;
157236
}
158237

159-
protected function addTestModeSetting(\SimpleXMLElement $data)
238+
protected function addTransactionSettings(\SimpleXMLElement $data)
160239
{
161-
// Test mode setting
162-
$data->transactionRequest->transactionSettings->setting->settingName = 'testRequest';
163-
$data->transactionRequest->transactionSettings->setting->settingValue = $this->getTestMode() ? 'true' : 'false';
240+
$i = 0;
164241

165-
return $data;
166-
}
167-
168-
public function sendData($data)
169-
{
170-
$headers = array('Content-Type' => 'text/xml; charset=utf-8');
171-
$data = $data->saveXml();
172-
$httpResponse = $this->httpClient->post($this->getEndpoint(), $headers, $data)->send();
173-
174-
return $this->response = new AIMResponse($this, $httpResponse->getBody());
175-
}
242+
// The test mode setting indicates whether or not this is a live request or a test request
243+
$transactionRequest = $data->transactionRequest;
244+
$transactionRequest->transactionSettings->setting[$i]->settingName = 'testRequest';
245+
$transactionRequest->transactionSettings->setting[$i]->settingValue = $this->getTestMode() ? 'true' : 'false';
176246

177-
public function getLiveEndpoint()
178-
{
179-
return $this->getParameter('liveEndpoint');
180-
}
181-
182-
public function setLiveEndpoint($value)
183-
{
184-
return $this->setParameter('liveEndpoint', $value);
185-
}
186-
187-
public function getDeveloperEndpoint()
188-
{
189-
return $this->getParameter('developerEndpoint');
190-
}
191-
192-
public function setDeveloperEndpoint($value)
193-
{
194-
return $this->setParameter('developerEndpoint', $value);
195-
}
247+
// The duplicate window setting specifies the threshold for AuthorizeNet's duplicate transaction detection logic
248+
if (!is_null($this->getDuplicateWindow())) {
249+
$i++;
250+
$transactionRequest->transactionSettings->setting[$i]->settingName = 'duplicateWindow';
251+
$transactionRequest->transactionSettings->setting[$i]->settingValue = $this->getDuplicateWindow();
252+
}
196253

197-
public function getEndpoint()
198-
{
199-
return $this->getDeveloperMode() ? $this->getDeveloperEndpoint() : $this->getLiveEndpoint();
254+
return $data;
200255
}
201256
}

src/Message/AIMAuthorizeRequest.php

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,26 +13,33 @@ class AIMAuthorizeRequest extends AIMAbstractRequest
1313

1414
public function getData()
1515
{
16-
$this->validate('amount', 'card');
16+
$this->validate('amount');
17+
$data = $this->getBaseData();
18+
$data->transactionRequest->amount = $this->getAmount();
19+
$this->addPayment($data);
20+
$this->addCustomerIP($data);
21+
$this->addBillingData($data);
22+
$this->addTransactionSettings($data);
1723

24+
return $data;
25+
}
26+
27+
protected function addPayment(\SimpleXMLElement $data)
28+
{
29+
$this->validate('card');
1830
/** @var CreditCard $card */
1931
$card = $this->getCard();
2032
$card->validate();
21-
22-
$data = $this->getBaseData();
23-
$data->transactionRequest->amount = $this->getAmount();
2433
$data->transactionRequest->payment->creditCard->cardNumber = $card->getNumber();
2534
$data->transactionRequest->payment->creditCard->expirationDate = $card->getExpiryDate('my');
2635
$data->transactionRequest->payment->creditCard->cardCode = $card->getCvv();
36+
}
37+
38+
protected function addCustomerIP(\SimpleXMLElement $data)
39+
{
2740
$ip = $this->getClientIp();
2841
if (!empty($ip)) {
2942
$data->transactionRequest->customerIP = $ip;
3043
}
31-
32-
$this->addBillingData($data);
33-
$this->addTestModeSetting($data);
34-
$this->addExtraOptions($data);
35-
36-
return $data;
3744
}
3845
}

src/Message/AIMCaptureRequest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ public function getData()
1515

1616
$data = $this->getBaseData();
1717
$data->transactionRequest->amount = $this->getAmount();
18-
$data->transactionRequest->refTransId = $this->getTransactionReference();
19-
$this->addTestModeSetting($data);
18+
$data->transactionRequest->refTransId = $this->getTransactionReference()->getTransId();
19+
$this->addTransactionSettings($data);
2020

2121
return $data;
2222
}

src/Message/AIMRefundRequest.php

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,67 @@
22

33
namespace Omnipay\AuthorizeNet\Message;
44

5-
use Omnipay\Common\CreditCard;
6-
75
/**
86
* Authorize.net AIM Refund Request
97
*/
108
class AIMRefundRequest extends AIMAbstractRequest
119
{
1210
protected $action = 'refundTransaction';
1311

14-
public function getData()
12+
public function shouldVoidIfRefundFails()
13+
{
14+
return !!$this->getParameter('voidIfRefundFails');
15+
}
16+
17+
public function setVoidIfRefundFails($value)
1518
{
16-
$this->validate('transactionReference', 'amount', 'card');
19+
$this->setParameter('voidIfRefundFails', $value);
20+
}
1721

18-
/** @var CreditCard $card */
19-
$card = $this->getCard();
22+
public function getData()
23+
{
24+
$this->validate('transactionReference', 'amount');
2025

2126
$data = $this->getBaseData();
2227
$data->transactionRequest->amount = $this->getParameter('amount');
23-
$data->transactionRequest->payment->creditCard->cardNumber = $card->getNumber();
24-
$data->transactionRequest->payment->creditCard->expirationDate = $card->getExpiryDate('my');
25-
$data->transactionRequest->refTransId = $this->getTransactionReference();
26-
$this->addTestModeSetting($data);
28+
29+
$transactionRef = $this->getTransactionReference();
30+
if ($card = $transactionRef->getCard()) {
31+
$data->transactionRequest->payment->creditCard->cardNumber = $card->number;
32+
$data->transactionRequest->payment->creditCard->expirationDate = $card->expiry;
33+
} elseif ($cardRef = $transactionRef->getCardReference()) {
34+
$data->transactionRequest->profile->customerProfileId = $cardRef->getCustomerProfileId();
35+
$data->transactionRequest->profile->paymentProfile->paymentProfileId = $cardRef->getPaymentProfileId();
36+
} else {
37+
// Transaction reference only contains the transaction ID, so a card is required
38+
$this->validate('card');
39+
$card = $this->getCard();
40+
$data->transactionRequest->payment->creditCard->cardNumber = $card->getNumberLastFour();
41+
if ($card->getExpiryMonth()) {
42+
$data->transactionRequest->payment->creditCard->expirationDate = $card->getExpiryDate('my');
43+
}
44+
}
45+
$data->transactionRequest->refTransId = $transactionRef->getTransId();
46+
47+
$this->addTransactionSettings($data);
2748

2849
return $data;
2950
}
51+
52+
public function send()
53+
{
54+
/** @var AIMResponse $response */
55+
$response = parent::send();
56+
57+
if (!$response->isSuccessful() && $this->shouldVoidIfRefundFails() &&
58+
$response->getReasonCode() == AIMResponse::ERROR_RESPONSE_CODE_CANNOT_ISSUE_CREDIT
59+
) {
60+
// This transaction has not yet been settled, hence cannot be refunded. But a void is possible.
61+
$voidRequest = new CIMVoidRequest($this->httpClient, $this->httpRequest);
62+
$voidRequest->initialize($this->getParameters());
63+
$response = $voidRequest->send();
64+
}
65+
66+
return $response;
67+
}
3068
}

0 commit comments

Comments
 (0)