Judopay Documentation

Adding the PayByBankApp Button

Add the PayByBankApp button easily using the Mobile Payments Widget within Judopay’s mobile SDK

Not using the Payments Widget? You can still add the PayByBankApp button by integrating with the SDK directly to your app:

Certified Browsers and Devices

Browsers

Zapp has certified the Web Merchant Button library to work with the following browsers: 

Browser

Version

Chrome

44.0+

Firefox

39.0.3+

IE

10+

Safari

10+

 

Devices and Operating Systems

Zapp has certified the Web Merchant Button library to work with the following mobile devices and operating systems:

Note

Landscape orientation is not supported for Web on mobile browsers.

Android Device Manufacturer

OS Version

LG Nexus 5 (D821)

Android v22 5.1

Samsung Galaxy S6 or S6 edge (SM-G920F or SM-G925F)

Android v22 5.1

Samsung Galaxy Tab 3 (GT-P5210)

Android V19 4.4

LG Nexus 5 (D821)

Android v22 5.1

Apple Devices

iOS Version

iPhone:

  • SE

  • 5s

  • 6

  • 6 Plus

  • Air

  • 7

  • 7 Plus

8+

Third Party Component used in the PayByBankApp Button

Version

JQuery

1.11.3

iOS

PreRequisites

Using the Mobile Payments Widget

To add the PayByBankApp button using the Mobile Payments Widget:

Displaying PayByBankApp as a Payment Method
Screenshot_1592899442.png

 

To display the PayByBankApp as a Payment Method for iOS:

1. In the info.plist of app and LSApplicationQueriesSchemes:

  • Add the URL scheme of the merchant(CFBundleURLSchemes):

<key>CFBundleURLTypes</key>
	<array>
		<dict>
			<key>CFBundleTypeRole</key>
			<string>Editor</string>
			<key>CFBundleURLSchemes</key>
			<array>
				<string>judo</string>
			</array>
		</dict>
	</array>
	<key>LSApplicationQueriesSchemes</key>
	<array>
		<string>zapp</string>
	</array>

2. Add deeplink to the pbbaConfiguration object:

  self.pbbaConfig = [JPPBBAConfiguration new];
    self.pbbaConfig.deeplinkScheme = @"judo://pay";

3. To enable the PayByBankApp set the following options:

  • Add the pbba method to:

    • The paymentMethods array in JPConfiguration

  • Set currency:

    • GBP

Integrating Directly to your App

Not using the Mobile SDK Payments Widget?

To Integrate directly to your app:

Prerequisites

  • "Bank3 Test App" - Contact: developersupport@judopayments.com to get access, so you can test the PayByBankApp flow.

  • You have set your app's URL Scheme.

  • You have added zapp to the ApplicationQueriesSchemes:

An example of the Info.plist file:

info_plist.jpg
Step 1: Initialising the SDK

To integrate with the Judopay SDK directly to your iOS app, you can use either a:

  • basic authorization

    This uses a token and secret

  • session authorization

    This uses a token and paymentSession

Note

You can select the sandbox mode for testing purposes.

Set the value:isSandboxed = true

let authorization: JPAuthorization = JPBasicAuthorization(token: JUDO_TOKEN,
    andSecret: JUDO_SECRET)
        judoKit = JudoKit(authorization: authorization)
        judoKit.isSandboxed = true
Step 2: Check for Installed Bank Apps

To ensure a good customer experience, it is recommended to only display the PayByBankApp button when the consumer has a compatible mobile Banking app.

Before adding the PayByBankApp button in Step 3, check if any compatible PayByBankApp Bank apps are installed, using the JudoKit isBankingAppAvailable method:

if (JudoKit.isBankingAppAvailable()) {
    // Add the PBBA button
}
Step 3: Adding the PayByBankApp Button

Tip

We recommend you use the branded button to invoke a PayByBankApp transaction, however it is not mandatory.

Figure 1. PayByBankApp Button:
PayByBankApp Button:


The PayByBankApp Button uses the delegate property. The delegate property points to any class that implements the JPPBBAButtonDelegate interface:

let pbbaButton = JPPBBAButton(frame: container.bounds);
    pbbaButton.delegate = self
        view.addSubview(pbbaButton)

Caution

The JPBBAButton is a subclass of UIView, not UIButton.

