Integrate Razorpay with Angular

Yaseen Nadaf
13 min readJan 16, 2020

--

Angular & Razorpay Logo

This article will help you learn how to integrate Razorpay’s standard checkout with Web Application that uses Angular and Python.

This is going to be my first ever technical article and I will be explaining in layman’s terms, if you find this tedious, please cooperate. If anybody has other methods of integrating Razorpay with Angular other than what we are going to see in few seconds, please share your thoughts & methods, also please let me know of mistakes in this article if you find any. I implemented this integration with Angular 8 for frontend but I believe this should work fine with all Angular 2+ versions with slight modifications and Python 3.7.4 for the backend. So without a further due, let’s start.

Few Key Terms:

We are going to make use of some key terms for you to easily understand and for the ease of writing this article.

  • OI → Order ID
  • Txn → Transaction
  • DOM → Document Object Model
  • JWT → JSON Web Token (www.jwt.io)
  • DB → Database
  • RBI → Reserve Bank of India
  • i.e → that is

Requirements

  1. You will need Razorpay’s API credentials as in KEY and SECRET so that you can proceed, you will have to sign-up as a Merchant on Razorpay’s platform.
  2. Understand the complete flow of Txn(s) which is very important, if you don’t understand this, proceeding further might create lots of doubts. So I would suggest please understand this flow which we will see in detail.
  3. Choose razorpay’s feature you are going to use wisely.

The last point in requirements is a serious issue when it comes to the integration of any Payment Gateway as such. Please go through the payment gateway’s website and documentation properly before you start your implementation just by reading half of it.

I am saying this because even I have done the same mistake without realizing that there can be another option that supports the feature that you want to implement and I won’t like it if you also do the same mistake after reading this article. If you are going to implement a subscription flow in specific then have a look at Razorpay’s Subscription feature which will take lots of burden off your shoulders. We are not going to cover it in this article, maybe in the future one, for now, let’s focus on the general implementation.

Generate TEST API keys

So as the first step, after successful sign-up, you will be taken to Razorpay’s Dashboard, go to the settings page then API Keys tab. Let’s be under TEST mode until your implementation finishes and create TEST API credentials. The important point is while you create your API credentials, don’t forget to download it and keep safely somewhere with you or else you will not able to access SECRET of the KEY you just generated for future purposes.

Razorpay’s Payment Flow

Let’s understand this now in detail.

Image describing razorpay’s payment flow
Source: https://razorpay.com/docs/assets/images/tech_flow_2.png

Generally, the Txn begins when the user clicks on the button to proceed to the checkout page, so at this point make sure you have the data ready such as the Amount, the user is going to pay. Once you are ready with data, (1) you will make an HTTP request to your Backend API. (2) Your backend API requests Razorpay API to create an OI for the current Txn. Now you may be wondering as to why do we need an OI for any Txn, creating this OI helps you in following —

  • Prevent multiple payments by binding a single successful payment for a particular order.
  • Auto capture payments immediately after authorization (once the user inputs his preferred method & other details to complete the Txn) for the payment to get settled to your account.

If you don’t create this OI, you may have to handle multiple Txn(s) towards a particular order yourself and capture the payment manually to settle it in your account or else even if the payment has been successful, razorpay auto initiates its Refund Procedure after 5 days of successful Txn if not captured ( i.e if any “Authorised” Txn has not been captured within 5 days ).

Note: Once the user completes the Txn and it has gone successful, then that Txn is called as “Authorised”. If you capture this authorized Txn then it will be updated as “Captured” (meaning the amount will get settled to your account)

(3) Now razorpay will return you the OI that means (4) the OI for our Txn has been created, which you will then save it in a particular record in your DB that has all info about the current Txn or order. (5) After saving this OI in your DB, you will then forward this to your frontend app wherein you will pass all the necessary data to Razorpay’s Checkout Form. (6) Now the user selects his/her preferred method and completes the txn and once it goes successful, razorpay will return a response to your frontend app which will have razorpay_payment_id, razorpay_order_id, razorpay_signature (7) this response will then be passed to your backend where you will have to generate your signature using razorpay_payment_id, razorpay_order_id, key secret (key secret will be available in your downloaded API key file which you generated in the first step) and SHA256 algorithm, construct an HMAC hexdigest of the result from the SHA256 algorithm, compare your generated signature against razorpay_signature if they match that means the Txn has gone successful (a way for you to identify and make sure it’s successful), payment will get auto captured based on a condition and wah-lah you can then take further steps as per your need.

Notes:

  1. As per guidelines, you must not save user’s payment credentials unless you are certified from respective institutes such as PCI and others. If any user wants to save their card or other details for faster checkouts in the future they can do so on razorpay and since razorpay has all necessary certifications, razorpay can store these credentials on their platform ensuring user’s security.
  2. In the 6th point of Payment Flow, we considered that Txn has been successful. If Txn fails for any reason, then razorpay will take care of it and provides an option for the user to Retry for the same OI. Hence there is no need for you to handle Txn failures. Although there is one such condition that you must handle which is if the user closes the form while the Txn is in progress, we will see how to handle it in the Implementation.
  3. In the 7th point of Payment Flow, I mentioned that payment will get auto-captured if Txn has gone successful based on a condition that is while you generate OI in your backend (in 2nd point of Payment Flow), there is an option to specify whether the Txn can be auto captured or not by using a key called payment_capture, once the Txn has been authorized i.e. it has been successful.

