cancel
Showing results for 
Search instead for 
Did you mean: 

AuthnetXML problem

I'm using AuthnetXML class from http://www.johnconde.net/blog/tutorial-integrate-authorize-net-xml-api-universal-php-class/ -- generally works great, but I have noticed a problem with creation of associative array which class then converts to XML. Usage examples show associative array creation like:

 

    $xml->createTransactionRequest(array(
        'refId' => rand(1000000, 100000000),
        'transactionRequest' => array(
            'transactionType' => 'authCaptureTransaction',
            'amount' => 5,
            'payment' => array(
                'creditCard' => array(
                    'cardNumber' => '4111111111111111',
                    'expirationDate' => '122016',
                    'cardCode' => '999',
                ),
            ),
            'order' => array(
                'invoiceNumber' => '1324567890',
                'description' => 'this is a test transaction',
            ),
            'lineItems' => array(
                'lineItem' => array(
                    'itemId' => '1',
                    'name' => 'vase',
                    'description' => 'Cannes logo',
                    'quantity' => '18',
                    'unitPrice' => '45.00',
                ),
            ),
            'tax' => array(
               'amount' => '4.26',
               'name' => 'level2 tax name',
               'description' => 'level2 tax',
            ),
            'duty' => array(
               'amount' => '8.55',
               'name' => 'duty name',
               'description' => 'duty description',
            ),
            'shipping' => array(
               'amount' => '4.26',
               'name' => 'level2 tax name',
               'description' => 'level2 tax',
            ),
            'poNumber' => '456654',
            'customer' => array(
               'id' => '18',
               'email' => 'someone@blackhole.tv',
            ),
            'billTo' => array(
               'firstName' => 'Ellen',
               'lastName' => 'Johnson',
               'company' => 'Souveniropolis',
               'address' => '14 Main Street',
               'city' => 'Pecan Springs',
               'state' => 'TX',
               'zip' => '44628',
               'country' => 'USA',
            ),
            'shipTo' => array(
               'firstName' => 'China',
               'lastName' => 'Bayles',
               'company' => 'Thyme for Tea',
               'address' => '12 Main Street',
               'city' => 'Pecan Springs',
               'state' => 'TX',
               'zip' => '44628',
               'country' => 'USA',
            ),
            'customerIP' => '192.168.1.1',
            'transactionSettings' => array(
                'setting' => array(
                    'settingName' => 'allowPartialAuth',
                    'settingValue' => 'false',
                ),
                'setting' => array(
                    'settingName' => 'duplicateWindow',
                    'settingValue' => '0',
                ),
                'setting' => array(
                    'settingName' => 'emailCustomer',
                    'settingValue' => 'false',
                ),
                'setting' => array(
                  'settingName' => 'recurringBilling',
                  'settingValue' => 'false',
                ),
                'setting' => array(
                    'settingName' => 'testRequest',
                    'settingValue' => 'false',
                ),
            ),
            'userFields' => array(
                'userField' => array(
                    'name' => 'MerchantDefinedFieldName1',
                    'value' => 'MerchantDefinedFieldValue1',
                ),
                'userField' => array(
                    'name' => 'favorite_color',
                    'value' => 'blue',
                ),
            ),
        ),
    ));

 

However, that results in XML to be submitted to Authorize.Net  like:

 

