|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* Easily interact with the Authorize.Net Card Present API. |
|
4
|
|
|
* |
|
5
|
|
|
* |
|
6
|
|
|
* @package AuthorizeNet |
|
7
|
|
|
* @subpackage AuthorizeNetCP |
|
8
|
|
|
* @link http://www.authorize.net/support/CP_guide.pdf Card Present Guide |
|
9
|
|
|
*/ |
|
10
|
|
|
|
|
11
|
|
|
|
|
12
|
|
|
/** |
|
13
|
|
|
* Builds and sends an AuthorizeNet CP Request. |
|
14
|
|
|
* |
|
15
|
|
|
* @package AuthorizeNet |
|
16
|
|
|
* @subpackage AuthorizeNetCP |
|
17
|
|
|
*/ |
|
18
|
|
|
class AuthorizeNetCP extends AuthorizeNetAIM |
|
|
|
|
|
|
19
|
|
|
{ |
|
20
|
|
|
|
|
21
|
|
|
const LIVE_URL = 'https://cardpresent.authorize.net/gateway/transact.dll'; |
|
22
|
|
|
|
|
23
|
|
|
public $verify_x_fields = false; |
|
24
|
|
|
|
|
25
|
|
|
/** |
|
26
|
|
|
* Holds all the x_* name/values that will be posted in the request. |
|
27
|
|
|
* Default values are provided for best practice fields. |
|
28
|
|
|
*/ |
|
29
|
|
|
protected $_x_post_fields = array( |
|
30
|
|
|
"cpversion" => "1.0", |
|
31
|
|
|
"delim_char" => ",", |
|
32
|
|
|
"encap_char" => "|", |
|
33
|
|
|
"market_type" => "2", |
|
34
|
|
|
"response_format" => "1", // 0 - XML, 1 - NVP |
|
35
|
|
|
); |
|
36
|
|
|
|
|
37
|
|
|
/** |
|
38
|
|
|
* Device Types (x_device_type) |
|
39
|
|
|
* 1 = Unknown |
|
40
|
|
|
* 2 = Unattended Terminal |
|
41
|
|
|
* 3 = Self Service Terminal |
|
42
|
|
|
* 4 = Electronic Cash Register |
|
43
|
|
|
* 5 = Personal Computer- Based Terminal |
|
44
|
|
|
* 6 = AirPay |
|
45
|
|
|
* 7 = Wireless POS |
|
46
|
|
|
* 8 = Website |
|
47
|
|
|
* 9 = Dial Terminal |
|
48
|
|
|
* 10 = Virtual Terminal |
|
49
|
|
|
*/ |
|
50
|
|
|
|
|
51
|
|
|
/** |
|
52
|
|
|
* Only used if merchant wants to send custom fields. |
|
53
|
|
|
*/ |
|
54
|
|
|
private $_custom_fields = array(); |
|
|
|
|
|
|
55
|
|
|
|
|
56
|
|
|
/** |
|
57
|
|
|
* Strip sentinels and set track1 field. |
|
58
|
|
|
* |
|
59
|
|
|
* @param string $track1data |
|
60
|
|
|
*/ |
|
61
|
1 |
|
public function setTrack1Data($track1data) { |
|
62
|
1 |
|
if (preg_match('/^%.*\?$/', $track1data)) { |
|
63
|
1 |
|
$this->track1 = substr($track1data, 1, -1); |
|
|
|
|
|
|
64
|
|
|
} else { |
|
65
|
|
|
$this->track1 = $track1data; |
|
|
|
|
|
|
66
|
|
|
} |
|
67
|
1 |
|
} |
|
68
|
|
|
|
|
69
|
|
|
/** |
|
70
|
|
|
* Strip sentinels and set track2 field. |
|
71
|
|
|
* |
|
72
|
|
|
* @param string $track2data |
|
73
|
|
|
*/ |
|
74
|
2 |
|
public function setTrack2Data($track2data) { |
|
75
|
2 |
|
if (preg_match('/^;.*\?$/', $track2data)) { |
|
76
|
|
|
$this->track2 = substr($track2data, 1, -1); |
|
|
|
|
|
|
77
|
|
|
} else { |
|
78
|
2 |
|
$this->track2 = $track2data; |
|
|
|
|
|
|
79
|
|
|
} |
|
80
|
2 |
|
} |
|
81
|
|
|
|
|
82
|
|
|
/** |
|
83
|
|
|
* |
|
84
|
|
|
* |
|
85
|
|
|
* @param string $response |
|
86
|
|
|
* |
|
87
|
|
|
* @return AuthorizeNetAIM_Response |
|
88
|
|
|
*/ |
|
89
|
5 |
|
protected function _handleResponse($response) |
|
90
|
|
|
{ |
|
91
|
5 |
|
return new AuthorizeNetCP_Response($response, $this->_x_post_fields['delim_char'], $this->_x_post_fields['encap_char'], $this->_custom_fields); |
|
|
|
|
|
|
92
|
|
|
} |
|
93
|
|
|
|
|
94
|
|
|
} |
|
95
|
|
|
|
|
96
|
|
|
|
|
97
|
|
|
/** |
|
98
|
|
|
* Parses an AuthorizeNet Card Present Response. |
|
99
|
|
|
* |
|
100
|
|
|
* @package AuthorizeNet |
|
101
|
|
|
* @subpackage AuthorizeNetCP |
|
102
|
|
|
*/ |
|
103
|
|
|
class AuthorizeNetCP_Response extends AuthorizeNetResponse |
|
|
|
|
|
|
104
|
|
|
{ |
|
105
|
|
|
private $_response_array = array(); // An array with the split response. |
|
106
|
|
|
|
|
107
|
|
|
/** |
|
108
|
|
|
* Constructor. Parses the AuthorizeNet response string. |
|
109
|
|
|
* |
|
110
|
|
|
* @param string $response The response from the AuthNet server. |
|
111
|
|
|
* @param string $delimiter The delimiter used (default is ",") |
|
112
|
|
|
* @param string $encap_char The encap_char used (default is "|") |
|
113
|
|
|
* @param array $custom_fields Any custom fields set in the request. |
|
114
|
|
|
*/ |
|
115
|
5 |
|
public function __construct($response, $delimiter, $encap_char, $custom_fields) |
|
|
|
|
|
|
116
|
|
|
{ |
|
117
|
5 |
|
if ($response) { |
|
118
|
|
|
|
|
119
|
|
|
// If it's an XML response |
|
120
|
5 |
|
if (substr($response, 0, 5) == "<?xml") { |
|
121
|
|
|
|
|
122
|
|
|
$this->xml = @simplexml_load_string($response); |
|
|
|
|
|
|
123
|
|
|
// Set all fields |
|
124
|
|
|
$this->version = array_pop(array_slice(explode('"', $response), 1,1)); |
|
|
|
|
|
|
125
|
|
|
$this->response_code = (string)$this->xml->ResponseCode; |
|
126
|
|
|
|
|
127
|
|
|
if ($this->response_code == 1) { |
|
128
|
|
|
$this->response_reason_code = (string)$this->xml->Messages->Message->Code; |
|
129
|
|
|
$this->response_reason_text = (string)$this->xml->Messages->Message->Description; |
|
130
|
|
|
} else { |
|
131
|
|
|
$this->response_reason_code = (string)$this->xml->Errors->Error->ErrorCode; |
|
132
|
|
|
$this->response_reason_text = (string)$this->xml->Errors->Error->ErrorText; |
|
133
|
|
|
} |
|
134
|
|
|
|
|
135
|
|
|
$this->authorization_code = (string)$this->xml->AuthCode; |
|
136
|
|
|
$this->avs_code = (string)$this->xml->AVSResultCode; |
|
|
|
|
|
|
137
|
|
|
$this->card_code_response = (string)$this->xml->CVVResultCode; |
|
138
|
|
|
$this->transaction_id = (string)$this->xml->TransID; |
|
139
|
|
|
$this->md5_hash = (string)$this->xml->TransHash; |
|
140
|
|
|
$this->user_ref = (string)$this->xml->UserRef; |
|
|
|
|
|
|
141
|
|
|
$this->card_num = (string)$this->xml->AccountNumber; |
|
|
|
|
|
|
142
|
|
|
$this->card_type = (string)$this->xml->AccountType; |
|
143
|
|
|
$this->test_mode = (string)$this->xml->TestMode; |
|
|
|
|
|
|
144
|
|
|
$this->ref_trans_id = (string)$this->xml->RefTransID; |
|
|
|
|
|
|
145
|
|
|
|
|
146
|
|
|
|
|
147
|
|
|
} else { // If it's an NVP response |
|
148
|
|
|
|
|
149
|
|
|
// Split Array |
|
150
|
5 |
|
$this->response = $response; |
|
151
|
5 |
|
if ($encap_char) { |
|
152
|
5 |
|
$this->_response_array = explode($encap_char.$delimiter.$encap_char, substr($response, 1, -1)); |
|
153
|
|
|
} else { |
|
154
|
|
|
$this->_response_array = explode($delimiter, $response); |
|
155
|
|
|
} |
|
156
|
|
|
|
|
157
|
|
|
/** |
|
158
|
|
|
* If AuthorizeNet doesn't return a delimited response. |
|
159
|
|
|
*/ |
|
160
|
5 |
|
if (count($this->_response_array) < 10) { |
|
161
|
|
|
$this->approved = false; |
|
162
|
|
|
$this->error = true; |
|
163
|
|
|
$this->error_message = "Unrecognized response from AuthorizeNet: $response"; |
|
|
|
|
|
|
164
|
|
|
return; |
|
165
|
|
|
} |
|
166
|
|
|
|
|
167
|
|
|
|
|
168
|
|
|
|
|
169
|
|
|
// Set all fields |
|
170
|
5 |
|
$this->version = $this->_response_array[0]; |
|
171
|
5 |
|
$this->response_code = $this->_response_array[1]; |
|
172
|
5 |
|
$this->response_reason_code = $this->_response_array[2]; |
|
173
|
5 |
|
$this->response_reason_text = $this->_response_array[3]; |
|
174
|
5 |
|
$this->authorization_code = $this->_response_array[4]; |
|
175
|
5 |
|
$this->avs_code = $this->_response_array[5]; |
|
176
|
5 |
|
$this->card_code_response = $this->_response_array[6]; |
|
177
|
5 |
|
$this->transaction_id = $this->_response_array[7]; |
|
178
|
5 |
|
$this->md5_hash = $this->_response_array[8]; |
|
179
|
5 |
|
$this->user_ref = $this->_response_array[9]; |
|
180
|
5 |
|
$this->card_num = $this->_response_array[20]; |
|
181
|
5 |
|
$this->card_type = $this->_response_array[21]; |
|
182
|
5 |
|
$this->split_tender_id = isset($this->_response_array[22]) ? $this->_response_array[22] : NULL; |
|
183
|
5 |
|
$this->requested_amount = isset($this->_response_array[23]) ? $this->_response_array[23] : NULL; |
|
184
|
5 |
|
$this->approved_amount = isset($this->_response_array[24]) ? $this->_response_array[24] : NULL; |
|
|
|
|
|
|
185
|
5 |
|
$this->card_balance = isset($this->_response_array[25]) ? $this->_response_array[25] : NULL; |
|
|
|
|
|
|
186
|
|
|
|
|
187
|
|
|
|
|
188
|
|
|
|
|
189
|
|
|
} |
|
190
|
5 |
|
$this->approved = ($this->response_code == self::APPROVED); |
|
191
|
5 |
|
$this->declined = ($this->response_code == self::DECLINED); |
|
192
|
5 |
|
$this->error = ($this->response_code == self::ERROR); |
|
193
|
5 |
|
$this->held = ($this->response_code == self::HELD); |
|
194
|
|
|
|
|
195
|
|
|
|
|
196
|
5 |
|
if ($this->error) { |
|
197
|
1 |
|
$this->error_message = "AuthorizeNet Error: |
|
198
|
1 |
|
Response Code: ".$this->response_code." |
|
199
|
1 |
|
Response Reason Code: ".$this->response_reason_code." |
|
200
|
1 |
|
Response Reason Text: ".$this->response_reason_text." |
|
201
|
5 |
|
"; |
|
202
|
|
|
} |
|
203
|
|
|
|
|
204
|
|
|
} else { |
|
205
|
|
|
$this->approved = false; |
|
206
|
|
|
$this->error = true; |
|
207
|
|
|
$this->error_message = "Error connecting to AuthorizeNet"; |
|
208
|
|
|
} |
|
209
|
5 |
|
} |
|
210
|
|
|
|
|
211
|
|
|
/** |
|
212
|
|
|
* Is the MD5 provided correct? |
|
213
|
|
|
* |
|
214
|
|
|
* @param string $api_login_id |
|
215
|
|
|
* @param string $md5_setting |
|
216
|
|
|
* @return bool |
|
217
|
|
|
*/ |
|
218
|
|
|
public function isAuthorizeNet($api_login_id = false, $md5_setting = false) |
|
219
|
|
|
{ |
|
220
|
|
|
$amount = ($this->amount ? $this->amount : '0.00'); |
|
221
|
|
|
$api_login_id = ($api_login_id ? $api_login_id : AUTHORIZENET_API_LOGIN_ID); |
|
222
|
|
|
$md5_setting = ($md5_setting ? $md5_setting : AUTHORIZENET_MD5_SETTING); |
|
223
|
|
|
return ($this->md5_hash == strtoupper(md5($md5_setting . $api_login_id . $this->transaction_id . $amount))); |
|
224
|
|
|
} |
|
225
|
|
|
|
|
226
|
|
|
} |
|
227
|
|
|
|
|
228
|
|
|
|
You can fix this by adding a namespace to your class:
When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.