Transaction XML Datafeeds: Instant Transaction Notification

Transaction XML Datafeed

NOTE: The Transaction XML Datafeed is deprecated Though this legacy datafeed works and will continue to function in the future, it will not see any new functionality. We recommend any new integrations requiring a feed of transactions use FoxyCart's JSON Webhook: https://wiki.foxycart.com/v/2.0/webhooks#json_webhook

An Overview of FoxyCart's Transaction XML Datafeed

In order to allow the flexibility and integration options that you need, FoxyCart can be configured to send encrypted XML to a URL of your choosing. This allows you to integrate FoxyCart without duplicating data across applications.

When you configure it for your store, it will send you an encrypted XML data via a POST of your new transactions immediately upon a successful transaction. You can use this to update inventory, create users or manage user permissions for a paid subscription site, or add users to your mailing list on a 3rd party email service provider's system. There are many examples.

Please note that FoxyCart's XML datafeeds do not include credit card information (number, CSC, date, etc.).

DETAILS, BEST PRACTICES and TESTING Recommendations

Setting your datafeed URL

The datafeed can be enabled for your store from the “Advanced” settings page of the FoxyCart administration. Check the option labelled “Would you like to enable your store datafeed?”, and enter your datafeed endpoint URL into the text input labelled “datafeed url” that appears below it.

Getting the datafeed decryption key

The datafeed payload is encrypted with a key from your store, which you can access from the “advanced” settings page in the FoxyCart administration, from the "store secret" value.

Details

  • When the datafeed is sent it REQUIRES A RESPONSE OF foxy in order to indicate success. If anything other than foxy is returned by your datafeed processing script, FoxyCart will assume that your script errored, and you will be alerted.
  • The Transaction XML Datafeed is sent immediately, in between the checkout and the receipt during your customers' transactions.

Security and encryption

  • The datafeed is RC4-encrypted and URLencoded. As RC4 libraries are difficult to find, and URLencoding is odd, it's typically far easier to start with the example code in your language and/or system of choice at the Integrations page.

Testing

When you're testing your custom XML integration, don't run transactions through FoxyCart. This is both time consuming (as you have to add-to-cart and checkout), but it also doesn't give you any indication of what's actually going wrong.

