WooCommerce Order Status Choices

I recently put together a custom payment gateway for WooCommerce—an offshoot of a client project that I since spent quite some hours tweaking and refining—and, as always, had to make a fair amount of choices. One particular type of choice had to do with order statuses throughout the payment processing flow.

Some Background

This specific payment method required quite a few external API calls, all of which—however unlikely—could possibly fail. If that was to happen, I asked myself, should I then mark the order ‘On-hold’, ‘Failed’, or simply leave it ‘Pending’?

Also, the nature of this payment service is such that it takes at least a day or so to finally verify and confirm payment. That alone made me want to use ‘On-hold’ (which would also reduce stock) only if payment coming through was close to guaranteed.

The Docs

As mentioned in the WooCommerce documentation, an order should never really stay ‘Pending’ (i.e., ‘unpaid’) unless something went wrong communicating with the external payment provider. (Seems ‘Pending’ is an option, then, for dealing with a failed API call!)

Note: an order that remains pending for a little while will automatically get canceled. ‘On-hold’ pretty much means payment’s on the way but unconfirmed.

‘Failed’ really means ‘payment failed’. (‘Processing’ means: in the process of being packaged or shipped, something like that. And ‘Complete’ is just that: fully done with.)

But: different gateways will sometimes deal with this differently. There’s no definite right or wrong, really.

One Possible Solution

In the end, I decided to keep things simple and went with the following reasoning: any payment failure, whatever the cause, results in a failed order. Success leads to an ‘On-hold’ status.

The final verification (the one that hopefully results in a ‘Processing’ status) is always done through a separate WP cron job.

Order notices are used to communicate back to customers in case anything goes wrong.

Of Note

Error notices are not displayed on the so-called ‘Pay for Order’ screen or if the cart’s already been emptied. (Mind you, the overall chance of ending up in this situation is rather small. Still, I decided to not clear the cart until the very end of the ordering process, despite, well, other downsides to that approach.)