I have a website which uploads job postings to my API, there are multiple steps to doing this:
Upload a logo image to file storage.
Insert data about the job posting into a database.
Process a payment with a third-party provider.
Send an email through a third-party provider.
In general, you can imagine other steps being present here in different applications, e.g. getting some information from a 3rd party API, validating a ReCAPTCHA, updating Google Indexing API, sending an SMS, etc., etc.
Since all of these are using 3rd parties and are independent of the server handling the API call, any one of them can fail to leave some of the steps successfully completed and others not (e.g. logo updated but payment not collected).
My question is how are errors in these kinds of multi-step actions between clients and servers typically handled in production systems? Are there any accepted standards or best practices?
I have considered:
Not handling errors and just hoping it all goes through without error.
Defining an 'undo' function on the backend for each of the steps and if one of the steps fails, then calling that on the previous steps. With actions consisting of many steps, this could turn into spaghetti code pretty quickly, and some steps cannot be undone so easily - e.g. sending an email.
Creating a separate endpoint on the backend for each of the steps and letting the client call each one in turn. This could also use an 'undo' API endpoint so if the client receives an error on one of the steps it can then undo all previous steps. This has the advantage of allowing the client to estimate the progress of the action being completed, i.e. it could display '1 of 5 steps completed' to the user.
Creating a row in a DB (or in-memory database?) for each action and when each step is completed marking the corresponding column as completed. When every column in the row is completed then sending a response back to the user.