问题
First off thanks for writing this class. It has made life much easier for me in building applications.
I have CIM set up and I have no problem adding users, processing payments, etc. However I am stuck on adding line items. The examples on github use static population of the array used to create the XML request EX:
'lineItems' => array(
'itemId' => 'ITEM00001',
'name' => 'name of item sold',
'description' => 'Description of item sold',
'quantity' => '1',
'unitPrice' => '6.95',
'taxable' => 'true'
),
'lineItems' => array(
'itemId' => 'ITEM00002',
'name' => 'other name of item sold',
'description' => 'Description of other item sold',
'quantity' => '1',
'unitPrice' => '1.00',
'taxable' => 'true'
),
This works great if you are manually creating things but I am dynamically creating these line items based on user input. Unfortunately, I am unable do add multiple line items to the array due to the fact that the key ('lineItems') gets overwritten and I end up with one line item.
I have tried creating an array of lineItems and then merging it with no luck. Hopefully I am just missing a simple fix for this.
回答1:
Thanks for responding John! Once again, great work on this class it has made my life much easier.
Here is what I ended up doing for simplicity. I am sure this can be expounded upon if necessary, but for me this worked perfect. Instead of passing multiple line items on the same level of the array I created line items as their own array and then modified setParamaters() to iterate through that array.
private function setParameters($xml, $array)
{
if (is_array($array))
{
foreach ($array as $key => $value)
{
if (is_array($value))
{
if($key == 'lineItems'){
foreach($value as $lineitems){
$line_item = $xml->addChild('lineItems');
foreach($lineitems as $itemkey => $itemvalue) {
$line_item->addChild($itemkey, $itemvalue);
}
}
}
else
{
$xml->addChild($key);
$this->setParameters($xml->$key, $value);
}
}
else
{
$xml->$key = $value;
}
}
}
}
This suited my needs perfectly and made it so I did not have to change anything on the front end except nesting the lineItems array. So the array I am sending looks more like this:
["lineItems"]=>
array(2) {
[0]=>
array(6) {
["itemId"]=>
string(9) "ITEM00010"
["name"]=>
string(21) "Blah Blah"
["description"]=>
string(21) "Blah Blah Description"
["quantity"]=>
string(1) "1"
["unitPrice"]=>
string(4) "100"
["taxable"]=>
string(5) "false"
}
[1]=>
array(6) {
["itemId"]=>
string(9) "ITEM00011"
["name"]=>
string(25) "Thing Thing"
["description"]=>
string(25) "Thing Thing Description"
["quantity"]=>
string(1) "2"
["unitPrice"]=>
string(3) "50"
["taxable"]=>
string(5) "false"
}
}
Also, for anyone out there looking to build the arrays for the line items I did this:
foreach ($services as $key => $service){
$line_items["lineItems"][] = array(
'itemId' => 'ITEM000'.$key,
'name' => $service->name,
'description' => $service->name,
'quantity' => $service_count[$key],
'unitPrice' => $service->price,
'taxable' => 'false'
);
}
And then just added it to the transaction_array that I passed to the AuthnetXML instance.
Thanks again!
Joel
回答2:
I am the author of that class. The AuthnetXML class currently has a bug in it that results in the results you saw. You would need to make a change to core class to work around this.
I received an email from a user who offered a solution which I have not had a chance to review yet. I'll give you the same information they gave me and hopefully it helps you:
The problem is that you can't have duplicate keys at the same level in an 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;
}
}
}
}
UPDATE 2012-08-21
This bug has been fixed. Sample code has been updated.
回答3:
EDIT: I've solved this issue. The lineItems
key must be passed in like so:
'lineItems' => array(
'itemId' => '13',
'name' => 'hello',
'description' => 'hello description',
'quantity' => '1',
'unitPrice' => '55.00'
),
Note this differs from what's provided the samples over at the Authorize.net-XML repo. I'm going to head over there now and submit a fix.
ORIGINAL QUESTION:
I'm running into a similar problem involving the Authorize.net-XML class; when executing the createCustomerProfileTransactionRequest()
method I receive the following error:
The element 'lineItems' in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd' has
invalid child element 'lineItem' in namespace
'AnetApi/xml/v1/schema/AnetApiSchema.xsd'.
List of possible elements expected: 'itemId' in namespace
'AnetApi/xml/v1/schema/AnetApiSchema.xsd'.' (length=272)
I've even gone so far as to paste in the sample input provided here, but receive the identical error? The class is otherwise working just fine; I use the createTransactionRequest()
and createCustomerProfileRequest()
methods to process AIM transactions and create CIM profiles without problem.
To reiterate, I'm even attempting to use identical sample input as that found on GitHub.
Any ideas?
Thanks so much! Jason
来源:https://stackoverflow.com/questions/12011971/authorize-net-xml-adding-line-items