To integrate your own app with the Rabo SmartPin app, follow the below steps:

Set up

Step 1 - Apply for Rabo Smart Pay and Rabo SmartPin

If you are not already a Rabo Smart Pay customer, you need to apply for it:

  1. Start your application for one or more Rabo SmartPin card readers or Tap to Pay subscriptions through the Rabo Smart Pay dashboard.
  2. Follow the required steps to become a customer.
  3. After your application is submitted and approved, you should receive an electronic contract . Tap to Pay can be used immediately.

    You should receive the Rabo SmartPin card reader(s) within 5 business days.

  4. Install the Rabo SmartPin app on the smartphone or tablet where your own app is available.

    Tap to Pay requires: 

    • iPhone XS or higher with the latest iOS. 
    • Android device requires at least version 11. 
      • Android 11+ on devices are originally shipped with Android version 8 or higher. 
      • NFC technology should be available and enabled. 
      • Google Mobile Services should be available (in other words, the mobile device is GMS certified). 

    We recommend using the latest software version for devices.

  5. Test if you can initiate a debit card payment.

Do you already have a Rabo SmartPin card reader? Or a Tap to Pay subscription? You can skip the above steps.

If the payment is successful, activate app-in-app in the Rabo SmartPin app:

  1. Go to Settings.
  2. Choose Developer options.

Step 2 - Integrate Rabo SmartPin with your own app

You have the option to include the following fields from your own app:

  • Amount
  • Payment Id
  • Transaction reference
  • Payment method

Your user can fill in these fields for each payment in your own app or choose to have the application fill them in by default.

After the payment is made, your app receives back successful or failed payment data fields, including debit card receipt details.

This process is different for Android and iOS, For a comprehensive overview, see App-in-App with card reader demonstration and Rabo Smart Pin App-in-App screens demonstration.

For the initial transaction, enter your password in the Rabo SmartPin app. You are only required to do this once a day.

Payment flow:

  1. In your own app, enter the amount you want your customer to pay. Add a reference, if necessary.
  2. Tap Pay.
  3. You automatically enter the Rabo SmartPin app.
  4. Select the desired payment option. For example, the Rabo SmartPin card reader or Tap to Pay.
  5. If all is fine, you receive the Approved status and your payment is done.

Receipt

  1. After the payment is complete, tap To Checkout to return to your own app.
  2. The Transaction fields are automatically copied from the Rabo SmartPin app.
  3. In the Rabo SmartPin app Daily Totals, you should find a transaction summary, which is broken down by date and payment method. You also have the option here of resending the receipt to the customer after the transaction is done (accepted or declined)

If you have multiple outlets, card readers, or Tap to Pay subscriptions you can also filter these transactions.

Transactions made using the Rabo SmartPin app-in-app link can be recognized by the following icon:

If a payment reference is entered using the cash register system from the merchant that calls the app in app connection you can find the payment reference in the Daily Totals with the payments that have a transaction reference added.

Android integration

Initiating payments from a third-party app - Android

Request:

You can initiate a payment from a third-party app using the Intents mechanism. The following data can be included:

Var

Format

Description

  id

string

Mandatory, unique value that can be used by the merchant to identify the transaction

amount

int

Mandatory, amount in cents

callbackUrl

string

Mandatory when integrating using URL. The URL is used to provide status feedback.

reference

string

Optional, payment reference (max length 255 characters)

type

string

Optional, payment method. [“PIN”|”CASH”| “TAPTOPAY”]

Response:

After the payment is complete, you receive feedback with the status of the payment with the following fields:

Merchant data, which we return:

  id

string

As provided by the third-party app 

amount

int

As provided by the third-party app 

reference

string

As provided by the third-party app 

type

string

Payment method. [“PIN”|”CASH”| “TAPTOPAY”]

Transaction data returned by Rabobank:

datetime

string

Date and time of payment (ISO8601)

state

string

Payment status (see below)

transactionId

string

Transaction ID

terminalId

string

Pin-only, terminal ID

cardType

string

Pin-only, card type

AID

string

Pin-only, AID

truncatedPan

string

Pin-only, card number

authCode

string

Pin-only, authorization code

errorCode

string

Pin-only, error code

change

int

 Cash only, change in cents

The following statuses are used:

Status

Message

APPROVED

payment is successful

DECLINED

payment failed

PENDING

payment is pending, check the daily totals in the Rabo SmartPin app for payment status 

CANCELLED

