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.