0

Good day, please I am trying to write a code that removes money from a certain account document on mongo db and credits the other account, in doing this I am creating a transaction, I can't seem to figure out the logic to solve the problem

const Transactions = require("../models/transaction");
const Accounts = require("../models/account");
const { StatusCodes } = require("http-status-codes");
const { BadRequestError, NotFoundError } = require("../errors");

/**
 * Credits an account by an amount
 *
 * @param {String} account_number the account number of the account to be credited
 * @param {Number} amount the amount to be credited
 */
const credit = async (account_number, amount) => {
  return await Accounts.findOneAndUpdate(
    { account_number },
    { $inc: { account_balance: amount } },
    { new: true }
  );
};

/**
 * Debits an account by an amount
 *
 * @param {String} account_number the account number of the account to be debited
 * @param {Number} amount the amount to be debited
 */
const debit = async (account_number, amount) => {
  return await Accounts.findOneAndUpdate(
    { account_number },
    { $inc: { account_balance: -amount } },
    { new: true }
  );
};

const transfer = async (req, res) => {
  // debit the sender
  // credit the recipient
  // create the transaction
  // return a response to throw an error
};

module.exports = { transfer };

This is the transaction schema

const { Schema, model, Types } = require("mongoose");

var TransactionSchema = new Schema(
  {
    description: {
      type: String,
    },
    amount: {
      type: Number,
      require: true,
    },
    recipient: {
      type: Types.ObjectId,
      ref: "Account",
      required: true,
    },
    sender: {
      type: Types.ObjectId,
      ref: "Account",
    },
    type: {
      type: String,
      enum: ["Debit", "Credit", "Reversal"],
      required: true,
    },
  },
  { timestamps: true }
);

module.exports = model("Transaction", TransactionSchema);

How do I please handle the transfer logic

  • Some useful info: (1) [What is a database transaction](https://stackoverflow.com/questions/974596/what-is-a-database-transaction) (2) [MongoDB Transactions](https://docs.mongodb.com/manual/core/transactions/) (3) I think you want to do the debit and the credit on two accounts - within a transaction. – prasad_ Feb 21 '22 at 15:52

1 Answers1

1

Now it depends on where you are, the country, and how the banking system works. In my country, you always need to generate a unique sessionID before the transaction(i.e during name validation process and another when initiating the transfer. Assuming all the pre-validation has been done, your current logic will require additional fields which will come in handy when you are doing after the transaction but should work as is. However the following is critical:

  1. Ensure that you execute the transfer logic within a Transaction(ACID) this prevent a case where you have debit without corresponding credit or vise- versa(this will surely mess-up your trial-balance). See an example here! This also locks the doc to ensure no other transactions occurs until this has been completed (success or fail).
  2. You should include the charges/ deduction in your transfer function.
  3. not really necessary if using a Mongo Transaction-check the balance before and balance after for both records, just to be doubly sure.
  4. You should also have a wallet/account where these credit and debit are persisted against
cigien
  • 57,834
  • 11
  • 73
  • 112
d3xt3r
  • 11
  • 1