├── .github
└── FUNDING.yml
├── .gitignore
├── README.md
├── package-lock.json
├── package.json
├── src
└── index.ts
└── tsconfig.json
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
13 | custom:
14 | - https://buy.stripe.com/5kAdRHbfx9e32Y028a
15 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | lerna-debug.log*
8 | .pnpm-debug.log*
9 |
10 | # Diagnostic reports (https://nodejs.org/api/report.html)
11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
12 |
13 | # Runtime data
14 | pids
15 | *.pid
16 | *.seed
17 | *.pid.lock
18 |
19 | # Directory for instrumented libs generated by jscoverage/JSCover
20 | lib-cov
21 |
22 | # Coverage directory used by tools like istanbul
23 | coverage
24 | *.lcov
25 |
26 | # nyc test coverage
27 | .nyc_output
28 |
29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
30 | .grunt
31 |
32 | # Bower dependency directory (https://bower.io/)
33 | bower_components
34 |
35 | # node-waf configuration
36 | .lock-wscript
37 |
38 | # Compiled binary addons (https://nodejs.org/api/addons.html)
39 | build/Release
40 |
41 | # Dependency directories
42 | node_modules/
43 | jspm_packages/
44 |
45 | # Snowpack dependency directory (https://snowpack.dev/)
46 | web_modules/
47 |
48 | # TypeScript cache
49 | *.tsbuildinfo
50 |
51 | # Optional npm cache directory
52 | .npm
53 |
54 | # Optional eslint cache
55 | .eslintcache
56 |
57 | # Microbundle cache
58 | .rpt2_cache/
59 | .rts2_cache_cjs/
60 | .rts2_cache_es/
61 | .rts2_cache_umd/
62 |
63 | # Optional REPL history
64 | .node_repl_history
65 |
66 | # Output of 'npm pack'
67 | *.tgz
68 |
69 | # Yarn Integrity file
70 | .yarn-integrity
71 |
72 | # dotenv environment variables file
73 | .env
74 | .env.test
75 | .env.production
76 |
77 | # parcel-bundler cache (https://parceljs.org/)
78 | .cache
79 | .parcel-cache
80 |
81 | # Next.js build output
82 | .next
83 | out
84 |
85 | # Nuxt.js build / generate output
86 | .nuxt
87 | dist
88 |
89 | # Gatsby files
90 | .cache/
91 | # Comment in the public line in if your project uses Gatsby and not Next.js
92 | # https://nextjs.org/blog/next-9-1#public-directory-support
93 | # public
94 |
95 | # vuepress build output
96 | .vuepress/dist
97 |
98 | # Serverless directories
99 | .serverless/
100 |
101 | # FuseBox cache
102 | .fusebox/
103 |
104 | # DynamoDB Local files
105 | .dynamodb/
106 |
107 | # TernJS port file
108 | .tern-port
109 |
110 | # Stores VSCode versions used for testing VSCode extensions
111 | .vscode-test
112 |
113 | # yarn v2
114 | .yarn/cache
115 | .yarn/unplugged
116 | .yarn/build-state.yml
117 | .yarn/install-state.gz
118 | .pnp.*
119 | # Logs
120 | logs
121 | *.log
122 | npm-debug.log*
123 | yarn-debug.log*
124 | yarn-error.log*
125 | lerna-debug.log*
126 | .pnpm-debug.log*
127 |
128 | # Diagnostic reports (https://nodejs.org/api/report.html)
129 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
130 |
131 | # Runtime data
132 | pids
133 | *.pid
134 | *.seed
135 | *.pid.lock
136 |
137 | # Directory for instrumented libs generated by jscoverage/JSCover
138 | lib-cov
139 |
140 | # Coverage directory used by tools like istanbul
141 | coverage
142 | *.lcov
143 |
144 | # nyc test coverage
145 | .nyc_output
146 |
147 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
148 | .grunt
149 |
150 | # Bower dependency directory (https://bower.io/)
151 | bower_components
152 |
153 | # node-waf configuration
154 | .lock-wscript
155 |
156 | # Compiled binary addons (https://nodejs.org/api/addons.html)
157 | build/Release
158 |
159 | # Dependency directories
160 | node_modules/
161 | jspm_packages/
162 |
163 | # Snowpack dependency directory (https://snowpack.dev/)
164 | web_modules/
165 |
166 | # TypeScript cache
167 | *.tsbuildinfo
168 |
169 | # Optional npm cache directory
170 | .npm
171 |
172 | # Optional eslint cache
173 | .eslintcache
174 |
175 | # Optional stylelint cache
176 | .stylelintcache
177 |
178 | # Microbundle cache
179 | .rpt2_cache/
180 | .rts2_cache_cjs/
181 | .rts2_cache_es/
182 | .rts2_cache_umd/
183 |
184 | # Optional REPL history
185 | .node_repl_history
186 |
187 | # Output of 'npm pack'
188 | *.tgz
189 |
190 | # Yarn Integrity file
191 | .yarn-integrity
192 |
193 | # dotenv environment variable files
194 | .env
195 | .env.development.local
196 | .env.test.local
197 | .env.production.local
198 | .env.local
199 |
200 | # parcel-bundler cache (https://parceljs.org/)
201 | .cache
202 | .parcel-cache
203 |
204 | # Next.js build output
205 | .next
206 | out
207 |
208 | # Nuxt.js build / generate output
209 | .nuxt
210 | dist
211 |
212 | # Gatsby files
213 | .cache/
214 | # Comment in the public line in if your project uses Gatsby and not Next.js
215 | # https://nextjs.org/blog/next-9-1#public-directory-support
216 | # public
217 |
218 | # vuepress build output
219 | .vuepress/dist
220 |
221 | # vuepress v2.x temp and cache directory
222 | .temp
223 | .cache
224 |
225 | # Docusaurus cache and generated files
226 | .docusaurus
227 |
228 | # Serverless directories
229 | .serverless/
230 |
231 | # FuseBox cache
232 | .fusebox/
233 |
234 | # DynamoDB Local files
235 | .dynamodb/
236 |
237 | # TernJS port file
238 | .tern-port
239 |
240 | # Stores VSCode versions used for testing VSCode extensions
241 | .vscode-test
242 |
243 | # yarn v2
244 | .yarn/cache
245 | .yarn/unplugged
246 | .yarn/build-state.yml
247 | .yarn/install-state.gz
248 | .pnp.*
249 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React Razorpay
2 |
3 | Integrate Razorpay Payment gateway in your react application.
4 |
5 | ## Basic Example
6 |
7 | ```js
8 | // Import the package
9 | import useRazorpay from "react-razorpay";
10 | ```
11 |
12 | ```js
13 | const [Razorpay] = useRazorpay();
14 |
15 | const handlePayment = async (params) => {
16 | const order = await createOrder(params); // Create order on your backend
17 |
18 | const options = {
19 | key: "YOUR_KEY_ID", // Enter the Key ID generated from the Dashboard
20 | amount: "50000", // Amount is in currency subunits. Default currency is INR. Hence, 50000 refers to 50000 paise
21 | currency: "INR",
22 | name: "Acme Corp",
23 | description: "Test Transaction",
24 | image: "https://example.com/your_logo",
25 | order_id: "order_9A33XWu170gUtm", //This is a sample Order ID. Pass the `id` obtained in the response of createOrder().
26 | handler: function (response) {
27 | alert(response.razorpay_payment_id);
28 | alert(response.razorpay_order_id);
29 | alert(response.razorpay_signature);
30 | },
31 | prefill: {
32 | name: "Piyush Garg",
33 | email: "youremail@example.com",
34 | contact: "9999999999",
35 | },
36 | notes: {
37 | address: "Razorpay Corporate Office",
38 | },
39 | theme: {
40 | color: "#3399cc",
41 | },
42 | };
43 |
44 | const rzp1 = new Razorpay(options);
45 |
46 | rzp1.on("payment.failed", function (response) {
47 | alert(response.error.code);
48 | alert(response.error.description);
49 | alert(response.error.source);
50 | alert(response.error.step);
51 | alert(response.error.reason);
52 | alert(response.error.metadata.order_id);
53 | alert(response.error.metadata.payment_id);
54 | });
55 |
56 | rzp1.open();
57 | };
58 | ```
59 |
60 | Offical Docs of Razorpay: https://razorpay.com/docs/payment-gateway/web-integration/standard/
61 |
62 | # Full Code Example
63 |
64 | ```ts
65 | import { useCallback } from "react";
66 | import useRazorpay from "react-razorpay";
67 |
68 | export default function App() {
69 | const [Razorpay] = useRazorpay();
70 |
71 | const handlePayment = useCallback(() => {
72 | const order = await createOrder(params);
73 |
74 | const options: RazorpayOptions = {
75 | key: "YOUR_KEY_ID",
76 | amount: "3000",
77 | currency: "INR",
78 | name: "Acme Corp",
79 | description: "Test Transaction",
80 | image: "https://example.com/your_logo",
81 | order_id: order.id,
82 | handler: (res) => {
83 | console.log(res);
84 | },
85 | prefill: {
86 | name: "Piyush Garg",
87 | email: "youremail@example.com",
88 | contact: "9999999999",
89 | },
90 | notes: {
91 | address: "Razorpay Corporate Office",
92 | },
93 | theme: {
94 | color: "#3399cc",
95 | },
96 | };
97 |
98 | const rzpay = new Razorpay(options);
99 | rzpay.open();
100 | }, [Razorpay]);
101 |
102 | return (
103 |
104 |
105 |
106 | );
107 | }
108 | ```
109 |
110 | # Full example with trigger on page load
111 |
112 | ```ts
113 | import { useCallback } from "react";
114 | import useRazorpay from "react-razorpay";
115 |
116 | export default function App() {
117 | const [Razorpay, isLoaded] = useRazorpay();
118 |
119 | const handlePayment = useCallback(() => {
120 | const order = await createOrder(params);
121 |
122 | const options: RazorpayOptions = {
123 | key: "YOUR_KEY_ID",
124 | amount: "3000",
125 | currency: "INR",
126 | name: "Acme Corp",
127 | description: "Test Transaction",
128 | image: "https://example.com/your_logo",
129 | order_id: order.id,
130 | handler: (res) => {
131 | console.log(res);
132 | },
133 | prefill: {
134 | name: "Piyush Garg",
135 | email: "youremail@example.com",
136 | contact: "9999999999",
137 | },
138 | notes: {
139 | address: "Razorpay Corporate Office",
140 | },
141 | theme: {
142 | color: "#3399cc",
143 | },
144 | };
145 |
146 | const rzpay = new Razorpay(options);
147 | rzpay.open();
148 | }, [Razorpay]);
149 |
150 | useEffect(() => {
151 | if (isLoaded) {
152 | handlePayment();
153 | }
154 | }, [isLoaded, handlePayment])
155 |
156 | return (
157 |
158 |
159 |
160 | );
161 | }
162 | ```
163 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-razorpay",
3 | "version": "1.2.0",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "react-razorpay",
9 | "version": "1.2.0",
10 | "license": "ISC",
11 | "devDependencies": {
12 | "@types/react": "^17.0.18",
13 | "typescript": "^4.3.5"
14 | },
15 | "peerDependencies": {
16 | "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
17 | }
18 | },
19 | "node_modules/@types/prop-types": {
20 | "version": "15.7.4",
21 | "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz",
22 | "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==",
23 | "dev": true
24 | },
25 | "node_modules/@types/react": {
26 | "version": "17.0.38",
27 | "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.38.tgz",
28 | "integrity": "sha512-SI92X1IA+FMnP3qM5m4QReluXzhcmovhZnLNm3pyeQlooi02qI7sLiepEYqT678uNiyc25XfCqxREFpy3W7YhQ==",
29 | "dev": true,
30 | "dependencies": {
31 | "@types/prop-types": "*",
32 | "@types/scheduler": "*",
33 | "csstype": "^3.0.2"
34 | }
35 | },
36 | "node_modules/@types/scheduler": {
37 | "version": "0.16.2",
38 | "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
39 | "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==",
40 | "dev": true
41 | },
42 | "node_modules/csstype": {
43 | "version": "3.0.10",
44 | "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.10.tgz",
45 | "integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==",
46 | "dev": true
47 | },
48 | "node_modules/js-tokens": {
49 | "version": "4.0.0",
50 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
51 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
52 | "peer": true
53 | },
54 | "node_modules/loose-envify": {
55 | "version": "1.4.0",
56 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
57 | "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
58 | "peer": true,
59 | "dependencies": {
60 | "js-tokens": "^3.0.0 || ^4.0.0"
61 | },
62 | "bin": {
63 | "loose-envify": "cli.js"
64 | }
65 | },
66 | "node_modules/object-assign": {
67 | "version": "4.1.1",
68 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
69 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
70 | "peer": true,
71 | "engines": {
72 | "node": ">=0.10.0"
73 | }
74 | },
75 | "node_modules/react": {
76 | "version": "17.0.2",
77 | "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz",
78 | "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==",
79 | "peer": true,
80 | "dependencies": {
81 | "loose-envify": "^1.1.0",
82 | "object-assign": "^4.1.1"
83 | },
84 | "engines": {
85 | "node": ">=0.10.0"
86 | }
87 | },
88 | "node_modules/typescript": {
89 | "version": "4.5.5",
90 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz",
91 | "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==",
92 | "dev": true,
93 | "bin": {
94 | "tsc": "bin/tsc",
95 | "tsserver": "bin/tsserver"
96 | },
97 | "engines": {
98 | "node": ">=4.2.0"
99 | }
100 | }
101 | },
102 | "dependencies": {
103 | "@types/prop-types": {
104 | "version": "15.7.4",
105 | "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz",
106 | "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==",
107 | "dev": true
108 | },
109 | "@types/react": {
110 | "version": "17.0.38",
111 | "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.38.tgz",
112 | "integrity": "sha512-SI92X1IA+FMnP3qM5m4QReluXzhcmovhZnLNm3pyeQlooi02qI7sLiepEYqT678uNiyc25XfCqxREFpy3W7YhQ==",
113 | "dev": true,
114 | "requires": {
115 | "@types/prop-types": "*",
116 | "@types/scheduler": "*",
117 | "csstype": "^3.0.2"
118 | }
119 | },
120 | "@types/scheduler": {
121 | "version": "0.16.2",
122 | "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
123 | "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==",
124 | "dev": true
125 | },
126 | "csstype": {
127 | "version": "3.0.10",
128 | "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.10.tgz",
129 | "integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==",
130 | "dev": true
131 | },
132 | "js-tokens": {
133 | "version": "4.0.0",
134 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
135 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
136 | "peer": true
137 | },
138 | "loose-envify": {
139 | "version": "1.4.0",
140 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
141 | "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
142 | "peer": true,
143 | "requires": {
144 | "js-tokens": "^3.0.0 || ^4.0.0"
145 | }
146 | },
147 | "object-assign": {
148 | "version": "4.1.1",
149 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
150 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
151 | "peer": true
152 | },
153 | "react": {
154 | "version": "17.0.2",
155 | "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz",
156 | "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==",
157 | "peer": true,
158 | "requires": {
159 | "loose-envify": "^1.1.0",
160 | "object-assign": "^4.1.1"
161 | }
162 | },
163 | "typescript": {
164 | "version": "4.5.5",
165 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz",
166 | "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==",
167 | "dev": true
168 | }
169 | }
170 | }
171 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-razorpay",
3 | "version": "1.2.0",
4 | "description": "Integrate Razorpay Payment gateway in your react application.",
5 | "main": "dist/index.js",
6 | "scripts": {
7 | "build": "tsc -p ."
8 | },
9 | "files": [
10 | "dist/"
11 | ],
12 | "types": "dist/index.d.ts",
13 | "author": "Piyush Garg ",
14 | "license": "ISC",
15 | "peerDependencies": {
16 | "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
17 | },
18 | "repository": {
19 | "type": "git",
20 | "url": "https://github.com/piyushgarg-dev/react-razorpay"
21 | },
22 | "devDependencies": {
23 | "@types/react": "^17.0.18",
24 | "typescript": "^4.3.5"
25 | },
26 | "keywords": [
27 | "react-razorpay",
28 | "razorpay",
29 | "razorpay payments",
30 | "react razorpay"
31 | ]
32 | }
33 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import { useEffect, useCallback, useMemo, useState } from "react";
2 |
3 | interface RazorpaySuccesshandlerArgs {
4 | razorpay_signature: string;
5 | razorpay_order_id: string;
6 | razorpay_payment_id: string;
7 | }
8 |
9 | export interface RazorpayOptions {
10 | key: string;
11 | amount: string;
12 | currency: string;
13 | name: string;
14 | description?: string;
15 | image?: string;
16 | order_id: string;
17 | handler?: (args: RazorpaySuccesshandlerArgs) => void;
18 | prefill?: {
19 | name?: string;
20 | email?: string;
21 | contact?: string;
22 | method?: "card" | "netbanking" | "wallet" | "emi" | "upi";
23 | };
24 | notes?: {};
25 | theme?: {
26 | hide_topbar?: boolean;
27 | color?: string;
28 | backdrop_color?: string;
29 | };
30 | modal?: {
31 | backdropclose?: boolean;
32 | escape?: boolean;
33 | handleback?: boolean;
34 | confirm_close?: boolean;
35 | ondismiss?: () => void;
36 | animation?: boolean;
37 | };
38 | subscription_id?: string;
39 | subscription_card_change?: boolean;
40 | recurring?: boolean;
41 | callback_url?: string;
42 | redirect?: boolean;
43 | customer_id?: string;
44 | timeout?: number;
45 | remember_customer?: boolean;
46 | readonly?: {
47 | contact?: boolean;
48 | email?: boolean;
49 | name?: boolean;
50 | };
51 | hidden?: {
52 | contact?: boolean;
53 | email?: boolean;
54 | };
55 | send_sms_hash?: boolean;
56 | allow_rotation?: boolean;
57 | retry?: {
58 | enabled?: boolean;
59 | max_count?: boolean;
60 | };
61 | config?: {
62 | display: {
63 | language: "en" | "ben" | "hi" | "mar" | "guj" | "tam" | "tel";
64 | };
65 | };
66 | }
67 |
68 | class Razorpay {
69 | private options: RazorpayOptions;
70 | private rzrpayInstannce: any;
71 |
72 | constructor(options: RazorpayOptions) {
73 | this.options = options;
74 | if (typeof window !== "undefined")
75 | this.rzrpayInstannce = new (window as any).Razorpay(this.options);
76 | }
77 |
78 | public on(event: string, callback: Function) {
79 | this.rzrpayInstannce.on(event, callback);
80 | }
81 |
82 | public open() {
83 | this.rzrpayInstannce.open();
84 | }
85 | }
86 |
87 | const useRazorpay = () => {
88 | /* Constants */
89 | const RAZORPAY_SCRIPT = "https://checkout.razorpay.com/v1/checkout.js";
90 |
91 | const isClient = useMemo(() => typeof window !== "undefined", []);
92 |
93 | const [isLoaded, setIsLoaded] = useState(false);
94 |
95 | const checkScriptLoaded: () => boolean = useCallback(() => {
96 | if (!isClient || !("Razorpay" in window)) return false;
97 | return true;
98 | }, []);
99 |
100 | const loadScript = useCallback((scriptUrl: string) => {
101 | if (!isClient) return; // Don't execute this function if it's rendering on server side
102 | return new Promise((resolve, reject) => {
103 | const scriptTag = document.createElement("script");
104 | scriptTag.src = scriptUrl;
105 | scriptTag.onload = (ev) => {
106 | setIsLoaded(true), resolve(ev);
107 | };
108 | scriptTag.onerror = (err) => reject(err);
109 | document.body.appendChild(scriptTag);
110 | });
111 | }, []);
112 |
113 | useEffect(() => {
114 | if (!checkScriptLoaded()) {
115 | (async () => {
116 | try {
117 | await loadScript(RAZORPAY_SCRIPT);
118 | } catch (error: any) {
119 | throw new Error(error);
120 | }
121 | })();
122 | }
123 | }, []);
124 |
125 | return [Razorpay, isLoaded] as [typeof Razorpay, boolean];
126 | };
127 |
128 | export default useRazorpay;
129 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */
4 |
5 | /* Basic Options */
6 | // "incremental": true, /* Enable incremental compilation */
7 | "target": "ES2015" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */,
8 | "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
9 | // "lib": [], /* Specify library files to be included in the compilation. */
10 | // "allowJs": true, /* Allow javascript files to be compiled. */
11 | // "checkJs": true, /* Report errors in .js files. */
12 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
13 | "declaration": true /* Generates corresponding '.d.ts' file. */,
14 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
15 | "sourceMap": true /* Generates corresponding '.map' file. */,
16 | // "outFile": "./", /* Concatenate and emit output to single file. */
17 | "outDir": "./dist" /* Redirect output structure to the directory. */,
18 | "rootDir": "./src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
19 | // "composite": true, /* Enable project compilation */
20 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
21 | // "removeComments": true, /* Do not emit comments to output. */
22 | // "noEmit": true, /* Do not emit outputs. */
23 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */
24 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
25 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
26 |
27 | /* Strict Type-Checking Options */
28 | "strict": true /* Enable all strict type-checking options. */,
29 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
30 | // "strictNullChecks": true, /* Enable strict null checks. */
31 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */
32 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
33 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
34 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
35 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
36 |
37 | /* Additional Checks */
38 | // "noUnusedLocals": true, /* Report errors on unused locals. */
39 | // "noUnusedParameters": true, /* Report errors on unused parameters. */
40 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
41 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
42 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
43 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an 'override' modifier. */
44 | // "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */
45 |
46 | /* Module Resolution Options */
47 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
48 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
49 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
50 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
51 | // "typeRoots": [], /* List of folders to include type definitions from. */
52 | // "types": [], /* Type declaration files to be included in compilation. */
53 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
54 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
55 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
56 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
57 |
58 | /* Source Map Options */
59 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
60 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
61 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
62 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
63 |
64 | /* Experimental Options */
65 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
66 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
67 |
68 | /* Advanced Options */
69 | "skipLibCheck": true /* Skip type checking of declaration files. */,
70 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
71 | }
72 | }
73 |
--------------------------------------------------------------------------------