├── .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 | --------------------------------------------------------------------------------