A much better method is to use the XML Test Post script or application (C#). This effectively mimics what FoxyCart is actually doing when sending the XML to your server in the first place. Make sure you update the test XML in the script to the appropriate version (below).

If you'd like to test using real data from your store, you can run a test transaction and write the datafeed to a file, then copy it out and put it in the Test Post script. Alternatively, you can use UltraHook or ngrok to setup a live relay between FoxyCart and your development environment on localhost.

If you're struggling to just get started with reading the feed, try this: on your script page, capture all the POST data and write it to a file. Test it by posting a simple form to this page just to ensure that it works, and then you can run a single FoxyCart transaction to capture its data. You should end up with an array with a key of 'FoxyData' and pages of url-encrypted data, e.g. “%EBrV%8C%E9…”. After you've saved this to a file, you can work out the other details of your script, e.g. decoding the XML and routing it to your database or 3rd party applications (e.g. MailChimp).

Best Practices

  • Test according to the above method.
  • If you're doing complicated stuff, you may want to backup the XML to a database. This allows you to re-process things at a later date (like if you change mailing list service providers, add a new member functionality, etc.).
  • Don't make assumptions about the data structure. Rather than just accessing a node and assuming the value is there, test first. This can prevent errors down the road.
  • Keep in mind the updateinfo transaction contains no transaction details, so don't assume a value is there but instead check for it.

Creating / Synching Users from the Datafeed

It might not be immediately obvious, but the instant transaction datafeed does indeed contain all the customer's information, so you can create new customers or update existing customer records via the datafeed. If you're using the API or Single Sign-On, make sure you understand the SSO Best Practices for this type of integration.

Notes

  • The transaction XML datafeed comes with a POST name of FoxyData. This is different than the Subscription XML Datafeeds, which has a POST name of FoxySubscriptionData.

Country Codes

For compatibility, FoxyCart uses ISO country codes in our XML:

Hosted Gateways

Using a hosted gateway? Multiple notifications will be sent per transaction.

If you use any of the hosted gateways, note that every transaction may generate more than one notification. Every time our IPN server gets a notification from the gateway we also send you a notification. If your store supports a hosted gateway, the XML Datafeed will include a status field which is updated with each notification. Valid status entries include approved, authorized, declined, pending, and rejected.

For instance, depending on your account settings BitPay server may send up to 4 notifications for every transaction. Other hosted gateways usually send 2 notifications: when the transaction is initiated and when it is complete.

Here is the current list of hosted gateways which take advantage of the status field:

  • 2Checkout
  • Adyen
  • Amazon
  • BitPay
  • Coinbase
  • Comgate
  • Cybersource Secure Acceptance Web/Mobile
  • DIBS
  • Dwolla
  • MercadoPago
  • Mollie
  • Ogone
  • PayPal Express Checkout
  • PayPal Plus
  • PesaPal
  • Skrill

Errors

If there's an error sending the XML datafeed to your store, FoxyCart will send an email notification to the store admins. Here's some info about what happens when a datafeed fails.

Did the transaction go through? Was the customer's payment impacted?

The transaction that triggered the datafeed still completed successfully, the customer was charged and you'll receive payment for the transaction as your chosen payment gateway processes it.

What do I do now?

  1. Check the error: You can see the specific error that was triggered by your datafeed by viewing the errors page of your stores FoxyCart administration. Check out this page: http://wiki.foxycart.com/primer/errors for information on what the error logs mean for your datafeed. Based on the particular error you're receiving, you may need to make changes to your endpoint to correct the issue. If you don't manage your particular endpoint, you'll need to get in touch with the people that do with details of the error.
  2. Refeed the transaction: You can also try to refeed the transaction details to your endpoint, which you can do by navigating to the transactions report section of the FoxyCart administration, expanding the relevant transaction and clicking the option to “Re-feed it now”

Example XML

NOTE: The user agent that is used for datafeed requests to your endpoint is: FoxyCart Webhook v2.0 (http://wiki.foxycart.com/v/2.0/webhooks)

Non-MultiShip Store

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<foxydata>
	<transactions>
		<transaction>
			<id><![CDATA[52768]]></id>
			<store_id><![CDATA[9]]></store_id>
			<store_version><![CDATA[0.7.0]]></store_version>
			<is_test><![CDATA[1]]></is_test>
			<is_hidden><![CDATA[0]]></is_hidden>
			<data_is_fed><![CDATA[0]]></data_is_fed>
			<transaction_date><![CDATA[2010-08-19 13:50:00]]></transaction_date>
			<processor_response><![CDATA[Authorize.net Transaction ID:2154082729]]></processor_response>
			<customer_id><![CDATA[193]]></customer_id>
			<is_anonymous><![CDATA[0]]></is_anonymous>
			<minfraud_score><![CDATA[0]]></minfraud_score>
			<customer_first_name><![CDATA[Jörgé •™¡ªº]]></customer_first_name>
			<customer_last_name><![CDATA[Cantú]]></customer_last_name>
			<customer_company><![CDATA[Your Company]]></customer_company>
			<customer_address1><![CDATA[&amp;]]></customer_address1>
			<customer_address2><![CDATA[]]></customer_address2>
			<customer_city><![CDATA[seal beach]]></customer_city>
			<customer_state><![CDATA[CA]]></customer_state>
			<customer_postal_code><![CDATA[90740]]></customer_postal_code>
			<customer_country><![CDATA[US]]></customer_country>
			<customer_phone><![CDATA[]]></customer_phone>
			<customer_email><![CDATA[test@example.com]]></customer_email>
			<customer_ip><![CDATA[123.123.123.123]]></customer_ip>
			<shipping_first_name><![CDATA[]]></shipping_first_name>
			<shipping_last_name><![CDATA[]]></shipping_last_name>
			<shipping_company><![CDATA[]]></shipping_company>
			<shipping_address1><![CDATA[]]></shipping_address1>
			<shipping_address2><![CDATA[]]></shipping_address2>
			<shipping_city><![CDATA[]]></shipping_city>
			<shipping_state><![CDATA[]]></shipping_state>
			<shipping_postal_code><![CDATA[]]></shipping_postal_code>
			<shipping_country><![CDATA[]]></shipping_country>
			<shipping_phone><![CDATA[]]></shipping_phone>
			<shipto_shipping_service_description><![CDATA[USPS Priority Mail Flat Rate Envelope]]></shipto_shipping_service_description>
			<purchase_order><![CDATA[]]></purchase_order>
			<cc_number_masked><![CDATA[xxxxxxxxxxxx4242]]></cc_number_masked>
			<cc_type><![CDATA[Visa]]></cc_type>
			<cc_exp_month><![CDATA[08]]></cc_exp_month>
			<cc_exp_year><![CDATA[2013]]></cc_exp_year>
			<cc_start_date_month><![CDATA[06]]></cc_start_date_month>
			<cc_start_date_year><![CDATA[2008]]></cc_start_date_year>
			<cc_issue_number><![CDATA[01]]></cc_issue_number>
			<product_total><![CDATA[12.35]]></product_total>
			<tax_total><![CDATA[0]]></tax_total>
			<shipping_total><![CDATA[7.52]]></shipping_total>
			<order_total><![CDATA[14.87]]></order_total>
			<payment_gateway_type><![CDATA[authorize]]></payment_gateway_type>
			<receipt_url><![CDATA[http://themancan.foxycart.com/receipt?id=28a313c5217794e89a989ccd69eefa40]]></receipt_url>
			<taxes/>
			<discounts>
				<discount>
					<code><![CDATA[asdf]]></code>
					<valid_categories/>
					<name><![CDATA[$5 off all orders over $5!]]></name>
					<amount><![CDATA[-5]]></amount>
					<display><![CDATA[-5.00]]></display>
					<coupon_discount_type><![CDATA[price_amount]]></coupon_discount_type>
					<coupon_discount_details><![CDATA[5-5]]></coupon_discount_details>
				</discount>
			</discounts>
			<attributes/>
			<status>approved</status>
			<customer_password><![CDATA[2e29f4fa2efb67dc28860abf05523a1784829a90177c1477460e42da00f81659]]></customer_password>
			<customer_password_salt><![CDATA[SSCtVKDnH1vAwuLyY2XHziIFv3fN5laN8DbYiIcUDBkZW2pP]]></customer_password_salt>
			<customer_password_hash_type><![CDATA[sha256_salted_suffix]]></customer_password_hash_type>
			<customer_password_hash_config><![CDATA[48]]></customer_password_hash_config>
			<custom_fields>
				<custom_field>
					<custom_field_name><![CDATA[example_hidden]]></custom_field_name>
					<custom_field_value><![CDATA[value_1]]></custom_field_value>
					<custom_field_is_hidden><![CDATA[1]]></custom_field_is_hidden>
				</custom_field>
				<custom_field>
					<custom_field_name><![CDATA[Hidden_Value]]></custom_field_name>
					<custom_field_value><![CDATA[My Name Is_Jonas©;&amp;texture &amp;_ smoothness=rough||929274e2c2b22d8d51540d8bf657eef133121d7e67c05284687edcd8bfdcd946]]></custom_field_value>
					<custom_field_is_hidden><![CDATA[1]]></custom_field_is_hidden>
				</custom_field>
			</custom_fields>
			<transaction_details>
				<transaction_detail>
					<product_name><![CDATA[Example Product with Hex and Plus Spaces]]></product_name>
					<product_price><![CDATA[10.00]]></product_price>
					<product_quantity><![CDATA[2]]></product_quantity>
					<product_weight><![CDATA[4.000]]></product_weight>
					<product_code><![CDATA[abc123zzz]]></product_code>
					<parent_code><![CDATA[]]></parent_code>
					<image><![CDATA[]]></image>
					<url><![CDATA[]]></url>
					<length><![CDATA[]]></length>
					<width><![CDATA[]]></width>
					<height><![CDATA[]]></height>
					<expires><![CDATA[]]></expires>
					<sub_token_url><![CDATA[]]></sub_token_url>
					<subscription_frequency><![CDATA[]]></subscription_frequency>
					<subscription_startdate><![CDATA[0000-00-00]]></subscription_startdate>
					<subscription_nextdate><![CDATA[0000-00-00]]></subscription_nextdate>
					<subscription_enddate><![CDATA[0000-00-00]]></subscription_enddate>
					<is_future_line_item>0</is_future_line_item>
					<shipto><![CDATA[]]></shipto>
					<category_description><![CDATA[Discount: Price: Percentage]]></category_description>
					<category_code><![CDATA[discount_price_percentage]]></category_code>
					<product_delivery_type><![CDATA[shipped]]></product_delivery_type>
					<transaction_detail_options>
						<transaction_detail_option>
							<product_option_name><![CDATA[color]]></product_option_name>
							<product_option_value><![CDATA[red]]></product_option_value>
							<price_mod><![CDATA[-4.000]]></price_mod>
							<weight_mod><![CDATA[0.000]]></weight_mod>
						</transaction_detail_option>
						<transaction_detail_option>
							<product_option_name><![CDATA[Quantity Discount]]></product_option_name>
							<product_option_value><![CDATA[$0.50]]></product_option_value>
							<price_mod><![CDATA[0.500]]></price_mod>
							<weight_mod><![CDATA[0.000]]></weight_mod>
						</transaction_detail_option>
						<transaction_detail_option>
							<product_option_name><![CDATA[Price Discount Amount]]></product_option_name>
							<product_option_value><![CDATA[-5%]]></product_option_value>
							<price_mod><![CDATA[-0.325]]></price_mod>
							<weight_mod><![CDATA[0.000]]></weight_mod>
						</transaction_detail_option>
					</transaction_detail_options>
				</transaction_detail>
			</transaction_details>
			<shipto_addresses/>
		</transaction>
	</transactions>
</foxydata>

MultiShip Store

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<foxydata>
	<transactions>
		<transaction>
			<id><![CDATA[52769]]></id>
			<store_id><![CDATA[9]]></store_id>
			<store_version><![CDATA[0.7.0]]></store_version>
			<is_test><![CDATA[1]]></is_test>
			<is_hidden><![CDATA[0]]></is_hidden>
			<data_is_fed><![CDATA[0]]></data_is_fed>
			<transaction_date><![CDATA[2010-08-19 13:51:00]]></transaction_date>
			<processor_response><![CDATA[Authorize.net Transaction ID:2154082799]]></processor_response>
			<customer_id><![CDATA[193]]></customer_id>
			<is_anonymous><![CDATA[0]]></is_anonymous>
			<minfraud_score><![CDATA[0]]></minfraud_score>
			<customer_first_name><![CDATA[Jörgé •™¡ªº]]></customer_first_name>
			<customer_last_name><![CDATA[Cantú]]></customer_last_name>
			<customer_company><![CDATA[Your Company]]></customer_company>
			<customer_address1><![CDATA[&amp;]]></customer_address1>
			<customer_address2><![CDATA[]]></customer_address2>
			<customer_city><![CDATA[seal beach]]></customer_city>
			<customer_state><![CDATA[CA]]></customer_state>
			<customer_postal_code><![CDATA[90740]]></customer_postal_code>
			<customer_country><![CDATA[US]]></customer_country>
			<customer_phone><![CDATA[]]></customer_phone>
			<customer_email><![CDATA[test@example.com]]></customer_email>
			<customer_ip><![CDATA[108.13.30.173]]></customer_ip>
			<shipping_first_name><![CDATA[]]></shipping_first_name>
			<shipping_last_name><![CDATA[]]></shipping_last_name>
			<shipping_company><![CDATA[]]></shipping_company>
			<shipping_address1><![CDATA[]]></shipping_address1>
			<shipping_address2><![CDATA[]]></shipping_address2>
			<shipping_city><![CDATA[]]></shipping_city>
			<shipping_state><![CDATA[]]></shipping_state>
			<shipping_postal_code><![CDATA[]]></shipping_postal_code>
			<shipping_country><![CDATA[]]></shipping_country>
			<shipping_phone><![CDATA[]]></shipping_phone>
			<shipto_shipping_service_description><![CDATA[]]></shipto_shipping_service_description>
			<purchase_order><![CDATA[]]></purchase_order>
			<cc_number_masked><![CDATA[xxxxxxxxxxxx4242]]></cc_number_masked>
			<cc_type><![CDATA[Visa]]></cc_type>
			<cc_exp_month><![CDATA[08]]></cc_exp_month>
			<cc_exp_year><![CDATA[2013]]></cc_exp_year>
			<cc_start_date_month><![CDATA[06]]></cc_start_date_month>
			<cc_start_date_year><![CDATA[2008]]></cc_start_date_year>
			<cc_issue_number><![CDATA[01]]></cc_issue_number>
			<product_total><![CDATA[47.55]]></product_total>
			<tax_total><![CDATA[0.12]]></tax_total>
			<shipping_total><![CDATA[25.93]]></shipping_total>
			<order_total><![CDATA[73.6]]></order_total>
			<payment_gateway_type><![CDATA[authorize]]></payment_gateway_type>
			<receipt_url><![CDATA[http://themancan.foxycart.com/receipt?id=29e1200f11320a8f45a665fc264cca6f]]></receipt_url>
			<taxes>
				<tax>
					<tax_rate><![CDATA[1.5000]]></tax_rate>
					<tax_name><![CDATA[US Federal Tax]]></tax_name>
					<tax_amount><![CDATA[0.0150]]></tax_amount>
				</tax>
				<tax>
					<tax_rate><![CDATA[1.0000]]></tax_rate>
					<tax_name><![CDATA[Global Tax]]></tax_name>
					<tax_amount><![CDATA[0.0100]]></tax_amount>
				</tax>
				<tax>
					<tax_rate><![CDATA[8.8800]]></tax_rate>
					<tax_name><![CDATA[California Bankruptcy Tax]]></tax_name>
					<tax_amount><![CDATA[0.0888]]></tax_amount>
				</tax>
				<tax>
					<tax_rate><![CDATA[0.2376]]></tax_rate>
					<tax_name><![CDATA[Seal Beach Awesomeness Tax]]></tax_name>
					<tax_amount><![CDATA[0.0024]]></tax_amount>
				</tax>
			</taxes>
			<discounts>
				<discount>
					<code><![CDATA[asdf]]></code>
					<valid_categories/>
					<name><![CDATA[$5 off all orders over $5!]]></name>
					<amount><![CDATA[-5]]></amount>
					<display><![CDATA[-5.00]]></display>
					<coupon_discount_type><![CDATA[price_amount]]></coupon_discount_type>
					<coupon_discount_details><![CDATA[5-5]]></coupon_discount_details>
				</discount>
			</discounts>
			<attributes>
				<attribute>
					<name><![CDATA[Order Notes]]></name>
					<value><![CDATA[This was a phone-in order]]></value>
				</attribute>
				<attribute>
					<name><![CDATA[Tracking #]]></name>
					<value><![CDATA[95445848744564]]></value>
				</attribute>
			</attributes>
			<status>approved</status>
			<customer_password><![CDATA[912ec803b2ce49e4a541068d495ab570]]></customer_password>
			<custom_fields>
				<custom_field>
					<custom_field_name><![CDATA[example_hidden]]></custom_field_name>
					<custom_field_value><![CDATA[value_1]]></custom_field_value>
					<custom_field_is_hidden><![CDATA[1]]></custom_field_is_hidden>
				</custom_field>
				<custom_field>
					<custom_field_name><![CDATA[Hidden_Value]]></custom_field_name>
					<custom_field_value><![CDATA[My Name Is_Jonas©;&amp;texture &amp;_ smoothness=rough||929274e2c2b22d8d51540d8bf657eef133121d7e67c05284687edcd8bfdcd946]]></custom_field_value>
					<custom_field_is_hidden><![CDATA[1]]></custom_field_is_hidden>
				</custom_field>
			</custom_fields>
			<transaction_details>
				<transaction_detail>
					<product_name><![CDATA[Example Subscription]]></product_name>
					<product_price><![CDATA[10.00]]></product_price>
					<product_quantity><![CDATA[1]]></product_quantity>
					<product_weight><![CDATA[4.000]]></product_weight>
					<product_code><![CDATA[xyz456]]></product_code>
					<parent_code><![CDATA[]]></parent_code>
					<image><![CDATA[]]></image>
					<url><![CDATA[]]></url>
					<length><![CDATA[]]></length>
					<width><![CDATA[]]></width>
					<height><![CDATA[]]></height>
					<expires><![CDATA[]]></expires>
					<downloadable_url><![CDATA[]]></downloadable_url>
					<sub_token_url><![CDATA[https://themancan.foxycart.com/cart?sub_token=8b13b7e14f3f5c9a710f7bb22cab9a2d]]></sub_token_url>
					<subscription_frequency><![CDATA[1m]]></subscription_frequency>
					<subscription_startdate><![CDATA[2010-08-19]]></subscription_startdate>
					<subscription_nextdate><![CDATA[2010-09-19]]></subscription_nextdate>
					<subscription_enddate><![CDATA[2013-01-01]]></subscription_enddate>
					<is_future_line_item>0</is_future_line_item>
					<shipto><![CDATA[Me]]></shipto>
					<category_description><![CDATA[Default for all products]]></category_description>
					<category_code><![CDATA[DEFAULT]]></category_code>
					<product_delivery_type><![CDATA[shipped]]></product_delivery_type>
					<transaction_detail_options>
						<transaction_detail_option>
							<product_option_name><![CDATA[color]]></product_option_name>
							<product_option_value><![CDATA[red]]></product_option_value>
							<price_mod><![CDATA[-4.000]]></price_mod>
							<weight_mod><![CDATA[0.000]]></weight_mod>
						</transaction_detail_option>
					</transaction_detail_options>
				</transaction_detail>
				<transaction_detail>
					<product_name><![CDATA[Example Product with Hex and Plus Spaces]]></product_name>
					<product_price><![CDATA[10.00]]></product_price>
					<product_quantity><![CDATA[10]]></product_quantity>
					<product_weight><![CDATA[4.000]]></product_weight>
					<product_code><![CDATA[abc123zzz]]></product_code>
					<downloadable_url><![CDATA[]]></downloadable_url>
					<sub_token_url><![CDATA[]]></sub_token_url>
					<subscription_frequency><![CDATA[]]></subscription_frequency>
					<subscription_startdate><![CDATA[0000-00-00]]></subscription_startdate>
					<subscription_nextdate><![CDATA[0000-00-00]]></subscription_nextdate>
					<subscription_enddate><![CDATA[0000-00-00]]></subscription_enddate>
					<shipto><![CDATA[Me]]></shipto>
					<category_description><![CDATA[Discount: Price: Percentage]]></category_description>
					<category_code><![CDATA[discount_price_percentage]]></category_code>
					<product_delivery_type><![CDATA[shipped]]></product_delivery_type>
					<transaction_detail_options>
						<transaction_detail_option>
							<product_option_name><![CDATA[color]]></product_option_name>
							<product_option_value><![CDATA[red]]></product_option_value>
							<price_mod><![CDATA[-4.000]]></price_mod>
							<weight_mod><![CDATA[0.000]]></weight_mod>
						</transaction_detail_option>
						<transaction_detail_option>
							<product_option_name><![CDATA[Quantity Discount]]></product_option_name>
							<product_option_value><![CDATA[-$1.10]]></product_option_value>
							<price_mod><![CDATA[-1.100]]></price_mod>
							<weight_mod><![CDATA[0.000]]></weight_mod>
						</transaction_detail_option>
						<transaction_detail_option>
							<product_option_name><![CDATA[Price Discount Amount]]></product_option_name>
							<product_option_value><![CDATA[-5%]]></product_option_value>
							<price_mod><![CDATA[-0.245]]></price_mod>
							<weight_mod><![CDATA[0.000]]></weight_mod>
						</transaction_detail_option>
					</transaction_detail_options>
				</transaction_detail>
			</transaction_details>
			<shipto_addresses>
				<shipto_address>
					<address_id><![CDATA[73]]></address_id>
					<address_name><![CDATA[Me]]></address_name>
					<shipto_first_name><![CDATA[Mother]]></shipto_first_name>
					<shipto_last_name><![CDATA[Dearest]]></shipto_last_name>
					<shipto_company><![CDATA[The Family Stone]]></shipto_company>
					<shipto_address1><![CDATA[¡Fü Bár!]]></shipto_address1>
					<shipto_address2><![CDATA[]]></shipto_address2>
					<shipto_city><![CDATA[seal beach]]></shipto_city>
					<shipto_state><![CDATA[CA]]></shipto_state>
					<shipto_postal_code><![CDATA[90740]]></shipto_postal_code>
					<shipto_country><![CDATA[US]]></shipto_country>
					<date_created><![CDATA[2010-08-19 13:58:53]]></date_created>
					<date_modified><![CDATA[2010-08-19 13:58:53]]></date_modified>
					<shipto_shipping_service_description><![CDATA[USPS Express Mail Flat Rate Envelope Hold For Pickup]]></shipto_shipping_service_description>
					<shipto_subtotal><![CDATA[52.55]]></shipto_subtotal>
					<shipto_tax_total><![CDATA[0.12]]></shipto_tax_total>
					<shipto_shipping_total><![CDATA[21.6]]></shipto_shipping_total>
					<shipto_total><![CDATA[78.60]]></shipto_total>
					<shipto_custom_fields/>
				</shipto_address>
			</shipto_addresses>
		</transaction>
	</transactions>
</foxydata>

Example Parsing Code

Here's a PHP script that you can use which loops through the datafeed and sets variables for easy usage:

//Script by David Hollander, www.foxy-shop.com
//version 1.0, 7/9/2012
 
//Set Globals and Get Settings
$apikey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
 
//-----------------------------------------------------
// TRANSACTION DATAFEED
//-----------------------------------------------------
if (isset($_POST["FoxyData"])) {
 
 
	//DECRYPT (required)
	//-----------------------------------------------------
	$FoxyData_decrypted = foxycart_decrypt($_POST["FoxyData"]);
	$xml = simplexml_load_string($FoxyData_decrypted, NULL, LIBXML_NOCDATA);
 
 
	//For Each Transaction
	foreach($xml->transactions->transaction as $transaction) {
 
		//This variable will tell us whether this is a multi-ship store or not
		$is_multiship = 0;
 
		//Get FoxyCart Transaction Information
		//Simply setting lots of helpful data to PHP variables so you can access it easily
		//If you need to access more variables, you can see some sample XML here: http://wiki.foxycart.com/v/1.1/transaction_xml_datafeed
		$transaction_id = (string)$transaction->id;
		$transaction_date = (string)$transaction->transaction_date;
		$customer_ip = (string)$transaction->customer_ip;
		$customer_id = (string)$transaction->customer_id;
		$customer_first_name = (string)$transaction->customer_first_name;
		$customer_last_name = (string)$transaction->customer_last_name;
		$customer_company = (string)$transaction->customer_company;
		$customer_email = (string)$transaction->customer_email;
		$customer_password = (string)$transaction->customer_password;
		$customer_address1 = (string)$transaction->customer_address1;
		$customer_address2 = (string)$transaction->customer_address2;
		$customer_city = (string)$transaction->customer_city;
		$customer_state = (string)$transaction->customer_state;
		$customer_postal_code = (string)$transaction->customer_postal_code;
		$customer_country = (string)$transaction->customer_country;
		$customer_phone = (string)$transaction->customer_phone;
 
 
		//This is for a multi-ship store. The shipping addresses will go in a $shipto array with the address name as the key
		$shipto = array();
		foreach($transaction->shipto_addresses->shipto_address as $shipto_address) {
			$is_multiship = 1;
			$shipto_name = (string)$shipto_address->address_name;
			$shipto[$shipto_name] = array(
				'first_name' => (string)$shipto_address->shipto_first_name,
				'last_name' => (string)$shipto_address->shipto_last_name,
				'company' => (string)$shipto_address->shipto_company,
				'address1' => (string)$shipto_address->shipto_address1,
				'address2' => (string)$shipto_address->shipto_address2,
				'city' => (string)$shipto_address->shipto_city,
				'state' => (string)$shipto_address->shipto_state,
				'postal_code' => (string)$shipto_address->shipto_postal_code,
				'country' => (string)$shipto_address->shipto_country,
				'shipping_service_description' => (string)$shipto_address->shipto_shipping_service_description,
				'subtotal' => (string)$shipto_address->shipto_subtotal,
				'tax_total' => (string)$shipto_address->shipto_tax_total,
				'shipping_total' => (string)$shipto_address->shipto_shipping_total,
				'total' => (string)$shipto_address->shipto_,
				'custom_fields' => array()
			);
 
			//Putting the Custom Fields in an array if they are there
			if (!empty($shipto_address->custom_fields)) {
				foreach($shipto_address->custom_fields->custom_field as $custom_field) {
					$shipto[$shipto_name]['custom_fields'][(string)$custom_field->custom_field_name] = (string)$custom_field->custom_field_value;
				}
			}
		}
 
		//This is setup for a single ship store
		if (!$is_multiship) {
			$shipping_first_name = (string)$transaction->shipping_first_name ? (string)$transaction->shipping_first_name : $customer_first_name;
			$shipping_last_name = (string)$transaction->shipping_last_name ? (string)$transaction->shipping_last_name : $customer_last_name;
			$shipping_company = (string)$transaction->shipping_company ? (string)$transaction->shipping_company : $customer_company;
			$shipping_address1 = (string)$transaction->shipping_address1 ? (string)$transaction->shipping_address1 : $customer_address1;
			$shipping_address2 = (string)$transaction->shipping_address1 ? (string)$transaction->shipping_address2 : $customer_address2;
			$shipping_city = (string)$transaction->shipping_city ? (string)$transaction->shipping_city : $customer_city;
			$shipping_state = (string)$transaction->shipping_state ? (string)$transaction->shipping_state : $customer_state;
			$shipping_postal_code = (string)$transaction->shipping_postal_code ? (string)$transaction->shipping_postal_code : $customer_postal_code;
			$shipping_country = (string)$transaction->shipping_country ? (string)$transaction->shipping_country : $customer_country;
			$shipping_phone = (string)$transaction->shipping_phone ? (string)$transaction->shipping_phone : $customer_phone;
			$shipto_shipping_service_description = (string)$transaction->shipto_shipping_service_description;
		}
 
		//Putting the Custom Fields in an array if they are there. These are on the top level and could be there for both single ship and multiship stores
		$custom_fields = array();
		if (!empty($transaction->custom_fields)) {
			foreach($transaction->custom_fields->custom_field as $custom_field) {
				$custom_fields[(string)$custom_field->custom_field_name] = (string)$custom_field->custom_field_value;
			}
		}
 
 
 
 
 
 
		//For Each Transaction Detail
		foreach($transaction->transaction_details->transaction_detail as $transaction_detail) {
			$product_name = (string)$transaction_detail->product_name;
			$product_code = (string)$transaction_detail->product_code;
			$product_quantity = (int)$transaction_detail->product_quantity;
			$product_price = (double)$transaction_detail->product_price;
			$product_shipto = (double)$transaction_detail->shipto;
			$category_code = (string)$transaction_detail->category_code;
			$product_delivery_type = (string)$transaction_detail->product_delivery_type;
			$sub_token_url = (string)$transaction_detail->sub_token_url;
			$subscription_frequency = (string)$transaction_detail->subscription_frequency;
			$subscription_startdate = (string)$transaction_detail->subscription_startdate;
			$subscription_nextdate = (string)$transaction_detail->subscription_nextdate;
			$subscription_enddate = (string)$transaction_detail->subscription_enddate;
 
			//These are the options for the product
			$transaction_detail_options = array();
			foreach($transaction_detail->transaction_detail_options->transaction_detail_option as $transaction_detail_option) {
				$product_option_name = $transaction_detail_option->product_option_name;
				$product_option_value = (string)$transaction_detail_option->product_option_value;
				$price_mod = (double)$transaction_detail_option->price_mod;
				$weight_mod = (double)$transaction_detail_option->weight_mod;
 
 
 
 
			}
 
 
 
 
 
			//If you have custom code to run for each product, put it here:
 
 
 
 
 
 
 
 
 
 
		}
 
		//If you have custom code to run for each order, put it here:
 
 
 
 
 
 
 
 
 
 
 
 
	}
 
	//All Done!
	die("foxy");
 
 
 
 
 
 
 
//-----------------------------------------------------
// NO POST CONTENT SENT
//-----------------------------------------------------
} else {
	die('No Content Received From Datafeed');
}
 
 
 
 
//Decrypt Data From Source
function foxycart_decrypt($src) {
    	global $apikey;
	return rc4crypt::decrypt($apikey,urldecode($src));
}
 
 
// ======================================================================================
// RC4 ENCRYPTION CLASS
// Do not modify.
// ======================================================================================
/**
 * RC4Crypt 3.2
 *
 * RC4Crypt is a petite library that allows you to use RC4
 * encryption easily in PHP. It's OO and can produce outputs
 * in binary and hex.
 *
 * (C) Copyright 2006 Mukul Sabharwal [http://mjsabby.com]
 *     All Rights Reserved
 *
 * @link http://rc4crypt.devhome.org
 * @author Mukul Sabharwal <mjsabby@gmail.com>
 * @version $Id: class.rc4crypt.php,v 3.2 2006/03/10 05:47:24 mukul Exp $
 * @copyright Copyright &copy; 2006 Mukul Sabharwal
 * @license http://www.gnu.org/copyleft/gpl.html
 * @package RC4Crypt
 */
class rc4crypt {
	/**
	 * The symmetric encryption function
	 *
	 * @param string $pwd Key to encrypt with (can be binary of hex)
	 * @param string $data Content to be encrypted
	 * @param bool $ispwdHex Key passed is in hexadecimal or not
	 * @access public
	 * @return string
	 */
	public static function encrypt ($pwd, $data, $ispwdHex = 0) {
		if ($ispwdHex) $pwd = @pack('H*', $pwd); // valid input, please!
 		$key[] = '';
		$box[] = '';
		$cipher = '';
		$pwd_length = strlen($pwd);
		$data_length = strlen($data);
		for ($i = 0; $i < 256; $i++) {
			$key[$i] = ord($pwd[$i % $pwd_length]);
			$box[$i] = $i;
		}
		for ($j = $i = 0; $i < 256; $i++) {
			$j = ($j + $box[$i] + $key[$i]) % 256;
			$tmp = $box[$i];
			$box[$i] = $box[$j];
			$box[$j] = $tmp;
		}
		for ($a = $j = $i = 0; $i < $data_length; $i++) {
			$a = ($a + 1) % 256;
			$j = ($j + $box[$a]) % 256;
			$tmp = $box[$a];
			$box[$a] = $box[$j];
			$box[$j] = $tmp;
			$k = $box[(($box[$a] + $box[$j]) % 256)];
			$cipher .= chr(ord($data[$i]) ^ $k);
		}
		return $cipher;
	}
	/**
	 * Decryption, recall encryption
	 *
	 * @param string $pwd Key to decrypt with (can be binary of hex)
	 * @param string $data Content to be decrypted
	 * @param bool $ispwdHex Key passed is in hexadecimal or not
	 * @access public
	 * @return string
	 */
	public static function decrypt ($pwd, $data, $ispwdHex = 0) {
		return rc4crypt::encrypt($pwd, $data, $ispwdHex);
	}
}

Node.js example:

var crypto = require('crypto');
var request_body = '%C9C%9F';
var encrypted = unescape(request_body.replace(/\+/g, ' '));
var key = 'foo';
var decipher = crypto.createDecipheriv('rc4', key, '');
var message = decipher.update(encrypted, 'binary', 'utf8') + decipher.final('utf8');
console.log(message); // bar

Site Tools