I can also confirm that this is the way things are. It's very difficult to know whether a subscription has failed. If a subscription payment is declined after the first payment, there's currently no way to be notified of that fact. No webhook notification is sent, and the status of the subscription remains as active.
Here's my method for detecting a failed subscription transaction:
- For each customer, we save in our db the user's subscription id, subscription status etc.
- Run a cron task that:
- Does a GetUnsettledTransactionList request to fetch all unsettled transactions
- For each unsettled transaction with transactionStatus of declined:
- Use the transId to do a GetTransactionDetails request
- Check if the transaction type is AuthCaptureTransaction (all of our non subscription transactions are AuthOnlyTransactions followed by PriorAuthCaptureTransactions, so we know that an AuthCaptureTransaction is a subscription payment. This probably won't work for everyone.)
- Get the customer id to fetch the user from our db (you have to pass the customer id to the create subscription request)
- If the user is marked as active in our db, immdiately send a CancelSubscription request (since auto retry is broken and has unpredictable behavior) then mark the user as terminated in our db
This algorithm evolved over months of relying on webhooks to work properly and being sorely disappointed. There's essentially no way to replicate this stuff in sandbox, so you don't find out about it until you shoot yourself in the foot in production. If I could go back to 2017, I would roll my own subscription system with a job scheduler and transaction requests. I would've saved time in the long run from all the time I've spent dealing with arb not working properly. Case in point: this thread