Ionic 4 InAppBrowser for third party payment solution

In an Ionic 4 hybrid app project I had the requirement of opening a third party page (a payment service called Klarna) inside an Ionic 4 app. The payment solution itself uses a payment registration page and sends the user to a confirmation page when the payment is ready. The solutions should work on both iOS and Android. Using Ionic 4 with Cordova, I considered the following options:

  • Opening the page in an iFrame
  • Using the Ionic Native BrowserTab plugin (Cordova)
  • Using the Ionic Native InAppBrowser plugin (Cordova)

The first alternative, the iFrame solution, was skipped because of the risk for getting the app rejected on the iOS App Store when using an iFrame.

In the app, I needed the user to be able to close the third party page with a close button and we needed to listen for the navigation and close events in the app. The BrowserTab plugin does not have a close button (it’s just a Tab!), so we ended up choosing the InAppBrower plugin.

The first step of the solution was to add the Ionic Native Cordova plugin for InAppBrowser to the project:

ionic cordova plugin add cordova-plugin-inappbrowser
npm install --save @ionic-native/in-app-browser

There are four available events being emitted from the in-app-browser:

  • loadstart: fires when the InAppBrowser starts to load a URL.
  • loadstop: fires when the InAppBrowser finishes loading a URL.
  • loaderror: fires when the InAppBrowser encounters an error when loading a URL.
  • exit: fires when the InAppBrowser window is closed

In my case, I needed to know when the InAppBrowser had loaded the confirmation page of the payment solution (Klarna) in order to get the order id from the url. The source code for the openBrowser function is as follows:

	openBrowser(url: string, target: string) {
		const browser: InAppBrowserObject = this.theInAppBrowser.create(url, target, this.options);
		const btn: HTMLElement = this.hiddenBtn.nativeElement as HTMLElement;

		if (browser.on('loadstop')) {
			browser.on('loadstop').subscribe((ev: InAppBrowserEvent) => {
				// do whatever is needed here, for example check the url of the browser event
				if (ev.url) {
					// do stuff based on url and url parameters
					// in our solution we got an order id from a confirmation page
				}
				// for the event to trigger we added a hidden button to interact with the screen
				btn.click();
			});
		}
	}

When first testing the ‘loadstop’ event I noticed that the event did not trigger before the user touched the screen. Of course, I wanted this event to be triggered without a user interaction so the problem was solved by adding a hidden button to the page that is being “clicked” in code.

<ion-button #hiddenBtn style="display:none">hidden</ion-button>

The hidden button is available in the page component via the Angluar ViewChild directive:

@ViewChild('hiddenBtn') hiddenBtn: ElementRef;

For reference, the options used for the in-app-browser were:

	options: InAppBrowserOptions = {
		location: 'yes',
		hidden: 'no',
		clearcache: 'yes',
		clearsessioncache: 'yes',
		zoom: 'yes',
		hardwareback: 'yes',
		mediaPlaybackRequiresUserAction: 'no',
		shouldPauseOnSuspend: 'no',
		closebuttoncaption: 'Close',
		disallowoverscroll: 'no',
		toolbar: 'yes',
		enableViewportScale: 'no',
		allowInlineMediaPlayback: 'no',
		presentationstyle: 'pagesheet',
		fullscreen: 'yes',
		footer: 'yes'
	};

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s