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. Implement the interface

    Implement the interface CardProcessTransactionListener for merchant powered bank pages(card payments) else implement PaytmSDKCallbackListener
    1. Implement the interface PaytmSDKCallbackListener

      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

         
    2. Implement the interface CardProcessTransactionListener

      Implement the interface CardProcessTransactionListener instead of PaytmSDKCallbackListener to get process transaction info for merchant powered bank pages in case of card payment . It extends the above PaytmSDKCallbackListener. The interface has the following callback method in additional to that of PaytmSDKCallbackListener callback methods
      1.  onCardProcessTransactionResponse : This will provide the response of the process transaction API in a JSON string.You can find all the details about Process Transaction API response and sample data forProcessTransactionInfo here
        fun onCardProcessTransactionResponse(processTransactionInfo: ProcessTransactionInfo?)    
        {
        }
        
  2. Generate transaction token from your backend

    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.

  3. Fetch paytm user’s saved instruments

    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.

  4. PaytmSDK builder creation

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

    PaytmSDK.Builder builder = new PaytmSDK.Builder(this, mid, orderId, txnToken, amount
    /*PaytmSDKCallbackListener* or *CardProcessTransactionListener(for merchant powered bank pages)*/);
    
    
    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 1.ii..
    double amount   Order amount for the current transaction
    PaytmSDKCallbackListener

    OR

    CardProcessTransactionListener
      Interface implementation to get the result of a payment transaction.
    Refer to Step 1.i.

    OR

    Interface implementation to get the process transaction response for merchant powered bank pages in addition to result of a payment transaction.
    Refer to Step 1.ii.

    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, isEligibleForCoFT, isUserConsentGiven, isCardPTCInfoRequired)

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 (conditional) CVV of the card (Mandatory for new cards
Optional for saved cards whenever CVV is not required)
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 and tokenized at Paytm’s end. Default value is false
isEligibleForCoFT Boolean (optional) COFT eligibility flag received in fetchBinDetails API for new card and fetchPaymenOptions API for saved card.
Default value : false
isUserConsentGiven Boolean (optional) flag to indicate if the saved card should be tokenized at Paytm’s end.
Default value : false
isCardPTCInfoRequired Boolean (optional) Flag to indicate if to provide support for merchant powered bank pages. 
Default value : false

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)

Note: upiId that merchant sets in UpiCollectRequestModel(paymentFlow,upiId) needs to be fetched from the response of VPAValidateResponse. 

 

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

isAutomaticPayment

Boolean(conditional)

True for automatic payments. Default value is false.

subscriptionMaxAmount

String(conditional)

Maximum amount that can be charged to the customer in each frequency cycle. Default value is null

  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)
    Note: PaytmSDK.getPaymentsHelper().getUpiAppsInstalled(Context context, Boolean isAutomaticPayment)
    isAutomaticPayment = true is only mandatory for automatic payments
    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.
     
    Note: To support PSP Apps (UPI Intent) or to invoke Paytm app for Target SDK version 30 ( Android 11) and above. Please add below query in AndroidManifest.xml.
    <queries>
       <package android:name=“net.one97.paytm” />
         <intent>
          <action android:name=“android.intent.action.MAIN” />
       </intent>
    </queries>
  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.

TokenizedCardRequestModel tokenizedCardRequestModel = new TokenizedCardRequestModel(paymentMode, paymentFlow, cardToken, tokenExpiry, TAVV, lastFourDigits, par, authMode, cardCvv, emiPlanId, bankCode, channelCode )


 

Attribute Type Description
paymentMode String(mandatory) type of card (DEBIT_CARD, CREDIT_CARD)
paymentFlow String(mandatory) current payment flow (NONE, ADDNPAY)
cardToken String(mandatory) 16 digits Token PAN
tokenExpiry String(mandatory) Token expiry. Format: MMYYYY
TAVV String(mandatory) Token Verification Value generated by the network valid for a single token card  payment
lastFourDigits String(mandatory) Last 4 digits of the actual card.
par String(mandatory) The pan unique reference allocated to the Primary Account Number by the card network
authMode String(mandatory) the mode of 2FA chosen for a card(either by 'pin' or 'OTP')
cardCvv String(conditional) CVV of the card (Optional for cards whenever CVV is not required)
emiPlanId String (conditional) emiPlan id in case of an EMI transaction
bankCode String (conditional) bank code of card (eg. ICICI, AXIS)
channelCode String (conditional) channelCode of card (eg. VISA, MASTER)
  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. If PaytmSDKCallbackListener is implemented, the result of the transaction will be received via PaytmSDKCallbackListener Interface described in Step1. i.
    If CardProcessTransactionListener is implemented and the boolean isCardPTCInfoRequired  is true, the response of Process Transaction will be received via CardProcessTransactionListenerInterface described in Step1. ii. in case of card payments. In other cases (other than card payment) the result of the transaction will be received in a similar way to that of PaytmSDKCallbackListener

  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)


Note: The vpaAddress parameter that the merchant sets in init(withTransactionToken: txnToken, orderId,  shouldOpenNativePlusFlow, mid, flowType, paymentModes, vpaAddress, upiFlowType, redirectionUrl) in the class AINativeNUPIParameterModel needs to be fetched from the response of VPAValidateResponse.

 

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
vpaAddress String Virtual Payment Address(eg.xyz@paytm) received in response of isVpaValidated method. Key Name: vpa
flowType String 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?"

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  }

Use the below method to get the list of available intent Apps.

Method Signature: getUpiList

public func getUpiList(txnToken: String, merchantId: String,completion: @escaping (([[String:Any]]) -> Void))

Sample Code:

self.aiHandler.getUpiList(txnToken: self.txnToken, merchantId: self.merchantId)
{ PspApplist in 
//Code here
}

We will send an Array of dictionaries in response to the getUpiList method from which you can pass dict["displayName"] for whichever psp the user will chose in the psp parameter in callProcessTransactionAPIForUPIIntent method.

If you want to use our custom polling then you need to set shouldShowCustomIntentPolling as true, if you want want to do your own invoke and polling then set shouldShowCustomIntentPolling as false.

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

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

Add the schema of the apps into Info.plist LSApplicationQueriesSchemes(Array):

Method Signature: callProcessTransactionAPIForUPIIntent

func callProcessTransactionAPIForUPIIntent(flowType: AINativePaymentFlow, amount : CGFloat, orderId: String, mid: String, txnToken: String, pspApp: String, shouldShowCustomIntentPolling: Bool, delegate: AIDelegate, completionHandler: (([String : Any]?, String?) -> Void)?)

Sample Code:

self.aiHandler.callProcessTransactionAPIForUPIIntent(flowType: flowType, amount: self.amount, orderId: self.orderId, mid: self.merchantId, txnToken: self.txnToken, pspApp: pspName, shouldShowCustomIntentPolling: true, delegate:
self){ response, error in 
//Code here 
}

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
flowType String Pass the value "None"
Amount float Transaction Amount

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.