the retailer cancelled payment

DISABLED

third-party payments are not permitted under your contract 

INVALID

a mandatory field is missing

IN_PROGRESS

another payment is already in progress

REFUND_OFFLINE

refund not possible in restricted mode

REFUND_FORBIDDEN

refund not permitted for logged-in user

CASH_FORBIDDEN

cash transactions are not permitted under your contract

TAPTOPAY_FORBIDDEN

Tap to Pay conditions have not been met/have yet to be met. 

Initiating payment through Intents 

final Intent intent = new Intent(); intent.setAction(“nl.rabobank.smartpin.PAY”); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.putExtra(“id”, “abcdefg”); intent.putExtra(“amount”, 1234); intent.putExtra(“reference”, “Mijn betaling”); // Optional intent.putExtra(“type”, “PIN”); // Optional
if (getContext().getPackageManager().queryIntentActivities(intent, MATCH_DEFAULT_ONLY).size() > 0) { startActivityForResult(intent, SMARTPIN_ACTIVITY);
}

After the payment is received

private void parseOkResult(Intent data) {
PaymentFinishedFragment paymentFinishedFragment = new PaymentFinishedFragment(); String id = data.getStringExtra(“id”);
String reference = data.getStringExtra(“reference”);
String amount = data.getStringExtra(“amount”);
String type = data.getStringExtra(“type”);
String datetime = data.getStringExtra(“datetime”);
String state = data.getStringExtra(“state”);
String transactionId = data.getStringExtra(“transactionId”);
// For pin
String terminalId = data.getStringExtra(“terminalId”); String cardType = data.getStringExtra(“cardType”);
String AID = data.getStringExtra(“AID”);
String truncatedPan = data.getStringExtra(“truncatedPan”); String authCode = data.getStringExtra(“authCode”);
String errorCode = data.getStringExtra(“errorCode”);
// For cash
int change = data.getIntExtra(“change”);
// Handle transaction with above parameters }
private void parseCancelResult(Intent data) {
PaymentFinishedFragment paymentFinishedFragment = new PaymentFinishedFragment(); if (data != null) {
String id = data.getStringExtra(“id”);
String state = data.getStringExtra(“state”); String amount = data.getStringExtra(“amount”);
// Handle cancelled transaction with above parameters }
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == SMARTPIN_ACTIVITY) { switch (resultCode) {
case Activity.RESULT_OK: parseOkResult(data); break;
case Activity.RESULT_CANCELED: parseCancelResult(data); break;
} }
super.onActivityResult(requestCode, resultCode, data); }

Initiating a payment using URL

Uri uri = Uri.parse("smartpin://payment?id="            
+ System.currentTimeMillis() +
"&amount="+ amountInCents +
"&reference=" +reference +
"&type="+ paymentMethod +
"&showResult=false" +
"&url=thirdparty://result");
Intent mapIntent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(mapIntent);

After payment is received

// In the url/activity that will be called by the smartpin app after a transaction
 
Uri data = getIntent().getData();
if (data != null) {
String id = data.getQueryParameter("id");
String state = data.getQueryParameter("state");
int amount = Integer.parseInt(data.getQueryParameter("amount"));
String type = data.getQueryParameter("type");
String datetime = data.getQueryParameter("datetime");
String reference = data.getQueryParameter("reference");
 
//For Pin
String transactionId = data.getQueryParameter("transactionId");
String cardType = data.getQueryParameter("cardType");
String AID = data.getQueryParameter("AID");
String truncatedPan = data.getQueryParameter("truncatedPan");
String authCode = data.getQueryParameter("authCode");
String errorCode = data.getQueryParameter("errorCode");
 
//For cash
int change = Integer.parseInt(data.getQueryParameter("change"));
 
// Handle transaction with above parameters }
private void parseCancelResult(Intent data) {
PaymentFinishedFragment paymentFinishedFragment = newPaymentFinishedFragment(); if (data != null) {
String id = data.getStringExtra(“id”);
String state = data.getStringExtra(“state”); String amount = data.getStringExtra(“amount”);
 
// Handle cancelled transaction with above parameters }
}
@Override
public void onActivityResult(intrequestCode, int resultCode, Intent data) {
if (requestCode == SMARTPIN_ACTIVITY) { switch(resultCode) {
case Activity.RESULT_OK: parseOkResult(data); break;
case Activity.RESULT_CANCELED: parseCancelResult(data); break;
} }
super.onActivityResult(requestCode, resultCode, data); }

iOS integration

Initiating payments from a third-party app - iOS

Request:

You can initiate a payment from a third-party app using a dedicated URL. The following data can be included:

Var

Format

Description

  id

string

Mandatory, unique value that can be used by the merchant to identify the transaction

amount

int

Mandatory, amount in cents

callbackUrl

string

Mandatory, URL used to provide status feedback

reference

string

Optional, payment reference (max length 255 characters)

type

string

Optional, payment method. [“PIN”|”CASH”| “TAPTOPAY”]

Response:

After the payment is complete, you receive feedback with the status of the payment with the following fields:

Merchant data, which we return:

  idstringAs provided by the third-party app
amountintAs provided by the third-party app
referencestringAs provided by the third-party app 
typestringPayment method. [“PIN”|”CASH”| “TAPTOPAY”]

Transaction data returned by Rabobank:

datetimestringDate and time of payment (ISO8601)
statestringPayment status (see below)
transactionIdstringTransaction ID     
 
terminalIdstringPin-only, terminal ID
cardTypestringPin-only, card type
AIDstringPin-only, AID
truncatedPanstringPin-only, card number
authCodestringPin-only, authorization code
errorCodestringPin-only, error code
changeintCash only, change in cents

The following statuses are used:

Status

Message

APPROVED

payment is successful

DECLINED

payment failed

PENDING

payment is pending, check the daily totals in the Rabo SmartPin app for payment status 

CANCELLED

the retailer cancelled payment

DISABLED

third-party payments are not permitted under your contract 

INVALID

a mandatory field is missing

IN_PROGRESS

another payment is already in progress

REFUND_OFFLINE

refund not possible in restricted mode

REFUND_FORBIDDEN

refund not permitted for logged-in user

CASH_FORBIDDEN

cash transactions are not permitted under your contract

TAPTOPAY_FORBIDDEN

cash transactions are not permitted under your contract

Initiating a payment using URL

let url = URL(string: “smartpin://payment”)
if let url = url, let urlComponents = NSURLComponents(url: url, resolvingAgainstBaseURL: false) {
var parameters : [URLQueryItem] = []
parameters.append(URLQueryItem(name: “id”, value: “abcdefg”)) parameters.append(URLQueryItem(name: “amount”, value: “1234”)) parameters.append(URLQueryItem(name: “callbackUrl”, value: “thisappscheme://finished”)) parameters.append(URLQueryItem(name: “reference”, value: “Mijn betaling”)) // Optional parameters.append(URLQueryItem(name: “type”, value: “PIN”)) // Optional urlComponents.queryItems = parameters
if let compiledCallbackUrl = urlComponents.url {
if UIApplication.shared.canOpenURL(compiledCallbackUrl) {
// Perform the operation on SmartPin by calling the SmartPin URL scheme + parameters UIApplication.shared.openURL(compiledCallbackUrl)
} else {
// If application is not installed: display an error message
let alertController = UIAlertController(title: “Not installed”, message: “SmartPin application not installed, please install and try
again.”, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: “Okay”, style: .default, handler: nil)) self.present(alertController, animated: true, completion: nil)
} }
}

After the payment is received 

func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool { if let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false), urlComponents.host == “finished” 
{ 
// Move the URL query paramets to a String dictionary var parameters : [String:String] = [:] if let queryItems = urlComponents.queryItems { 
for item in queryItems { 
if let value = item.value { 
parameters[item.name] = value; }
 } } 
let id = parameters[“id”] 
let reference = parameters[“reference”] 
let amount = parameters[“amount”] 
let type = parameters[“type”] 
let datetime = parameters[“datetime”] 
let state = parameters[“state”] 
let transactionId = parameters[“transactionId”] 
// For pin 
let terminalId = parameters[“terminalId”] 
let cardType = parameters[“cardType”] 
let AID = parameters[“AID”] 
let truncatedPan = parameters[“truncatedPan”] 
let authCode = parameters[“authCode”] 
let errorCode = parameters[“errorCode”] 
// For cash let change = parameters[“change”] 
// Handle transaction with above parameters return true } 
}

Contact 

Should you have any questions while these steps are being outlined or later on while using Rabo SmartPin, please contact the Rabo Smart Pay Support Team on telephone number +31 (0)88 727 11 57. Opening hours are weekdays from 8 AM to 6 PM and Saturdays from 9 AM to 5:30 PM.