├── .cursorignore ├── .github ├── ISSUE_TEMPLATE.md ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── config.yml │ └── feature_Request.md ├── dependabot.yml ├── pull_request_template.md └── workflows │ └── genesis.yml ├── .gitignore ├── .npmignore ├── .semgrepignore ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── RazorpayCheckout.js ├── ReleaseHelper.md ├── Scripts └── SelectDefaultXcode.sh ├── android ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── razorpay │ └── rn │ ├── RazorpayModule.java │ ├── RazorpayPackage.java │ └── Utils.java ├── code_of_conduct.md ├── example └── SampleApp │ ├── .buckconfig │ ├── .bundle │ └── config │ ├── .eslintrc.js │ ├── .flowconfig │ ├── .gitignore │ ├── .prettierrc.js │ ├── .ruby-version │ ├── .watchmanconfig │ ├── App.js │ ├── Gemfile │ ├── Gemfile.lock │ ├── __tests__ │ └── App-test.js │ ├── android │ ├── app │ │ ├── _BUCK │ │ ├── build.gradle │ │ ├── build_defs.bzl │ │ ├── debug.keystore │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── debug │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── sampleapp │ │ │ │ └── ReactNativeFlipper.java │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ └── com │ │ │ │ └── sampleapp │ │ │ │ ├── MainActivity.java │ │ │ │ ├── MainApplication.java │ │ │ │ └── newarchitecture │ │ │ │ ├── MainApplicationReactNativeHost.java │ │ │ │ ├── components │ │ │ │ └── MainComponentsRegistry.java │ │ │ │ └── modules │ │ │ │ └── MainApplicationTurboModuleManagerDelegate.java │ │ │ ├── jni │ │ │ ├── Android.mk │ │ │ ├── MainApplicationModuleProvider.cpp │ │ │ ├── MainApplicationModuleProvider.h │ │ │ ├── MainApplicationTurboModuleManagerDelegate.cpp │ │ │ ├── MainApplicationTurboModuleManagerDelegate.h │ │ │ ├── MainComponentsRegistry.cpp │ │ │ ├── MainComponentsRegistry.h │ │ │ └── OnLoad.cpp │ │ │ └── res │ │ │ ├── drawable │ │ │ └── rn_edit_text_material.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ └── values │ │ │ ├── strings.xml │ │ │ └── styles.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle │ ├── app.json │ ├── babel.config.js │ ├── index.js │ ├── ios │ ├── Podfile │ ├── Podfile.lock │ ├── SampleApp.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── SampleApp.xcscheme │ ├── SampleApp.xcworkspace │ │ └── contents.xcworkspacedata │ ├── SampleApp │ │ ├── AppDelegate.h │ │ ├── AppDelegate.mm │ │ ├── Images.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── Info.plist │ │ ├── LaunchScreen.storyboard │ │ └── main.m │ └── SampleAppTests │ │ ├── Info.plist │ │ └── SampleAppTests.m │ ├── metro.config.js │ ├── package.json │ └── yarn.lock ├── ios ├── RazorpayCheckout.h ├── RazorpayCheckout.m ├── RazorpayCheckout.xcodeproj │ └── project.pbxproj ├── RazorpayEventEmitter.h ├── RazorpayEventEmitter.m ├── SelectDefaultXcode.sh └── react-native-razorpay.podspec ├── package.json ├── react-native-razorpay.podspec ├── scripts └── UpdateReactCheckout.sh └── src └── index.js /.cursorignore: -------------------------------------------------------------------------------- 1 | # Distribution and Environment 2 | dist/* 3 | build/* 4 | venv/* 5 | env/* 6 | *.env 7 | .env.* 8 | virtualenv/* 9 | .python-version 10 | .ruby-version 11 | .node-version 12 | 13 | # Logs and Temporary Files 14 | *.log 15 | *.tsv 16 | *.csv 17 | *.txt 18 | tmp/* 19 | temp/* 20 | .tmp/* 21 | *.temp 22 | *.cache 23 | .cache/* 24 | logs/* 25 | 26 | # Sensitive Data 27 | *.json 28 | *.xml 29 | *.yml 30 | *.yaml 31 | *.properties 32 | properties.json 33 | *.sqlite 34 | *.sqlite3 35 | *.dbsql 36 | secrets.* 37 | *secret* 38 | *password* 39 | *credential* 40 | .npmrc 41 | .yarnrc 42 | .aws/* 43 | .config/* 44 | 45 | # Credentials and Keys 46 | *.pem 47 | *.ppk 48 | *.key 49 | *.pub 50 | *.p12 51 | *.pfx 52 | *.htpasswd 53 | *.keystore 54 | *.jks 55 | *.truststore 56 | *.cer 57 | id_rsa* 58 | known_hosts 59 | authorized_keys 60 | .ssh/* 61 | .gnupg/* 62 | .pgpass 63 | 64 | # Config Files 65 | *.conf 66 | *.toml 67 | *.ini 68 | .env.local 69 | .env.development 70 | .env.test 71 | .env.production 72 | config/* 73 | 74 | # Documentation and Notes 75 | *.md 76 | *.mdx 77 | *.rst 78 | *.txt 79 | docs/* 80 | README* 81 | CHANGELOG* 82 | LICENSE* 83 | CONTRIBUTING* 84 | 85 | # Database Files 86 | *.sql 87 | *.db 88 | *.dmp 89 | *.dump 90 | *.backup 91 | *.restore 92 | *.mdb 93 | *.accdb 94 | *.realm* 95 | 96 | # Backup and Archive Files 97 | *.bak 98 | *.backup 99 | *.swp 100 | *.swo 101 | *.swn 102 | *~ 103 | *.old 104 | *.orig 105 | *.archive 106 | *.gz 107 | *.zip 108 | *.tar 109 | *.rar 110 | *.7z 111 | 112 | # Compiled and Binary Files 113 | *.pyc 114 | *.pyo 115 | **/__pycache__/** 116 | *.class 117 | *.jar 118 | *.war 119 | *.ear 120 | *.dll 121 | *.exe 122 | *.so 123 | *.dylib 124 | *.bin 125 | *.obj 126 | 127 | # IDE and Editor Files 128 | .idea/* 129 | *.iml 130 | .vscode/* 131 | .project 132 | .classpath 133 | .settings/* 134 | *.sublime-* 135 | .atom/* 136 | .eclipse/* 137 | *.code-workspace 138 | .history/* 139 | 140 | # Build and Dependency Directories 141 | node_modules/* 142 | bower_components/* 143 | vendor/* 144 | packages/* 145 | jspm_packages/* 146 | .gradle/* 147 | target/* 148 | out/* 149 | 150 | # Testing and Coverage Files 151 | coverage/* 152 | .coverage 153 | htmlcov/* 154 | .pytest_cache/* 155 | .tox/* 156 | junit.xml 157 | test-results/* 158 | 159 | # Mobile Development 160 | *.apk 161 | *.aab 162 | *.ipa 163 | *.xcarchive 164 | *.provisionprofile 165 | google-services.json 166 | GoogleService-Info.plist 167 | 168 | # Certificate and Security Files 169 | *.crt 170 | *.csr 171 | *.ovpn 172 | *.p7b 173 | *.p7s 174 | *.pfx 175 | *.spc 176 | *.stl 177 | *.pem.crt 178 | ssl/* 179 | 180 | # Container and Infrastructure 181 | *.tfstate 182 | *.tfstate.backup 183 | .terraform/* 184 | .vagrant/* 185 | docker-compose.override.yml 186 | kubernetes/* 187 | 188 | # Design and Media Files (often large and binary) 189 | *.psd 190 | *.ai 191 | *.sketch 192 | *.fig 193 | *.xd 194 | assets/raw/* 195 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **Common to Both platforms :-** 2 | 3 | - [ ] I have gone through the README (https://github.com/razorpay/react-native-razorpay) 4 | - [ ] I have searched for a similar issue (https://github.com/razorpay/react-native-razorpay/issues) 5 | - [ ] I am using the latest version of our framework (https://github.com/razorpay/react-native-razorpay/releases) 6 | - [ ] I have cleaned my project. 7 | - [ ] I have gone through FAQ's (https://github.com/razorpay/react-native-razorpay/wiki/FAQ's) 8 | 9 | 10 | * **Specific to iOS Users :-** 11 | 12 | - [ ] I have modified the module map as specified in the readme (https://github.com/razorpay/react-native-razorpay) 13 | - [ ] I have deleted the contents of the derived data folder and rebuild it. 14 | 15 | 16 | 17 | ## IDE Specs 18 | 19 | 20 | 21 | 22 | ## Retro Steps 23 | 26 | 27 | ## Screenshots 28 | 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "🐛 Bug Report" 3 | about: Report a reproducible bug or regression in React Native Razorpay Plugin. 4 | title: '' 5 | labels: 'Needs: Triage :mag:' 6 | 7 | --- 8 | 9 | 18 | 19 | ## Description 20 | Please provide a clear and concise description of what the bug is. Include screenshots if needed. 21 | Please test using the latest React Native Razorpay plugin release to make sure your issue has not already been fixed. 22 | 23 | * **Specific to iOS Users :-** 24 | - [ ] I have tried updating Razorpay pod to the latest version by using 'pod update'. 25 | 26 | ## Razorpay Package Version : 27 | Open `Package.json`. > Copy `react-native-razorpay` version here. 28 | 29 | ## Xcode Version (iOS) : 30 | Open Xcode > Go to `About Xcode` > copy the Xcode version here. 31 | 32 | ## Razorpay-pod version (iOS) : 33 | Go to your project path > Go to folder named `ios` > open 'podfile.lock' file > search for 'razorpay-pod' > copy the line here 34 | 35 | ## Java and Gradle Version (android) : 36 | Specify your Java and Gradle version. 37 | 38 | ### What you did: 39 | 40 | 41 | 42 | ### What happened: 43 | 44 | 45 | 46 | ## Steps To Reproduce 47 | Provide a detailed list of steps that reproduce the issue. 48 | 49 | 1. 50 | 2. 51 | 52 | ### Suggested solution: 53 | 54 | 58 | 59 | ## Code example, screenshot, or link to a repository: 60 | Please provide a link to a repository on GitHub, or provide a minimal code example that reproduces the problem. 61 | You may provide a screenshot of the application if you think it is relevant to your bug report. 62 | Here are some tips for providing a minimal example: https://stackoverflow.com/help/mcve 63 | 64 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: 🤔 Need some help in Integrations 4 | url: https://razorpay.com/integrations/ 5 | about: Looking for help with your app? Please refer to the integration documentation. 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_Request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 💡 Feature Request 3 | about: I have a suggestion (and might want to implement myself 🙂)! 4 | --- 5 | 6 | 19 | 20 | ### Describe the feature you'd like: 21 | 22 | 26 | 27 | ### Suggested implementation: 28 | 29 | 30 | 31 | ### Describe alternatives you've considered: 32 | 33 | 37 | 38 | ### Teachability, Documentation, Adoption, Migration Strategy: 39 | 40 | 44 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "04:00" 8 | timezone: Asia/Calcutta 9 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Note :- Please follow the below points while attaching test cases document link below: 2 | ### - If label `Tested` is added then test cases document URL is mandatory. 3 | ### - Link added should be a valid URL and accessible throughout the org. 4 | ### - If the branch name contains hotfix / revert by default the BVT workflow check will pass. 5 | 6 | | Test Case Document URL | 7 | |-----------------------------------------------| 8 | | Please paste test case document link here.... | 9 | -------------------------------------------------------------------------------- /.github/workflows/genesis.yml: -------------------------------------------------------------------------------- 1 | name: Quality Checks 2 | on: 3 | schedule: 4 | - cron: "0 17 * * *" 5 | jobs: 6 | Analysis: 7 | uses: razorpay/genesis/.github/workflows/quality-checks.yml@master 8 | secrets: inherit 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | *-lock.json 24 | project.xcworkspace 25 | 26 | # Android/IJ 27 | # 28 | *.iml 29 | .idea 30 | .gradle 31 | local.properties 32 | 33 | # node.js 34 | 35 | npm-debug.log 36 | 37 | # BUCK 38 | buck-out/ 39 | \.buckd/ 40 | android/app/libs 41 | android/keystores/debug.keystore 42 | node_modules 43 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | example/* 2 | DeploymentScripts/ 3 | -------------------------------------------------------------------------------- /.semgrepignore: -------------------------------------------------------------------------------- 1 | README.md -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | We love contributions from everyone. 4 | By participating in this project, 5 | you agree to abide by our [code_of_conduct]. 6 | 7 | We expect everyone to follow the code of conduct 8 | anywhere in Razorpay's project codebases, 9 | issue trackers, chatrooms, and mailing lists. 10 | 11 | ## Contributing Code 12 | 13 | Checkout the latest master to make sure the feature hasn't been implemented or 14 | the bug hasn't been fixed yet. 15 | 16 | Check the issue tracker to make sure someone already hasn't requested it and/or 17 | contributed to it. 18 | 19 | Fork the repo. 20 | 21 | 1. Use the example project to test the module. 22 | 2. Delete the `postinstall` step from `package.json`. Remember to revert this 23 | change when commiting. 24 | 3. Edit example/reload.sh to configure your path. 25 | 4. Follow instructions to link your project with the iOS SDK, as given in the [README]. 26 | 5. Run example/reload.sh every time you make a change to the module. 27 | 28 | Make your change. Follow this [style guide][style]. 29 | 30 | Push to your fork. Write a [good commit message][commit]. Submit a pull request. 31 | 32 | Others will give constructive feedback. 33 | This is a time for discussion and improvements, 34 | and making the necessary changes will be required before we can 35 | merge the contribution. 36 | 37 | [code_of_conduct]: code_of_conduct.md "Code of Conduct" 38 | [commit]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html "A short guide on how to write good commit messages" 39 | [README]: README.md#linking-ios-sdk "Linking to the iOS SDK" 40 | [style]: https://github.com/thoughtbot/guides/tree/master/style "Styleguides by Thoughtbot" 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Razorpay Software Pvt. Ltd. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-native-razorpay 2 | [![npm](https://img.shields.io/npm/l/express.svg)]() 3 | [![NPM Version](http://img.shields.io/npm/v/react-native-razorpay.svg?style=flat)](https://www.npmjs.com/package/react-native-razorpay) 4 | [![NPM Downloads](https://img.shields.io/npm/dm/react-native-razorpay.svg?style=flat)](https://npmcharts.com/compare/react-native-razorpay?minimal=true) 5 | [![install size](https://packagephobia.com/badge?p=react-native-razorpay@2.1.35)](https://packagephobia.com/result?p=react-native-razorpay@2.1.35) 6 | 7 | [![NPM](https://nodei.co/npm/react-native-razorpay.png?downloads=true)](https://nodei.co/npm/react-native-razorpay/) 8 | 9 | React Native wrapper around our Android and iOS mobile SDKs 10 | 11 | 12 | * [Prerequisites](#prerequisites) 13 | * [Installation](#installation) 14 | * [Requirements](#requirements) 15 | * [Linking](#linking) 16 | * [Usage](#usage) 17 | * [Example App](https://github.com/razorpay/react-native-razorpay/tree/master/example/SampleProject) 18 | * [Proguard Rules](#proguard-rules) 19 | * [Notes](#things-to-be-taken-care) 20 | * [FAQ's](#faqs) 21 | * [Contributing](#contributing) 22 | * [License](#license) 23 | 24 | The following documentation is only focussed on the react-native wrapper around our Android and iOS sdks. To know more about our react-native SDK, refer to the following documentation - 25 | 26 | https://razorpay.com/docs/payment-gateway/react-native-integration/ 27 | 28 | To know more about Razorpay payment flow and steps involved, read up here: 29 | 30 | 31 | ## Prerequisites 32 | 33 | - Learn about the Razorpay Payment Flow. 34 | - Sign up for a Razorpay Account and generate the API Keys from the Razorpay Dashboard. Using the Test keys helps simulate a sandbox environment. No actual monetary transaction happens when using the Test keys. Use Live keys once you have thoroughly tested the application and are ready to go live. 35 | 36 | ## Installation 37 | 38 | Using npm: 39 | 40 | ```shell 41 | npm install --save react-native-razorpay 42 | ``` 43 | 44 | or using yarn: 45 | 46 | ```shell 47 | yarn add react-native-razorpay 48 | ``` 49 | 50 | For Expo Users: 51 | ```shell 52 | npx expo install react-native-razorpay 53 | ``` 54 | 55 | ## Requirements 56 | 57 | - iOS 10.0+ / macOS 10.12+ / tvOS 10.0+ / watchOS 3.0+ 58 | - Xcode 11+ 59 | - Swift 5.1+ 60 | 61 | ## Linking 62 | 63 | ### Automatic 64 | 65 |
66 | iOS 67 | 68 | ### For React Native 0.60+ 69 | 70 | ```sh 71 | # install 72 | npm install react-native-razorpay --save 73 | cd ios && open podfile # Change the platform from iOS 9.0 to 10.0 74 | pod install && cd .. # CocoaPods on iOS needs this extra step 75 | # run 76 | yarn react-native run-ios 77 | ``` 78 | ### For React Native 0.59 and lower 79 | 80 | 81 | 1. `$ npm install react-native-razorpay --save` // Install the Razorpay React Native Standard SDK using the npm command. 82 | 83 | 2. `react-native link react-native-razorpay` // Link the SDK with React Native Project using Xcode. 84 | 85 | 3. Drag the `Razorpay.framework` file from the Libraries folder and drop it under the root folder, for more info follow [this link](https://razorpay.com/docs/payment-gateway/react-native-integration/standard/#step-2---link-the-sdk-with-react), 86 | after this go to **Target** > **General Settings**> **Framework, Libraries and Embedded Content** section, set the **Embed** status of Razorpay.framework to **Embed & Sign**. 87 | 88 | 6. Also make sure the razorpay framework is added in the embedded binaries section and you have Always Embed Swift 89 | Standard Binaries set to yes in build settings. 90 |
91 | 92 | ### Manual 93 | 94 |
95 | iOS (via CocoaPods) 96 | 97 | Add the following line to your build targets in your `Podfile` 98 | 99 | `pod 'react-native-razorpay', :path => '../node_modules/react-native-razorpay'` 100 | 101 | Then run `pod install` 102 | 103 |
104 | 105 |
106 | iOS (without CocoaPods) 107 | 108 | In XCode, in the project navigator: 109 | 110 | * Right click _Libraries_ 111 | * Add Files to _[your project's name]_ 112 | * Go to `node_modules/react-native-razorpay` 113 | * Add the `.xcodeproj` file 114 | 115 | In XCode, in the project navigator, select your project. 116 | 117 | * Add the `libRNDeviceInfo.a` from the _deviceinfo_ project to your project's _Build Phases ➜ Link Binary With Libraries_ 118 | * Click `.xcodeproj` file you added before in the project navigator and go the _Build Settings_ tab. Make sure _All_ is toggled on (instead of _Basic_). 119 | * Look for _Header Search Paths_ and make sure it contains both `$(SRCROOT)/../react-native/React` and `$(SRCROOT)/../../React` 120 | * Mark both as recursive (should be OK by default). 121 | 122 | Run your project (Cmd+R) 123 | 124 |
125 | 126 |
127 | Android 128 | 129 | 130 | 1. Open up `android/app/src/main/java/[...]/MainApplication.java` 131 | - Add `import com.razorpay.rn.RazorpayPackage;` to the imports at the top of 132 | the file 133 | - Add `new RazorpayPackage()` to the list returned by the `getPackages()` method 134 | 2. Append the following lines to `android/settings.gradle`: 135 | ```gradle 136 | include ':react-native-razorpay' 137 | project(':react-native-razorpay').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-razorpay/android') 138 | ``` 139 | 3. Insert the following lines inside the dependencies block in 140 | `android/app/build.gradle`: 141 | ```gradle 142 | implementation project(':react-native-razorpay') 143 | ``` 144 |
145 | 146 | ### Note for Expo Applications: 147 | 148 | After adding the react-native-razorpay package,the option to `prebuild` the app must be used(this generates the android/ios platform folders in the project to use native-modules). Command for which, 149 | ```shell 150 | npx expo prebuild 151 | ``` 152 | After which the application will be installed on the device/emulator. 153 | ```shell 154 | npx expo run:[ios|android] --device 155 | ``` 156 | 157 | 158 | ## Usage 159 | 160 | Sample code to integrate with Razorpay can be found in 161 | [index.js][index.js] in the included example directory. 162 | 163 | To run the example, simply do the following in example directory and then 164 | link iOS SDK as explained in the previous section: 165 | 166 | `$ npm i` 167 | 168 | ### Steps 169 | 170 | 1. Import RazorpayCheckout module to your component: 171 | ```js 172 | import RazorpayCheckout from 'react-native-razorpay'; 173 | ``` 174 | 175 | 2. Call `RazorpayCheckout.open` method with the payment `options`. The method 176 | returns a **JS Promise** where `then` part corresponds to a successful payment 177 | and the `catch` part corresponds to payment failure. 178 | ```js 179 | { 180 | var options = { 181 | description: 'Credits towards consultation', 182 | image: 'https://i.imgur.com/3g7nmJC.png', 183 | currency: 'INR', 184 | key: '', // Your api key 185 | amount: '5000', 186 | name: 'foo', 187 | prefill: { 188 | email: 'void@razorpay.com', 189 | contact: '9191919191', 190 | name: 'Razorpay Software' 191 | }, 192 | theme: {color: '#F37254'} 193 | } 194 | RazorpayCheckout.open(options).then((data) => { 195 | // handle success 196 | alert(`Success: ${data.razorpay_payment_id}`); 197 | }).catch((error) => { 198 | // handle failure 199 | alert(`Error: ${error.code} | ${error.description}`); 200 | }); 201 | }}> 202 | ``` 203 | 204 | A descriptive [list of valid options for checkout][options] is available (under 205 | Manual Checkout column). 206 | 207 | ## Proguard Rules 208 | If you are using proguard for your builds, you need to add following lines to proguard files 209 | ``` 210 | -keepattributes *Annotation* 211 | -dontwarn com.razorpay.** 212 | -keep class com.razorpay.** {*;} 213 | -optimizations !method/inlining/ 214 | -keepclasseswithmembers class * { 215 | public void onPayment*(...); 216 | } 217 | ``` 218 | 219 | ## Things to be taken care 220 | 221 | - The react native plugin is wrapper around native SDK, so it doesn't work with the tools like expo which doesn't support native modules. 222 | 223 | ## FAQ's 224 | 225 | - For UPI Intent in iOS, the info.plist in iOS should be modified to include `LSApplicationQueriesSchemes` 226 | - For Bare React-Native Apps: 227 | - info.plist can directly be modified from the xcode project. LSApplicationQueriesSchemes takes as array value and can currently include only ["tez","phonepe","paytmmp"] 228 | - For Expo Apps: 229 | - Directly modifying info.plist is discouraged, and hence this should be added in app.json 230 | ```shell 231 | "ios": { 232 | "infoPlist": { 233 | "LSApplicationQueriesSchemes": [ 234 | "tez", 235 | "phonepe", 236 | "paytmmp" 237 | ] 238 | } 239 | } 240 | ``` 241 | - P.S: The apps won't be visible if the application is run with metro builder. The info.plist is generated successfully and integrated only when the app is built as standalone app. 242 | - Still having trouble with integrating our payment gateway? Follow [this link](https://github.com/razorpay/react-native-razorpay/wiki/FAQ's) for more info. 243 | 244 | ## Contributing 245 | 246 | See the [CONTRIBUTING] document. Thank you, [contributors]! 247 | 248 | ## License 249 | 250 | react-native-razorpay is Copyright (c) 2020 Razorpay Software Pvt. Ltd. 251 | It is distributed under [the MIT License][LICENSE]. 252 | 253 | We ♥ open source software! 254 | See [our other supported plugins / SDKs][integrations] 255 | or [contact us][contact] to help you with integrations. 256 | 257 | [contact]: mailto:integrations@razorpay.com?subject=Help%20with%20React%20Native "Send us a mail" 258 | [CONTRIBUTING]: CONTRIBUTING.md "Our contributing guidelines" 259 | [contributors]: https://github.com/razorpay/react-native-razorpay/graphs/contributors "List of contributors" 260 | [index.js]: example/SampleProject/index.js "index.js" 261 | [integrations]: https://razorpay.com/integrations "List of our integrations" 262 | [ios-docs]: https://docs.razorpay.com/v1/page/ios-integration "Documentation for the iOS Integration" 263 | [LICENSE]: /LICENSE "MIT License" 264 | [options]: https://docs.razorpay.com/docs/checkout-form#checkout-fields "Checkout Options" 265 | [wiki]: https://github.com/razorpay/react-native-razorpay/wiki/Manual-Installation 266 | -------------------------------------------------------------------------------- /RazorpayCheckout.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import { NativeModules, NativeEventEmitter } from 'react-native'; 4 | 5 | const razorpayEvents = new NativeEventEmitter(NativeModules.RazorpayEventEmitter); 6 | 7 | const removeSubscriptions = () => { 8 | razorpayEvents.removeAllListeners('Razorpay::PAYMENT_SUCCESS'); 9 | razorpayEvents.removeAllListeners('Razorpay::PAYMENT_ERROR'); 10 | razorpayEvents.removeAllListeners('Razorpay::EXTERNAL_WALLET_SELECTED'); 11 | }; 12 | 13 | class RazorpayCheckout { 14 | static open(options, successCallback, errorCallback) { 15 | return new Promise(function(resolve, reject) { 16 | razorpayEvents.addListener('Razorpay::PAYMENT_SUCCESS', (data) => { 17 | let resolveFn = successCallback || resolve; 18 | resolveFn(data); 19 | removeSubscriptions(); 20 | }); 21 | razorpayEvents.addListener('Razorpay::PAYMENT_ERROR', (data) => { 22 | let rejectFn = errorCallback || reject; 23 | rejectFn(data); 24 | removeSubscriptions(); 25 | }); 26 | NativeModules.RNRazorpayCheckout.open(options); 27 | }); 28 | } 29 | static onExternalWalletSelection(externalWalletCallback) { 30 | razorpayEvents.addListener('Razorpay::EXTERNAL_WALLET_SELECTED', (data) => { 31 | externalWalletCallback(data); 32 | removeSubscriptions(); 33 | }); 34 | } 35 | } 36 | 37 | export default RazorpayCheckout; 38 | -------------------------------------------------------------------------------- /ReleaseHelper.md: -------------------------------------------------------------------------------- 1 | # Release Helper 2 | 3 | ## What is this ? 4 | 5 | A doc that helps you release the react-native package by bypassing the manual overhead. 6 | 7 | ### How to use it ? 8 | 9 | Well , its fairly simple there is a script called UpdateReactCheckout.sh in the scripts folder , run it and enter what it asks you.It will ask you for the path of 10 | the react native directory, the latest version of the framework and the version of the example.Thats it !! 11 | 12 | It will create a branch , download the required files , update the package.json ,create a tag and a PR.All you have 13 | do is add an assignee get it merged and execute npm publish. 14 | -------------------------------------------------------------------------------- /Scripts/SelectDefaultXcode.sh: -------------------------------------------------------------------------------- 1 | # to make sure that any command that fails in turn return a non zero status and does not continue further 2 | 3 | set -e 4 | 5 | # get framework path from command line or use the current working directory as the path 6 | 7 | if [ $# -eq 0 ] ; then 8 | FRAMEWORK_PATH=$(pwd)/Razorpay.framework/ 9 | echo "Using the current working directory as the framework path which is $FRAMEWORK_PATH" 10 | else 11 | FRAMEWORK_PATH=$1 12 | fi 13 | 14 | #navigate to the module map 15 | 16 | cd "$FRAMEWORK_PATH/Modules/" 17 | 18 | #find xcode path and replace it with the default 19 | 20 | DEFAULT_XCODE_PATH="$(xcode-select -p)" 21 | IFS='/' 22 | read -ra ARRAY <<< "$DEFAULT_XCODE_PATH" 23 | XCODE_COMPONENT=${ARRAY[2]} 24 | STRING_TO_BE_REPLACED="Xcode.app" 25 | sed -i '' "s/$STRING_TO_BE_REPLACED/$XCODE_COMPONENT/g" module.modulemap 26 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | repositories { 3 | mavenCentral() 4 | } 5 | def safeExtGet(prop, fallback) { 6 | rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback 7 | } 8 | 9 | android { 10 | compileSdkVersion safeExtGet('compileSdkVersion', 28) 11 | 12 | 13 | defaultConfig { 14 | minSdkVersion safeExtGet('minSdkVersion', 16) 15 | targetSdkVersion safeExtGet('targetSdkVersion', 28) 16 | versionCode 1 17 | versionName "1.0" 18 | } 19 | } 20 | 21 | dependencies { 22 | implementation 'com.facebook.react:react-native:+' 23 | implementation 'com.razorpay:checkout:1.6.+' 24 | } 25 | 26 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/razorpay/react-native-razorpay/af7ee40f81029cfa7aede7eebdac2326591cce30/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Jan 21 17:10:52 IST 2020 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip 7 | -------------------------------------------------------------------------------- /android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /android/src/main/java/com/razorpay/rn/RazorpayModule.java: -------------------------------------------------------------------------------- 1 | 2 | package com.razorpay.rn; 3 | 4 | import com.facebook.react.bridge.ReactApplicationContext; 5 | import com.facebook.react.bridge.ReactContextBaseJavaModule; 6 | import com.facebook.react.bridge.ReactMethod; 7 | import com.facebook.react.bridge.ActivityEventListener; 8 | import com.facebook.react.bridge.Callback; 9 | import com.facebook.react.bridge.ReadableMap; 10 | import com.facebook.react.bridge.ReadableMapKeySetIterator; 11 | import com.facebook.react.bridge.ReadableType; 12 | import com.facebook.react.bridge.WritableArray; 13 | import com.facebook.react.bridge.WritableMap; 14 | import com.facebook.react.bridge.WritableNativeArray; 15 | import com.facebook.react.bridge.WritableNativeMap; 16 | import com.facebook.react.bridge.Arguments; 17 | import com.facebook.react.modules.core.DeviceEventManagerModule; 18 | import com.razorpay.CheckoutActivity; 19 | import com.razorpay.PaymentData; 20 | import com.razorpay.PaymentResultWithDataListener; 21 | import com.razorpay.ExternalWalletListener; 22 | import com.razorpay.Checkout; 23 | import org.json.JSONArray; 24 | import org.json.JSONException; 25 | import org.json.JSONObject; 26 | import java.util.Iterator; 27 | import android.app.Activity; 28 | import android.content.Intent; 29 | import android.os.Bundle; 30 | 31 | 32 | 33 | 34 | 35 | public class RazorpayModule extends ReactContextBaseJavaModule implements ActivityEventListener, PaymentResultWithDataListener , ExternalWalletListener { 36 | 37 | 38 | public static final int RZP_REQUEST_CODE = 72967729; 39 | public static final String MAP_KEY_RZP_PAYMENT_ID = "razorpay_payment_id"; 40 | public static final String MAP_KEY_PAYMENT_ID = "payment_id"; 41 | public static final String MAP_KEY_ERROR_CODE = "code"; 42 | public static final String MAP_KEY_ERROR_DESC = "description"; 43 | public static final String MAP_KEY_PAYMENT_DETAILS = "details"; 44 | public static final String MAP_KEY_WALLET_NAME="name"; 45 | ReactApplicationContext reactContext; 46 | public RazorpayModule(ReactApplicationContext reactContext) { 47 | super(reactContext); 48 | this.reactContext = reactContext; 49 | reactContext.addActivityEventListener(this); 50 | } 51 | 52 | @Override 53 | public String getName() { 54 | return "RNRazorpayCheckout"; 55 | } 56 | 57 | @ReactMethod 58 | public void open(ReadableMap options) { 59 | Activity currentActivity = getCurrentActivity(); 60 | try { 61 | JSONObject optionsJSON = Utils.readableMapToJson(options); 62 | Intent intent = new Intent(currentActivity, CheckoutActivity.class); 63 | intent.putExtra("OPTIONS", optionsJSON.toString()); 64 | intent.putExtra("FRAMEWORK", "react_native"); 65 | currentActivity.startActivityForResult(intent, Checkout.RZP_REQUEST_CODE); 66 | } catch (Exception e) {} 67 | } 68 | 69 | public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) { 70 | onActivityResult(requestCode, resultCode, data); 71 | } 72 | 73 | public void onNewIntent(Intent intent) {} 74 | 75 | 76 | public void onActivityResult(int requestCode, int resultCode, Intent data){ 77 | Checkout.handleActivityResult(getCurrentActivity(), requestCode, resultCode, data, this, this); 78 | } 79 | 80 | private void sendEvent(String eventName, WritableMap params) { 81 | reactContext 82 | .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) 83 | .emit(eventName, params); 84 | } 85 | 86 | @Override 87 | public void onPaymentSuccess(String razorpayPaymentId, PaymentData paymentData) { 88 | sendEvent("Razorpay::PAYMENT_SUCCESS", Utils.jsonToWritableMap(paymentData.getData())); 89 | } 90 | 91 | @Override 92 | public void onPaymentError(int code, String description, PaymentData paymentData) { 93 | WritableMap errorParams = Arguments.createMap(); 94 | JSONObject paymentDataJson = paymentData.getData(); 95 | try{ 96 | paymentDataJson.put(MAP_KEY_ERROR_CODE, code); 97 | paymentDataJson.put(MAP_KEY_ERROR_DESC, description); 98 | } catch(Exception e){ 99 | } 100 | sendEvent("Razorpay::PAYMENT_ERROR", Utils.jsonToWritableMap(paymentDataJson)); 101 | } 102 | 103 | @Override 104 | public void onExternalWalletSelected(String walletName, PaymentData paymentData){ 105 | sendEvent("Razorpay::EXTERNAL_WALLET_SELECTED", Utils.jsonToWritableMap(paymentData.getData())); 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /android/src/main/java/com/razorpay/rn/RazorpayPackage.java: -------------------------------------------------------------------------------- 1 | 2 | package com.razorpay.rn; 3 | 4 | import java.util.Arrays; 5 | import java.util.Collections; 6 | import java.util.List; 7 | 8 | import com.facebook.react.ReactPackage; 9 | import com.facebook.react.bridge.NativeModule; 10 | import com.facebook.react.bridge.ReactApplicationContext; 11 | import com.facebook.react.uimanager.ViewManager; 12 | import com.facebook.react.bridge.JavaScriptModule; 13 | 14 | public class RazorpayPackage implements ReactPackage { 15 | @Override 16 | public List createNativeModules(ReactApplicationContext reactContext) { 17 | return Arrays.asList(new RazorpayModule(reactContext)); 18 | } 19 | 20 | @Override 21 | public List createViewManagers(ReactApplicationContext reactContext) { 22 | return Collections.emptyList(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /android/src/main/java/com/razorpay/rn/Utils.java: -------------------------------------------------------------------------------- 1 | package com.razorpay.rn; 2 | 3 | import com.facebook.react.bridge.ReadableArray; 4 | import com.facebook.react.bridge.ReadableMap; 5 | import com.facebook.react.bridge.ReadableMapKeySetIterator; 6 | import com.facebook.react.bridge.WritableArray; 7 | import com.facebook.react.bridge.WritableMap; 8 | import com.facebook.react.bridge.WritableNativeArray; 9 | import com.facebook.react.bridge.WritableNativeMap; 10 | 11 | import org.json.JSONArray; 12 | import org.json.JSONException; 13 | import org.json.JSONObject; 14 | 15 | import java.util.Iterator; 16 | 17 | public class Utils { 18 | 19 | public static JSONObject readableMapToJson(ReadableMap readableMap) { 20 | JSONObject object = new JSONObject(); 21 | try { 22 | ReadableMapKeySetIterator iterator = readableMap.keySetIterator(); 23 | while (iterator.hasNextKey()) { 24 | String key = iterator.nextKey(); 25 | switch (readableMap.getType(key)) { 26 | case Null: 27 | object.put(key, JSONObject.NULL); 28 | break; 29 | case Boolean: 30 | object.put(key, readableMap.getBoolean(key)); 31 | break; 32 | case Number: 33 | object.put(key, readableMap.getDouble(key)); 34 | break; 35 | case String: 36 | object.put(key, readableMap.getString(key)); 37 | break; 38 | case Map: 39 | object.put(key, readableMapToJson(readableMap.getMap(key))); 40 | break; 41 | case Array: 42 | object.put(key, readableArrayToJson(readableMap.getArray(key))); 43 | break; 44 | } 45 | } 46 | 47 | } catch(JSONException e){ 48 | 49 | } 50 | return object; 51 | } 52 | 53 | public static JSONArray readableArrayToJson(ReadableArray readableArray) throws JSONException { 54 | JSONArray array = new JSONArray(); 55 | for (int i = 0; i < readableArray.size(); i++) { 56 | switch (readableArray.getType(i)) { 57 | case Null: 58 | break; 59 | case Boolean: 60 | array.put(readableArray.getBoolean(i)); 61 | break; 62 | case Number: 63 | array.put(readableArray.getDouble(i)); 64 | break; 65 | case String: 66 | array.put(readableArray.getString(i)); 67 | break; 68 | case Map: 69 | array.put(readableMapToJson(readableArray.getMap(i))); 70 | break; 71 | case Array: 72 | array.put(readableArrayToJson(readableArray.getArray(i))); 73 | break; 74 | } 75 | } 76 | return array; 77 | } 78 | 79 | public static WritableMap jsonToWritableMap(JSONObject jsonObject) { 80 | WritableMap writableMap = new WritableNativeMap(); 81 | try { 82 | Iterator iterator = jsonObject.keys(); 83 | while(iterator.hasNext()) { 84 | String key = (String) iterator.next(); 85 | Object value = jsonObject.get(key); 86 | if (value instanceof Float || value instanceof Double) { 87 | writableMap.putDouble(key, jsonObject.getDouble(key)); 88 | } else if (value instanceof Number) { 89 | writableMap.putInt(key, jsonObject.getInt(key)); 90 | } else if (value instanceof String) { 91 | writableMap.putString(key, jsonObject.getString(key)); 92 | } else if (value instanceof JSONObject) { 93 | writableMap.putMap(key, jsonToWritableMap(jsonObject.getJSONObject(key))); 94 | } else if (value instanceof JSONArray){ 95 | writableMap.putArray(key, jsonToWritableArray(jsonObject.getJSONArray(key))); 96 | } else if (value == JSONObject.NULL){ 97 | writableMap.putNull(key); 98 | } 99 | } 100 | } catch(JSONException e){ 101 | // Fail silently 102 | } 103 | return writableMap; 104 | } 105 | 106 | public static WritableArray jsonToWritableArray(JSONArray jsonArray) { 107 | WritableArray writableArray = new WritableNativeArray(); 108 | try { 109 | for(int i=0; i < jsonArray.length(); i++) { 110 | Object value = jsonArray.get(i); 111 | if (value instanceof Float || value instanceof Double) { 112 | writableArray.pushDouble(jsonArray.getDouble(i)); 113 | } else if (value instanceof Number) { 114 | writableArray.pushInt(jsonArray.getInt(i)); 115 | } else if (value instanceof String) { 116 | writableArray.pushString(jsonArray.getString(i)); 117 | } else if (value instanceof JSONObject) { 118 | writableArray.pushMap(jsonToWritableMap(jsonArray.getJSONObject(i))); 119 | } else if (value instanceof JSONArray){ 120 | writableArray.pushArray(jsonToWritableArray(jsonArray.getJSONArray(i))); 121 | } else if (value == JSONObject.NULL){ 122 | writableArray.pushNull(); 123 | } 124 | } 125 | } catch(JSONException e){ 126 | // Fail silently 127 | } 128 | 129 | return writableArray; 130 | } 131 | } -------------------------------------------------------------------------------- /code_of_conduct.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at [coc@razorpay.com](mailto:coc@razorpay.com?subject=Code of Conduct Issue). All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at [http://contributor-covenant.org/version/1/4][version] 72 | 73 | [homepage]: http://contributor-covenant.org 74 | [version]: http://contributor-covenant.org/version/1/4/ 75 | -------------------------------------------------------------------------------- /example/SampleApp/.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /example/SampleApp/.bundle/config: -------------------------------------------------------------------------------- 1 | BUNDLE_PATH: "vendor/bundle" 2 | BUNDLE_FORCE_RUBY_PLATFORM: 1 3 | -------------------------------------------------------------------------------- /example/SampleApp/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: '@react-native-community', 4 | }; 5 | -------------------------------------------------------------------------------- /example/SampleApp/.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | ; We fork some components by platform 3 | .*/*[.]android.js 4 | 5 | ; Ignore "BUCK" generated dirs 6 | /\.buckd/ 7 | 8 | ; Ignore polyfills 9 | node_modules/react-native/Libraries/polyfills/.* 10 | 11 | ; Flow doesn't support platforms 12 | .*/Libraries/Utilities/LoadingView.js 13 | 14 | .*/node_modules/resolve/test/resolver/malformed_package_json/package\.json$ 15 | 16 | [untyped] 17 | .*/node_modules/@react-native-community/cli/.*/.* 18 | 19 | [include] 20 | 21 | [libs] 22 | node_modules/react-native/interface.js 23 | node_modules/react-native/flow/ 24 | 25 | [options] 26 | emoji=true 27 | 28 | exact_by_default=true 29 | 30 | format.bracket_spacing=false 31 | 32 | module.file_ext=.js 33 | module.file_ext=.json 34 | module.file_ext=.ios.js 35 | 36 | munge_underscores=true 37 | 38 | module.name_mapper='^react-native/\(.*\)$' -> '/node_modules/react-native/\1' 39 | module.name_mapper='^@?[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> '/node_modules/react-native/Libraries/Image/RelativeImageStub' 40 | 41 | suppress_type=$FlowIssue 42 | suppress_type=$FlowFixMe 43 | suppress_type=$FlowFixMeProps 44 | suppress_type=$FlowFixMeState 45 | 46 | [lints] 47 | sketchy-null-number=warn 48 | sketchy-null-mixed=warn 49 | sketchy-number=warn 50 | untyped-type-import=warn 51 | nonstrict-import=warn 52 | deprecated-type=warn 53 | unsafe-getters-setters=warn 54 | unnecessary-invariant=warn 55 | signature-verification-failure=warn 56 | 57 | [strict] 58 | deprecated-type 59 | nonstrict-import 60 | sketchy-null 61 | unclear-type 62 | unsafe-getters-setters 63 | untyped-import 64 | untyped-type-import 65 | 66 | [version] 67 | ^0.170.0 68 | -------------------------------------------------------------------------------- /example/SampleApp/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | 24 | # Android/IntelliJ 25 | # 26 | build/ 27 | .idea 28 | .gradle 29 | local.properties 30 | *.iml 31 | *.hprof 32 | 33 | # node.js 34 | # 35 | node_modules/ 36 | npm-debug.log 37 | yarn-error.log 38 | 39 | # BUCK 40 | buck-out/ 41 | \.buckd/ 42 | *.keystore 43 | !debug.keystore 44 | 45 | # fastlane 46 | # 47 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 48 | # screenshots whenever they are needed. 49 | # For more information about the recommended setup visit: 50 | # https://docs.fastlane.tools/best-practices/source-control/ 51 | 52 | */fastlane/report.xml 53 | */fastlane/Preview.html 54 | */fastlane/screenshots 55 | 56 | # Bundle artifact 57 | *.jsbundle 58 | 59 | # Ruby / CocoaPods 60 | /ios/Pods/ 61 | /vendor/bundle/ 62 | -------------------------------------------------------------------------------- /example/SampleApp/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | arrowParens: 'avoid', 3 | bracketSameLine: true, 4 | bracketSpacing: false, 5 | singleQuote: true, 6 | trailingComma: 'all', 7 | }; 8 | -------------------------------------------------------------------------------- /example/SampleApp/.ruby-version: -------------------------------------------------------------------------------- 1 | 2.7.4 2 | -------------------------------------------------------------------------------- /example/SampleApp/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /example/SampleApp/App.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | * 5 | * @format 6 | * @flow strict-local 7 | */ 8 | 9 | import React from 'react'; 10 | import type {Node} from 'react'; 11 | import { 12 | Button, 13 | SafeAreaView, 14 | ScrollView, 15 | StatusBar, 16 | StyleSheet, 17 | Text, 18 | useColorScheme, 19 | View, 20 | } from 'react-native'; 21 | 22 | import { 23 | Colors, 24 | DebugInstructions, 25 | Header, 26 | LearnMoreLinks, 27 | ReloadInstructions, 28 | } from 'react-native/Libraries/NewAppScreen'; 29 | 30 | import RazorpayCheckout from 'react-native-razorpay'; 31 | 32 | const Section = ({children, title}): Node => { 33 | const isDarkMode = useColorScheme() === 'dark'; 34 | return ( 35 | 36 | 43 | {title} 44 | 45 | 52 | {children} 53 | 54 | 55 | ); 56 | }; 57 | 58 | const App: () => Node = () => { 59 | const isDarkMode = useColorScheme() === 'dark'; 60 | 61 | const backgroundStyle = { 62 | backgroundColor: isDarkMode ? Colors.darker : Colors.lighter, 63 | }; 64 | 65 | return ( 66 | 67 | 68 | 71 |
72 | 76 |