Adding the PayByBankApp Button
Add the PayByBankApp button easily using the Mobile Payments Widget within Judopay’s mobile SDK:
Android, see Displaying PayByBankApp as a Payment Method.
React Native, see Displaying PayByBankApp as a Payment Method.
Not using the Payments Widget? You can still add the PayByBankApp button by integrating with the SDK directly to your app:
iOS, see Step 1: Initialising the SDK.
Android, see Step 1: Configure the Judo Object.
React Native, see Configuring the PaybyBankApp Button.
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:
| 8+ |
Third Party Component used in the PayByBankApp Button | Version |
---|---|
JQuery | 1.11.3 |
iOS
PreRequisites
You have set up your Judopay account.
You have the latest version of the iOS SDK.
For more details, see iOS Integration with Judopay.
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 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:

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.

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 } } }
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. | |
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:
| |
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:
Listen to this event.
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") ... }
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:
Add the deeplinkURL to the configuration
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 } } }
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:
Invoke a manual order status request:
Use the JPApiService to invoke a manual order status request.
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 } }
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
![]() |
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. To catch the first response, create a broadcastReceiver:
private val broadcastReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { val result = intent?.getParcelableExtra<JudoResult>(PBBA_RESULT) // Handle result } }
6. Register the defined receiver in onCreate:
LocalBroadcastManager.getInstance(this).registerReceiver( orderIdReceiver, IntentFilter(BR_PBBA_RESULT) )
7. 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. To catch the first response, create a broadcastReceiver:
private val broadcastReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { val result = intent?.getParcelableExtra<JudoResult>(PBBA_RESULT) // Handle result } }
6. Register the defined receiver in onCreate:
LocalBroadcastManager.getInstance(this).registerReceiver( orderIdReceiver, IntentFilter(BR_PBBA_RESULT) )
7. 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) }
8. 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
You have set up your Judopay account.
You have the latest version of the Android SDK. For more details, see Android Integration with Judopay.
You have the latest version of the iOS SDK. For more details, see iOS Integration with Judopay.
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:
Create a JudoPBBAConfiguration:
export interface JudoPBBAConfiguration { mobileNumber?: string emailAddress?: string appearsOnStatement?: string deeplinkScheme?: string deeplinkURL?: string }
Parameter | Description |
---|---|
String | Consumer's mobile number. Sent with the transaction as an additional parameter. |
String | Consumer's email address. Sent with the transaction as an additional parameter. |
String | Sent with the transaction as an additional parameter. |
String | Used in the deeplinking process to identify your app. |
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 }
DeepLink Scheme
When the consumer invokes the PaybyBankApp transaction, in order to complete the transaction, the app redirects to the user's bank app. When the interaction is finished, the bank app redirects back to your app via the deeplinkScheme sending a deeplinkURL.
Note
The deeplink scheme has to be set manually for iOS and Android, via the Info.plist (iOS) and the AndroidManifest.xml (Android). For more details, see the iOS and Android sections of the PaybyBankApp documentation.
The deeplinkURL can be used to start polling the transaction status. The deeplink events can be captured with the linking package already built in ReactNative.
Note
Check the ReactNative sample app for the implementation reference.
Once you have captured the deeplinkURL, pass it to the deeplinkURL parameter of the JudoPBBAConfiguration. If this parameter is set once the invokePayByBankApp is called, the polling process should automatically start.
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:
Add the branded PaybyBankApp button
Add the method as a button press action
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.