Front-End Implementation

So now that we have understood the payment flow and have our API keys ready, let’s jump right into the implementation.

I will proceed further by assuming that you already have an Angular project, I will be using Python and it’s Flask framework at the backend for writing APIs. I will be only writing important code snippets or how your APIs should be structured and the rest logic you have to implement according to your requirements.

index.html

In your Angular project, inside index.html file include razorpay’s checkout.js as below —

index.html

window-ref.service.ts

Now let’s create Window Ref service through CLI command to access the DOM window object via angular scope.

ng g s window-ref --module=app

g to generate s to specify service and --module=app only if you have more than one module in your project other than the app.module.ts. This will generate a window-ref service file with boilerplate code, replace that with the following code —

window-ref.service.ts

If your project is Angular Universal then use the following code —

window-ref.service.ts for Angular Universal

payments.component.ts

Now let’s see the component where you may call the Razorpay checkout form, let’s say this component name is payments, let’s create it using CLI command.

ng g c payments --module=app

g to generate c to specify components and --module=app only if you have more than one module. Here goes the code —

payments.component.ts — Call Razorpay Checkout Form

Back-End Implementation

Up to this point, we covered our frontend, now let’s check the backend. You can have all the APIs related to Txn(s) in one single file.

I am assuming that you have taken proper measures to secure your APIs because whenever you are integrating payment gateways, the communication between your frontend & backend must be secured enough and the data passed between them must be properly encoded to avoid any kind of breach. I have used JWT & Role Management to secure my APIs and to provide authorized access to users in my project.

As a first step, let’s install the razorpay library for python. For other info such as python version support, etc, please check out their platform.

  • Download the latest Source code zip file from the Releases section on GitHub.
  • Unzip the file.
  • Navigate to the unzipped folder in your terminal, and run pip install razorpay to install this library.

Once installed, let’s create payments.py to write our APIs and take the necessary steps of importing the libraries and set up the razorpay client.

import razorpay
import hmac
import hashlib
razpay_key = '<rzp_test_key>'
razpay_secret = '<test_key_secret>'
rzpay = razorpay.Client(auth=(razpay_key, razpay_secret))
rzpay.set_app_details({"title" : "<Your App Name>", "version" : "<Your App Version>"})

Note that I have imported hmac & hashlib also which we will be making use of in our APIs.

Order API

In this API, after collecting the data from the frontend, if there is any logic you might want to implement then do the needful after which you’ll create a record in your DB which will have all the info about the Txn and this will have a key let’s say receipt_id whose value must be unique. After creating the record, let’s prepare the data that you should pass to razorpay’s order API that accepts the following arguments —

rzData = { 
"amount": amount of order,
"currency": currency of order,
"receipt": receipt_id of order,
"payment_capture": 1 or 0,
"notes": notes for order (optional)
}
  • amount → its value must be integer & in paise format. For example: To create OI for the amount of Rs 1225, you must specify this as 122500 i.e including paise without a decimal point.
  • currency → its value must be a string. For example: To specify Indian currency, you must pass ‘INR’. To support other currencies, please contact the razorpay’s support team.
  • receipt → its value can be either integer or string. Assign the receipt_id value to this key, which you gained after creating the record for the current Txn above.
  • payment_capture → its value must be boolean. Note that if you specify this field to be True i.e 1, then as soon as the user completes the Txn, it will be auto-captured and there won’t be any necessity to capture the Txn by you and if the field is False i.e 0, then you will have the control whether you should capture the Txn or not.
  • notes → this field is optional and its value can include key-value pairs but neither array nor any key containing array value.

Bonus Point

I would like to suggest specifying payment_capture value to be False because in cases where Txn will be under processing state either because of user’s network issue or user bank’s technical issue, which may or may not become successful, such Txn(s) are called Late Authorised if it goes successful after certain period otherwise it will be Failed Txn. Now chances of any Txn to be Late Authorized is less than 0.5% as specified by razorpay’s docs. If you desire to handle these Late Authorized Txn(s), you may do so through following razorpay’s docs, but when chances of them being less than 0.5% or in situations where you are providing the service or product keeping some time constraint such as Food Delivery within 30 minutes so and so forth, it doesn’t make any sense to handle these Txn(s) rather you may issue the Refund to the user and here again, razorpay takes care of it by initiating their refund procedure after 5 days if you don’t capture any such Late Authorized Txn(s).

Now pass the data you just prepared to razorpay’s order API which will then return OI using following function —

rzresp = rzpay.order.create(data=rzData)

Save this OI in the record in DB which has the receipt_id value you specified while creating the current OI. After saving, pass this OI you just created along with any necessary data and HTTP response status to the frontend.

order-api part of payments.py

