Solutions Swish for merchants API manuals

5. Launching Swish app from merchant app

5. Launching Swish app from merchant app

5.1 Detecting if Swish app is installed on the device

Merchant apps, excluding web browsers, can detect if the Swish app is installed on the device. Below are code snippets that shows this. Notice that it is not possible from a Windows Phone application to detect if the Swish app is installed on the device.

5.1.1 iOS (detect)


static inline bool isSwishAppInstalled(void){
return [[UIApplication sharedApplication
canOpenURL:[NSURL URLWithString:@"swish://"]];
}

5.1.2 Android (detect)


//Swish package name is “se.bankgirot.swish”
protected boolean isSwishAppInstalled(Context _context, String
SwishPackageName) {
boolean isSwishInstalled = false;
try {
_context.getPackageManager().getApplicationInfo(SwishPackageName, 0);
isSwishInstalled = true;
} catch(PackageManager.NameNotFoundException e) {
}
return isSwishInstalled;
}

5.1.3 Windows Phone (call the Swish app)


// The URI to launch
string uriToLaunch = @"swish://paymentrequest<parameters>";
// Create a Uri object from a URI string
var uri = new Uri(uriToLaunch);
// Launch the URI
async void DefaultLaunch(){
// Launch the URI
var success = await Windows.System.Launcher.LaunchUriAsync(uri);
if (success) {
// URI launched
}
else
{
// URI launch failed
}
}

5.1.4 Detection with mobile web browsers

The investigation of the abilities to determine if Swish is installed on a device shows that there is an absence of a standard, documented way to do this from the web browsers. The found workaround is based on the time during which the return to the browser was performed. The idea of this approach is that JavaScript code on current page will be frozen right after calling Swish application because the control flow will be given to the Swish if it started successfully. Control flow will be returned back to JavaScript when Swish will be finished.

Thus if the JavaScript code continue executing after short time from the moment of the trying to call Swish – this means that Swish is not installed on the device. The JavaScript code snippet given below:


//remember the time of start application
timestart = new Date().getTime();
//try to run application (Swish) in the frame by opening custom URL-SCHEME
createIFrame(url+"&browser="+browserName+"&back="+encodeURIComponent(location.toString())+"&useragent="+encodeURIComponent(userAgent));
//remember time of returning from application
timeend = new Date().getTime();
//if from the moment of the attempt to run the application to moment when the
//control returns back to this code passed enough much time (more then 3 sec),
//most probably this means that the application was successfully started and
//the user spent the time using the application
if(timeend — timestart > 3000) {
isSwishInstalled = true;
} else {
isSwishInstalled = false;
}

But, as investigations show, this approach does not work for WinPhone and Android Chrome version 25 and newer. Moreover, because Android’s default browser is now based on Chrome core, this is also true for default browser.

In the 3 variants, WinPhone browser (Internet Explorer), Android default platform browser and Android Chrome from version 25, they do not immediately return the control to the JavaScript code when the called application (Swish) is not installed on the device – instead they open a dialog and offer the user to go to the platform’s market to download the required application (Swish).

This means, that in this case the browser will either successfully open Swish or ask the user to go to the market to download and install Swish.

5.2 Switch to Swish app, and back

The merchant apps, including mobile web browsers, will call the Swish app using the Custom URL Scheme “swish://paymentrequest”.

The merchant app has to send the Swish app the following:

  • Payment request token
    
The merchant receives the payment request token from the CPC.
  • A callback URL
    This is a string that Swish will use as parameter to switch back to the merchant app after payment is finished. The goal of this parameter is to force the application to open a given GUI view – or for a browser, to open a specific URL.
The callback URL should be passed in in URL-encoded format.

Both parameters are required, so the correct URL to open Swish app is:

swish://paymentrequest?token=&callbackurl=

When Swish is finished, it (or BankID app) will call the provided callback URL. For the merchant app to react on this call, the merchant app needs to register for that URL scheme and provide code for handling the request.

Code snippets describing switch to Swish as well as information about declaring URL scheme and handling calls to it are provided below for each platform.

Note that the URL Scheme “merchant:\\” is used in the examples below. This is only an example – each merchant shall use its own unique scheme.

5.2.1 iOS

The following code can be used to switch to Swish from the merchant app.


// character set is used to encode callback URL properly
NSCharacterSet *notAllowedCharactersSet =
[NSCharacterSet characterSetWithCharactersInString:@"!*'();:@&=+$,/?%#[]"];
NSCharacterSet *allowedCharactersSet =
[notAllowedCharactersSet invertedSet];
NSString *callbackURLStr = @"merchant://";
NSString *encodedCallbackURLStr =
[callbackURLStr
stringByAddingPercentEncodingWithAllowedCharacters:allowedCharactersSet];
NSString *swishURLStr = [NSString
stringWithFormat:@"swish://paymentrequest?token=%@&callbackurl=%@", token,
encodedCallbackURLStr];
NSURL *swishURL = [[NSURL alloc] initWithString: swishURLStr];
if ([[UIApplication sharedApplication] canOpenURL:swishURL]) {
if ([[UIApplication sharedApplication] openURL:swishURL]) {
// Success
}
else {
// Error handling
}
}
else {
// Swish app is not installed
// error handling
}

The enable the switch back from Swish, the merchant app needs to register a URL scheme. This is done by including a CFBundleURLTypes key in the app’s Info.plist.

The merchant app must also implement the following function that will be called when the switch back happens.


-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation;

5.2.2 Android

The following code can be used to switch to Swish from the merchant app.


public static boolean startSwish(Activity activity, String token, String
callBackUrl, int requestCode) {
If ( token == null || token.length() == 0 || callBackUrl == null ||
callBackUrl.length() == 0 || activity == null) {
return false;
}
Uri scheme =
Uri.parse("swish://paymentrequest?token="+token+"&callbackurl="+callBackUrl
);
Intent intent = new Intent(Intent.ACTION_VIEW, scheme);
intent.setPackage("se.bankgirot.swish");
boolean started=true;
try {
activity.startActivityForResult(intent, requestCode);
} catch (Exception e){
started=false;
}
return started;
}

The app manifest file is used to register the URL scheme in the merchant app:


<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="merchant" />
</intent-filter>

The merchant app also needs to process then intent in onCreate and onNewIntent methods when switch back happens.

5.2.3 WinPhone

The following code can be used to switch to Swish from the merchant app.


// Create the URI string
var uriToLaunch =
string.Format("swish://paymentrequest?token={0}&callbackurl={1}",
<INSERT TOKEN HERE>, Uri.EscapeDataString("merchant://"));
// Create the URI to launch from a string.
var uri = new Uri(uriToLaunch);
// Launch the URI.
bool success = await Windows.System.Launcher.LaunchUriAsync(uri);

If the Swish app is not present on the device the operating system presents a dialogue asking to open Windows Phone store. Merchant app must inform the user.

The merchant app registers an URL scheme in Visual Studio as:

  1. Open Package.appxmanifest
  2. 1. Open the tab Declarations.
  3. Add a “Protocol”. Under name enter ”merchant”.
  4. Enter a logo and a “Display name”.

Merchant must also implement the following to be successfully re-launched by Swish App. In Visual Studio add the class AssociationUriMapper:


/// <summary>
/// The association uri mapper.
/// </summary>
internal class AssociationUriMapper : UriMapperBase {
/// <summary>
/// When overridden in a derived class, converts a requested uniform
resource identifier (URI) to a new URI.
/// </summary>
/// <returns>
/// A URI to use for the request instead of the value in the <paramref
name="uri"/> parameter.
/// </returns>
/// <param name="uri">The original URI value to be mapped to a new
URI.</param>
public override Uri MapUri(Uri uri) {
var tempUri = System.Net.HttpUtility.UrlDecode(uri.ToString());
// URI association launch.
if (tempUri.StartsWith("/Protocol")) {
// Here we can redirect to the correct page, but for now we don't
return new Uri("/MainPage.xaml", UriKind.Relative);
}
// Otherwise perform normal launch.
return uri;
}
}

In App.xaml.cs, add AssociationUriMapper as UriMapper by adding the following line to the method InitializePhoneApplication:


// Assign the URI-mapper class to the application frame.
RootFrame.UriMapper = new AssociationUriMapper();

5.2.4 JavaScript in mobile web browser

The URL syntax below works on most built-in web browsers

swish://paymentrequest?token=value&callbackurl=back_scheme