search

Custom UI SDK Integration - Transaction processing

This part of Custom UI SDK integration is regarding the transaction processing through the SDK. Before continuing with the steps mentioned below, please make sure that the integration steps mentioned in SDK initialisation and Account linking (if applicable) are already executed.

  1.  
    1

    Implement the interface PaytmSDKCallbackListener

  2. Implement the interface PaytmSDKCallbackListener to get the status of a transaction for different payment instruments. This interface has the following callbacks methods.

    1. onTransactionResponse: This will provide the response status data related to a transaction. The response will contain a JSON string of TxnInfo. Refer the following:
      // get json string of txnInfo
      public void onTransactionResponse(TransactionInfo bundle) {
          if (bundle != null) {
              if (bundle.getTxnInfo() != null) {
                  String s = new Gson().toJson(bundle.getTxnInfo());
                  Toast.makeText(this, s, Toast.LENGTH_LONG).show();
              }
          }
      }            
      Sample TxnInfo data
      {
          "ORDERID": "PARCEL15816826759",
          "MID": "AliSub58582630351896",
          "TXNID": "20200214111212800110168052313701129",
          "TXNAMOUNT": "1.00",
          "PAYMENTMODE": "CC",
          "CURRENCY": "INR",
          "TXNDATE": "2020-02-14 17:48:13.0",
          "STATUS": "TXN_SUCCESS",
          "RESPCODE": "01",
          "RESPMSG": "Txn Success",
          "MERC_UNQ_REF": "test4",
          "UDF_1": "test1",
          "UDF_2": "test2",
          "UDF_3": "test3",
          "ADDITIONAL_INFO": "test5",
          "GATEWAYNAME": "ICICIPAY",
          "BANKTXNID": "68568621250",
          "BANKNAME": "HSBC",
          "PROMO_CAMP_ID": "PROMO CODE",
          "PROMO_RESPCODE": "702",
          "PROMO_STATUS": "FAILURE"
      }
    2. TransactionInfo.ResultInfo: This will contain the status of a transaction, along with retry supported information in case payment can be retried for the same orderId. Status of the transaction can be obtained using ResultInfo.resultStatus contains the transaction status and has only three values: TXN_SUCCESS, TXN_FAILURE and PENDING.
    3. onBackPressedCancelTransaction: This method will be called if a user presses the Back button on any of the screens during the transaction such as the OTP page.
    4. onGenericError (String errorCode, String errorMsg): This method will be called if you report No Network cases or Timeouts.
      Error code Error message
      101 No Internet connection
      103 TIMEOUT
      104 UNKNOWN
  3.  
    2

    Generate transaction token from your backend

  4. After the user adds the product in the cart and clicks the button to proceed for checkout, your app calls the backend server to get the order payout. Then, your backend server calls Initiate Transaction API from the backend to generate the Transaction Token.

    Note: In case you wish to use the custom Callback URL in Initiate Transaction API then please include the config setMerchantCallbackUrl during Initialization of SDK.

  5. 3

    Fetch paytm user’s saved instruments

  6. Using the Transaction token received above, your backend server calls the Fetch Payment Options API to receive the different payment options including the user's saved instruments and other instruments like CC/DC, NB, UPI, EMI etc.

    Note: In case you do not want to create order first, you may call the Fetch Payment Options API before Initiate Transaction. For more details please Get in touch with us.

  7. 4

    PaytmSDK builder creation

  8. Create PaytmSDK builder using the parameters mid, orderId, txnToken, and amount.

    Signature:
    PaytmSDK.Builder builder = new PaytmSDK.Builder(this, mid, orderId, txnToken, amount, this
    /*PaytmSDKCallbackListener*/);
    
    builder.setMerchantCallbackUrl(Constants.callBackUrl);
    
    PaytmSDK paytmSDK = builder.build();

    Method Parameters:

    Attribute Type Description
    context Context Your application context
    mid String Merchant id identifying a merchant
    orderId String Unique identifier for current order
    txnToken String Transaction token to identify the current transaction received in response to Initiate Transaction API from Paytm. Refer to Step 2.
    double amount   Order amount for the current transaction
    PaytmSDKCallbackListener   Interface implementation to get the result of a payment transaction. Refer to Step 1.

    Note: You can make changes for some of the optional configurations. Please refer to the Optional Methods.

  1. 5

    Proceed for the Transaction

  2. When a user clicks the Pay button after entering the payment instrument’s details in the selected payment method, you need to proceed with the transaction. Please follow the steps below for proceeding with the transaction.

    1. Create a model of PaymentRequestModel type based on the type of payment mode chosen by the user.

