cancel
Showing results for 
Search instead for 
Did you mean: 

Convert from AIM to CIM

I have this cart and it uses the AIM method. I need to use the CIM.  Searching through allthe files there is only one file called Authorize.net.php  Below is the code on this page.

 

<?php

class AuthorizeNet extends GatewayFramework implements GatewayModule {

	var $cards = array("visa", "mc", "amex", "disc", "jcb", "dc");

	var $liveurl = 'https://secure.authorize.net/gateway/transact.dll';
	var $testurl = 'https://secure.authorize.net/gateway/transact.dll';

	function AuthorizeNet () {
		parent::__construct();
		$this->setup('login','password','testmode');
	}

	function actions () {
		add_action('mycart_process_order',array(&$this,'process'));
	}

	function process () {
		$transaction = $this->build();
		$Response = $this->send($transaction);
		if ($Response->code == '1') { // success
			$this->Order->transaction($this->txnid($Response),'CHARGED');
			return;
		} elseif ($Response->code == '4') { // flagged for merchant review or risk management
			$this->Order->transaction($this->txnid($Response),'PENDING');
			return;
		} else $this->error($Response);
	}

	function txnid ($Response) {
		if (empty($Response->transactionid)) return parent::txnid();
		return $Response->transactionid;
	}

	function error ($Response) {
		return new MycartError($Response->reason,'authorize_net_error',MYCART_TRXN_ERR,
			array('code'=>$Response->reasoncode));
	}

	function build () {
		$Order = $this->Order;
		$_ = array();

		// Options
		$_['x_test_request']		= ($this->settings['testmode'] == "on")?"TRUE":"FALSE"; // Set "TRUE" while testing
		$_['x_login'] 				= $this->settings['login'];
		$_['x_password'] 			= $this->settings['password'];
		$_['x_Delim_Data'] 			= "TRUE";
		$_['x_Delim_Char'] 			= ",";
		$_['x_Encap_Char'] 			= "";
		$_['x_version'] 			= "3.1";
		$_['x_relay_response']		= "FALSE";
		$_['x_type'] 				= "AUTH_ONLY";
		//= "AUTH_CAPTURE";
		$_['x_method']				= "CC";
		$_['x_email_customer']		= "FALSE";
		$_['x_merchant_email']		= $this->settings['merchant_email'];

		// Required Fields
		$_['x_amount']				= $Order->Cart->Totals->total;
		$_['x_customer_ip']			= $_SERVER["REMOTE_ADDR"];
		$_['x_fp_sequence']			= mktime();
		$_['x_fp_timestamp']		= time();
		// $_['x_fp_hash']				= hash_hmac("md5","{$_['x_login']}^{$_['x_fp_sequence']}^{$_['x_fp_timestamp']}^{$_['x_amount']}",$_['x_password']);

		// Customer Contact
		$_['x_first_name']			= $Order->Customer->firstname;
		$_['x_last_name']			= $Order->Customer->lastname;
		$_['x_email']				= $Order->Customer->email;
		$_['x_phone']				= $Order->Customer->phone;

		// Billing
		$_['x_card_num']			= $Order->Billing->card;
		$_['x_exp_date']			= date("my",$Order->Billing->cardexpires);
		$_['x_card_code']			= $Order->Billing->cvv;
		$_['x_address']				= $Order->Billing->address;
		$_['x_city']				= $Order->Billing->city;
		$_['x_state']				= $Order->Billing->state;
		$_['x_zip']					= $Order->Billing->postcode;
		$_['x_country']				= $Order->Billing->country;

		// Shipping
		$_['x_ship_to_first_name']  = $Order->Customer->firstname;
		$_['x_ship_to_last_name']	= $Order->Customer->lastname;
		$_['x_ship_to_address']		= $Order->Shipping->address;
		$_['x_ship_to_city']		= $Order->Shipping->city;
		$_['x_ship_to_state']		= $Order->Shipping->state;
		$_['x_ship_to_zip']			= $Order->Shipping->postcode;
		$_['x_ship_to_country']		= $Order->Shipping->country;

		// Transaction
		$_['x_freight']				= $Order->Cart->Totals->shipping;
		$_['x_tax']					= $Order->Cart->Totals->tax;

		// Line Items
		$i = 1;
		foreach($Order->Cart->contents as $Item) {
			$_['x_line_item'][] = ($i++)."<|>".substr($Item->name,0,31)."<|>".((sizeof($Item->options) > 1)?" (".substr($Item->option->label,0,253).")":"")."<|>".(int)$Item->quantity."<|>".number_format($Item->unitprice,$this->precision,'.','')."<|>".(($Item->tax)?"Y":"N");
		}

		return $this->encode($_);
	}

	function send ($data) {
		if ($this->settings['testmode'] == "on") $url = $this->testurl;
		else $url = $this->liveurl;
		$url = apply_filters('mycart_authorize_net_url',$url);
		return $this->response(parent::send($data,$url));
	}

