Integrating Linked Accounts Beta API, Orders API, and Razorpay Webhook in a Week

Jeevan Surendran
Turtlewig
Published in
8 min readSep 9, 2020

A few weeks ago, our dev team had to come up with creating a marketplace payment solution. To give a little bit of context on what we had to solve, to make files hands-off easier and collect payments in a single place. Freelancers can upload their files they are supposed to share with their clients to our platform. Later they can request their clients for money. Once a client pays, they get access to download all the files they paid for.

So I started doing my research and came across many online payment services, going through various options and exploring a little I came across Razorpay API’s which seemed really promising.

To split up on what I have to do:

  1. I had to come up with a centralized database and accounts management system to store the user’s bank details.
  2. I had to provide a feature where payments made by the client are transferred to freelancers.
  3. Provide a checkout option with various payment methods for the clients to make payment.
  4. Real-time updates on payments, transactions processed, and resolving failed payments.

I started going through docs and came across some API’s that would work for me.

So my idea to solve my tasks were:

  1. Use Accounts API [Beta] to create a pseudo account for a user. This account would contain all the bank information given by the user. API returns an ‘id’, which is needed later. (Eg: acc_gHQwerty123ggd)
  2. Use Orders API to maintain every payment being made related to a single entity in the same place. Also, create transfers using Route API to transfer funds. An order with transfers require account_id to transfer amount, once paid.
  3. Use the Checkout.js API to checkout and make payment for an order.
  4. Use webhooks to subscribe for realtime updates about payments and orders. I can later integrate this webhook in our backend to update our database and monitor changes.

So if this seems a little intimidating, that’s okay. Reading more would clear up stuff.

1. Linked Accounts creation using Accounts API [Beta]

A Linked Account is similar to a partial Razorpay account. Linked account users have access to a dashboard, settlement management, refunds, and reconciliations by interacting with these linked accounts. Creating a Linked account was limited to an admin’s dashboard or a developers dashboard, which was an issue. Unlike other services, we do not want our users to create an account in Razorpay and provide the account_id to us. So after reaching out to Razorpay, we were made aware of a beta API that allowed creating a linked account in our platform, and this was called Accounts API.

Accounts API[Beta] lets us create a pseudo account that holds bank information and provides an account_id. We use this account_id to route money into that account while making orders and payments.

Creation of a linked account :

Linked account creation using accounts API [BETA] in curl or REST

or

Linked account creation using accounts API [BETA] in Node JS

So a response would be:

An example response from our API call

Here we save our id (I call it account_id because it is in the format acc_gHQwerty123ggd) so that we can use it later for creating orders or payment requests.

2. Creating Payment Requests using Orders API

Understanding Orders?

An order is an entity that is related to a certain amount of money that has to be paid. This means an order is somewhat similar to a restaurant order or an online shopping order. Once a restaurant order is created, you can make payment to fulfill this order. Payment is also another entity, which is an abstraction to a single payment attempt. So once you place your restaurant order and you are asked to pay, you can fulfill the payment. This payment could be paid with a debit card, internet banking, UPI, or more. Once you make a payment, it has good chances for it to fail, you might try again and it might fail again too. Hence, you would have multiple payment entities that have failed. It can also be successful, processed, and paid. You can handle all the payment entities and statuses under a single object called order.

Why Orders?

Razorpay enables you to create Orders that can be linked to payments. It is recommended to associate every payment with an Order as it helps in:

  • Preventing multiple payments.
  • Automatically capturing payments.

What are payments and capturing payments?

A payment entity is a detailed object that stores data about a single payment attempt. It contains multiple information that decides the state of a payment.

here is an example of a payment entity:

Here the status of the payment is important because it indicates whether a payment has been made or not.

A payment status could be one of the following :

  • created — created a payment request
  • authorized — the payment has been done and is authorized by the bank
  • captured — Once the payment is authorized by the customer’s bank, you must verify if the authorized amount deducted from the customer’s account is the same as the amount paid by the customer on your website or app.
  • refunded — Refund a paid amount or a failed request
  • failed — Failed to make the payment because of various reasons

Handling all the hassles between these payments in honestly a mess and they themselves recommend us to use Orders API.

Order flow while Making a payment :

Now we create an order from Orders API using Transfer:

Creating order in curl

or

Order creation in node

Response from API:

Understanding the request and response :

The request object contains information about the amount, transfers, payment capture, and holds. In my request, an amount of ₹20 splits to two accounts. Accounts account_id in the request create a transfer to specified linked accounts. Transfers to a linked account are scheduled using the on_hold and on_hold_until field. Since payment capture is enabled, we need not authorize the payments and they will be captured automatically.

From the documentation these are the following status for an order:

  • created — When you create an order it is in the created state. It stays in this state till payment is attempted on it.
  • attempted — An order moves from created to attempted state when payment is first attempted on it. It remains in the attempted state till one payment associated with that order is captured.
  • paid — After the successful capture of the payment, the order moves to the paid state. No further payment requests are permitted once the order moves to the paid state. The order stays in the paid state even if the payment associated with the order is refunded.

Also, if the amount for orders and routes don’t add up. The remaining amount is debited to the main bank account associated with the admin account.

Now we save the order_id so that we can use it to pay the requested amount and the requested amount can be processed via checkout.js

3. Making payment for a payment request(or an Order) using Checkout :

We cannot make a payment for an order from our backend without using checkout.js for obvious reasons. Hence, your front web or android app must integrate this checkout API. Checkout provides a custom color theme, running offers on various payment methods, and a test and a live mode.

Order flow:

Previously, we have obtained an order_id, which can be used to checkout.

To integrate checkout for web:

  1. Add this script to your root html file.
<script src="https://checkout.razorpay.com/v1/checkout.js"></script>

2. Add the following code in your front end.

3. If these steps don’t open up a UI to pay your amount for the order, then follow the documentation here.

Here we pass a handler function to obtain the response once paid. This can be useful because you can obtain the payment status.

Call the function openPaymentScreen to open up a standard checkout integration when payment needs to be paid.

4. Do follow the steps from documentation to verify the signature of the response obtained.

And voila you have successfully made a payment, and also routed the money to a linked account for which the order id was created.

Order flow for transfers

But wait are we done yet?

I also have to come up with a system to make the payments live and also handle payment status changes in real-time.

4. Webhooks and realtime payment updates!

A webhook is an endpoint that a developer creates so that they get a callback when there are certain changes taking place in payment and order statuses. Here we use Razorpay as a service and the callback we provide is a HTTP endpoint that Razorpay calls when there is a change in an entity we want to observe.

You can check out the documentation to understand all the different state changes you can observe.

This image below may help you get a better idea:

Creating a webhook

Host your code and obtain a valid URL.

Connecting your webhook in Dashboard:

Go to dashboard > Settings and the webhook menu

Do test your webhook and check if it’s working.

And again voila! you have your own small payment ecosystem. If you are confident enough with your implementation. You could go ahead and test with live keys!

Do check out routes to learn more about splitting payments and linking accounts in between.

Try www.turtlewig.com to see our payment integrations in real-time. We provide solutions for freelancers to handoff files, collect payments, and increase productivity for freelancers. If interested, join our waitlist and obtain access to our private beta and a personal onboarding process.

Special thanks to Aniruddha Mysore, Gautam Padiyar, Akash Hamirwasia, and Purva for making this happen.

Also, try Razorpay.

--

--