React Native PayUMoney Bridge

In recent past years, react native has gain lot of popularity. There are lots of third party libraries available on GitHub which everyone can use easily. But there are some cases where we have to create some functionality our self which is not available till now. So today we will take a look at, how we can create react native bridge with the PayUMoney example. PayUMoney provides the SDKs in native android and iOS but there is no support for react native right now so we will create the react native bridge in android and iOS both.

First create the account in PayUMoney site and get the merchant ID, merchant Key and merchant Salt.

Setting up Android

Import the PayUMoney dependency in gradle file at app level.

  • compile ‘com.paymoney.sdkui:plug-n-play:1.5.0’

Now create class name PayUMoney which extends ReactContextBaseJavaModule and implement the methods of parent class. If you want to send the result to react native then you will have to implement ActivityEventListener. In our case we will pass the response from PayUMoney to react native so we will implement ActivityEventListener and will emit the events. You can return whatever name you want in getName method which will be used to access the Module from react native class.

@Override
    public String getName() {
        return "PayUMoney";
    }

Now create method name makePayment and overwrite it with @ReactMethod which will expose this method to react native and we can directly call this method from react native class.

@ReactMethod
public void makePayment(final String amount, String txnId, final String productName, final String firstName, final String email, final String phone, final String merchantId, final String merchantKey, final String merchantSUrl, final String merchantFUrl, final Boolean merchantSandbox, final String hash) {

        PayUmoneySdkInitializer.PaymentParam.Builder builder = new PayUmoneySdkInitializer.PaymentParam.Builder();
        builder.setAmount(Double.parseDouble(amount))
                .setTxnId(txnId).setPhone(phone)
                .setProductName(productName).setFirstName(firstName)
                .setEmail(email).setsUrl(merchantSUrl)
                .setfUrl(merchantFUrl).setIsDebug(merchantSandbox)
                .setKey(merchantKey)
                .setIsDebug(true)
                .setMerchantId(merchantId);

        PayUmoneySdkInitializer.PaymentParam paymentParam = null;
        try {
            paymentParam = builder.build();
            paymentParam.setMerchantHash(hash);
            PayUmoneyFlowManager.startPayUMoneyFlow(paymentParam, PayActivity.this, R.style.AppTheme_default, true);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Above method will initiate the PayUMoney SDK in debug mode. If you want to release the app then you will have to pass false in setIsDebug method. Before calling this method you must calculate hash using your key and salt. PayUMoney will match your parameters with your hash and if it matches than only than PayUMoney SDK will be initiated. After payment transaction pay-u will send back you the response in onActivityResult method. We will emit the response to react native using RCTDeviceEventEmitter class. So first create method as bellow which will emit the response back to react native.

private void sendEvent(String eventName, String params) {
        ReactApplicationContext context = getReactApplicationContext();
        context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                .emit(eventName, params);
    }


@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Intent intent = new Intent();
        if (requestCode == PayUmoneyFlowManager.REQUEST_CODE_PAYMENT && resultCode == RESULT_OK && data != null) {
            TransactionResponse transactionResponse = data.getParcelableExtra(PayUmoneyFlowManager.INTENT_EXTRA_TRANSACTION_RESPONSE);
            ResultModel resultModel = data.getParcelableExtra(PayUmoneyFlowManager.ARG_RESULT);
            if (transactionResponse != null && transactionResponse.getPayuResponse() != null) {
                if (transactionResponse.getTransactionStatus().equals(TransactionResponse.TransactionStatus.SUCCESSFUL)) {
                    String payuResponse = transactionResponse.getPayuResponse();
                    sendEvent("PAYU_PAYMENT_SUCCESS", payuResponse);
                } else {
                    sendEvent("PAYU_PAYMENT_SUCCESS", "{error:true}");
                }
            } else {
                sendEvent("PAYU_PAYMENT_SUCCESS", "{error:true}");
            }
        }
    }

We will check if transaction is successful or not and send event according it. We have to pass event name so we can listen for that event in react native.

Now you will have to create class called PayUMoneyPackage as bellow and add that in getPackaes method of MainApplication class.

@Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          new MainReactPackage(),
            new PayUMoneyPackage()
      );
    }

public class PayUMoneyPackage implements ReactPackage  {
    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }
    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();
        modules.add(new PayUMoney(reactContext));
        return modules;
    }
}

That’s it for android.

Setting up in iOS

First you will have to download the plug-n-play sdk using following command or you can directly download it form PayUMoney site itself.

$ git clone –recursive https://github.com/payu-intrepos/PayUMoney-IOS-SDK.git

Open your project in Xcode. After download, extract the folder.

  • Drag the PlugNPlay.framework into xcode project. Add PlugNPlay.framework in Build Phases tab if not added.
  • Drag PayUMoneyCoreSDK.framework in Xcode project and add it to Embedded Binaries section if not added.
  • Navigate to Dependencies/CB folder and drag PayUCustomBrowser.framework inot Xcode project and add it to Embedded Binaries section if not added.

