skip to Main Content

In the backend of my app, there is a route that first process payment and then writes to a collection in my MongoDB. So:

await call_payment_vendor_api();
// system fails here
await write_to_collection();

Now there is an inconsistency in the system. How do I recover from that?

3

Answers


  1. My solution would be that if your backend starts, you check the payment vendor API for any payments that have been payed, but not yet been processed by your application.

    Different way would be to have multiple instances over multiple hosts (e.g. load-balancing) to ensure that an instance stay up.

    Login or Signup to reply.
  2. Transactions across systems are often a bit tricky and there are multiple approaches to handle this. There is no silver bullet, though, which is why many so-called microservice systems end up as distributed monoliths.

    The most straightforward way if you’re in a sync-context (I.e. need to answer a web request immediately ): try/catch the exception from MongoDB, then refund the payment if it fails.

    For a better user experience, I’d try putting the writing into a background job queue, which processes the pending update and maybe retries a couple of times before giving up and refunding. Or maybe escalates to a technical support who can take a look and maybe fix things through a back-office admin UI.
    But again, in the context of a web request, you might have to poll the job status to update the website or re-design the flow altogether.

    Another possibility:
    In MongoDB, create a transaction, first write your data, then call out to the payment provider. If they confirm, you’ll only have to commit the transaction which (usually) is much less likely to fail.

    Login or Signup to reply.
  3. I have two ways to solve this.

    1. The First method is to create an exception handling in your code to save the error history. And then you can make an automatic function to execute write_to_collection() for specific data in that database.
    try {
        await call_payment_vendor_api();
        // system fails here
        await write_to_collection();
    } catch(err) {
        await save_error_history_to_database();
    }
    
    1. The Second method is to make sure your vendor API has a Reversal Payment Process. You can return the money to the specific client by calling Reversal API.
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search