@@ -362,7 +362,7 @@ discard block |
||
| 362 | 362 | /** |
| 363 | 363 | * Posts the request to AuthorizeNet & returns response. |
| 364 | 364 | * |
| 365 | - * @param $payment |
|
| 365 | + * @param EEI_Payment $payment |
|
| 366 | 366 | * @return \EE_AuthorizeNetAIM_Response |
| 367 | 367 | */ |
| 368 | 368 | private function _sendRequest($payment) |
@@ -451,7 +451,7 @@ discard block |
||
| 451 | 451 | /** |
| 452 | 452 | * Removes characters Authorize.net doesn't handle well. |
| 453 | 453 | * @since $VID:$ |
| 454 | - * @param $text |
|
| 454 | + * @param string $text |
|
| 455 | 455 | * @return string |
| 456 | 456 | */ |
| 457 | 457 | private function prepareStringForAuthnet($text) |
@@ -1,6 +1,5 @@ |
||
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | -use EventEspresso\core\services\formatters\AsciiOnly; |
|
| 4 | 3 | use EventEspresso\core\services\loaders\LoaderFactory; |
| 5 | 4 | |
| 6 | 5 | /** |
@@ -26,442 +26,442 @@ discard block |
||
| 26 | 26 | class EEG_Aim extends EE_Onsite_Gateway |
| 27 | 27 | { |
| 28 | 28 | |
| 29 | - const LIVE_URL = 'https://secure2.authorize.net/gateway/transact.dll'; // Authnet URL |
|
| 30 | - |
|
| 31 | - const SANDBOX_URL = 'https://test.authorize.net/gateway/transact.dll'; |
|
| 32 | - |
|
| 33 | - protected $_login_id; |
|
| 34 | - |
|
| 35 | - protected $_transaction_key; |
|
| 36 | - |
|
| 37 | - protected $_server; |
|
| 38 | - |
|
| 39 | - protected $_currencies_supported = array( |
|
| 40 | - 'AUD', |
|
| 41 | - 'USD', |
|
| 42 | - 'CAD', |
|
| 43 | - 'EUR', |
|
| 44 | - 'GBP', |
|
| 45 | - 'NZD', |
|
| 46 | - ); |
|
| 47 | - |
|
| 48 | - /** |
|
| 49 | - * Whether to send test transactions (even to live site) |
|
| 50 | - * |
|
| 51 | - * @var boolean |
|
| 52 | - */ |
|
| 53 | - protected $_test_transactions; |
|
| 54 | - |
|
| 55 | - private $VERIFY_PEER = false; |
|
| 56 | - |
|
| 57 | - private $_x_post_fields = array( |
|
| 58 | - "version" => "3.1", |
|
| 59 | - "delim_char" => ",", |
|
| 60 | - "delim_data" => "TRUE", |
|
| 61 | - "relay_response" => "FALSE", |
|
| 62 | - "encap_char" => "|", |
|
| 63 | - ); |
|
| 64 | - |
|
| 65 | - private $_additional_line_items = array(); |
|
| 66 | - |
|
| 67 | - /** |
|
| 68 | - * A list of all fields in the AIM API. |
|
| 69 | - * Used to warn user if they try to set a field not offered in the API. |
|
| 70 | - */ |
|
| 71 | - private $_all_aim_fields = array( |
|
| 72 | - "address", |
|
| 73 | - "allow_partial_auth", |
|
| 74 | - "amount", |
|
| 75 | - "auth_code", |
|
| 76 | - "authentication_indicator", |
|
| 77 | - "bank_aba_code", |
|
| 78 | - "bank_acct_name", |
|
| 79 | - "bank_acct_num", |
|
| 80 | - "bank_acct_type", |
|
| 81 | - "bank_check_number", |
|
| 82 | - "bank_name", |
|
| 83 | - "card_code", |
|
| 84 | - "card_num", |
|
| 85 | - "cardholder_authentication_value", |
|
| 86 | - "city", |
|
| 87 | - "company", |
|
| 88 | - "country", |
|
| 89 | - "cust_id", |
|
| 90 | - "customer_ip", |
|
| 91 | - "delim_char", |
|
| 92 | - "delim_data", |
|
| 93 | - "description", |
|
| 94 | - "duplicate_window", |
|
| 95 | - "duty", |
|
| 96 | - "echeck_type", |
|
| 97 | - "email", |
|
| 98 | - "email_customer", |
|
| 99 | - "encap_char", |
|
| 100 | - "exp_date", |
|
| 101 | - "fax", |
|
| 102 | - "first_name", |
|
| 103 | - "footer_email_receipt", |
|
| 104 | - "freight", |
|
| 105 | - "header_email_receipt", |
|
| 106 | - "invoice_num", |
|
| 107 | - "last_name", |
|
| 108 | - "line_item", |
|
| 109 | - "login", |
|
| 110 | - "method", |
|
| 111 | - "phone", |
|
| 112 | - "po_num", |
|
| 113 | - "recurring_billing", |
|
| 114 | - "relay_response", |
|
| 115 | - "ship_to_address", |
|
| 116 | - "ship_to_city", |
|
| 117 | - "ship_to_company", |
|
| 118 | - "ship_to_country", |
|
| 119 | - "ship_to_first_name", |
|
| 120 | - "ship_to_last_name", |
|
| 121 | - "ship_to_state", |
|
| 122 | - "ship_to_zip", |
|
| 123 | - "split_tender_id", |
|
| 124 | - "state", |
|
| 125 | - "tax", |
|
| 126 | - "tax_exempt", |
|
| 127 | - "test_request", |
|
| 128 | - "tran_key", |
|
| 129 | - "trans_id", |
|
| 130 | - "type", |
|
| 131 | - "version", |
|
| 132 | - "zip", |
|
| 133 | - "solution_id", |
|
| 134 | - "currency_code" |
|
| 135 | - ); |
|
| 136 | - |
|
| 137 | - |
|
| 138 | - /** |
|
| 139 | - * Gets the URL where the request should go. This is filterable |
|
| 140 | - * |
|
| 141 | - * @return string |
|
| 142 | - */ |
|
| 143 | - protected function _get_server_url() |
|
| 144 | - { |
|
| 145 | - return apply_filters( |
|
| 146 | - 'FHEE__EEG_Aim___get_server_url', |
|
| 147 | - $this->_debug_mode ? self::SANDBOX_URL : self::LIVE_URL, |
|
| 148 | - $this |
|
| 149 | - ); |
|
| 150 | - } |
|
| 151 | - |
|
| 152 | - |
|
| 153 | - /** |
|
| 154 | - * TEMPORARY CALLBACK! Do not use |
|
| 155 | - * Callback which filters the server url. This is added so site admins can revert to using |
|
| 156 | - * the old AIM server in case Akamai service breaks their integration. |
|
| 157 | - * Using Akamai will, however, be mandatory on June 30th 2016 Authorize.net |
|
| 158 | - * (see http://www.authorize.net/support/akamaifaqs/#firewall?utm_campaign=April%202016%20Technical%20Updates%20for%20Merchants.html&utm_medium=email&utm_source=Eloqua&elqTrackId=46103bdc375c411a979c2f658fc99074&elq=7026706360154fee9b6d588b27d8eb6a&elqaid=506&elqat=1&elqCampaignId=343) |
|
| 159 | - * Once that happens, this will be obsolete and WILL BE REMOVED. |
|
| 160 | - * |
|
| 161 | - * @param string $url |
|
| 162 | - * @param EEG_Aim $gateway_object |
|
| 163 | - * @return string |
|
| 164 | - */ |
|
| 165 | - public function possibly_use_deprecated_aim_server($url, EEG_Aim $gateway_object) |
|
| 166 | - { |
|
| 167 | - if ($gateway_object->_server === 'authorize.net' && ! $gateway_object->_debug_mode) { |
|
| 168 | - return 'https://secure.authorize.net/gateway/transact.dll'; |
|
| 169 | - } else { |
|
| 170 | - return $url; |
|
| 171 | - } |
|
| 172 | - } |
|
| 173 | - |
|
| 174 | - |
|
| 175 | - /** |
|
| 176 | - * Asks the gateway to do whatever it does to process the payment. Onsite gateways will |
|
| 177 | - * usually send a request directly to the payment provider and update the payment's status based on that; |
|
| 178 | - * whereas offsite gateways will usually just update the payment with the URL and query parameters to use |
|
| 179 | - * for sending the request via http_remote_request() |
|
| 180 | - * |
|
| 181 | - * @param EEI_Payment $payment |
|
| 182 | - * @param array $billing_info { |
|
| 183 | - * @type $credit_card string |
|
| 184 | - * @type $cvv string |
|
| 185 | - * @type $exp_month string |
|
| 186 | - * @type $exp_year string |
|
| 187 | - * @see parent::do_direct_payment |
|
| 188 | - * } |
|
| 189 | - * @return EEI_Payment updated |
|
| 190 | - */ |
|
| 191 | - public function do_direct_payment($payment, $billing_info = null) |
|
| 192 | - { |
|
| 193 | - add_filter('FHEE__EEG_Aim___get_server_url', array($this, 'possibly_use_deprecated_aim_server'), 10, 2); |
|
| 194 | - // Enable test mode if needed |
|
| 195 | - // 4007000000027 <-- test successful visa |
|
| 196 | - // 4222222222222 <-- test failure card number |
|
| 197 | - |
|
| 198 | - $item_num = 1; |
|
| 199 | - $transaction = $payment->transaction(); |
|
| 200 | - $gateway_formatter = $this->_get_gateway_formatter(); |
|
| 201 | - $order_description = $this->prepareStringForAuthnet($gateway_formatter->formatOrderDescription($payment)); |
|
| 202 | - $primary_registrant = $transaction->primary_registration(); |
|
| 203 | - // if we're are charging for the full amount, show the normal line items |
|
| 204 | - // and the itemized total adds up properly |
|
| 205 | - if ($this->_can_easily_itemize_transaction_for($payment)) { |
|
| 206 | - $total_line_item = $transaction->total_line_item(); |
|
| 207 | - foreach ($total_line_item->get_items() as $line_item) { |
|
| 208 | - if ($line_item->quantity() == 0) { |
|
| 209 | - continue; |
|
| 210 | - } |
|
| 211 | - $this->addLineItem( |
|
| 212 | - $item_num++, |
|
| 213 | - $gateway_formatter->formatLineItemName($line_item, $payment), |
|
| 214 | - $gateway_formatter->formatLineItemDesc($line_item, $payment), |
|
| 215 | - $line_item->quantity(), |
|
| 216 | - $line_item->unit_price(), |
|
| 217 | - 'N' |
|
| 218 | - ); |
|
| 219 | - $order_description .= $this->prepareStringForAuthnet($line_item->desc()) . ', '; |
|
| 220 | - } |
|
| 221 | - foreach ($total_line_item->tax_descendants() as $tax_line_item) { |
|
| 222 | - $this->addLineItem( |
|
| 223 | - $item_num++, |
|
| 224 | - $tax_line_item->name(), |
|
| 225 | - $tax_line_item->desc(), |
|
| 226 | - 1, |
|
| 227 | - $tax_line_item->total(), |
|
| 228 | - 'N' |
|
| 229 | - ); |
|
| 230 | - } |
|
| 231 | - } |
|
| 232 | - |
|
| 233 | - // start transaction |
|
| 234 | - // if in debug mode, use authorize.net's sandbox id; otherwise use the Event Espresso partner id |
|
| 235 | - $partner_id = $this->_debug_mode ? 'AAA100302' : 'AAA105363'; |
|
| 236 | - $this->setField('solution_id', $partner_id); |
|
| 237 | - $this->setField('amount', $gateway_formatter->formatCurrency($payment->amount())); |
|
| 238 | - $this->setField('description', substr(rtrim($order_description, ', '), 0, 255)); |
|
| 239 | - $this->_set_sensitive_billing_data($billing_info); |
|
| 240 | - $this->setField('first_name', $billing_info['first_name']); |
|
| 241 | - $this->setField('last_name', $billing_info['last_name']); |
|
| 242 | - $this->setField('email', $billing_info['email']); |
|
| 243 | - $this->setField('company', $billing_info['company']); |
|
| 244 | - $this->setField('address', $billing_info['address'].' '.$billing_info['address2']); |
|
| 245 | - $this->setField('city', $billing_info['city']); |
|
| 246 | - $this->setField('state', $billing_info['state']); |
|
| 247 | - $this->setField('country', $billing_info['country']); |
|
| 248 | - $this->setField('zip', $billing_info['zip']); |
|
| 249 | - $this->setField('fax', $billing_info['fax']); |
|
| 250 | - $this->setField('cust_id', $primary_registrant->ID()); |
|
| 251 | - $this->setField('phone', $billing_info['phone']); |
|
| 252 | - $currency_config = LoaderFactory::getLoader()->load('EE_Currency_Config'); |
|
| 253 | - $this->setField('currency_code', $currency_config->code); |
|
| 254 | - // invoice_num would be nice to have it be unique per SPCO page-load, that way if users |
|
| 255 | - // press back, they don't submit a duplicate. However, we may be keeping the user on teh same spco page |
|
| 256 | - // in which case, we need to generate teh invoice num per request right here... |
|
| 257 | - $this->setField('invoice_num', wp_generate_password(12, false));// $billing_info['_reg-page-billing-invoice-'.$this->_gateway_name]['value']); |
|
| 258 | - // tell AIM that any duplicates sent in the next 5 minutes are to be ignored |
|
| 259 | - $this->setField('duplicate_window', 5 * MINUTE_IN_SECONDS); |
|
| 260 | - |
|
| 261 | - if ($this->_test_transactions) { |
|
| 262 | - $this->test_request = "true"; |
|
| 263 | - } |
|
| 264 | - |
|
| 265 | - // Capture response |
|
| 266 | - $this->type = "AUTH_CAPTURE"; |
|
| 267 | - $response = $this->_sendRequest($payment); |
|
| 268 | - if (! empty($response)) { |
|
| 269 | - if ($response->error_message) { |
|
| 270 | - $payment->set_status($this->_pay_model->failed_status()); |
|
| 271 | - $payment->set_gateway_response($response->error_message); |
|
| 272 | - } else { |
|
| 273 | - $payment_status = $response->approved |
|
| 274 | - ? $this->_pay_model->approved_status() |
|
| 275 | - : $this->_pay_model->declined_status(); |
|
| 276 | - $payment->set_status($payment_status); |
|
| 277 | - // make sure we interpret the AMT as a float, not an international string (where periods are thousand separators) |
|
| 278 | - $payment->set_amount((float) $response->amount); |
|
| 279 | - $payment->set_gateway_response( |
|
| 280 | - sprintf( |
|
| 281 | - esc_html__('%1$s (Reason Code: %2$s)', 'event_espresso'), |
|
| 282 | - $response->response_reason_text, |
|
| 283 | - $response->response_reason_code |
|
| 284 | - ) |
|
| 285 | - ); |
|
| 286 | - if ($this->_debug_mode) { |
|
| 287 | - $txn_id = $response->invoice_number; |
|
| 288 | - } else { |
|
| 289 | - $txn_id = $response->transaction_id; |
|
| 290 | - } |
|
| 291 | - $payment->set_txn_id_chq_nmbr($txn_id); |
|
| 292 | - } |
|
| 293 | - $payment->set_extra_accntng($primary_registrant->reg_code()); |
|
| 294 | - $payment->set_details(print_r($response, true)); |
|
| 295 | - } else { |
|
| 296 | - $payment->set_status($this->_pay_model->failed_status()); |
|
| 297 | - $payment->set_gateway_response(__("There was no response from Authorize.net", 'event_espresso')); |
|
| 298 | - $payment->set_details(print_r($response, true)); |
|
| 299 | - } |
|
| 300 | - return $payment; |
|
| 301 | - } |
|
| 302 | - |
|
| 303 | - |
|
| 304 | - /** |
|
| 305 | - * Sets billing data for the upcoming request to AIM that is considered sensitive; |
|
| 306 | - * also this method can be overridden by children classes to easily change |
|
| 307 | - * what billing data gets sent |
|
| 308 | - * |
|
| 309 | - * @param array $billing_info |
|
| 310 | - */ |
|
| 311 | - protected function _set_sensitive_billing_data($billing_info) |
|
| 312 | - { |
|
| 313 | - $this->setField('card_num', $billing_info['credit_card']); |
|
| 314 | - $this->setField('exp_date', $billing_info['exp_month'] . $billing_info['exp_year']); |
|
| 315 | - $this->setField('card_code', $billing_info['cvv']); |
|
| 316 | - } |
|
| 317 | - |
|
| 318 | - |
|
| 319 | - /** |
|
| 320 | - * Add a line item. |
|
| 321 | - * |
|
| 322 | - * @param string $item_id |
|
| 323 | - * @param string $item_name |
|
| 324 | - * @param string $item_description |
|
| 325 | - * @param string $item_quantity |
|
| 326 | - * @param string $item_unit_price |
|
| 327 | - * @param string $item_taxable |
|
| 328 | - */ |
|
| 329 | - public function addLineItem($item_id, $item_name, $item_description, $item_quantity, $item_unit_price, $item_taxable) |
|
| 330 | - { |
|
| 331 | - $args = array( |
|
| 332 | - substr($item_id, 0, 31), |
|
| 333 | - substr($this->prepareStringForAuthnet($item_name), 0, 31), |
|
| 334 | - substr($this->prepareStringForAuthnet($item_description), 0, 255), |
|
| 335 | - number_format(abs($item_quantity), 2, '.', ''), |
|
| 336 | - number_format(abs($item_unit_price), 2, '.', ''), |
|
| 337 | - $item_taxable === 'N' ? 'N' : 'Y' |
|
| 338 | - ); |
|
| 339 | - $this->_additional_line_items[] = implode('<|>', $args); |
|
| 340 | - } |
|
| 341 | - |
|
| 342 | - |
|
| 343 | - /** |
|
| 344 | - * Set an individual name/value pair. This will append x_ to the name |
|
| 345 | - * before posting. |
|
| 346 | - * |
|
| 347 | - * @param string $name |
|
| 348 | - * @param string $value |
|
| 349 | - * @throws AuthorizeNetException |
|
| 350 | - */ |
|
| 351 | - protected function setField($name, $value) |
|
| 352 | - { |
|
| 353 | - if (in_array($name, $this->_all_aim_fields)) { |
|
| 354 | - $this->_x_post_fields[ $name ] = $value; |
|
| 355 | - } else { |
|
| 356 | - throw new AuthorizeNetException("Error: no field $name exists in the AIM API. |
|
| 29 | + const LIVE_URL = 'https://secure2.authorize.net/gateway/transact.dll'; // Authnet URL |
|
| 30 | + |
|
| 31 | + const SANDBOX_URL = 'https://test.authorize.net/gateway/transact.dll'; |
|
| 32 | + |
|
| 33 | + protected $_login_id; |
|
| 34 | + |
|
| 35 | + protected $_transaction_key; |
|
| 36 | + |
|
| 37 | + protected $_server; |
|
| 38 | + |
|
| 39 | + protected $_currencies_supported = array( |
|
| 40 | + 'AUD', |
|
| 41 | + 'USD', |
|
| 42 | + 'CAD', |
|
| 43 | + 'EUR', |
|
| 44 | + 'GBP', |
|
| 45 | + 'NZD', |
|
| 46 | + ); |
|
| 47 | + |
|
| 48 | + /** |
|
| 49 | + * Whether to send test transactions (even to live site) |
|
| 50 | + * |
|
| 51 | + * @var boolean |
|
| 52 | + */ |
|
| 53 | + protected $_test_transactions; |
|
| 54 | + |
|
| 55 | + private $VERIFY_PEER = false; |
|
| 56 | + |
|
| 57 | + private $_x_post_fields = array( |
|
| 58 | + "version" => "3.1", |
|
| 59 | + "delim_char" => ",", |
|
| 60 | + "delim_data" => "TRUE", |
|
| 61 | + "relay_response" => "FALSE", |
|
| 62 | + "encap_char" => "|", |
|
| 63 | + ); |
|
| 64 | + |
|
| 65 | + private $_additional_line_items = array(); |
|
| 66 | + |
|
| 67 | + /** |
|
| 68 | + * A list of all fields in the AIM API. |
|
| 69 | + * Used to warn user if they try to set a field not offered in the API. |
|
| 70 | + */ |
|
| 71 | + private $_all_aim_fields = array( |
|
| 72 | + "address", |
|
| 73 | + "allow_partial_auth", |
|
| 74 | + "amount", |
|
| 75 | + "auth_code", |
|
| 76 | + "authentication_indicator", |
|
| 77 | + "bank_aba_code", |
|
| 78 | + "bank_acct_name", |
|
| 79 | + "bank_acct_num", |
|
| 80 | + "bank_acct_type", |
|
| 81 | + "bank_check_number", |
|
| 82 | + "bank_name", |
|
| 83 | + "card_code", |
|
| 84 | + "card_num", |
|
| 85 | + "cardholder_authentication_value", |
|
| 86 | + "city", |
|
| 87 | + "company", |
|
| 88 | + "country", |
|
| 89 | + "cust_id", |
|
| 90 | + "customer_ip", |
|
| 91 | + "delim_char", |
|
| 92 | + "delim_data", |
|
| 93 | + "description", |
|
| 94 | + "duplicate_window", |
|
| 95 | + "duty", |
|
| 96 | + "echeck_type", |
|
| 97 | + "email", |
|
| 98 | + "email_customer", |
|
| 99 | + "encap_char", |
|
| 100 | + "exp_date", |
|
| 101 | + "fax", |
|
| 102 | + "first_name", |
|
| 103 | + "footer_email_receipt", |
|
| 104 | + "freight", |
|
| 105 | + "header_email_receipt", |
|
| 106 | + "invoice_num", |
|
| 107 | + "last_name", |
|
| 108 | + "line_item", |
|
| 109 | + "login", |
|
| 110 | + "method", |
|
| 111 | + "phone", |
|
| 112 | + "po_num", |
|
| 113 | + "recurring_billing", |
|
| 114 | + "relay_response", |
|
| 115 | + "ship_to_address", |
|
| 116 | + "ship_to_city", |
|
| 117 | + "ship_to_company", |
|
| 118 | + "ship_to_country", |
|
| 119 | + "ship_to_first_name", |
|
| 120 | + "ship_to_last_name", |
|
| 121 | + "ship_to_state", |
|
| 122 | + "ship_to_zip", |
|
| 123 | + "split_tender_id", |
|
| 124 | + "state", |
|
| 125 | + "tax", |
|
| 126 | + "tax_exempt", |
|
| 127 | + "test_request", |
|
| 128 | + "tran_key", |
|
| 129 | + "trans_id", |
|
| 130 | + "type", |
|
| 131 | + "version", |
|
| 132 | + "zip", |
|
| 133 | + "solution_id", |
|
| 134 | + "currency_code" |
|
| 135 | + ); |
|
| 136 | + |
|
| 137 | + |
|
| 138 | + /** |
|
| 139 | + * Gets the URL where the request should go. This is filterable |
|
| 140 | + * |
|
| 141 | + * @return string |
|
| 142 | + */ |
|
| 143 | + protected function _get_server_url() |
|
| 144 | + { |
|
| 145 | + return apply_filters( |
|
| 146 | + 'FHEE__EEG_Aim___get_server_url', |
|
| 147 | + $this->_debug_mode ? self::SANDBOX_URL : self::LIVE_URL, |
|
| 148 | + $this |
|
| 149 | + ); |
|
| 150 | + } |
|
| 151 | + |
|
| 152 | + |
|
| 153 | + /** |
|
| 154 | + * TEMPORARY CALLBACK! Do not use |
|
| 155 | + * Callback which filters the server url. This is added so site admins can revert to using |
|
| 156 | + * the old AIM server in case Akamai service breaks their integration. |
|
| 157 | + * Using Akamai will, however, be mandatory on June 30th 2016 Authorize.net |
|
| 158 | + * (see http://www.authorize.net/support/akamaifaqs/#firewall?utm_campaign=April%202016%20Technical%20Updates%20for%20Merchants.html&utm_medium=email&utm_source=Eloqua&elqTrackId=46103bdc375c411a979c2f658fc99074&elq=7026706360154fee9b6d588b27d8eb6a&elqaid=506&elqat=1&elqCampaignId=343) |
|
| 159 | + * Once that happens, this will be obsolete and WILL BE REMOVED. |
|
| 160 | + * |
|
| 161 | + * @param string $url |
|
| 162 | + * @param EEG_Aim $gateway_object |
|
| 163 | + * @return string |
|
| 164 | + */ |
|
| 165 | + public function possibly_use_deprecated_aim_server($url, EEG_Aim $gateway_object) |
|
| 166 | + { |
|
| 167 | + if ($gateway_object->_server === 'authorize.net' && ! $gateway_object->_debug_mode) { |
|
| 168 | + return 'https://secure.authorize.net/gateway/transact.dll'; |
|
| 169 | + } else { |
|
| 170 | + return $url; |
|
| 171 | + } |
|
| 172 | + } |
|
| 173 | + |
|
| 174 | + |
|
| 175 | + /** |
|
| 176 | + * Asks the gateway to do whatever it does to process the payment. Onsite gateways will |
|
| 177 | + * usually send a request directly to the payment provider and update the payment's status based on that; |
|
| 178 | + * whereas offsite gateways will usually just update the payment with the URL and query parameters to use |
|
| 179 | + * for sending the request via http_remote_request() |
|
| 180 | + * |
|
| 181 | + * @param EEI_Payment $payment |
|
| 182 | + * @param array $billing_info { |
|
| 183 | + * @type $credit_card string |
|
| 184 | + * @type $cvv string |
|
| 185 | + * @type $exp_month string |
|
| 186 | + * @type $exp_year string |
|
| 187 | + * @see parent::do_direct_payment |
|
| 188 | + * } |
|
| 189 | + * @return EEI_Payment updated |
|
| 190 | + */ |
|
| 191 | + public function do_direct_payment($payment, $billing_info = null) |
|
| 192 | + { |
|
| 193 | + add_filter('FHEE__EEG_Aim___get_server_url', array($this, 'possibly_use_deprecated_aim_server'), 10, 2); |
|
| 194 | + // Enable test mode if needed |
|
| 195 | + // 4007000000027 <-- test successful visa |
|
| 196 | + // 4222222222222 <-- test failure card number |
|
| 197 | + |
|
| 198 | + $item_num = 1; |
|
| 199 | + $transaction = $payment->transaction(); |
|
| 200 | + $gateway_formatter = $this->_get_gateway_formatter(); |
|
| 201 | + $order_description = $this->prepareStringForAuthnet($gateway_formatter->formatOrderDescription($payment)); |
|
| 202 | + $primary_registrant = $transaction->primary_registration(); |
|
| 203 | + // if we're are charging for the full amount, show the normal line items |
|
| 204 | + // and the itemized total adds up properly |
|
| 205 | + if ($this->_can_easily_itemize_transaction_for($payment)) { |
|
| 206 | + $total_line_item = $transaction->total_line_item(); |
|
| 207 | + foreach ($total_line_item->get_items() as $line_item) { |
|
| 208 | + if ($line_item->quantity() == 0) { |
|
| 209 | + continue; |
|
| 210 | + } |
|
| 211 | + $this->addLineItem( |
|
| 212 | + $item_num++, |
|
| 213 | + $gateway_formatter->formatLineItemName($line_item, $payment), |
|
| 214 | + $gateway_formatter->formatLineItemDesc($line_item, $payment), |
|
| 215 | + $line_item->quantity(), |
|
| 216 | + $line_item->unit_price(), |
|
| 217 | + 'N' |
|
| 218 | + ); |
|
| 219 | + $order_description .= $this->prepareStringForAuthnet($line_item->desc()) . ', '; |
|
| 220 | + } |
|
| 221 | + foreach ($total_line_item->tax_descendants() as $tax_line_item) { |
|
| 222 | + $this->addLineItem( |
|
| 223 | + $item_num++, |
|
| 224 | + $tax_line_item->name(), |
|
| 225 | + $tax_line_item->desc(), |
|
| 226 | + 1, |
|
| 227 | + $tax_line_item->total(), |
|
| 228 | + 'N' |
|
| 229 | + ); |
|
| 230 | + } |
|
| 231 | + } |
|
| 232 | + |
|
| 233 | + // start transaction |
|
| 234 | + // if in debug mode, use authorize.net's sandbox id; otherwise use the Event Espresso partner id |
|
| 235 | + $partner_id = $this->_debug_mode ? 'AAA100302' : 'AAA105363'; |
|
| 236 | + $this->setField('solution_id', $partner_id); |
|
| 237 | + $this->setField('amount', $gateway_formatter->formatCurrency($payment->amount())); |
|
| 238 | + $this->setField('description', substr(rtrim($order_description, ', '), 0, 255)); |
|
| 239 | + $this->_set_sensitive_billing_data($billing_info); |
|
| 240 | + $this->setField('first_name', $billing_info['first_name']); |
|
| 241 | + $this->setField('last_name', $billing_info['last_name']); |
|
| 242 | + $this->setField('email', $billing_info['email']); |
|
| 243 | + $this->setField('company', $billing_info['company']); |
|
| 244 | + $this->setField('address', $billing_info['address'].' '.$billing_info['address2']); |
|
| 245 | + $this->setField('city', $billing_info['city']); |
|
| 246 | + $this->setField('state', $billing_info['state']); |
|
| 247 | + $this->setField('country', $billing_info['country']); |
|
| 248 | + $this->setField('zip', $billing_info['zip']); |
|
| 249 | + $this->setField('fax', $billing_info['fax']); |
|
| 250 | + $this->setField('cust_id', $primary_registrant->ID()); |
|
| 251 | + $this->setField('phone', $billing_info['phone']); |
|
| 252 | + $currency_config = LoaderFactory::getLoader()->load('EE_Currency_Config'); |
|
| 253 | + $this->setField('currency_code', $currency_config->code); |
|
| 254 | + // invoice_num would be nice to have it be unique per SPCO page-load, that way if users |
|
| 255 | + // press back, they don't submit a duplicate. However, we may be keeping the user on teh same spco page |
|
| 256 | + // in which case, we need to generate teh invoice num per request right here... |
|
| 257 | + $this->setField('invoice_num', wp_generate_password(12, false));// $billing_info['_reg-page-billing-invoice-'.$this->_gateway_name]['value']); |
|
| 258 | + // tell AIM that any duplicates sent in the next 5 minutes are to be ignored |
|
| 259 | + $this->setField('duplicate_window', 5 * MINUTE_IN_SECONDS); |
|
| 260 | + |
|
| 261 | + if ($this->_test_transactions) { |
|
| 262 | + $this->test_request = "true"; |
|
| 263 | + } |
|
| 264 | + |
|
| 265 | + // Capture response |
|
| 266 | + $this->type = "AUTH_CAPTURE"; |
|
| 267 | + $response = $this->_sendRequest($payment); |
|
| 268 | + if (! empty($response)) { |
|
| 269 | + if ($response->error_message) { |
|
| 270 | + $payment->set_status($this->_pay_model->failed_status()); |
|
| 271 | + $payment->set_gateway_response($response->error_message); |
|
| 272 | + } else { |
|
| 273 | + $payment_status = $response->approved |
|
| 274 | + ? $this->_pay_model->approved_status() |
|
| 275 | + : $this->_pay_model->declined_status(); |
|
| 276 | + $payment->set_status($payment_status); |
|
| 277 | + // make sure we interpret the AMT as a float, not an international string (where periods are thousand separators) |
|
| 278 | + $payment->set_amount((float) $response->amount); |
|
| 279 | + $payment->set_gateway_response( |
|
| 280 | + sprintf( |
|
| 281 | + esc_html__('%1$s (Reason Code: %2$s)', 'event_espresso'), |
|
| 282 | + $response->response_reason_text, |
|
| 283 | + $response->response_reason_code |
|
| 284 | + ) |
|
| 285 | + ); |
|
| 286 | + if ($this->_debug_mode) { |
|
| 287 | + $txn_id = $response->invoice_number; |
|
| 288 | + } else { |
|
| 289 | + $txn_id = $response->transaction_id; |
|
| 290 | + } |
|
| 291 | + $payment->set_txn_id_chq_nmbr($txn_id); |
|
| 292 | + } |
|
| 293 | + $payment->set_extra_accntng($primary_registrant->reg_code()); |
|
| 294 | + $payment->set_details(print_r($response, true)); |
|
| 295 | + } else { |
|
| 296 | + $payment->set_status($this->_pay_model->failed_status()); |
|
| 297 | + $payment->set_gateway_response(__("There was no response from Authorize.net", 'event_espresso')); |
|
| 298 | + $payment->set_details(print_r($response, true)); |
|
| 299 | + } |
|
| 300 | + return $payment; |
|
| 301 | + } |
|
| 302 | + |
|
| 303 | + |
|
| 304 | + /** |
|
| 305 | + * Sets billing data for the upcoming request to AIM that is considered sensitive; |
|
| 306 | + * also this method can be overridden by children classes to easily change |
|
| 307 | + * what billing data gets sent |
|
| 308 | + * |
|
| 309 | + * @param array $billing_info |
|
| 310 | + */ |
|
| 311 | + protected function _set_sensitive_billing_data($billing_info) |
|
| 312 | + { |
|
| 313 | + $this->setField('card_num', $billing_info['credit_card']); |
|
| 314 | + $this->setField('exp_date', $billing_info['exp_month'] . $billing_info['exp_year']); |
|
| 315 | + $this->setField('card_code', $billing_info['cvv']); |
|
| 316 | + } |
|
| 317 | + |
|
| 318 | + |
|
| 319 | + /** |
|
| 320 | + * Add a line item. |
|
| 321 | + * |
|
| 322 | + * @param string $item_id |
|
| 323 | + * @param string $item_name |
|
| 324 | + * @param string $item_description |
|
| 325 | + * @param string $item_quantity |
|
| 326 | + * @param string $item_unit_price |
|
| 327 | + * @param string $item_taxable |
|
| 328 | + */ |
|
| 329 | + public function addLineItem($item_id, $item_name, $item_description, $item_quantity, $item_unit_price, $item_taxable) |
|
| 330 | + { |
|
| 331 | + $args = array( |
|
| 332 | + substr($item_id, 0, 31), |
|
| 333 | + substr($this->prepareStringForAuthnet($item_name), 0, 31), |
|
| 334 | + substr($this->prepareStringForAuthnet($item_description), 0, 255), |
|
| 335 | + number_format(abs($item_quantity), 2, '.', ''), |
|
| 336 | + number_format(abs($item_unit_price), 2, '.', ''), |
|
| 337 | + $item_taxable === 'N' ? 'N' : 'Y' |
|
| 338 | + ); |
|
| 339 | + $this->_additional_line_items[] = implode('<|>', $args); |
|
| 340 | + } |
|
| 341 | + |
|
| 342 | + |
|
| 343 | + /** |
|
| 344 | + * Set an individual name/value pair. This will append x_ to the name |
|
| 345 | + * before posting. |
|
| 346 | + * |
|
| 347 | + * @param string $name |
|
| 348 | + * @param string $value |
|
| 349 | + * @throws AuthorizeNetException |
|
| 350 | + */ |
|
| 351 | + protected function setField($name, $value) |
|
| 352 | + { |
|
| 353 | + if (in_array($name, $this->_all_aim_fields)) { |
|
| 354 | + $this->_x_post_fields[ $name ] = $value; |
|
| 355 | + } else { |
|
| 356 | + throw new AuthorizeNetException("Error: no field $name exists in the AIM API. |
|
| 357 | 357 | To set a custom field use setCustomField('field','value') instead."); |
| 358 | - } |
|
| 359 | - } |
|
| 360 | - |
|
| 361 | - |
|
| 362 | - /** |
|
| 363 | - * Posts the request to AuthorizeNet & returns response. |
|
| 364 | - * |
|
| 365 | - * @param $payment |
|
| 366 | - * @return \EE_AuthorizeNetAIM_Response |
|
| 367 | - */ |
|
| 368 | - private function _sendRequest($payment) |
|
| 369 | - { |
|
| 370 | - $this->_x_post_fields['login'] = $this->_login_id; |
|
| 371 | - $this->_x_post_fields['tran_key'] = $this->_transaction_key; |
|
| 372 | - $x_keys = array(); |
|
| 373 | - foreach ($this->_x_post_fields as $key => $value) { |
|
| 374 | - $x_keys[] = "x_$key=" . urlencode($this->_get_unsupported_character_remover()->format($value)); |
|
| 375 | - } |
|
| 376 | - // Add line items |
|
| 377 | - foreach ($this->_additional_line_items as $key => $value) { |
|
| 378 | - $x_keys[] = "x_line_item=" . urlencode($this->_get_unsupported_character_remover()->format($value)); |
|
| 379 | - } |
|
| 380 | - $this->_log_clean_request($x_keys, $payment); |
|
| 381 | - $post_url = $this->_get_server_url(); |
|
| 382 | - $curl_request = curl_init($post_url); |
|
| 383 | - $post_body = implode("&", $x_keys); |
|
| 384 | - curl_setopt($curl_request, CURLOPT_POSTFIELDS, $post_body); |
|
| 385 | - curl_setopt($curl_request, CURLOPT_HEADER, 0); |
|
| 386 | - curl_setopt($curl_request, CURLOPT_TIMEOUT, 45); |
|
| 387 | - curl_setopt($curl_request, CURLOPT_RETURNTRANSFER, 1); |
|
| 388 | - curl_setopt($curl_request, CURLOPT_SSL_VERIFYHOST, 2); |
|
| 389 | - if ($this->VERIFY_PEER) { |
|
| 390 | - curl_setopt($curl_request, CURLOPT_CAINFO, dirname(__DIR__) . '/ssl/cert.pem'); |
|
| 391 | - } else { |
|
| 392 | - curl_setopt($curl_request, CURLOPT_SSL_VERIFYPEER, false); |
|
| 393 | - } |
|
| 394 | - |
|
| 395 | - if (preg_match('/xml/', $post_url)) { |
|
| 396 | - curl_setopt($curl_request, CURLOPT_HTTPHEADER, array("Content-Type: text/xml")); |
|
| 397 | - } |
|
| 398 | - |
|
| 399 | - $response = curl_exec($curl_request); |
|
| 400 | - |
|
| 401 | - curl_close($curl_request); |
|
| 402 | - $response_obj = new EE_AuthorizeNetAIM_Response($response); |
|
| 403 | - |
|
| 404 | - return $this->_log_and_clean_response($response_obj, $payment); |
|
| 405 | - } |
|
| 406 | - |
|
| 407 | - |
|
| 408 | - /** |
|
| 409 | - * Logs the clean data only |
|
| 410 | - * |
|
| 411 | - * @param array $request_array |
|
| 412 | - * @param EEI_Payment $payment |
|
| 413 | - */ |
|
| 414 | - protected function _log_clean_request($request_array, $payment) |
|
| 415 | - { |
|
| 416 | - $keys_to_filter_out = array('x_card_num', 'x_card_code', 'x_exp_date'); |
|
| 417 | - foreach ($request_array as $index => $keyvaltogether) { |
|
| 418 | - foreach ($keys_to_filter_out as $key) { |
|
| 419 | - if (strpos($keyvaltogether, $key) === 0) { |
|
| 420 | - // found it at the first character |
|
| 421 | - // so its one of them |
|
| 422 | - unset($request_array[ $index ]); |
|
| 423 | - } |
|
| 424 | - } |
|
| 425 | - } |
|
| 426 | - $this->log( |
|
| 427 | - array( |
|
| 428 | - 'AIM Request sent:' => $request_array, |
|
| 429 | - 'Server URL' => $this->_get_server_url() |
|
| 430 | - ), |
|
| 431 | - $payment |
|
| 432 | - ); |
|
| 433 | - } |
|
| 434 | - |
|
| 435 | - |
|
| 436 | - |
|
| 437 | - /** |
|
| 438 | - * Logs the response and cleans it |
|
| 439 | - * |
|
| 440 | - * @param EE_AuthorizeNetAIM_Response $response_obj |
|
| 441 | - * @param EE_Payment $payment |
|
| 442 | - * @return \EE_AuthorizeNetAIM_Response |
|
| 443 | - */ |
|
| 444 | - private function _log_and_clean_response($response_obj, $payment) |
|
| 445 | - { |
|
| 446 | - $response_obj->account_number = ''; |
|
| 447 | - $this->log(array('AIM Response received:' => (array) $response_obj), $payment); |
|
| 448 | - return $response_obj; |
|
| 449 | - } |
|
| 450 | - |
|
| 451 | - /** |
|
| 452 | - * Removes characters Authorize.net doesn't handle well. |
|
| 453 | - * @since $VID:$ |
|
| 454 | - * @param $text |
|
| 455 | - * @return string |
|
| 456 | - */ |
|
| 457 | - private function prepareStringForAuthnet($text) |
|
| 458 | - { |
|
| 459 | - return str_replace( |
|
| 460 | - ['\''], |
|
| 461 | - [''], |
|
| 462 | - $text |
|
| 463 | - ); |
|
| 464 | - } |
|
| 358 | + } |
|
| 359 | + } |
|
| 360 | + |
|
| 361 | + |
|
| 362 | + /** |
|
| 363 | + * Posts the request to AuthorizeNet & returns response. |
|
| 364 | + * |
|
| 365 | + * @param $payment |
|
| 366 | + * @return \EE_AuthorizeNetAIM_Response |
|
| 367 | + */ |
|
| 368 | + private function _sendRequest($payment) |
|
| 369 | + { |
|
| 370 | + $this->_x_post_fields['login'] = $this->_login_id; |
|
| 371 | + $this->_x_post_fields['tran_key'] = $this->_transaction_key; |
|
| 372 | + $x_keys = array(); |
|
| 373 | + foreach ($this->_x_post_fields as $key => $value) { |
|
| 374 | + $x_keys[] = "x_$key=" . urlencode($this->_get_unsupported_character_remover()->format($value)); |
|
| 375 | + } |
|
| 376 | + // Add line items |
|
| 377 | + foreach ($this->_additional_line_items as $key => $value) { |
|
| 378 | + $x_keys[] = "x_line_item=" . urlencode($this->_get_unsupported_character_remover()->format($value)); |
|
| 379 | + } |
|
| 380 | + $this->_log_clean_request($x_keys, $payment); |
|
| 381 | + $post_url = $this->_get_server_url(); |
|
| 382 | + $curl_request = curl_init($post_url); |
|
| 383 | + $post_body = implode("&", $x_keys); |
|
| 384 | + curl_setopt($curl_request, CURLOPT_POSTFIELDS, $post_body); |
|
| 385 | + curl_setopt($curl_request, CURLOPT_HEADER, 0); |
|
| 386 | + curl_setopt($curl_request, CURLOPT_TIMEOUT, 45); |
|
| 387 | + curl_setopt($curl_request, CURLOPT_RETURNTRANSFER, 1); |
|
| 388 | + curl_setopt($curl_request, CURLOPT_SSL_VERIFYHOST, 2); |
|
| 389 | + if ($this->VERIFY_PEER) { |
|
| 390 | + curl_setopt($curl_request, CURLOPT_CAINFO, dirname(__DIR__) . '/ssl/cert.pem'); |
|
| 391 | + } else { |
|
| 392 | + curl_setopt($curl_request, CURLOPT_SSL_VERIFYPEER, false); |
|
| 393 | + } |
|
| 394 | + |
|
| 395 | + if (preg_match('/xml/', $post_url)) { |
|
| 396 | + curl_setopt($curl_request, CURLOPT_HTTPHEADER, array("Content-Type: text/xml")); |
|
| 397 | + } |
|
| 398 | + |
|
| 399 | + $response = curl_exec($curl_request); |
|
| 400 | + |
|
| 401 | + curl_close($curl_request); |
|
| 402 | + $response_obj = new EE_AuthorizeNetAIM_Response($response); |
|
| 403 | + |
|
| 404 | + return $this->_log_and_clean_response($response_obj, $payment); |
|
| 405 | + } |
|
| 406 | + |
|
| 407 | + |
|
| 408 | + /** |
|
| 409 | + * Logs the clean data only |
|
| 410 | + * |
|
| 411 | + * @param array $request_array |
|
| 412 | + * @param EEI_Payment $payment |
|
| 413 | + */ |
|
| 414 | + protected function _log_clean_request($request_array, $payment) |
|
| 415 | + { |
|
| 416 | + $keys_to_filter_out = array('x_card_num', 'x_card_code', 'x_exp_date'); |
|
| 417 | + foreach ($request_array as $index => $keyvaltogether) { |
|
| 418 | + foreach ($keys_to_filter_out as $key) { |
|
| 419 | + if (strpos($keyvaltogether, $key) === 0) { |
|
| 420 | + // found it at the first character |
|
| 421 | + // so its one of them |
|
| 422 | + unset($request_array[ $index ]); |
|
| 423 | + } |
|
| 424 | + } |
|
| 425 | + } |
|
| 426 | + $this->log( |
|
| 427 | + array( |
|
| 428 | + 'AIM Request sent:' => $request_array, |
|
| 429 | + 'Server URL' => $this->_get_server_url() |
|
| 430 | + ), |
|
| 431 | + $payment |
|
| 432 | + ); |
|
| 433 | + } |
|
| 434 | + |
|
| 435 | + |
|
| 436 | + |
|
| 437 | + /** |
|
| 438 | + * Logs the response and cleans it |
|
| 439 | + * |
|
| 440 | + * @param EE_AuthorizeNetAIM_Response $response_obj |
|
| 441 | + * @param EE_Payment $payment |
|
| 442 | + * @return \EE_AuthorizeNetAIM_Response |
|
| 443 | + */ |
|
| 444 | + private function _log_and_clean_response($response_obj, $payment) |
|
| 445 | + { |
|
| 446 | + $response_obj->account_number = ''; |
|
| 447 | + $this->log(array('AIM Response received:' => (array) $response_obj), $payment); |
|
| 448 | + return $response_obj; |
|
| 449 | + } |
|
| 450 | + |
|
| 451 | + /** |
|
| 452 | + * Removes characters Authorize.net doesn't handle well. |
|
| 453 | + * @since $VID:$ |
|
| 454 | + * @param $text |
|
| 455 | + * @return string |
|
| 456 | + */ |
|
| 457 | + private function prepareStringForAuthnet($text) |
|
| 458 | + { |
|
| 459 | + return str_replace( |
|
| 460 | + ['\''], |
|
| 461 | + [''], |
|
| 462 | + $text |
|
| 463 | + ); |
|
| 464 | + } |
|
| 465 | 465 | } |
| 466 | 466 | |
| 467 | 467 | |
@@ -477,192 +477,192 @@ discard block |
||
| 477 | 477 | class EE_AuthorizeNetAIM_Response |
| 478 | 478 | { |
| 479 | 479 | |
| 480 | - const APPROVED = '1'; |
|
| 481 | - const DECLINED = '2'; |
|
| 482 | - const ERROR = '3'; |
|
| 483 | - const HELD = '4'; |
|
| 484 | - |
|
| 485 | - protected $_x_post_fields = array( |
|
| 486 | - "version" => "3.1", |
|
| 487 | - "delim_char" => ",", |
|
| 488 | - "delim_data" => "TRUE", |
|
| 489 | - "relay_response" => "FALSE", |
|
| 490 | - "encap_char" => "|", |
|
| 491 | - ); |
|
| 492 | - public $approved; |
|
| 493 | - public $declined; |
|
| 494 | - public $error; |
|
| 495 | - public $held; |
|
| 496 | - public $response_code; |
|
| 497 | - public $response_subcode; |
|
| 498 | - public $response_reason_code; |
|
| 499 | - public $response_reason_text; |
|
| 500 | - public $authorization_code; |
|
| 501 | - public $avs_response; |
|
| 502 | - public $transaction_id; |
|
| 503 | - public $invoice_number; |
|
| 504 | - public $description; |
|
| 505 | - public $amount; |
|
| 506 | - public $method; |
|
| 507 | - public $transaction_type; |
|
| 508 | - public $customer_id; |
|
| 509 | - public $first_name; |
|
| 510 | - public $last_name; |
|
| 511 | - public $company; |
|
| 512 | - public $address; |
|
| 513 | - public $city; |
|
| 514 | - public $state; |
|
| 515 | - public $zip_code; |
|
| 516 | - public $country; |
|
| 517 | - public $phone; |
|
| 518 | - public $fax; |
|
| 519 | - public $email_address; |
|
| 520 | - public $ship_to_first_name; |
|
| 521 | - public $ship_to_last_name; |
|
| 522 | - public $ship_to_company; |
|
| 523 | - public $ship_to_address; |
|
| 524 | - public $ship_to_city; |
|
| 525 | - public $ship_to_state; |
|
| 526 | - public $ship_to_zip_code; |
|
| 527 | - public $ship_to_country; |
|
| 528 | - public $tax; |
|
| 529 | - public $duty; |
|
| 530 | - public $freight; |
|
| 531 | - public $tax_exempt; |
|
| 532 | - public $purchase_order_number; |
|
| 533 | - public $md5_hash; |
|
| 534 | - public $card_code_response; |
|
| 535 | - public $cavv_response; // cardholder_authentication_verification_response |
|
| 536 | - public $account_number; |
|
| 537 | - public $card_type; |
|
| 538 | - public $split_tender_id; |
|
| 539 | - public $requested_amount; |
|
| 540 | - public $balance_on_card; |
|
| 541 | - public $response; // The response string from AuthorizeNet. |
|
| 542 | - public $error_message; |
|
| 543 | - private $_response_array = array(); // An array with the split response. |
|
| 544 | - |
|
| 545 | - |
|
| 546 | - /** |
|
| 547 | - * Constructor. Parses the AuthorizeNet response string |
|
| 548 | - * |
|
| 549 | - * @param string $response The response from the AuthNet server. |
|
| 550 | - * @var string $delimiter The delimiter used (default is ",") |
|
| 551 | - * @var string $encap_char The encap_char used (default is "|") |
|
| 552 | - * @var array $custom_fields Any custom fields set in the request. |
|
| 553 | - */ |
|
| 554 | - |
|
| 555 | - public function __construct($response) |
|
| 556 | - { |
|
| 557 | - $encap_char = $this->_x_post_fields['encap_char']; |
|
| 558 | - $delimiter = $this->_x_post_fields['delim_char']; |
|
| 559 | - if ($response) { |
|
| 560 | - // Split Array |
|
| 561 | - $this->response = $response; |
|
| 562 | - if ($encap_char) { |
|
| 563 | - $this->_response_array = explode($encap_char . $delimiter . $encap_char, substr($response, 1, -1)); |
|
| 564 | - } else { |
|
| 565 | - $this->_response_array = explode($delimiter, $response); |
|
| 566 | - } |
|
| 567 | - |
|
| 568 | - /** |
|
| 569 | - * If AuthorizeNet doesn't return a delimited response. |
|
| 570 | - */ |
|
| 571 | - if (count($this->_response_array) < 10) { |
|
| 572 | - $this->approved = false; |
|
| 573 | - $this->error = true; |
|
| 574 | - $this->error_message = sprintf( |
|
| 575 | - esc_html__('Unrecognized response from Authorize.net: %1$s', 'event_espresso'), |
|
| 576 | - esc_html($response) |
|
| 577 | - ); |
|
| 578 | - return; |
|
| 579 | - } |
|
| 580 | - |
|
| 581 | - |
|
| 582 | - |
|
| 583 | - // Set all fields |
|
| 584 | - $this->response_code = $this->_response_array[0]; |
|
| 585 | - $this->response_subcode = $this->_response_array[1]; |
|
| 586 | - $this->response_reason_code = $this->_response_array[2]; |
|
| 587 | - $this->response_reason_text = $this->_response_array[3]; |
|
| 588 | - $this->authorization_code = $this->_response_array[4]; |
|
| 589 | - $this->avs_response = $this->_response_array[5]; |
|
| 590 | - $this->transaction_id = $this->_response_array[6]; |
|
| 591 | - $this->invoice_number = $this->_response_array[7]; |
|
| 592 | - $this->description = $this->_response_array[8]; |
|
| 593 | - $this->amount = $this->_response_array[9]; |
|
| 594 | - $this->method = $this->_response_array[10]; |
|
| 595 | - $this->transaction_type = $this->_response_array[11]; |
|
| 596 | - $this->customer_id = $this->_response_array[12]; |
|
| 597 | - $this->first_name = $this->_response_array[13]; |
|
| 598 | - $this->last_name = $this->_response_array[14]; |
|
| 599 | - $this->company = $this->_response_array[15]; |
|
| 600 | - $this->address = $this->_response_array[16]; |
|
| 601 | - $this->city = $this->_response_array[17]; |
|
| 602 | - $this->state = $this->_response_array[18]; |
|
| 603 | - $this->zip_code = $this->_response_array[19]; |
|
| 604 | - $this->country = $this->_response_array[20]; |
|
| 605 | - $this->phone = $this->_response_array[21]; |
|
| 606 | - $this->fax = $this->_response_array[22]; |
|
| 607 | - $this->email_address = $this->_response_array[23]; |
|
| 608 | - $this->ship_to_first_name = $this->_response_array[24]; |
|
| 609 | - $this->ship_to_last_name = $this->_response_array[25]; |
|
| 610 | - $this->ship_to_company = $this->_response_array[26]; |
|
| 611 | - $this->ship_to_address = $this->_response_array[27]; |
|
| 612 | - $this->ship_to_city = $this->_response_array[28]; |
|
| 613 | - $this->ship_to_state = $this->_response_array[29]; |
|
| 614 | - $this->ship_to_zip_code = $this->_response_array[30]; |
|
| 615 | - $this->ship_to_country = $this->_response_array[31]; |
|
| 616 | - $this->tax = $this->_response_array[32]; |
|
| 617 | - $this->duty = $this->_response_array[33]; |
|
| 618 | - $this->freight = $this->_response_array[34]; |
|
| 619 | - $this->tax_exempt = $this->_response_array[35]; |
|
| 620 | - $this->purchase_order_number = $this->_response_array[36]; |
|
| 621 | - $this->md5_hash = $this->_response_array[37]; |
|
| 622 | - $this->card_code_response = $this->_response_array[38]; |
|
| 623 | - $this->cavv_response = $this->_response_array[39]; |
|
| 624 | - $this->account_number = $this->_response_array[50]; |
|
| 625 | - $this->card_type = $this->_response_array[51]; |
|
| 626 | - $this->split_tender_id = $this->_response_array[52]; |
|
| 627 | - $this->requested_amount = $this->_response_array[53]; |
|
| 628 | - $this->balance_on_card = $this->_response_array[54]; |
|
| 629 | - |
|
| 630 | - $this->approved = ($this->response_code === self::APPROVED); |
|
| 631 | - $this->declined = ($this->response_code === self::DECLINED); |
|
| 632 | - $this->error = ($this->response_code === self::ERROR); |
|
| 633 | - $this->held = ($this->response_code === self::HELD); |
|
| 634 | - } else { |
|
| 635 | - $this->approved = false; |
|
| 636 | - $this->error = true; |
|
| 637 | - $this->error_message = esc_html__( |
|
| 638 | - 'Error connecting to Authorize.net', |
|
| 639 | - 'event_espresso' |
|
| 640 | - ); |
|
| 641 | - } |
|
| 642 | - } |
|
| 480 | + const APPROVED = '1'; |
|
| 481 | + const DECLINED = '2'; |
|
| 482 | + const ERROR = '3'; |
|
| 483 | + const HELD = '4'; |
|
| 484 | + |
|
| 485 | + protected $_x_post_fields = array( |
|
| 486 | + "version" => "3.1", |
|
| 487 | + "delim_char" => ",", |
|
| 488 | + "delim_data" => "TRUE", |
|
| 489 | + "relay_response" => "FALSE", |
|
| 490 | + "encap_char" => "|", |
|
| 491 | + ); |
|
| 492 | + public $approved; |
|
| 493 | + public $declined; |
|
| 494 | + public $error; |
|
| 495 | + public $held; |
|
| 496 | + public $response_code; |
|
| 497 | + public $response_subcode; |
|
| 498 | + public $response_reason_code; |
|
| 499 | + public $response_reason_text; |
|
| 500 | + public $authorization_code; |
|
| 501 | + public $avs_response; |
|
| 502 | + public $transaction_id; |
|
| 503 | + public $invoice_number; |
|
| 504 | + public $description; |
|
| 505 | + public $amount; |
|
| 506 | + public $method; |
|
| 507 | + public $transaction_type; |
|
| 508 | + public $customer_id; |
|
| 509 | + public $first_name; |
|
| 510 | + public $last_name; |
|
| 511 | + public $company; |
|
| 512 | + public $address; |
|
| 513 | + public $city; |
|
| 514 | + public $state; |
|
| 515 | + public $zip_code; |
|
| 516 | + public $country; |
|
| 517 | + public $phone; |
|
| 518 | + public $fax; |
|
| 519 | + public $email_address; |
|
| 520 | + public $ship_to_first_name; |
|
| 521 | + public $ship_to_last_name; |
|
| 522 | + public $ship_to_company; |
|
| 523 | + public $ship_to_address; |
|
| 524 | + public $ship_to_city; |
|
| 525 | + public $ship_to_state; |
|
| 526 | + public $ship_to_zip_code; |
|
| 527 | + public $ship_to_country; |
|
| 528 | + public $tax; |
|
| 529 | + public $duty; |
|
| 530 | + public $freight; |
|
| 531 | + public $tax_exempt; |
|
| 532 | + public $purchase_order_number; |
|
| 533 | + public $md5_hash; |
|
| 534 | + public $card_code_response; |
|
| 535 | + public $cavv_response; // cardholder_authentication_verification_response |
|
| 536 | + public $account_number; |
|
| 537 | + public $card_type; |
|
| 538 | + public $split_tender_id; |
|
| 539 | + public $requested_amount; |
|
| 540 | + public $balance_on_card; |
|
| 541 | + public $response; // The response string from AuthorizeNet. |
|
| 542 | + public $error_message; |
|
| 543 | + private $_response_array = array(); // An array with the split response. |
|
| 544 | + |
|
| 545 | + |
|
| 546 | + /** |
|
| 547 | + * Constructor. Parses the AuthorizeNet response string |
|
| 548 | + * |
|
| 549 | + * @param string $response The response from the AuthNet server. |
|
| 550 | + * @var string $delimiter The delimiter used (default is ",") |
|
| 551 | + * @var string $encap_char The encap_char used (default is "|") |
|
| 552 | + * @var array $custom_fields Any custom fields set in the request. |
|
| 553 | + */ |
|
| 554 | + |
|
| 555 | + public function __construct($response) |
|
| 556 | + { |
|
| 557 | + $encap_char = $this->_x_post_fields['encap_char']; |
|
| 558 | + $delimiter = $this->_x_post_fields['delim_char']; |
|
| 559 | + if ($response) { |
|
| 560 | + // Split Array |
|
| 561 | + $this->response = $response; |
|
| 562 | + if ($encap_char) { |
|
| 563 | + $this->_response_array = explode($encap_char . $delimiter . $encap_char, substr($response, 1, -1)); |
|
| 564 | + } else { |
|
| 565 | + $this->_response_array = explode($delimiter, $response); |
|
| 566 | + } |
|
| 567 | + |
|
| 568 | + /** |
|
| 569 | + * If AuthorizeNet doesn't return a delimited response. |
|
| 570 | + */ |
|
| 571 | + if (count($this->_response_array) < 10) { |
|
| 572 | + $this->approved = false; |
|
| 573 | + $this->error = true; |
|
| 574 | + $this->error_message = sprintf( |
|
| 575 | + esc_html__('Unrecognized response from Authorize.net: %1$s', 'event_espresso'), |
|
| 576 | + esc_html($response) |
|
| 577 | + ); |
|
| 578 | + return; |
|
| 579 | + } |
|
| 580 | + |
|
| 581 | + |
|
| 582 | + |
|
| 583 | + // Set all fields |
|
| 584 | + $this->response_code = $this->_response_array[0]; |
|
| 585 | + $this->response_subcode = $this->_response_array[1]; |
|
| 586 | + $this->response_reason_code = $this->_response_array[2]; |
|
| 587 | + $this->response_reason_text = $this->_response_array[3]; |
|
| 588 | + $this->authorization_code = $this->_response_array[4]; |
|
| 589 | + $this->avs_response = $this->_response_array[5]; |
|
| 590 | + $this->transaction_id = $this->_response_array[6]; |
|
| 591 | + $this->invoice_number = $this->_response_array[7]; |
|
| 592 | + $this->description = $this->_response_array[8]; |
|
| 593 | + $this->amount = $this->_response_array[9]; |
|
| 594 | + $this->method = $this->_response_array[10]; |
|
| 595 | + $this->transaction_type = $this->_response_array[11]; |
|
| 596 | + $this->customer_id = $this->_response_array[12]; |
|
| 597 | + $this->first_name = $this->_response_array[13]; |
|
| 598 | + $this->last_name = $this->_response_array[14]; |
|
| 599 | + $this->company = $this->_response_array[15]; |
|
| 600 | + $this->address = $this->_response_array[16]; |
|
| 601 | + $this->city = $this->_response_array[17]; |
|
| 602 | + $this->state = $this->_response_array[18]; |
|
| 603 | + $this->zip_code = $this->_response_array[19]; |
|
| 604 | + $this->country = $this->_response_array[20]; |
|
| 605 | + $this->phone = $this->_response_array[21]; |
|
| 606 | + $this->fax = $this->_response_array[22]; |
|
| 607 | + $this->email_address = $this->_response_array[23]; |
|
| 608 | + $this->ship_to_first_name = $this->_response_array[24]; |
|
| 609 | + $this->ship_to_last_name = $this->_response_array[25]; |
|
| 610 | + $this->ship_to_company = $this->_response_array[26]; |
|
| 611 | + $this->ship_to_address = $this->_response_array[27]; |
|
| 612 | + $this->ship_to_city = $this->_response_array[28]; |
|
| 613 | + $this->ship_to_state = $this->_response_array[29]; |
|
| 614 | + $this->ship_to_zip_code = $this->_response_array[30]; |
|
| 615 | + $this->ship_to_country = $this->_response_array[31]; |
|
| 616 | + $this->tax = $this->_response_array[32]; |
|
| 617 | + $this->duty = $this->_response_array[33]; |
|
| 618 | + $this->freight = $this->_response_array[34]; |
|
| 619 | + $this->tax_exempt = $this->_response_array[35]; |
|
| 620 | + $this->purchase_order_number = $this->_response_array[36]; |
|
| 621 | + $this->md5_hash = $this->_response_array[37]; |
|
| 622 | + $this->card_code_response = $this->_response_array[38]; |
|
| 623 | + $this->cavv_response = $this->_response_array[39]; |
|
| 624 | + $this->account_number = $this->_response_array[50]; |
|
| 625 | + $this->card_type = $this->_response_array[51]; |
|
| 626 | + $this->split_tender_id = $this->_response_array[52]; |
|
| 627 | + $this->requested_amount = $this->_response_array[53]; |
|
| 628 | + $this->balance_on_card = $this->_response_array[54]; |
|
| 629 | + |
|
| 630 | + $this->approved = ($this->response_code === self::APPROVED); |
|
| 631 | + $this->declined = ($this->response_code === self::DECLINED); |
|
| 632 | + $this->error = ($this->response_code === self::ERROR); |
|
| 633 | + $this->held = ($this->response_code === self::HELD); |
|
| 634 | + } else { |
|
| 635 | + $this->approved = false; |
|
| 636 | + $this->error = true; |
|
| 637 | + $this->error_message = esc_html__( |
|
| 638 | + 'Error connecting to Authorize.net', |
|
| 639 | + 'event_espresso' |
|
| 640 | + ); |
|
| 641 | + } |
|
| 642 | + } |
|
| 643 | 643 | } |
| 644 | 644 | |
| 645 | 645 | if (! class_exists('AuthorizeNetException')) { |
| 646 | - /** |
|
| 647 | - * Class AuthorizeNetException |
|
| 648 | - * |
|
| 649 | - * @package AuthorizeNet |
|
| 650 | - */ |
|
| 651 | - class AuthorizeNetException extends Exception |
|
| 652 | - { |
|
| 653 | - |
|
| 654 | - /** |
|
| 655 | - * Construct the exception. Note: The message is NOT binary safe. |
|
| 656 | - * |
|
| 657 | - * @link http://php.net/manual/en/exception.construct.php |
|
| 658 | - * @param string $message [optional] The Exception message to throw. |
|
| 659 | - * @param int $code [optional] The Exception code. |
|
| 660 | - * @param Exception $previous [optional] The previous exception used for the exception chaining. Since 5.3.0 |
|
| 661 | - * @since 5.1.0 |
|
| 662 | - */ |
|
| 663 | - public function __construct($message = "", $code = 0, Exception $previous = null) |
|
| 664 | - { |
|
| 665 | - parent::__construct($message, $code, $previous); |
|
| 666 | - } |
|
| 667 | - } |
|
| 646 | + /** |
|
| 647 | + * Class AuthorizeNetException |
|
| 648 | + * |
|
| 649 | + * @package AuthorizeNet |
|
| 650 | + */ |
|
| 651 | + class AuthorizeNetException extends Exception |
|
| 652 | + { |
|
| 653 | + |
|
| 654 | + /** |
|
| 655 | + * Construct the exception. Note: The message is NOT binary safe. |
|
| 656 | + * |
|
| 657 | + * @link http://php.net/manual/en/exception.construct.php |
|
| 658 | + * @param string $message [optional] The Exception message to throw. |
|
| 659 | + * @param int $code [optional] The Exception code. |
|
| 660 | + * @param Exception $previous [optional] The previous exception used for the exception chaining. Since 5.3.0 |
|
| 661 | + * @since 5.1.0 |
|
| 662 | + */ |
|
| 663 | + public function __construct($message = "", $code = 0, Exception $previous = null) |
|
| 664 | + { |
|
| 665 | + parent::__construct($message, $code, $previous); |
|
| 666 | + } |
|
| 667 | + } |
|
| 668 | 668 | } |
@@ -216,7 +216,7 @@ discard block |
||
| 216 | 216 | $line_item->unit_price(), |
| 217 | 217 | 'N' |
| 218 | 218 | ); |
| 219 | - $order_description .= $this->prepareStringForAuthnet($line_item->desc()) . ', '; |
|
| 219 | + $order_description .= $this->prepareStringForAuthnet($line_item->desc()).', '; |
|
| 220 | 220 | } |
| 221 | 221 | foreach ($total_line_item->tax_descendants() as $tax_line_item) { |
| 222 | 222 | $this->addLineItem( |
@@ -254,7 +254,7 @@ discard block |
||
| 254 | 254 | // invoice_num would be nice to have it be unique per SPCO page-load, that way if users |
| 255 | 255 | // press back, they don't submit a duplicate. However, we may be keeping the user on teh same spco page |
| 256 | 256 | // in which case, we need to generate teh invoice num per request right here... |
| 257 | - $this->setField('invoice_num', wp_generate_password(12, false));// $billing_info['_reg-page-billing-invoice-'.$this->_gateway_name]['value']); |
|
| 257 | + $this->setField('invoice_num', wp_generate_password(12, false)); // $billing_info['_reg-page-billing-invoice-'.$this->_gateway_name]['value']); |
|
| 258 | 258 | // tell AIM that any duplicates sent in the next 5 minutes are to be ignored |
| 259 | 259 | $this->setField('duplicate_window', 5 * MINUTE_IN_SECONDS); |
| 260 | 260 | |
@@ -265,7 +265,7 @@ discard block |
||
| 265 | 265 | // Capture response |
| 266 | 266 | $this->type = "AUTH_CAPTURE"; |
| 267 | 267 | $response = $this->_sendRequest($payment); |
| 268 | - if (! empty($response)) { |
|
| 268 | + if ( ! empty($response)) { |
|
| 269 | 269 | if ($response->error_message) { |
| 270 | 270 | $payment->set_status($this->_pay_model->failed_status()); |
| 271 | 271 | $payment->set_gateway_response($response->error_message); |
@@ -311,7 +311,7 @@ discard block |
||
| 311 | 311 | protected function _set_sensitive_billing_data($billing_info) |
| 312 | 312 | { |
| 313 | 313 | $this->setField('card_num', $billing_info['credit_card']); |
| 314 | - $this->setField('exp_date', $billing_info['exp_month'] . $billing_info['exp_year']); |
|
| 314 | + $this->setField('exp_date', $billing_info['exp_month'].$billing_info['exp_year']); |
|
| 315 | 315 | $this->setField('card_code', $billing_info['cvv']); |
| 316 | 316 | } |
| 317 | 317 | |
@@ -351,7 +351,7 @@ discard block |
||
| 351 | 351 | protected function setField($name, $value) |
| 352 | 352 | { |
| 353 | 353 | if (in_array($name, $this->_all_aim_fields)) { |
| 354 | - $this->_x_post_fields[ $name ] = $value; |
|
| 354 | + $this->_x_post_fields[$name] = $value; |
|
| 355 | 355 | } else { |
| 356 | 356 | throw new AuthorizeNetException("Error: no field $name exists in the AIM API. |
| 357 | 357 | To set a custom field use setCustomField('field','value') instead."); |
@@ -371,11 +371,11 @@ discard block |
||
| 371 | 371 | $this->_x_post_fields['tran_key'] = $this->_transaction_key; |
| 372 | 372 | $x_keys = array(); |
| 373 | 373 | foreach ($this->_x_post_fields as $key => $value) { |
| 374 | - $x_keys[] = "x_$key=" . urlencode($this->_get_unsupported_character_remover()->format($value)); |
|
| 374 | + $x_keys[] = "x_$key=".urlencode($this->_get_unsupported_character_remover()->format($value)); |
|
| 375 | 375 | } |
| 376 | 376 | // Add line items |
| 377 | 377 | foreach ($this->_additional_line_items as $key => $value) { |
| 378 | - $x_keys[] = "x_line_item=" . urlencode($this->_get_unsupported_character_remover()->format($value)); |
|
| 378 | + $x_keys[] = "x_line_item=".urlencode($this->_get_unsupported_character_remover()->format($value)); |
|
| 379 | 379 | } |
| 380 | 380 | $this->_log_clean_request($x_keys, $payment); |
| 381 | 381 | $post_url = $this->_get_server_url(); |
@@ -387,7 +387,7 @@ discard block |
||
| 387 | 387 | curl_setopt($curl_request, CURLOPT_RETURNTRANSFER, 1); |
| 388 | 388 | curl_setopt($curl_request, CURLOPT_SSL_VERIFYHOST, 2); |
| 389 | 389 | if ($this->VERIFY_PEER) { |
| 390 | - curl_setopt($curl_request, CURLOPT_CAINFO, dirname(__DIR__) . '/ssl/cert.pem'); |
|
| 390 | + curl_setopt($curl_request, CURLOPT_CAINFO, dirname(__DIR__).'/ssl/cert.pem'); |
|
| 391 | 391 | } else { |
| 392 | 392 | curl_setopt($curl_request, CURLOPT_SSL_VERIFYPEER, false); |
| 393 | 393 | } |
@@ -399,7 +399,7 @@ discard block |
||
| 399 | 399 | $response = curl_exec($curl_request); |
| 400 | 400 | |
| 401 | 401 | curl_close($curl_request); |
| 402 | - $response_obj = new EE_AuthorizeNetAIM_Response($response); |
|
| 402 | + $response_obj = new EE_AuthorizeNetAIM_Response($response); |
|
| 403 | 403 | |
| 404 | 404 | return $this->_log_and_clean_response($response_obj, $payment); |
| 405 | 405 | } |
@@ -419,7 +419,7 @@ discard block |
||
| 419 | 419 | if (strpos($keyvaltogether, $key) === 0) { |
| 420 | 420 | // found it at the first character |
| 421 | 421 | // so its one of them |
| 422 | - unset($request_array[ $index ]); |
|
| 422 | + unset($request_array[$index]); |
|
| 423 | 423 | } |
| 424 | 424 | } |
| 425 | 425 | } |
@@ -560,7 +560,7 @@ discard block |
||
| 560 | 560 | // Split Array |
| 561 | 561 | $this->response = $response; |
| 562 | 562 | if ($encap_char) { |
| 563 | - $this->_response_array = explode($encap_char . $delimiter . $encap_char, substr($response, 1, -1)); |
|
| 563 | + $this->_response_array = explode($encap_char.$delimiter.$encap_char, substr($response, 1, -1)); |
|
| 564 | 564 | } else { |
| 565 | 565 | $this->_response_array = explode($delimiter, $response); |
| 566 | 566 | } |
@@ -642,7 +642,7 @@ discard block |
||
| 642 | 642 | } |
| 643 | 643 | } |
| 644 | 644 | |
| 645 | -if (! class_exists('AuthorizeNetException')) { |
|
| 645 | +if ( ! class_exists('AuthorizeNetException')) { |
|
| 646 | 646 | /** |
| 647 | 647 | * Class AuthorizeNetException |
| 648 | 648 | * |