Verify Txn API

You should be making an HTTP request to this API only when the Txn has been successful and you received a response from razorpay in the frontend that contains razorpay_payment_id, razorpay_order_id & razorpay_signature otherwise, you can show Txn failed status in your frontend itself without the necessity to call this API.

Assuming that you specified the value of payment_capture to be False while generating the OI, now send the response data which you received from razorpay to this API along with any other necessary info from the frontend.

Fetch the record from your DB that has razorpay_order_id value which you have already saved in your Order API. Now let’s generate SHA256 algorithm HMAC hexdigest which will then be compared against razorpay_signature.

def hmac_sha256(val):
h = hmac.new(razpay_secret.encode("ASCII"), val.encode("ASCII"), digestmod=hashlib.sha256).hexdigest()
print(h)
return h

Please note that you should be passing your secret as the first argument by encoding in bytes format and then the second argument after concatenating razorpay_order_id & razorpay_payment_id and encoding in bytes format. You should concatenate in razorpay_order_id + “|” + razorpay_payment_id format only. You may call the above function to create your signature as follows —

generated_signature = hmac_sha256(reqData["razorpay_order_id"] + "|" + reqData["razorpay_payment_id"])

then compare your generated signature against razorpay_signature if they match, it means the Txn is successful and you can capture the Txn manually for the amount to get settled to your account in the following format —

res = rzpay.payment.capture(reqData["razorpay_payment_id"], reqData["amount"], {"currency":"INR"})

Note: Amount to be specified should be the same as the original amount while creating the OI.

If your signature and razorpay_signature doesn’t match either because of some technical issue at your end while generating the signature or some other specific reason, then don’t capture the payment and send an appropriate HTTP error status to your frontend based on which you can identify that there has been an error while comparing the signatures and then you can show your users the Txn ID/Receipt ID and Date of this Txn using which if any of your users contacts you regarding such Txn, you have an option either to capture that payment manually via logging into your Razorpay Dashboard or let your users know that if their amount has been debited from their bank account, it will be refunded in 5 working days from the date of the Txn without taking into account the processing time of their bank.

The standard settlement cycle for domestic payments is T+3 and for international payments is T + 7 working days, with T being the date of transaction capture. This implies that payments would be settled to the bank account registered with razorpay after 3 or 7 working days respectively. For detailed info on settlements please check out here.

verify-txn api part of payments.py

Failed-Txn API

You will be making an HTTP request to this API to handle the situation where the user has closed the Razorpay’s Checkout Form which may or may not result in Failed Txn. The occurrence of any user closing the checkout form can be either when the user doesn’t want to complete the Txn or the Form got closed by the user unintentionally.

In such situations, you already will have some data available to you from the checkout form in the frontend, for example, you could have TxnID/Receipt ID, Date of Txn, razorpay_order_id & other important data which you may have taken as notes according to your requirements. Make an HTTP request to this API along with the data you have in frontend after the form got closed, wherein you may fetch the record from your DB using razorpay_order_id and since the Txn has not been completed or failed due to timeout or the form got closed unintentionally, you may delete such unwanted records from your DB to reduce the storage.

Another option would be that you preserve such records and help the user complete the Txn for the same razorpay_order_id by notifying the user of such situations either via Email or SMS or both and include a call to action button or Url.

This API’s structure may appear as follows —

failed-txn part of payments.py

Test your Integration

Once your integration has been completed, test every possible situation of Txn using test cards provided by razorpay. Once its working fine and you are satisfied, switch to LIVE mode in your razorpay dashboard and replace your test key credentials with the live key in payments.py file before going into production.

Other Important Info

Razorpay provides a lot of other options as well for integration. They have two types of integration methods available for Web Applications i.e Standard checkout and Custom checkout. We have covered the standard one in this article.

For Mobile Applications they support Android Standard & Custom checkout, IOS Standard & Custom checkout and SDK integrations for Cordova, React Native and Flutter. Support for Server languages such as Python, PHP, Ruby, Nodejs, .Net & Java. They have several eCommerce plugins as well, check them out.

Txn Fees

Razorpay charges you 2% of your domestic & 3% of your international Txn(s) as their Txn fees. As per RBI guidelines, Txn(s) with the amount below INR 2000, razorpay won’t charge you any tax (GST) whereas if the amount goes above INR 2000, razorpay will charge you a tax (GST) of 18% over Txn fees. Calculate your service/product prices accordingly.

Please make sure that you check out their website once to remain updated on their Txn prices.

Resources

  • You can check out the example source code files here.
  • Razorpay’s documentation here.
  • Razorpay’s API reference guide here.
  • Razorpay’s python library and python APIs reference here.
  • If you have any other queries related to Razorpay, you may consult with their Technical/Support Team or check out their knowledge base and I will always be available to you through the comment section.

Lastly, If you are still here, I would like to appreciate your cooperation and thank you to read out this article.

--

--

Yaseen Nadaf

Full Stack Developer, enthusiastic and excited to read, learn & code. Linkedin — https://www.linkedin.com/in/yaseen-nadaf/