Mobile redirects (app-to-app)
Nowadays, more and more banks offer a way for their customers to verify and approve payments using their online banking app or other specific apps installed on their mobile device. This method is usually the easiest and most familiar for users to grant permission and make payments. This process is referred to as “app-to-app” or “app2app redirection”.
General implementation
- Set the payment URLs to the views in your mobile app
- Load the checkout URL in the web view
- Open the bank URL in the standard browser
- The user returns to any of the payment URLs from (1.)
1. Set payment URLs to the views in your mobile app
This step allows the user to return back to your intended flow in your app after the authorisation with their bank. This is ideally a URL or an app link.
Example
"paymentSuccessUrl":"https://your-domain.com/checkout/success"
"paymentSuccessUrl":"your-app://checkout/success"
Note that when using URLs, your app needs to claim the URL schema in the OS for a successful redirection.
2. Load the checkout URL in the web view
Typically the OS will support this by using the standard load method for the web view element.
webView.loadUrl("https://www.example.com");
3. Open the bank URL in the standard browser
Volt Checkout opens the URL of the bank (https://bank.com/). The bank URL has to be opened in the standard browser (Chrome on Android; Safari on iOS) for the app-to-app redirection to work. Other browsers, e.g. Firefox on Android, might not have the permissions, configuration or open the links incorrectly.
Note that any Volt Checkout URL (https://checkout.volt.io/…) should still be opened inside the web view, meaning the additional handling is only required for other URLs.
We recommend closing the web view once the user was redirected. This way, they can continue with the next step in the checkout process once they return from their mobile bank app.
Android
To catch the event when a webpage tries to open another webpage in a WebView
, you can use the WebViewClient
class and override its shouldOverrideUrlLoading
method.
WebView myWebView = findViewById(R.id.my_webview);
myWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
// Here, you should open the bank URL in Chrome
return false; // This will allow the WebView to handle the URL itself
}
});
In the shouldOverrideUrlLoading
method, you can put your own code to handle the event when the webpage tries to open another webpage. You can return true to indicate that you’ve handled the URL loading, or false to allow the WebView
to handle the URL itself.
Note that the shouldOverrideUrlLoading
method was deprecated in API level 24. Instead, you should use the shouldOverrideUrlLoading
method that takes a WebResourceRequest
parameter, as shown in the example above.
iOS
To catch the event when a webpage tries to open another webpage in a UIWebView
or WKWebView
on iOS, you can use the UIWebViewDelegate
or WKNavigationDelegate
respectively, and implement the shouldStartLoadWithRequest
or decidePolicyForNavigationAction
method.
Here are examples for UIWebView
and WKWebView
- UIWebView
- WKWebView
class MyViewController: UIViewController, UIWebViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let webView = UIWebView(frame: self.view.bounds)
webView.delegate = self
self.view.addSubview(webView)
let url = URL(string: "https://checkout.volt.io/...")
let request = URLRequest(url: url!)
webView.loadRequest(request)
}
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
// Here, you should open the bank URL in Safari
return true // Return true to allow the WebView to handle the URL itself, or false to cancel the navigation
}
}
In the shouldStartLoadWith
method, you can put your own code to handle the event when the webpage tries to open another webpage. You can return true to allow the WebView
to handle the URL itself, or false to cancel the navigation.
class MyViewController: UIViewController, WKNavigationDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let webView = WKWebView(frame: self.view.bounds)
webView.navigationDelegate = self
self.view.addSubview(webView)
let url = URL(string: "https://checkout.volt.io/...")
let request = URLRequest(url: url!)
webView.load(request)
}
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
// Here, you should open the bank URL in Safari
decisionHandler(.allow) // Call the decisionHandler with .allow to allow the navigation, or .cancel to cancel the navigation
}
}
In the decidePolicyFor
method, you can put your own code to handle the event when the webpage tries to open another webpage. You can call the decisionHandler
with .allow
to allow the navigation, or .cancel
to cancel the navigation.
Frameworks
- Cordova
- React Native
const INJECTED_JAVASCRIPT = `
window.voltRedirectCallback = function({url, type}) {
if (!webkit.messageHandlers.cordova_iab) {
throw 'Cordova IAB postMessage API not found!';
} else {
webkit.messageHandlers.cordova_iab.postMessage(JSON.stringify({url, type}));
}
}`;
function openInAppBrowser() {
/* Open URL */
inAppBrowserRef = cordova.InAppBrowser.open(
"https://checkout.volt.io/...",
"_blank",
"location=yes"
);
/* Inject JavaScript, make sure that JS is injected on the checkout.volt.io page */
inAppBrowserRef.addEventListener("loadstop", function () {
ref.executeScript({ code: INJECTED_JAVASCRIPT });
});
inAppBrowserRef.addEventListener("message", messageCallback);
}
/* Handle message from the injected JS */
function messageCallback(params) {
if (!params.data || typeof params.data !== "object") {
throw "Invalid message received";
}
if (params.data.type == "bank_redirect") {
cordova.InAppBrowser.open(params.data.url, "_system");
}
}
import { WebView } from "react-native-webview";
import { StyleSheet, Linking, View } from "react-native";
const checkoutURL = "https://checkout.volt.io/...";
const INJECTED_JAVASCRIPT = `
window.voltRedirectCallback = function({url, type}) {
window.ReactNativeWebView.postMessage(JSON.stringify({
type: type,
url: url
}));
}`;
export default function App() {
function messageCallback(event) {
const data = JSON.parse(event.nativeEvent.data);
if (typeof data !== "object") {
throw "Invalid message received";
}
if (data.type === "bank_redirect") {
Linking.openURL(data.url);
}
}
return (
<View style={styles.container}>
<WebView
style={styles.webView}
source={{ uri: checkoutURL }}
injectedJavaScript={INJECTED_JAVASCRIPT}
onMessage={messageCallback}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
webView: {
flex: 1,
},
});
What if we use a different framework for our mobile application?
The logic of the implementation remains the same for any other framework.
4. Payer returns to one of the payment URLs
When the payer returns from their mobile banking app, they are ready to continue the checkout.
We recommend closing the web view once the user was redirected, so that they can continue with the next step in the checkout process.
Follow our implementation guide for returning the payer to you.