	function response ($buffer) {
		$_ = new stdClass();

		list($_->code,
			 $_->subcode,
			 $_->reasoncode,
			 $_->reason,
			 $_->authcode,
			 $_->avs,
			 $_->transactionid,
			 $_->invoicenum,
			 $_->description,
			 $_->amount,
			 $_->method,
			 $_->type,
			 $_->customerid,
			 $_->firstname,
			 $_->lastname,
			 $_->company,
			 $_->address,
			 $_->city,
			 $_->state,
			 $_->zip,
			 $_->country,
			 $_->phone,
			 $_->fax,
			 $_->email,
			 $_->ship_to_first_name,
			 $_->ship_to_last_name,
			 $_->ship_to_company,
			 $_->ship_to_address,
			 $_->ship_to_city,
			 $_->ship_to_state,
			 $_->ship_to_zip,
			 $_->ship_to_country,
			 $_->tax,
			 $_->duty,
			 $_->freight,
			 $_->taxexempt,
			 $_->ponum,
			 $_->md5hash,
			 $_->cvv2code,
			 $_->cvv2response) = explode(",",$buffer);
		return $_;
	}

	function settings () {
		$this->ui->cardmenu(0,array(
			'name' => 'cards',
			'selected' => $this->settings['cards']
		),$this->cards);

		$this->ui->text(1,array(
			'name' => 'login',
			'value' => $this->settings['login'],
			'size' => '16',
			'label' => __('Enter your AuthorizeNet Login ID.','Mycart')
		));

		$this->ui->password(1,array(
			'name' => 'password',
			'value' => $this->settings['password'],
			'size' => '24',
			'label' => __('Enter your AuthorizeNet Password or Transaction Key.','Mycart')
		));

		$this->ui->checkbox(1,array(
			'name' => 'testmode',
			'checked' => $this->settings['testmode'],
			'label' => __('Enable test mode','Mycart')
		));

	}

} // END class AuthorizeNet

?>


 I was thinking I need to add the XML part to this page. Somehow to have it parse the XML.


//build xml to post
$content =
	"<?xml version=\"1.0\" encoding=\"utf-8\"?>" .
	"<createCustomerProfileTransactionRequest xmlns=\"AnetApi/xml/v1/schema/AnetApiSchema.xsd\">" .
	//MerchantAuthenticationBlock().
	"<transaction>".
	"<profileTransAuthOnly>".
	"<amount>" . $_['x_amount'] . "</amount>". // should include tax, shipping, and everything.
	"<shipping>".
	"<amount></amount>".
	"<name>Free Shipping</name>".
	"<description>Free UPS Ground shipping. Ships in 5-10 days.</description>".
	"</shipping>".
	"<lineItems>". $_['x_amount'] ."</lineItems>".
	//"<unitPrice>" . ($_POST["amount"] - 1.00) . "</unitPrice>".
	"<customerProfileId>12711484</customerProfileId>".
	"<customerPaymentProfileId>11714901</customerPaymentProfileId>".
	"<customerShippingAddressId>11804938</customerShippingAddressId>".
	"<order>".
	"<invoiceNumber>INV12345</invoiceNumber>".
	"</order>".
	"</profileTransAuthOnly>".
	"</transaction>".
	"</createCustomerProfileTransactionRequest>";

echo "Raw request: " . htmlspecialchars($content) . "<br><br>";
$response = send_xml_request($content);
echo "Raw response: " . htmlspecialchars($response) . "<br><br>";
$parsedresponse = parse_api_response($response);
if ("Ok" == $parsedresponse->messages->resultCode) {
	echo "A transaction was successfully created for customerProfileId <b>"
		. htmlspecialchars($_POST["customerProfileId"])
		. "</b>.<br><br>";
}
if (isset($parsedresponse->directResponse)) {
	echo "direct response: <br>"
		. htmlspecialchars($parsedresponse->directResponse)
		. "<br><br>";
		
	$directResponseFields = explode(",", $parsedresponse->directResponse);
	$responseCode = $directResponseFields[0]; // 1 = Approved 2 = Declined 3 = Error
	$responseReasonCode = $directResponseFields[2]; // See http://www.authorize.net/support/AIM_guide.pdf
	$responseReasonText = $directResponseFields[3];
	$approvalCode = $directResponseFields[4]; // Authorization code
	$transId = $directResponseFields[6];
	
	if ("1" == $responseCode) echo "The transaction was successful.<br>";
	else if ("2" == $responseCode) echo "The transaction was declined.<br>";
	else echo "The transaction resulted in an error.<br>";
	
	echo "responseReasonCode = " . htmlspecialchars($responseReasonCode) . "<br>";
	echo "responseReasonText = " . htmlspecialchars($responseReasonText) . "<br>";
	echo "approvalCode = " . htmlspecialchars($approvalCode) . "<br>";
	echo "transId = " . htmlspecialchars($transId) . "<br>";
}

echo "<br><a href=index.php?customerProfileId=" 
	. urlencode($_POST["customerProfileId"])
	. "&customerPaymentProfileId="
	. urlencode($_POST["customerPaymentProfileId"])
	. "&customerShippingAddressId="
	. urlencode($_POST["customerShippingAddressId"])
	. ">Continue</a><br>";

 

mallen
Regular Contributor
58 REPLIES 58

I added this:

curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, false);