<createTransactionRequest xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">
  <merchantAuthentication>
    <name>yourloginid</name>
    <transactionKey>yourtransactionkey</transactionKey>
  </merchantAuthentication>
  <refId>92347199</refId>
  <transactionRequest>
    <transactionType>authCaptureTransaction</transactionType>
    <amount>5</amount>
    <payment>
      <creditCard>
        <cardNumber>5424000000000015</cardNumber>
        <expirationDate>122016</expirationDate>
        <cardCode>999</cardCode>
      </creditCard>
    </payment>
    <order>
        <invoiceNumber>1324567890</invoiceNumber>
        <description>this is a test transaction</description>
    </order>
    <lineItems>
      <lineItem>
        <itemId>1</itemId>
        <name>vase</name>
        <description>Cannes logo</description>
        <quantity>18</quantity>
        <unitPrice>45.00</unitPrice>
      </lineItem>
    </lineItems>
    <tax>
      <amount>4.26</amount>
      <name>level2 tax name</name>
      <description>level2 tax</description>
    </tax>
    <duty>
      <amount>8.55</amount>
      <name>duty name</name>
      <description>duty description</description>
    </duty>
    <shipping>
      <amount>4.26</amount>
      <name>level2 tax name</name>
      <description>level2 tax</description>
    </shipping>
    <poNumber>456654</poNumber>
    <customer>
      <id>18</id>
      <email>someone@blackhole.tv</email>
    </customer>
    <billTo>
      <firstName>Ellen</firstName>
      <lastName>Johnson</lastName>
      <company>Souveniropolis</company>
      <address>14 Main Street</address>
      <city>Pecan Springs</city>
      <state>TX</state>
      <zip>44628</zip>
      <country>USA</country>
    </billTo>
    <shipTo>
      <firstName>China</firstName>
      <lastName>Bayles</lastName>
      <company>Thyme for Tea</company>
      <address>12 Main Street</address>
      <city>Pecan Springs</city>
      <state>TX</state>
      <zip>44628</zip>
      <country>USA</country>
    </shipTo>
    <customerIP>192.168.1.1</customerIP>
    <transactionSettings>
      <setting>
        <settingName>testRequest</settingName>
        <settingValue>false</settingValue>
      </setting>
    </transactionSettings>
    <userFields>
      <userField>
        <name>favorite_color</name>
        <value>blue</value>
      </userField>
    </userFields>
  </transactionRequest>
</createTransactionRequest>

 

Notice there is only one setting element in XML and only one userField element in XML -- in each case only the last specified in associative array is created in XML. Can anyone advise how to fix?

 

2 REPLIES 2

The problem is that you can't have duplicate keys at the same level in and array. If you do the last one entered wins and the rest are overwritten.

 

So you need a way to represent repeating items from XML in and array. I decide to use the JSON methods to keep it simple. A quick wat to convert Simple XML to and array is to pass it through JSON.

 

$array = json_decode( json_encode( $simpleXML), true);

 

That will convert XML like this:

 

<transactionSettings>
  <setting>
    <settingName>allowPartialAuth</settingName>
    <settingValue>false</settingValue>
  </setting>
  <setting>
    <settingName>duplicateWindow</settingName>
    <settingValue>0</settingValue>
  </setting>
  <setting>
    <settingName>emailCustomer</settingName>
    <settingValue>false</settingValue>
  </setting>
  <setting>
    <settingName>recurringBilling</settingName>
    <settingValue>false</settingValue>
  </setting>
  <setting>
    <settingName>testRequest</settingName>
    <settingValue>false</settingValue>
  </setting>
</transactionSettings>

 

To an array like this:

 

array(
'transactionSettings' => array(  
  'setting' => array(
    0 => array('settingName' =>'allowPartialAuth' ,  'settingValue' => 'false',),
    1 => array('settingName' => 'duplicateWindow', 'settingValue' => '0', ),
    2 => array('settingName' => 'emailCustomer', 'settingValue' => 'false', ),
    3 => array('settingName' => 'recurringBilling', 'settingValue' => 'false',),
    4 => array( 'settingName' => 'testRequest', false, ),
  )
);

 

So you need to modify AuthNetXML.class to recognize this format. Just replace your setParameters() method with:

 

  private function setParameters($xml, $array)
  {
    if (is_array($array))
    {
      $first = true;

      foreach ($array as $key => $value)
      {
        if (is_array($value)) {

          if( is_numeric($key) )  {
            if($first){
              $xmlx = $xml;
              $first = false;
            } else {
              $parent = $xml->xpath('parent::*');
              $xmlx = $parent[0]->addChild($xml->getName());
            }

          } else {

            $xmlx = $xml->addChild($key);

          }
          
          $this->setParameters($xmlx, $value);
        }
        else
        {
          $xml->$key = $value;
        }
      }
    }
  }

 

 

 

 

arky
Member

A little more then a week ago I made a modification to the core code which addresses this issue. You can now addd as kany line items as you wasnt and they won't get lost. You can get the new code and working sample code from the AuthnetXML github repository.


-------------------------------------------------------------------------------------------------------------------------------------------
John Conde :: Certified Authorize.Net Developer (Brainyminds) :: Official Authorize.Net Blogger

NEW! Handling Authorize.Net's Webhooks with PHP

Integrate Every Authorize.Net JSON API with One PHP Class (Sample code included)

Tutorials for integrating Authorize.Net with PHP: AIM, ARB, CIM, Silent Post
All About Authorize.Net's Silent Post
stymiee
Expert
Expert