Model name : CardRequestModel

Creation of Object:

CardRequestModel cardRequestModel = new CardRequestModel(paymentMode, paymentFlow, 
cardNumber, cardId, cardCvv, cardExpiry, bankCode, channelCode, authMode, emiPlanId, 
shouldSaveCard)

Constructor Attributes:

Attributes Type Description

paymentMode

String (mandatory)

type of card (DEBIT_CARD, CREDIT_CARD)

paymentFlow

String (mandatory) current payment flow (NONE, ADDNPAY)

newCardNumber

String (conditional) card number digits for a new card (null for the saved card)

savedCardId

String (conditional) cardId for a saved card (null for a new card)

cardCvv

String (mandatory) CVV of the card

cardExpiry

String (conditional) card expiry date in the format MM/YY (eg. 11/19)

channelCode

String (conditional) channelCode of card obtained from fetchBinDetails API(eg. VISA, MASTER)

bankCode

String (conditional) bank code of card obtained from fetchBinDetails API(eg. ICICI, AXIS)

authMode

String (mandatory) the mode of 2FA chosen for a card(either by 'pin' or 'OTP'), options obtained from fetchBinDetails API

emiPlanId

String (conditional) emiPlan id in case of an EMI transaction

shouldSaveCard

Boolean (optional) flag to indicate if the new card should be saved at Paytm’s end

Model name: WalletRequestModel

Creation of Object:

WalletRequestModel walletRequestModel = new WalletRequestModel(paymentFlow)

Constructor Attributes:

Attribute Type Description

paymentFlow

String current payment flow (NONE, ADDNPAY)

Model name: NetBankingRequestModel

Creation of Object:

NetBankingRequestModel netBankingRequestModel = new NetBankingRequestModel(paymentFlow,
bankCode)

Constructor Attributes:

Attribute Type Description

paymentFlow

String current payment flow (NONE, ADDNPAY)

bankCode

String bank code for the bank

Model name: UpiCollectRequestModel

Creation of Object:

UpiCollectRequestModel upiCollectRequestModel = new UpiCollectRequestModel(paymentFlow,
upiId)

Constructor Attributes:

Attribute Type Description

paymentFlow

String the current payment flow (NONE, ADDNPAY)

upiId

String UPI handle for making payment(eg. xyz@paytm)

Model name: UpiPushRequestModel

Creation of Object:

UpiPushRequestModel requestModel = new UpiPushRequestModel(paymentFlow,vpa,,bankAccount,merchantDetails)

Constructor Attributes:

Attribute Type Description

paymentFlow

String current payment flow (NONE, ADDNPAY)

vpa

String Virtual Payment Address(eg.xyz@paytm)

bankAccount

String JSON string representing a bank account for UPI

merchantDetails

String JSON string containing merchant info for which payment is required

enableCollectCustomPolling

Boolean

True, when custom polling page is implemented at the merchant end

The default value is false

  1. Merchant app needs to fetch the list of UPI Apps installed in the device by calling the below method:
    PaytmSDK.getPaymentsHelper().getUpiAppsInstalled(Context context)
    The above method returns a List <UpiOptionsModel> which can be used to display a list of apps which support UPI payment.UpiOptionsModel.getAppName() and UpiOptionsModel.getDrawable() can be used to show the App name and icon.
     
  2. Next when the user selects any UPI app to create an object of UpiIntentRequestModel to launch the selected app and start the transaction process.

    Model name: UpiIntentRequestModel

    Creation of Object:
    UpiIntentRequestModel upiCollectRequestModel = new UpiIntentRequestModel(paymentFlow,
    selectedAppName,activityInfo)
    
    Constructor Attributes:
    Attribute Type Description

    paymentFlow

    String The current payment flow (NONE, ADDNPAY)

    selectedAppName

    String UPI app to be launched for making payment (The name of app is obtained from UpiOptionsModel.getAppName() method)
    activityInfo ActivityInfo   Activity information about the UPI app to be launched (This parameter is obtained from UpiOptionsModel.getResolveInfo().activityInfo).
    Then call paytmSdk.startTransaction(Activity context, PaymentRequestModel paymentRequestModel) to start a transaction ( You need to initialise PaytmSDK first for calling this method as mentioned in Steps to initialize Paytm SDK)