Take this into consideration when integrating the PayByBankApp button via the Interface Builder.

The JPPBBAButtonDelegate interface has only one method: pbbaButtonDidPress(sender:), which is responsible for handling the button tap action.

Recommended PayByBankApp Button Size:

  • Minimum: Width 160pt | Height 40pt

  • Maximum: Width 310pt | Height 48pt

Step 4: Adding the Delegate Method

The delegate method is responsible for the button tap action.

To add the delegate method you must call the invokePBBA method in the Judopay SDK and provide the required configuration parameters:

func pbbaButtonDidPress(_ sender: JPPBBAButton) {

    // 1
    let amount = JPAmount(AMOUNT_VALUE, currency: "GBP")
    let reference = JPReference(consumerReference: CONSUMER_REF)

    configuration = JPConfiguration(judoID: JUDO_ID, amount: amount, reference: reference)

    // 2
    let pbbaConfiguration = JPPBBAConfiguration()
    pbbaConfiguration.mobileNumber = YOUR_MOBILE_NUMBER
    pbbaConfiguration.emailAddress = YOUR_EMAIL_ADDRESS
    pbbaConfiguration.appearsOnStatement = YOUR_APPEARS_ON_STATEMENT
    pbbaConfiguration.deeplinkScheme = YOUR_DEEPLINK_SCHEME

    configuration.pbbaConfiguration = pbbaConfiguration

    // 3
    judoKit.invokePBBA(with: configuration) { [weak self] (response, error) in
        if let response = response {
            // Handle response
        }

        if let error = error {
            // Handle error
        }
    }
}

1

Each Judopay transaction takes a JPConfiguration instance as a parameter.The configuration object sets up all the required parameters for a successful transaction. It also sets any optional parameters which you can configure to personalise the payment flow.

2

PayByBankApp transactions require some extra parameters to be set up, in addition to the basic transaction configuration. These optional parameters are defined in the JPPBBAConfiguration class, and used to add additional information to the transaction. The following two parameters are recommended:

  • deeplinkScheme

  • deeplinkURL

3

Call the invokePBBA method from the Judopay SDK.

The PayByBankApp flow will be triggered, opening the Bank app for consumers to make their transactions.

 

The deeplinkScheme

A deeplinkScheme identifies your app during the redirect process. When a consumer has completed their transaction using their Bank app, the Bank app will attempt to redirected the consumer back to your app.

Caution

The deeplinkScheme name should match the URL scheme defined in the Info.plist file.

For example: myapp -> myapp:/

 

The deeplinkURL

The deeplink URL enables the app to open the consumer's mobile Banking app, so they can complete the transaction.

When the Bank app redirects the consumer back to your app, it also provides you with a URL that you can use to poll the transaction status.

Add the deeplinkURL to the main configuration object. This will be sent as a parameter to the transaction method.

For more details, see Step 5: Handling the deeplinkURL.

Tip

It is a good idea to handle the errors within this step.

The most important information from the response is the orderId, accessed via response.orderDetails.orderId.

The orderId is used to manually check the transaction status. For more details, see Manually Checking the Transaction Status.

Step 5: Handling the deeplinkURL

Following the completed transaction, the bank flow will be triggered when the invokePBBA method is called, even if the deeplinkURL parameter is not provided.

However, if the deeplinkURL parameter is provided, calling invokePBBA will trigger the transaction status polling logic.

To handle the deeplinkURL:

  1. Listen to this event.

  2. Capture the redirect URL.

To capture the redirect URL:

  • In your AppDelegate file, add the following methods:

    • application(_:open:options:)

    • application(_:didFinishLaunchingWithOptions:)

func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {

     if let url = launchOptions?[.url] as? URL {
         UserDefaults.standard.set(url, forKey: "deeplinkURL")
     }

     ...
}

func application(
    _ app: UIApplication, open url: URL,
    options: [UIApplication.OpenURLOptionsKey : Any] = [:]
    ) -> Bool {

     UserDefaults.standard.set(url, forKey: "deeplinkURL")

     ...
}
  1. Pass the URL to the JPPBBAConfiguration instance.

For the purpose of this exercise, the deeplinkURL is saved in the app's UserDefaults. You can save the deeplinkURL in the Keychain or any alternative.

Step 6: Polling the Transaction Status

