diff --git a/README.md b/README.md index 4c64c9d99..6caa47c8c 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,9 @@ React Native wrapper around our Android and iOS mobile SDKs +To know more about Razorpay payment flow and steps involved, please read up here: + + ## Installation Run the following on terminal from your project directory: @@ -83,25 +86,13 @@ link iOS SDK as explained in the previous section: ### Steps -1. Import Razorpay module to your component: -```js -import { Razorpay } from 'react-native-razorpay'; -const { RazorpayCheckout, RazorpayEventEmitter } = Razorpay; -``` -2. Instantiate an event emitter with `RazorpayEventEmitter`: -```js -const razorpayEvents = new NativeEventEmitter(RazorpayEventEmitter); -``` -3. Add payment event listeners to your component, preferably in `componentWillMount`: +1. Import RazorpayCheckout module to your component: ```js -razorpayEvents.addListener('onPaymentError', (data) => { - alert("Error: " + data.code + " | " + data.description) -}); -razorpayEvents.addListener('onPaymentSuccess', (data) => { - alert("Success: " + data.payment_id) -}); +import RazorpayCheckout from 'react-native-razorpay'; ``` -4. Call RazorpayCheckout's `open` method with `options`, preferably on a user action: +2. Call `RazorpayCheckout.open` method with the payment `options`. The method +returns a **JS Promise** where `then` part corresponds to a successful payment +and the `catch` part corresponds to payment failure. ```js { var options = { @@ -111,17 +102,22 @@ razorpayEvents.addListener('onPaymentSuccess', (data) => { key: 'rzp_test_1DP5mmOlF5G5ag', amount: '5000', name: 'foo', - prefill: {email: 'pranav@razorpay.com', contact: '8879524924', name: 'Pranav Gupta'}, + prefill: { + email: 'akshay@razorpay.com', + contact: '8955806560', + name: 'Akshay Bhalotia' + }, theme: {color: '#F37254'} } - RazorpayCheckout.open(options) + RazorpayCheckout.open(options).then(data => + { alert("Success: " + data.payment_id) } + ).catch(data => + { alert("Error: " + data.code + " | " + data.description) } + ); }}> ``` -5. Stop listening for payment events, preferably in `componentWillMount`: -```js -razorpayEvents.remove(); -``` - +A descriptive [list of valid options for checkout][options] is available (under +Manual Checkout column). ## Contributing @@ -143,3 +139,4 @@ or [contact us][contact] to help you with integrations. [integrations]: https://razorpay.com/integrations "List of our integrations" [ios-docs]: https://docs.razorpay.com/v1/page/ios-integration "Documentation for the iOS Integration" [LICENSE]: /LICENSE "MIT License" +[options]: https://docs.razorpay.com/docs/checkout-form#checkout-fields "Checkout Options" diff --git a/RazorpayCheckout.js b/RazorpayCheckout.js index e3f57a844..9fd10a73b 100644 --- a/RazorpayCheckout.js +++ b/RazorpayCheckout.js @@ -2,7 +2,29 @@ import { NativeModules, NativeEventEmitter } from 'react-native'; -export const Razorpay = { - RazorpayCheckout: NativeModules.RazorpayCheckout, - RazorpayEventEmitter: NativeModules.RazorpayEventEmitter +const razorpayEvents = new NativeEventEmitter(NativeModules.RazorpayEventEmitter); + +const removeSubscriptions = () => { + razorpayEvents.removeAllListeners('Razorpay::PAYMENT_SUCCESS'); + razorpayEvents.removeAllListeners('Razorpay::PAYMENT_ERROR'); }; + +class RazorpayCheckout { + static open(options, successCallback, errorCallback) { + return new Promise(function(resolve, reject) { + razorpayEvents.addListener('Razorpay::PAYMENT_SUCCESS', (data) => { + let resolveFn = successCallback || resolve; + resolveFn(data); + removeSubscriptions(); + }); + razorpayEvents.addListener('Razorpay::PAYMENT_ERROR', (data) => { + let rejectFn = errorCallback || reject; + rejectFn(data); + removeSubscriptions(); + }); + NativeModules.RazorpayCheckout.open(options); + }); + } +} + +export default RazorpayCheckout; diff --git a/android/src/main/java/com/razorpay/rn/RazorpayModule.java b/android/src/main/java/com/razorpay/rn/RazorpayModule.java index 5dabfdd07..0e6d5846a 100644 --- a/android/src/main/java/com/razorpay/rn/RazorpayModule.java +++ b/android/src/main/java/com/razorpay/rn/RazorpayModule.java @@ -115,15 +115,15 @@ public void onActivityResult(int requestCode, int resultCode, Intent data){ if (data != null) { Bundle extras = data.getExtras(); if (extras != null) { - result = extras.getString("RESULT"); - } + result = extras.getString("RESULT"); + } } if (resultCode == 1) { try { JSONObject resultJson = new JSONObject(result); WritableMap successParams = Arguments.createMap(); successParams.putString(MAP_KEY_PAYMENT_ID, resultJson.getString(MAP_KEY_RZP_PAYMENT_ID)); - sendEvent("onPaymentSuccess", successParams); + sendEvent("Razorpay::PAYMENT_SUCCESS", successParams); } catch(Exception e){} } else { @@ -133,8 +133,8 @@ public void onActivityResult(int requestCode, int resultCode, Intent data){ WritableMap errorParams = Arguments.createMap(); errorParams.putInt(MAP_KEY_ERROR_CODE, resultCode); errorParams.putString(MAP_KEY_ERROR_DESC, result); - sendEvent("onPaymentError", errorParams); - } + sendEvent("Razorpay::PAYMENT_ERROR", errorParams); + } } private void sendEvent(String eventName, @Nullable WritableMap params) { diff --git a/example/index.js b/example/index.js index 69c02600e..6b9a66983 100644 --- a/example/index.js +++ b/example/index.js @@ -1,8 +1,8 @@ /** - * Sample React Native App - * https://github.com/facebook/react-native - * @flow - */ +* Sample React Native App +* https://github.com/facebook/react-native +* @flow +*/ import React, { Component } from 'react'; import { @@ -15,25 +15,14 @@ import { NativeEventEmitter } from 'react-native'; -import { Razorpay } from 'react-native-razorpay'; -const { RazorpayCheckout, RazorpayEventEmitter } = Razorpay; - -const razorpayEvents = new NativeEventEmitter(RazorpayEventEmitter); +import RazorpayCheckout from 'react-native-razorpay'; class example extends Component { - componentWillMount() { - razorpayEvents.addListener('onPaymentError', (data) => { - alert("Error: " + data.code + " | " + data.description) - }); - razorpayEvents.addListener('onPaymentSuccess', (data) => { - alert("Success: " + data.payment_id) - }); - } render() { return ( - { + { var options = { description: 'Credits towards consultation', image: 'https://i.imgur.com/3g7nmJC.png', @@ -41,21 +30,27 @@ class example extends Component { key: 'rzp_test_1DP5mmOlF5G5ag', amount: '5000', name: 'foo', - prefill: {email: 'pranav@razorpay.com', contact: '8879524924', name: 'Pranav Gupta'}, + prefill: { + email: 'akshay@razorpay.com', + contact: '8955806560', + name: 'Akshay Bhalotia' + }, theme: {color: '#F37254'} } - RazorpayCheckout.open(options) - }}> + RazorpayCheckout.open(options).then((data) => { + // handle success + alert(`Success: ${data.payment_id}`); + }).catch((error) => { + // handle failure + alert(`Error: ${error.code} | ${error.description}`); + }); + }}> Pay - - + + ); } - componentWillUnmount () { - razorpayEvents.remove(); - } - } const styles = StyleSheet.create({ diff --git a/example/package.json b/example/package.json index 1c73964f2..0f532a6a7 100644 --- a/example/package.json +++ b/example/package.json @@ -8,6 +8,6 @@ "dependencies": { "react": ">=15.0.0", "react-native": ">=0.30.0", - "react-native-razorpay": ">=1.0.0" + "react-native-razorpay": "./../" } } diff --git a/ios/RazorpayEventEmitter.m b/ios/RazorpayEventEmitter.m index 1c3aa32a2..ea8e82eec 100644 --- a/ios/RazorpayEventEmitter.m +++ b/ios/RazorpayEventEmitter.m @@ -19,7 +19,7 @@ @implementation RazorpayEventEmitter RCT_EXPORT_MODULE(); - (NSArray *)supportedEvents { - return @[ @"onPaymentSuccess", @"onPaymentError" ]; + return @[ @"Razorpay::PAYMENT_SUCCESS", @"Razorpay::PAYMENT_ERROR" ]; } - (void)startObserving { @@ -38,11 +38,13 @@ - (void)stopObserving { } - (void)paymentSuccess:(NSNotification *)notification { - [self sendEventWithName:@"onPaymentSuccess" body:notification.userInfo]; + [self sendEventWithName:@"Razorpay::PAYMENT_SUCCESS" + body:notification.userInfo]; } - (void)paymentError:(NSNotification *)notification { - [self sendEventWithName:@"onPaymentError" body:notification.userInfo]; + [self sendEventWithName:@"Razorpay::PAYMENT_ERROR" + body:notification.userInfo]; } + (void)onPaymentSuccess:(NSString *)payment_id {