and  I got an error back. ErrorE00003

So Iam getting closer. Does this mean the XML atleast sent?

mallen
Regular Contributor
<code>E00003</code>
      <text>The element 'createCustomerPaymentProfileRequest' in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd' has invalid child element 'shipToList' in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd'. List of possible elements expected: 'validationMode' in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd'.</text>
    </message>
  </messages>
mallen
Regular Contributor

Yes, it mean it got send to authorize.net.

the E00003 error mean the XML you send it not in the format authorize.net expected.

The sequence of the node is important. It look to me the xml have the shipToList is coming after the faxNumber, which is wrong. It should be after the bankName. See the XML documentation for detail

http://developer.authorize.net/api/cim/

Tried this. The validation mode was on it own line. Still getting same error.  Also the phone number was not in theis format (123)456-7829

 $xml = new AuthnetXML(AUTHNET_LOGIN, AUTHNET_TRANSKEY);
    $xml->createCustomerPaymentProfileRequest(array(
        'customerProfileId' => '666',
        'paymentProfile' => array(
            'billTo' => array(
                'firstName' => $Order->Customer->firstname,
                'lastName' => $Order->Customer->lastname,
                'address' => $Order->Billing->address,
                'city' => $Order->Billing->city,
                'state' => $Order->Billing->state,
                'zip' => $Order->Billing->postcode,
                'phoneNumber' => $Order->Customer->phone
            ),
            'payment' => array(
                'creditCard' => array(
                'cardNumber' => $Order->Billing->card,
               // 'expirationDate' => date("my",$Order->Billing->cardexpires)
				 'expirationDate' => '2013-08'
                ),
            ),
  ),
			'shipToList' => array(
     		        'firstName' => $Order->Customer->firstname,
			'lastName' => $Order->Customer->lastname,
			'address' => $Order->Shipping->address,
			'city' => $Order->Shipping->city,
			'state' => $Order->Shipping->state,
			'zip' => $Order->Shipping->postcode,
			'phoneNumber' => '(800)555-1234',
			'validationMode' => 'testMode'
   	),


));
		
echo $xml->messages->resultCode;
echo $xml->messages->message->code; echo $xml;

 

mallen
Regular Contributor

something doesn't look right, validationmode is for the whole call, not for each shiptolist.

Can you see what the xml you are sending?

XML:	

<?xml version="1.0"?>
<createCustomerPaymentProfileRequest>
  <merchantAuthentication>
    <name>xxxxxx</name>
    <transactionKey>xxxx</transactionKey>
  </merchantAuthentication>
  <profile>
    <merchantCustomerId>12347</merchantCustomerId>
    <email>user@example.com</email>
    <paymentProfiles>
      <billTo>
        <firstName>Joe</firstName>
        <lastName>Someone</lastName>
        <address>123 Some Place</address>
        <city>Some City</city>
        <state>Some State</state>
        <zip>99999</zip>
        <phoneNumber>1231234567</phoneNumber>
      </billTo>
      <payment>
        <creditCard>
          <cardNumber>5424000000000015</cardNumber>
          <expirationDate>2013-08</expirationDate>
        </creditCard>
      </payment>
    </paymentProfiles>
    <shipToList>
      <firstName>Joe</firstName>
      <lastName>Someone</lastName>
      <address>123 Some Place</address>
      <city>Some City</city>
      <state>Some State</state>
      <zip>99999</zip>
    </shipToList>
  </profile>
  <validationMode>liveMode</validationMode>
</createCustomerPaymentProfileRequest>

Response XML
XML:	

<?xml version="1.0" encoding="utf-8"?>
<ErrorResponse>
  <messages>
    <resultCode>Error</resultCode>
    <message>
      <code>E00003</code>
      <text>The element 'createCustomerPaymentProfileRequest' in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd' has invalid child element 'profile' in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd'. List of possible elements expected: 'refId, customerProfileId' in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd'.</text>
    </message>
  </messages>
</ErrorResponse>

 

mallen
Regular Contributor

I had createCustomerPaymentProfileRequest instead of createCustomerProfileRequest.

It sent and then gives me this error.

 

<?xml version="1.0" encoding="utf-8"?>
<createCustomerProfileResponse>
  <messages>
    <resultCode>Error</resultCode>
    <message>
      <code>E00007</code>
      <text>User authentication failed due to invalid authentication values.</text>
    </message>
  </messages>
</createCustomerProfileResponse>

 

mallen
Regular Contributor

If I remember it right, you are using a test account.  E00007 mean you are sending the XML to the production server. Need to change it to send to the test server.

Finally working. After 51 posts and 12 days. Thanks again to RaynorC1emen7 and especially John Conde for this tutorial and code. https://github.com/stymiee/Authorize.Net-XML  I had modified this line and had left off USE_DEVELOPMENT_SERVER and then I got the error that the account was in test mode. So atleast it is connecting and creating a profile. Now I will work on other parts such as transactions and integrating to my cart.

$xml = new AuthnetXML(AUTHNET_LOGIN, AUTHNET_TRANSKEY,AuthnetXML::USE_DEVELOPMENT_SERVER);

 

mallen
Regular Contributor