Once the Bank app has redirected the consumer back to your app, you can start polling the transaction status.

To start the PayByBankApp polling status:

  1. Add the deeplinkURL to the configuration

  2. Call the invokePBBA(configuration:) method:

func handleDeeplink() {
     guard let url = UserDefaults.standard.url(forKey: "deeplinkURL") else {
         return
     }

     configuration.pbbaConfiguration?.deeplinkURL = url

     judoKit.invokePBBA(with: configuration) { [weak self] (response, error) in
         if let response = response {
             // Handle response
         }

         if let error = error {
             // Handle error
         }
     }
 }
  1. In the JPResponse object, you can inspect the orderDetails containing information about the transaction status.

Note

Another option is to put a check in your viewDidAppear(animated:) method. If a deeplinkURL is set up, add it to the configuration and call the invokePBBA(configuration:) method again. This will start the polling status.

Manually Checking the Transaction Status

There may be cases where the Bank app closes before the transaction flow completes. This would mean the deeplinkURL is not returned and the polling process to check the transaction status will not begin.

To manually check the transaction status:

  1. Invoke a manual order status request:

    Use the JPApiService to invoke a manual order status request.

  1. Get the orderId from the initial request:

    When the Bank app is invoked during the PayByBankApp request, (Step 4) the orderId is captured from the callback response:

judoKit.invokePBBA(with: configuration) { [weak self] (response, error) in 
    if let response = response { 
        let orderId = response.orderDetails?.orderId 
            // Persist the orderId for later use 
} 
}
  1. Use the orderId to manually check the transaction status:

    Create an instance of JPApiService

    Note

    You would do this in the same way as Initialising the Judopay SDK, see Step 1: Initialising the SDK.

    Call the invokeOrderStatus method, with the orderId:

let apiService = JPApiService(authorization: authorization, isSandboxed: true)

    apiService.invokeOrderStatus(withOrderId: orderId) { (response, error) in
    // Handle response
}

The response will contain both the transaction status, and the order details of the transaction.

For a sample app, see Judopay's Judokit for iOS on Github.

Android

Prerequisites

  • You have set up your Judopay account.

  • You have the latest version of the Android SDK.

    For more details, see [→Android Integration].

Using the Mobile Payments Widget

To add the PayByBankApp button using the Mobile Payments Widget:

Displaying PayByBankApp as a Payment Method
Screenshot_1592899452.png

 

To display the PayByBankApp as a Payment Method for Android:

1. Add the intent-filter to the AndroidManifest.xml file

  • This registers the deep link URL:

<activity
            android:name=".MainActivity"
            android:launchMode="singleTask">
              <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data
                    android:scheme="your"
                    android:host="scheme" />
            </intent-filter>
        </activity>

2. Create the Judo object:

  • Set PaymentWidgetType to:

    • PAY_BY_BANK_APP, or

    • PAYMENT_METHODS

      If using the payments widget.

  • Set currency:

    • GBP

3. Create the PBBAConfiguration object:

  • set deepLinkScheme to the defined scheme in the AndroidManifest.xml file:

 val pbbaConfiguration = PBBAConfiguration.Builder()
        .setDeepLinkScheme("your://scheme")
        .build()
Judo.Builder(PaymentWidgetType.PAY_BY_BANK_APP)
            .setJudoId(judoId)
            .setApiToken(token)
            .setApiSecret(secret)
            .setAmount(amount)
            .setReference(reference)
            .setIsSandboxed(isSandboxed)
            .setSupportedCardNetworks(networks)
            .setPaymentMethods(paymentMethods)
            .setUiConfiguration(uiConfiguration)
            .setGooglePayConfiguration(googlePayConfiguration)
            .setPBBAConfiguration(pbbaConfiguration)
            .build()

