How to collect and disburse millions worth of payments securely.

This article aims to build a payment disbursement system, for the frequent and high worth of transactions at the order of 100s of Million.

Illustration showing payment collections and disbursements.

The core responsibility of a fin-tech or neo-bank start-up is to make sure money movement happens securely from companies (clients) to respective agencies and employees. Varied payment methods and frequencies make the entire collection and disbursement process a bit complex. While maintaining hyper-growth and operating at the rate of 100s of million dollars, a single miss could make us lose money in a similar order.

What is Disbursement?

  • Employee salaries
  • Payroll expenses
  • Payments to suppliers, contractors, and vendors
  • Reimbursements to workers for out-of-pocket expenses
  • Dividend payments to shareholders
  • Profit distributions to other business owners

Responsibilities and features

  1. Avoid duplicate payments: If beneficiaries get funds at regular frequencies due to dividend or salary. There’s a higher chance of duplicate payments due to the recurring nature of the code.
  2. Avoid over-payments: Disbursing the funds more than the funds collected from the company (including the in-flight amount) is a loss.
  3. Able to consume payment status: It’s not a rare occasion to have payment failure, this module should be able to rollback the calculation if there’s a failure.
  4. Check on the credit-limit: It’s common practice for businesses to allow credit-limit to their clients. At any point in time, the system should able to keep current credit per client.

Data models and Flow

  1. The true amount for payroll, loan, profit: will be stored in trueAmount
  2. Collections: will be stored in amountCollected
  3. Disbursements: will be stored in amountDisbursed

Important metrics to be observed

Overpayment: Amount paid to the agencies higher than the actual liabilities.

Overpayment = amountDisbursed - trueAmount

FroentedAmount: Amount paid to the agencies before collecting from the company.

FrontedAmount = amountDisbursed — amountCollected

DeficitAmount: Amount needs to be collected from the company for tax-liabilities.

DeficitAmount = trueAmount - amountCollected

And Transaction model will be the same and generic with the source and destination of the funds.

Data Models

  • Transactions
    - amount: Amount this transaction is carrying.
    -
    source: The entity where the amount will be debited.
    - destination: The entity where the amount will be credited.
    - transactionDate: This date will help to attribute quarter and year.

Data Flow

The following diagrams illustrate the flow connecting dependent components.

Data-flow diagram representing connection with relevant entities.

Implementation with MongoDB

Hence to work with MongoDB3.6, we will explore atomic operations restrict to a single document. As single document operations being atomic, MongoDB can only offer transaction-like semantics. It’s still possible for applications to return intermediate during the two-phase commit or rollback.

Commit

def commit(transaction):     
BalanceAccount.objects(
company=transaction.company,
transactions__ne=transaction
).modify(
inc__amount=transaction.amount,
push__transactions=transaction
)

Rollback

def rollback(transaction): 
assert transaction.canRollback
BalanceAccount.objects(
company=transaction.company,
transactions=transaction
).modify(
dec__amount=transaction.amount,
pull__transactions=transaction
)

Sample Code Snippet using Django ORM

Further reading

Let’s talk about scalable solutions, arts, and aspirations. co-Founded GreedyGame | IIT Ropar. Found at www.arinkverma.in

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store