Skip to main content
Known Participant
November 17, 2010
Question

chthread

  • November 17, 2010
  • 1 reply
  • 951 views

I'm trying to create an application that checks the status of recurring subscriptions with authorize.net.  To check subscriptions with auth.net, you must send an xml file with your content - For example.

<?xml version="1.0" encoding="utf-8"?>

<ARBGetSubscriptionStatusRequest xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">

<merchantAuthentication>

<name>mytestacct</name>

<transactionKey>112223344</transactionKey>

</merchantAuthentication>

<refId>Sample</refId>

<subscriptionId>100748</subscriptionId>

</ARBGetSubscriptionStatusRequest>

Then, you receive an xml response.  I can make this application work the following code below, but any more than 30 subscriptions, the application will timeout. I heard that if you use cfthread you can avoid timeout.  I read the documentation but don't get how you integrate it when you are sending data such as xml and requesting data. Any ideas would be great.

<cfloop from="1" to="#query.RecordCount#" index="i">

<cfoutput>

<cfsavecontent variable="strXML">

<?xml version="1.0" encoding="utf-8"?>

<ARBGetSubscriptionStatusRequest xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">

<merchantAuthentication>

<name>#LoginID#</name>

<transactionKey>#TransactionKey#</transactionKey>

</merchantAuthentication>

<refId>#PolicyNumber#</refId>

    <subscriptionId>#SubID#</subscriptionId>

</ARBGetSubscriptionStatusRequest>

</cfsavecontent>

<cfhttp url="https://api.authorize.net/xml/v1/request.api" method="POST" >

<cfhttpparam type="XML" value="#strXML.Trim()#"/>

</cfhttp>

</cfoutput>

<!--- Output the return message. --->

<cfoutput>

<cfset xmlDoc = XmlParse(#cfhttp.FileContent#)>

<cfset refID="#xmlDoc.xmlroot.refID.XmlText#">

<cfset ResponseCode="#xmlDoc.xmlroot.messages.resultCode.XmlText#">

<cfset Message="#xmlDoc.Xmlroot.messages.message.code.XmlText#">

<cfset MessageTxt="#xmlDoc.Xmlroot.messages.message.text.XmlText#">

<cfset Status="#xmlDoc.Xmlroot.status.XmlText#">

<cfset SubId="#refID#, #ResponseCode#, #Message#, #MessageTxt#, #Status#">

<p>The result is:<br />

#SubID#</p>

</cfoutput>

</cfloop>

    This topic has been closed for replies.

    1 reply

    Owainnorth
    Inspiring
    November 17, 2010

    I can see how you might use multiple threads to parallellelellellelse your web calls and so reduce the time taken, but I don't think it's as easy as using it to "get around timeouts" so much.

    There is also a finite number of threads CF will use (around 10 by default) so sooner or later you'll run out of threads or processing time and your request will be cancelled.

    What is it that actually takes the time? Is it the processing on your page, or is it simply that the remote webservice is a bit flaky?

    bknutzAuthor
    Known Participant
    November 17, 2010

    What actually takes the time is the looping request to auth.net.  There could eventually be thousands of subscriptions that I need to check the status of on a daily basis.  When I run the application as it is, it works fine to 20 or less.  It takes about 5-10 seconds to loop through 20 subscriptions and times out on 40 or more. But, what if I have 2000?  How can I loop through 2000 subscriptions without a timeout error.  My hosting company only allows 30 seconds.

    So, to answer your question of "What is it that actually takes the time?"  I'm assuming it is my approach to obtain Subscription Status of each subscription, but I can think of another way to do it.

    Query the db for subscription ID's > loop over the db results and sending each individual subid to auth.net to status check...then update my db based on the result code I get back from auth.net.  Looping though thousands of db results could take awhile, but I don't see another way.

    Owainnorth
    Inspiring
    November 17, 2010

    It may be worth checking if this'd work, it'd be quicker than trying to figure out what'd happen where.

    Your page loads. Select query of any subscriptions not updated today. Loop from maybe one to five, doing the call then marking the database row as updated.

    Rather than trying to carry on, just get the page to relocate back to itself using cflocation. The page will then just keep doing this until there are no database rows left to process.

    I *believe* CF will count it as a new request each time you cflocate, but I could be wrong. If I were you, I'd probably give that a go until someone comes along and posts up something better.