4. Override the onNewIntent method to catch the deeplink URL

  • Add the deepLinkURL to the PBBAConfiguration object

  • Start JudoActivity with the desired payment widget type

  • Add the same logic in onCreate

 override fun onNewIntent(intent: Intent?) {
        checkForDeepLink(intent)
        super.onNewIntent(intent)
    }
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
        checkForDeepLink()
        ...
    }
    
    private fun checkForDeepLink(intent: Intent? = this.intent) {
        val uri = intent?.data
        val newIntent = Intent(this, JudoActivity::class.java)
        if (uri.contains("your://scheme")) {  
            val newPbbaConfig = pbbaConfiguration.newBuilder()
                .setDeepLinkURL(uri)
                .build()
            val judo = getJudo(PaymentWidgetType.PAY_BY_BANK_APP).newBuilder()
                .setPBBAConfiguration(newPbbaConfig)
                .build()
            newIntent.putExtra(JUDO_OPTIONS, judo)
            startActivityForResult(newIntent, JUDO_PAYMENT_WIDGET_REQUEST_CODE)
        }
    }
    
    private fun getJudo(widgetType: PaymentWidgetType): Judo {
        return Judo.Builder(widgetType)
            .setJudoId(judoId)
            .setApiToken(token)
            .setApiSecret(secret)
            .setAmount(amount)
            .setReference(reference)
            .setIsSandboxed(isSandboxed)
            .setSupportedCardNetworks(networks)
            .setPaymentMethods(paymentMethods)
            .setUiConfiguration(uiConfiguration)
            .setGooglePayConfiguration(googlePayConfiguration)
            .setPBBAConfiguration(pbbaConfiguration)
            .build()

5. Catch the result in the onActivityResult method:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        if (requestCode == JUDO_PAYMENT_WIDGET_REQUEST_CODE) {
            when (resultCode) {
                PAYMENT_SUCCESS -> {
                    val result = data?.getParcelableExtra<JudoResult>(JUDO_RESULT)
                    //Process successful payment
                }
                PAYMENT_CANCELLED -> {
                    val result = data?.getParcelableExtra<JudoResult>(JUDO_RESULT)
                    //Process cancelled payment
                } 
                PAYMENT_ERROR -> {
                    val error = data?.getParcelableExtra<JudoError>(JUDO_ERROR)
                    //Process unsuccessful payment
                }    
            }
        }
    }

Integrating Directly to your App

Not using the Mobile SDK Payments Widget?

To Integrate directly to your app:

Configuring the PayByBankApp Button

To implement the PayByBankApp button for Android, if you are not using the Payments Widget:

1. Insert the button in the layout file:

<com.judokit.android.ui.common.PayByBankButton
        android:id="@+id/payByBankButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

2. Add intent-filter to the AndroidManifest.xml file.

  • This will register the deep link URL:

activity
            android:name=".MainActivity"
            android:launchMode="singleTask">
              <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data
                    android:scheme="your"
                    android:host="scheme" />
            </intent-filter>
        </activity>

3. Create the Judo object

  • Set the PaymentWidgetType to PAY_BY_BANK_APP

  • Create the PBBAConfiguration object

  • Set deepLinkScheme to the defined scheme in the AndroidManifest.xml file:

 val pbbaConfiguration = PBBAConfiguration.Builder()
        .setDeepLinkScheme("your://scheme")
        .build()
Judo.Builder(PaymentWidgetType.PAY_BY_BANK_APP)
            .setJudoId(judoId)
            .setApiToken(token)
            .setApiSecret(secret)
            .setAmount(amount)
            .setReference(reference)
            .setIsSandboxed(isSandboxed)
            .setSupportedCardNetworks(networks)
            .setPaymentMethods(paymentMethods)
            .setUiConfiguration(uiConfiguration)
            .setGooglePayConfiguration(googlePayConfiguration)
            .setPBBAConfiguration(pbbaConfiguration)
            .build()