Create class named PayUMoney in objective-c language and add the following code to PayUMoney.h file

#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>
@interface PayUMoney : RCTEventEmitter <RCTBridgeModule>
@end

Now import PlugNPlay SDK in PayUMoney.m file and add the RCT_EXPORT_MODULE () method which will expose the module to react native.

- (NSArray<NSString *> *)supportedEvents
{
  return @[@"PAYU_PAYMENT_SUCCESS",@"PAYU_PAYMENT_FAILED"];
}



RCT_EXPORT_METHOD(makePayment :(NSString *)amount :(NSString *)txid :(NSString *)productId
                  :(NSString *)name :(NSString *)email :(NSString *)phone :(NSString *)merchantId
                  :(NSString *)key :(NSString *)surl :(NSString *)furl :(NSString *)hash ) {

  PUMTxnParam *txnParam= [[PUMTxnParam alloc] init];
  txnParam.phone = phone;
  txnParam.email = email;
  txnParam.amount = amount;
  txnParam.environment = PUMEnvironmentTest;
  txnParam.firstname = name;
  txnParam.key = key;
  txnParam.merchantid = merchantId;
  txnParam.txnID = txid;
  txnParam.surl = surl;
  txnParam.furl = furl;
  txnParam.productInfo = productId;
  txnParam.hashValue = hash;
  
  dispatch_sync(dispatch_get_main_queue(), ^{
    [PlugNPlay setDisableCompletionScreen:YES];
    [PlugNPlay presentPaymentViewControllerWithTxnParams:txnParam
                                        onViewController:RCTPresentedViewController()
                                     withCompletionBlock:^(NSDictionary *paymentResponse, NSError *error, id extraParam) {
                                      NSLog(@"paymentResponse=%@",paymentResponse);
                                      NSLog(@"error=%@",error.localizedDescription);
                                      if (error) {
                                        NSString *ErrorDis = [NSString stringWithFormat:@"%@",error.localizedDescription];
                                        NSDictionary *JSONDic = [NSDictionary dictionaryWithObjectsAndKeys:
                                                            @false, @"success",
                                                            ErrorDis, @"Error",
                                                            nil];
                                        NSData *jsonData = [NSJSONSerialization dataWithJSONObject:JSONDic
                                                                                           options:NSJSONWritingPrettyPrinted
                                                                                             error:&error];
                                        NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
                                        [self sendEventWithName:@"PAYU_PAYMENT_FAILED" body:jsonString];
                                      } else {
                                        
                                        NSData *jsonData = [NSJSONSerialization dataWithJSONObject:paymentResponse
                                                                                           options:NSJSONWritingPrettyPrinted
                                                                                             error:&error];
                                        NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
                                        [self sendEventWithName:@"PAYU_PAYMENT_SUCCESS" body:jsonString];

                                      }
                                    }];
  });
}

Add above two methods in your PayUMoney.m file which will initiate the pay-u-money sdk in iOS and return the response back. We will check the response and send the response to react native using sendEventWithName method. That’s it for iOS part.

We have successfully created bridge in android and iOS. Now it’s time to call it from react native.

First import the NativeModules and NativeEventEmitter from react native and create constant variable as follows.

import { NativeModules, NativeEventEmitter} from "react-native";
const PayUMoney = NativeModules.PayUMoney;
const PayUMoneyEventEmitter = new NativeEventEmitter(PayUMoney);

Now add listeners in your screen where you want to start the pay-u-money sdk as follows.

PayUMoneyEventEmitter.addListener('PAYU_PAYMENT_SUCCESS', (res) => {
   console.log('PAYU_PAYMENT_SUCCESS=' + res)
   PayUMoneyEventEmitter.removeAllListeners('PAYU_PAYMENT_SUCCESS');
   PayUMoneyEventEmitter.removeAllListeners('PAYU_PAYMENT_FAILED');
});

PayUMoneyEventEmitter.addListener('PAYU_PAYMENT_FAILED', (res) => {
   console.log('PAYU_PAYMENT_FAILED=' + res) 
   PayUMoneyEventEmitter.removeAllListeners('PAYU_PAYMENT_SUCCESS');
   PayUMoneyEventEmitter.removeAllListeners('PAYU_PAYMENT_FAILED');
});

After that calculate the hash from your server and then you can start the pay-u-money payment flow by calling makePayment method as below.

PayUMoney.makePayment(amount, txnId, productId, name, email, phone, MERCHANT_ID,
                        MERCHANT_KEY, sURL, fURL, SANDBOX, hash)

You will get the pay-u-money response in listener method where you can easily identify the payment status. This will work in both android and iOS.

We have created a Native bridge which is cross Platform.

Leave a Reply

Your email address will not be published. Required fields are marked *