The result for the above call will be returned in PaytmSDKCallbackListener as for other transactions.

  1. Call paytmSDK.startTransaction to call the Process Transaction API. Once you have created the request model for the payment mode selected by the user, call the below method, to start a payment transaction.
      paytmSdk.startTransaction(Activity context, PaymentRequestModel paymentRequestModel)

    Method Params:

    Parameter Description
    Activity context SDK needs the context of activity as it might have to further launch new activities bank OTP pages/ website etc. based on payment mode selected.
    PaymentRequestModel paymentRequestModel The type of paymentRequestModel created for this transaction
  2. Fetch the payment result in PaytmSDKCallbackListenerThe result of the transaction will be received via PaytmSDKCallbackListener Interface described in Step 1.
  3. Clean up SDK instance

    After completing the transaction merchant should call the below method to clear payment SDK state when destroying the PG page.

    PaytmSDK.clearPaytmSDKData()
  1.  
    1

    Implement the interface AIDelegate

  2. Implement the interface AIDelegate to get the status of a transaction for different payment instruments.

AIDelegate

Interface protocol:

class {
 func didFinish(with success: Bool, response: [String:Any], 
    error : String?, withUserCancellation hasUserCancelledTransaction : Bool)
}

Method Params: This interface has the following parameters.

  1. success: It's value is true if the transaction is success otherwise false.
  2. response: This will contain the status of transaction, along with retry supported information in case payment can be retried for the same orderId. Status of transaction can be obtained using ResultInfo.resultStatus which contains the transaction status and has only three values - TXN_SUCCESS, TXN_FAILURE and PENDING.

    Sample TxnInfo data
    {
        STATUS=TXN_SUCCESS, 
        PROMO_RESPCODE=702, 
        BANKNAME=HSBC,
        ORDERID=PARCEL20000O71428, 
        TXNAMOUNT=1.00, 
        TXNDATE=2019-12-10 14:50:37.0, 
        MID=AliSub58582630351896, 
        TXNID=20191210111212800110168943202148446, 
        UDF_1=abc1, 
        UDF_2=abc2, 
        UDF_3=abc3,
        PROMO_CAMP_ID=PROMO CODE,
        RESPCODE=01, 
        PAYMENTMODE=CC, 
        MERC_UNQ_REF=vivek4, 
        BANKTXNID=201934434837540, 
        ADDITIONAL_INFO=vivek5, 
        CURRENCY=INR, 
        PROMO_STATUS=FAILURE, 
        GATEWAYNAME=HDFC, 
        RESPMSG=Txn Success
    }
                                    
  3. error: This will contain the error message in case of any network error.
  4. withUserCancellation: This method will be called if a user cancels the transaction in which case its value shall be 'true' else it's value is 'false'.
  1.  
    2

    Generate transaction token from your backend

  2. After the user adds the product in the cart and clicks the button to proceed for checkout, your app calls the backend server to get the order payout. Then, your backend server calls Initiate Transaction API from the backend to generate the Transaction Token.

  3. 3

    Fetch paytm user’s saved instruments

  4. Using the Transaction token received above, your backend server calls the Fetch Payment Options API to receive the different payment options including user's saved instruments and other instruments like CC/DC, NB, UPI, EMI etc.

    payment-transaction-flow-chart

    Note: In case you do not want to create order first, you may call the Fetch Payment Options API before Initiate Transaction. For more details please Get in touch with us.

  5. 4

    Create a model of AINativeBaseParameterModel

    Create the AINativeBaseParameterModel using the parameters like MerchantId(mid), TransactionToken as received in the above step, amount of transaction, Callback listener.

    func callProcessTransactionAPI(selectedPayModel : AINativeBaseParameterModel,
         delegate: AIDelegate,
         controller parentVC: UIViewController)

    Method Parameters

    Attribute Description
    selectedPayModel Create a model of AINativeBaseParameterModel according to the paymode type.
    AIDelegate It is Paytm SDK Callback listener, used to get callback of processTransaction Api. Refer to Step 3.
    parentVC parse the current Controller object for presenting/pushing the SDK controller.
  6. 5

    Proceed for the Transaction

    When the user clicks on the Pay button after entering the payment instrument’s details in the selected payment method, you need to proceed for the transaction. Please follow the steps below for proceeding with the transaction.

Class Name: AINativeSavedCardParameterModel
 

Method signature:

public init(withTransactionToken: txnToken, orderId,  shouldOpenNativePlusFlow,
 mid, flowType paymentModes, authMode, cardId, cardNumber, cvv, expiryDate, 
isNewCard, redirectionUrl)

Method Parameter:

Attribute Type Description
txnToken String Transaction token to identify the current transaction as received in Step 4.
mid String Merchant id identifying a merchant
orderId String Unique identifier for current order
shouldOpenNativePlusFlow Boolean True in case NativePlus is enabled, else False
flowType   Current payment flow (NONE, ADDNPAY)
paymentModes   type of card(DEBIT_CARD, CREDIT_CARD)

redirectionUrl

String Same Url defined in Initiate Transaction API in callback key. Default is "https://securegw.paytm.in/theia/api/v1/processTransaction?"
authMode   The mode of 2FA chosen for card(either by 'pin' or 'otp'), options obtained from fetchBinDetails API
cardId String cardId for a saved card (null for new card)
cardNumber String card number digits for a new card (null for saved card)
cvv String cvv of the card
expiryDate String card expiry date in the format MMYYYY (eg. 112023)
isNewCard Boolean Flag to indicate if the card needs to be saved at Paytm backend
storeInstrument String Flag to indicate if the new card need to be saved in local vault

Class Name: AINativeInhouseParameterModel

Method Signature:

public init(withTransactionToken txnToken, orderId, shouldOpenNativePlusFlow, mid, 
flowType : AINativePaymentFlow, paymentModes : AINativePaymentModes, 
redirectionUrl)

Method Parameter:

Attribute Type Description
txnToken String Transaction token to identify the current transaction as received in Step 4.
mid String Merchant id identifying a merchant
orderId String Unique identifier for current order
shouldOpenNativePlusFlow Boolean True in case NativePlus is enabled, else False
flowType   current payment flow (NONE, ADDNPAY)
paymentModes   Type of paymentMode, For wallet transaction, its value shall be a wallet
redirectionUrl String The same Url defined in Initiate Transaction API in callback key. Default is "https://securegw.paytm.in/theia/api/v1/processTransaction?"

Class Name: AINativeNBParameterModel

Method Signature:

public init(withTransactionToken: txnToken, orderId,  shouldOpenNativePlusFlow, mid, 
flowType, paymentModes, channelCode, redirectionUrl)

Method Parameter:

Attribute Type Description
txnToken String Transaction token to identify the current transaction as received in Step 4.
mid String Merchant id identifying a merchant
orderId String Unique identifier for current order
flowType Boolean True in case NativePlus is enabled, else False
paymentMode   current payment flow (NONE, ADDNPAY)
paymentMode String NET_BANKING
channelCode String Bank code to identify the bank.
redirectionUrl String The same URL defined in Initiate Transaction API in callback key. Default is "https://securegw.paytm.in/theia/api/v1/processTransaction?"

Class Name: AINativeNUPIParameterModel

Method Signature:

public init(withTransactionToken: txnToken, orderId,  shouldOpenNativePlusFlow, mid, 
flowType, paymentModes, vpaAddress, upiFlowType, redirectionUrl)

Method Parameter:

Attribute Type Description
txnToken String Transaction token to identify the current transaction as received in Step 4.
mid String Merchant id identifying a merchant
orderId String Unique identifier for current order
shouldOpenNativePlusFlow Boolean True in case NativePlus is enabled, else False
flowType   current payment flow (NONE, ADDNPAY)
paymentMode String UPI
upiFlowType String collect
redirectionUrl String The same Url defined in Initiate Transaction API in callback key. Default is "https://securegw.paytm.in/theia/api/v1/processTransaction?"

Class Name: AINativeNUPIarameterModel

let selectedPayModel = 
      AINativeNUPIarameterModel.init
          (withTransactionToken: txnToken, 
           orderId: orderId, 
           shouldOpenNativePlusFlow: true, 
           mid: merchantId, 
           flowType: flowType, 
           amount: amount, 
           paymentModes: .upi, 
           vpaAddress: self.vpaAddress, 
           upiFlowType: .push, 
           merchantInfo: self.merchantDetails, 
           bankDetail: self.bankDetails)

Polling Config:

let upiPollingConfig =  
       UpiCollectConfigurations(shouldAllowCustomPolling: false, 
       isAutoPolling: true)
  • For handling of polling screen by merchant set: shouldAllowCustomPolling = true
  • If a merchant wants to call polling API by himself set: isAutoPolling = false

Default config of polling:

 

shouldAllowCustomPolling = false
isAutoPolling = true

 

Use the method mentioned below Method to Invoke SDK:

public func callProcessTransactionAPIForUPI(selectedPayModel: selectedPayModel, 
       upiPollingConfig: PaytmNativeSDK.UpiCollectConfigurations, 
       delegate: PaytmNativeSDK.AIDelegate, 
       completionForPush: PaytmNativeSDK.MerchantPaymentCompletionBlock?, 
       completionForCollect : 
         (([String: Any]) -> Void) ?)

