Parsing DataFeed FoxyData XML with PHP

yougotericyougoteric Member
in Help edited February 2013
In creating an order management system for Wordpress (Yes I am aware of FoxyShop and Order Desk), which includes Single Sign On with FC, I have the requirement of creating FC passwords with phpass hash to match WP.

The data posted to the datafeed url in the FoxyData POST variable contains the user's pasword after having been processes via phpass. In many cases, this includes the inclusion of characters such as decimals and dollar signs. When parsing the xml to retreive the customer_password value (among many other fields), I am finding that PHP is treating passwords with dollar signs in them as empty variables, up untli the point when they run into a decimal/period.

Thereby a password that Foxy is outputting as $P$BmkkB6LIcyUflD9A.ReYrWN92wuYwe0 is being interpreted by my PHP as: $empty_variable . $empty_variable . '.ReYrWN92wuYwe0'.

In discussing with @brett, he mentioned that my data is coming in as a "heredoc" rather than a "nowdoc". However, try as I might to manipulate and hack at the FoxyData, I can't seem to get it to the point of parsing data from any node after the instance of a dollar sign.

I've come close to the human limits of frustration before spontaneous combustion with this issue and I'm hoping that someone ( @sparkweb perhaps) has run into this in the past and has found a solution. Any and all help appreciated as always.

Comments
  • fredfred FoxyCart Team
    Hey @yougoteric, can you strip your program down to just the problem you're having and post your code? If you want to send it privately, go ahead and whisper it here.

    At first blush it seems like what Brett said is correct, that you have some variables in a double-quoted (or heredoc) string in your program's code that PHP is expanding. I can't think of a way to make PHP to expand variables in strings that it receives via POST, etc., without using
    eval()
    
    or similar.
  • Thanks, @fred.

    My code is below.

    For testing purposes, I have my PHP prepended with the following (This yields the same results as live data.:
    $FoxyData_decrypted = <<<XML
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <foxydata>
    <store_version><![CDATA[1.0]]></store_version><transactions>
    <transaction><id><![CDATA[35419379]]></id><store_id><![CDATA[20933]]></store_id>
    .......
    <customer_password><![CDATA[$P$BmkkB6LIcyUflD9A.ReYrWN92wuYwe0]]></customer_password>
    <customer_password_salt><![CDATA[]]></customer_password_salt><customer_password_hash_type><![CDATA[phpass]]></customer_password_hash_type><customer_password_hash_config><![CDATA[8]]></customer_password_hash_config><custom_fields><custom_field><custom_field_name><![CDATA[Update_List]]></custom_field_name><custom_field_value><![CDATA[yes]]></custom_field_value><custom_field_is_hidden><![CDATA[0]]></custom_field_is_hidden></custom_field><custom_field><custom_field_name><![CDATA[Comments]]></custom_field_name><custom_field_value>
    .....
    </foxydata>
    XML;
    

    As you can see, the password contains two $ characters.
    Using the following code (as well as other techniques of evaluating/parsing the xml, the outputted value for customer password is always: ".ReYrWN92wuYwe0".
    $xml = simplexml_load_string($FoxyData_decrypted, null, LIBXML_NOCDATA);
    $customer_password = (string)$transaction->customer_password;
    echo $customer_password; // outputs: .ReYrWN92wuYwe0
    

    I have also tried this with the XML data in quotes, and saving it to a separate file (where it includes the full hashed password) and then trying to retrieve it with simplexml_load_file, file_get_contents. I have tried using xpath as well as xml_parser.

    In all cases, when evaluating the data with any of the aforementioned techniques and outputting via print_r, var_dump, or echo "$xml" in double quotes, the result is always the same with the password node being stripped down to everything after the "."



  • fredfred FoxyCart Team
    OK, so some quick testing shows that the code you posted still gets interpreted as a heredoc. It appears the magic to trigger a "nowdoc" in PHP is both the triple left-angle-brace AND single quotes like so:
    $FoxyData_decrypted = <<<'XML'
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <foxydata>
    <store_version><![CDATA[1.0]]></store_version><transactions>
    <transaction><id><![CDATA[35419379]]></id><store_id><![CDATA[20933]]></store_id>
    .......
    <customer_password><![CDATA[$P$BmkkB6LIcyUflD9A.ReYrWN92wuYwe0]]></customer_password>
    <customer_password_salt><![CDATA[]]></customer_password_salt><customer_password_hash_type><![CDATA[phpass]]></customer_password_hash_type><customer_password_hash_config><![CDATA[8]]></customer_password_hash_config><custom_fields><custom_field><custom_field_name><![CDATA[Update_List]]></custom_field_name><custom_field_value><![CDATA[yes]]></custom_field_value><custom_field_is_hidden><![CDATA[0]]></custom_field_is_hidden></custom_field><custom_field><custom_field_name><![CDATA[Comments]]></custom_field_name><custom_field_value>
    .....
    </foxydata>
    XML;
    

    See this for details: http://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.nowdoc

    If I copy and paste just the XML from above into a file called 'test.xml' then I get the hashed password correctly using file_get_contents().

    Let me know if that helps!
  • Are you using something like this?
    $fixed_xml = <<<'XML' . file_get_contents('test.xml') . XML;
    
    Or did you include the triple braces and 'XML' in your test.xml file?

    Mine's not working in either case :(
  • fredfred FoxyCart Team
    Hey @yougoteric,

    Two things:
    1. Here/nowdocs won't work on one line like that. It tells PHP "start reading the string here, stop when you see XML on a line by itself." Check that you're using PHP 5.3.0+, nowdocs were added there.
    2. There's no need to use a nowdoc here.

    Complete & working example:
    <?php
    $xml = file_get_contents('test.xml');
    $doc = simplexml_load_string($xml);
    
    echo $doc->transactions->transaction[0]->customer_password . "\n";
    
    ?>
    

    Your second reply threw me off because you said "didn't work", which I thought mean you still saw the original problem. When I put it into PHP I got a parse error, and immediately realized what was going on.

    Here's my test.xml: http://cl.ly/code/3b3w200O0K2u
  • How we check either payment is pending or completed in datafeed.
  • fc_adamfc_adam FoxyCart Team
    @Avinash,

    If you receive the XML datafeed, that means that the transaction was successful and completed. Depending on the gateway you're using, the money may only actually make it into your account in the following days - but the transaction is completed.
Sign In or Register to comment.