4. Override the onNewIntent method to catch the deeplink URL

  • Add the deepLinkURL to the PBBAConfiguration object

  • Start JudoActivity with the desired payment widget type

  • Add the same logic in onCreate

   override fun onNewIntent(intent: Intent?) {
        checkForDeepLink(intent)
        super.onNewIntent(intent)
    }
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
        checkForDeepLink()
        ...
    }
    
    private fun checkForDeepLink(intent: Intent? = this.intent) {
        val uri = intent?.data
        val newIntent = Intent(this, JudoActivity::class.java)
        if (uri.contains("your://scheme")) {  
            val newPbbaConfig = pbbaConfiguration.newBuilder()
                .setDeepLinkURL(uri)
                .build()
            val judo = getJudo(PaymentWidgetType.PAY_BY_BANK_APP).newBuilder()
                .setPBBAConfiguration(newPbbaConfig)
                .build()
            newIntent.putExtra(JUDO_OPTIONS, judo)
            startActivityForResult(newIntent, JUDO_PAYMENT_WIDGET_REQUEST_CODE)
        }
    }
    
    private fun getJudo(widgetType: PaymentWidgetType): Judo {
        return Judo.Builder(widgetType)
            .setJudoId(judoId)
            .setApiToken(token)
            .setApiSecret(secret)
            .setAmount(amount)
            .setReference(reference)
            .setIsSandboxed(isSandboxed)
            .setSupportedCardNetworks(networks)
            .setPaymentMethods(paymentMethods)
            .setUiConfiguration(uiConfiguration)
            .setGooglePayConfiguration(googlePayConfiguration)
            .setPBBAConfiguration(pbbaConfiguration)
            .build()

5. Set OnClickListener to the previously defined PayByBankApp button

  • JudoActivity will start and pass the result to merchant:

payByBankButton.setOnClickListener {
            val intent = Intent(this, JudoActivity::class.java)
            intent.putExtra(JUDO_OPTIONS, judo)
            startActivityForResult(intent, JUDO_PAYMENT_WIDGET_REQUEST_CODE)
        }

6. Catch the result in the onActivityResult method:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        if (requestCode == JUDO_PAYMENT_WIDGET_REQUEST_CODE) {
            when (resultCode) {
                PAYMENT_SUCCESS -> {
                    val result = data?.getParcelableExtra<JudoResult>(JUDO_RESULT)
                    //Process successful payment
                }
                PAYMENT_CANCELLED -> {
                    val result = data?.getParcelableExtra<JudoResult>(JUDO_RESULT)
                    //Process cancelled payment
                } 
                PAYMENT_ERROR -> {
                    val error = data?.getParcelableExtra<JudoError>(JUDO_ERROR)
                    //Process unsuccessful payment
                }    
            }
        }
    }

React Native

Prerequisites

Using the Mobile Payments Widget

To add the PayByBankApp button using the Mobile Payments Widget:

Displaying PayByBankApp as a Payment Method

To display the PayByBankApp as a Payment Method for ReactNative:

  1. Create a JudoPBBAConfiguration:

export interface JudoPBBAConfiguration {
mobileNumber?: string
emailAddress?: string
appearsOnStatement?: string
deeplinkScheme?: string
deeplinkURL?: string
}

Parameter

Description

mobileNumber

String

Consumer's mobile number.

Sent with the transaction as an additional parameter.

emailAddress

String

Consumer's email address.

Sent with the transaction as an additional parameter.

appearsOnStatement

String

Sent with the transaction as an additional parameter.

deeplinkScheme

String

Used in the deeplinking process to identify your app.

deeplinkURL

String

Specifies the app has opened as result of a redirect from the Bank App.

The deeplink URL contains the information needed to start polling the transaction status.

 

2. With the JudoPBBAConfiguration set, pass it to the main JudoConfiguration:

const pbbaConfig: JudoPBBAConfiguration = {
mobileNumber: "myMobileNumber",
emailAddress: "myEmailAddress",
appearsOnStatement: "myStatement",
deeplinkScheme: 'my://app'
}
const config: JudoConfiguration = {
...
pbbaConfiguration: pbbaConfig
...
}

3. Call the invokePayByBankApp method

4. Handle the response:

try {
const judo = new JudoPay(token, secret)
const response = await judo.invokePayByBankApp(config)
// Handle response
} catch (exception) {
// Handle exception
}

Integrating Directly to your App

Not using the Mobile SDK Payments Widget?

To Integrate directly to your app:

Configuring the PaybyBankApp Button

To implement the PayByBankApp button for ReactNative, if you are not using the Payments Widget:

Instead of calling invokePayByBankApp:

  1. Add the branded PaybyBankApp button

  2. Add the method as a button press action

  3. Expose the PaybyBankApp button as follows:

import { JudoPBBAButton } from 'judo-react-native'
<TouchableOpacity onPress={this.invokePayByBankApp}>
<JudoPBBAButton style={{ flex: 1 }} />
</TouchableOpacity>

Caution

Although, the JudoPBBAButton is refered to as a button, it does not handle button-related events, such as onPress. The JudoPBBAButton will need to be wrapped in a component that handles touch events, for example the TouchableOpacity component.