Incase if a different user login to the Paytm app, it will start the UPI collect flow and the response will be received in completionForCollect callback. The polling handling can be done in this callback.

 

Example method to handle polling from completionForCollect block:

 //MARK: USE Collect flow
    func handleForCollectFlow(responseDict: [String:Any]) {
        //MARK: Polling of transactionStatus API
        //use upiCollectPollingCompletion callback to handle if auto polling is true like this:
        self.appInvoke.upiCollectPollingCompletion = { (status, model) in
            print(status)
            let alert = UIAlertController(title: "", message: "transaction " + "\(status)", preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
            
            switch status {
            case .failure: break
            case .success: break
            default: break
            }
        }

Method Parameter:

Attribute Description
completionForPush it will return an enum of type AINativeTokenFlowStatus with possible values:
  • .appNotInstall- if the app is not installed on your device.
  • .error- if request parameters are not valid.
  • .inProcess- AppInvoke is a process initiated by SDK and you get the callback using the URL schema.
completionForCollect The polling handling can be done in this callback.
AIDelegate It is a Paytm SDK Callback listener which is used to get callback of processTransaction API. Refer to Step 3.
upiPollingConfig It is used for the configuration of polling page whether the merchant wants his own polling page or Paytm's polling page.
selectedPayModel model of type AINativeNUPIarameterModel.

Sample Response:

{
    "ADDITIONAL_INFO": "test5",
    "BANKTXNID": "101201854060",
    "CURRENCY": "INR",
    "GATEWAYNAME": "PPBEX",
    "MERC_UNQ_REF": "test4",
    "MID": "AliSub58582630351896",
    "ORDERID": "PARCEL16104595263",
    "PAYMENTMODE": "UPI",
    "RESPCODE": "01",
    "RESPMSG": "Txn Success",
    "STATUS": "TXN_SUCCESS",
    "TXNAMOUNT": "1.00",
    "TXNDATE": “2021 - 01 - 12 19: 22: 10.0 ","
    TXNID ":"
    20210112111212800110168844174480555 ","
    UDF_1 ":"
    test1 ","
    UDF_2 ":"
    test2 ","
    UDF_3 ":"
    test3 "}}

Method Signature:

 init(withTransactionToken txnToken : String, orderId : String,
  shouldOpenNativePlusFlow : Bool, mid : String, flowType : AINativePaymentFlow, 
amount : CGFloat, paymentModes : AINativePaymentModes, vpaAddress : String, 
upiFlowType : AINativeUPIFlow , merchantInfo : [String:*Any*]?, 
bankDetail : [String : *Any*]?, redirectionUrl : String)

Method Parameter:

Attribute Description
amount transaction amount
vpaAddress UPI handle for making payment(eg. xyz@paytm)
upiFlowType AINativeUPIFlow. UPI.
merchantInfo merchant details obtained from FetchPaymentOption API. It contains merchant details.
bankDetail bank detail obtained from Fetch Payment Option API. It contains bank details. Other parameters already defined above.
completion it will return an enum of type AINativeTokenFlowStatus with possible values:
  • .appNotInstall- if the app is not installed on your device.
  • .error- if request parameters are not valid.
  • .inProcess- AppInvoke is a process initiated by SDK and you get the callback using the URL schema.

Note: In the case of .inProcess state, the paytm app will invoke for payment and get the callback in appDelegate using UrlSchema.
Format of URL Schema :
paytm(self.mid)://payment?response=(responseInFormOfString)&status=(merchantPaymentStatus.rawValue)

Get the Deeplink URL for UPI Intent using the Process Transaction API.

We can create the DeepLink URL for Paytm, GooglePay, and PhonePe by passing the type in Methods call. Pass the PspApp type.

 

Method Signature: callProcessTransactionAPIForUPIIntent

func callProcessTransactionAPIForUPIIntent(orderId: String, mid: String, txnToken: String, pspApp: PspApp, completionHandler: UPIIntentCallBack?)

Method Params:

Parameter Type Description
orderId String Unique identifier for current order
Mid String Merchant id identifying a merchant
pspApp String Pass the type of DeepLink url you want like phonePe, gPay, and paytm.
completionHandler String Getting the response with deeplink

Sample Paytm Deeplink:

self.appInvoke.callProcessTransactionAPIForUPIIntent(orderId: orderId, mid: merchantId, txnToken: txnToken, pspApp: PspApp.paytm) { (response,	 error) in  }
If the merchant wants to integrate the optional methods, then please move to the next part of integration of optional methods.