Authorize.net and ARB Race Conditions
So I've had a problem on a recent project ever since I started using Authorize.net's recurring billing system. While it works fantastically for the most part, I've had issues with canceling subscriptions during their nightly billing process. The issue at hand is that Authorize.net doesn't actually cancel a subscription if a transaction is declined. They leave the subscription active and will just continue to try again and again until the subscription actually ends.
The above scenario doesn't really work for a subscription based website. Perhaps it does for a magazine, but if a user's payment on a site fails, the subscription should be immediately cancelled, the user should be notified, and then they can attempt to renew the subscription at their convenience.
That's all well and good, no problem. When I receive the nightly post from Authorize.net with all of the success and failures, I just turn right back around and submit a cancellation request for each transaction that was declined. The request to cancel the subscription looks like this:
And the response back from Authorize.net looks like this:
That's awesome right!? I sent a request, they responded that it was successful, all is peaches and cream. **WRONG**. Apparently, my cancellation request gets to Authorize.net's ARB api before their own system adds the transaction to the subscription and updates the next billing date. This results in me getting a successful response back from Authorize.net, and then Authorize.net overwriting my cancellation with the results from their own transactions. So the flow is going something like this:
* Authorize.net sends post to my processing script
* Read the results, and if the transaction is declined:
* Update my user record
* Update my subscription record
* Email the user that there was a problem
* Send an HTTP request to ANet to cancel the subscription
* I receive a success from Authorize.net
* Authorize.net finishes their processing and then updates the same subscription with an Active status and a new billing date, wiping out my cancellation
Authorize.net verified that this was exactly what's happening and told me that I need to queue up my cancellations that happen during the nightly billing, and run them no sooner than one hour after I receive their posts. Shouldn't my api updates take precedence over Authorize.net's? According to the ANet API it shouldn't even be possible to "un-cancel" a subscription. Once it's canceled, you have to create a new subscription.
Anyway, the main point of this post was to let other's using the ARB API to be careful about your updates during ARB's nightly posts. I've created a queue table for this purpose, and just drop all cancellations into the table and run them on a schedule so that they're all posted 2 hours after they're received (figured I should give ANet plenty of time).