Android
This section describes the steps required to perform an “app to app” call on Android applications. The technical development process consists of 3 different steps:
Step 1: Create an intent to call mPOS
Step 2: Define the object class MessageToSend
Step 3: Get a response from mPOS
Step 1: Create an intent to call mPOS
Communication with the mPOS application is done by using Android intents. This means that the call to the mPOS by an Android app is made through an Intent which contains a bundle with the required information for the transaction.
The data sent to the mPOS can be found in the following code sample:
private Intent createPendingIntent(String reference, String value){
Intent launchIntent = new Intent();
//Package of Smartpos that will be called
launch.Intente.setClassName(“pt.sibs.android.mpos.sibsPagamentosQly”,”pt.sibs.android.mpos.activities.MainActivity”);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addNextIntent(launchIntent);
// create a json with value and reference
MessageToSend messageToSend = new MessageToSend();
value? value.replaceAll(“[^\\d.]”, ””);
messageToSend.setAmount(value);
messageToSend.setReference(reference);
Gson gson = new GsonBuilder().create();
String message = gson.toJson(messageToSend,MessageToSend.class);
// create json to a Base64
byte[] bytes;
bytes = message.getBytes(StandardCharsets.UTF_8);
String base64msg = Base64.encodeToString(bytes, Base64.DEFAULT);
// create a bundle and intent to call mpos and send data over
Bundle data = new Bundle();
data.putString(PACKAGE_ID, BuildConfig.APPLICATION_ID);
data.putBoolean(REQUEST RESPONSE, sw.isChecked());
data.putBoolean(BYPASS_INSERT_VALUE, bypassSw.isChecked());
data.putBoolean(EDITABLE_REFERENCE, editReferenceSw.isChecked());
data.putBoolean(CALL_IN_APP_FECHO, fechoSw.isChecked());
data.putString(BASE64REFERENCE, base64msg);
data.putInt(REQUEST_KEY, activityRequestCode);
launchIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
launch.Intent.putExtra(DATA_MPOS, data);
return launchIntent;
}
The example illustrates a method that in the end returns an Intent with the necessary information. The Intent is created first, then the setClassName method is used to configure the mPOS Package and the Activity that will be invoked, in this case MainActivity. The name of the Activity to be used in the “app to app” call is: pt.sibs.android.mpos.activities.MainActivity.
After configuring the Intent, an object of a custom type called MessageToSend is created.
This object is used to hold values for the “reference”, “amount” and “gratuityAmount” fields, which are required for the mPOS transaction.
After creating the object and filling in the values of both fields, the object is converted to json, using the Gson lib , and then encode the json string into Base64.
After filling the object, we can create the Bundle to be passed along with the Intent. The Bundle must contain the following elements:
- A String with the Application ID of the app which is calling the mPOS;
- Boolean values indicating whether the app requires a response from the mPOS; allows to edit the amount and reference; whether it will execute a Closure instead of a Purchase;
- A String with the Base64-encoded JSON data;
- An Integer value used in the StartActivity that will use the Intent created by this method.
When the Bundle has been created, the FLAG_ACTIVITY_SINGLE_TOP flag is configured in the Intent. This flag is a configuration setting for the intent that specifies how the Activity should behave when it’s started. The keys used in the Bundle will be described further down in this guide. The development and production packages will be made available to developers once the integration journey initiates.
Step 2: Define the object class MessageToSend
In this object, the following fields must be populated:
- amount: this field contains the operation amount and is represented in cents.
Example: for a €10 purchase, the amount must be populated with ‘1000’. This field type is String; - reference: this field informs the reference associated to the operation. It is of the String type, 25- character length (maximum). May contain alphanumeric values.
- gratuityAmount: this field contains the amount of the gratuity related to the operation and is represented in cents. Example: for a purchase with a gratuity of €1, the value gratuityAmount must be populated with ‘100’. This field is of the String type.
Here is a code sample of the Class Message to send:
class MessageToSend {
@SerializedName("reference")
private String reference;
@SerializedName("ammount")
private String ammount;
void setReference(String reference) {
this.reference = reference;
}
void setAmmount(String amount) {
this.ammount = amount;
}
void setGratuityAmount(String gratuityAmount) {
this.gratuityAmount = gratuityAmount;
}
}
Step 3: Get a response from mPOS
After the execution of the operation, a response can be received from the mPOS, if the flag corresponding to the key “REQUEST_RESPONSE” marks the value true.
The following example illustrates how to read the response if it comes via on ActivityResult or on NewIntent:
@Override
protected void onNewIntent(Intent intent) {
String status = "";
String errorCode = "";
String date = "";
String reference = "";
String amount = "";
String mbwayDataJson = "";
MBWayCallInAppData mbwayCallInAppData = new MBWayCallInAppData();
// get response from mpos
if(intent != null && intent.getExtras() != null) {
if(intent.getExtras().containsKey(CALLIN ERROR KEY))
errorCode = intent.getExtras().getString(CALLIN_ERROR_KEY);
if(intent.getExtras().containsKey(CALLIN STATUS KEY))
status = intent.getExtras().getString(CALLIN_STATUS_KEY);
if(intent.getExtras().containsKey(CALLIN DATE KEY))
date = intent.getExtras().getString(CALLIN_DATE_KEY);
if(intent.getExtras().containsKey(CALLIN AMOUNT KEY))
amount = intent.getExtras().getString(CALLIN_AMOUNT_KEY);
if(intent.getExtras().containsKey(CALLIN REF))
reference = intent.getExtras().getString(CALLIN_REF);
Toast.makeText(getApplicationContext(), "STATUS2: "+status+"\nError: "+errorCode+"\nAmount: "+ amount + "\nDate: "+date+"\nReference: "+reference, Toast.LENGTH LONG).show());
}
super.onNewIntent(intent);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if(requestCode == activityRequestCode) {
String status = "";
String errorCode = "";
String date = "";
String reference = "";
String amount = "";
String mbwayDataJson = "";
String gratuity = "";
MBWayCallInAppData mbwayCallInAppData = new MBWayCallInAppData();
if(data != null && data.getExtras() != null) {
if (data.getExtras().containsKey(CALLIN ERROR KEY))
errorCode = data.getExtras().getString(CALLIN ERROR KEY);
if (data.getExtras().containsKey(CALLIN_STATUS_KEY))
status = data.getExtras().getString(CALLIN STATUS KEY);
if (data.getExtras().containsKey(CALLIN_DATE_KEY))
date = data.getExtras().getString(CALLIN DATE KEY);
if (data.getExtras().containsKey(CALLIN_AMOUNT_KEY))
amount = data.getExtras().getString(CALLIN DATE KEY);
if (data.getExtras().containsKey(CALLIN_REF))
reference = data.getExtras().getString(CALLIN REF);
if(data.getExtras().containsKey(CALLIN_GRATUITY_KEY))
gratuity = data.getExtras().getString(CALLIN_GRATUITY KEY);
Toast.makeText(getApplicationContext(), "STATUS2: "+status+"\nError: "+errorcode+"\nAmount: "+ amount + "\nGratuity: "+ gratuity +"\nDate: "+date+"\nReference: "+reference, Toast.LENGTH LONG.show());
}
}
}
In either case, an Intent is received containing a Bundle filled by the mPOS with the response data.
After validating that the Intent exists and contains the Bundle, the values of each Key will be obtained, if present.
The response returns 6 values, detailed on the following tables:
Value | Description | String Type |
---|---|---|
errorCode | Corresponds to the error code (if any) obtained by the mPOS while performing the operation | CALLIN_ERROR_KEY |
status | Informs the status of the operation performed by the mPOS, which can be: DeviceError Success Declined CommError Usercancelled UserTimeOut Missing Credentials | CALLIN_STATUS_KEY |
date | Informs the date when the operation was performed by the mPOS | CALLIN_DATE_KEY |
amount | Corresponds to the value used in the operation performed in mPOS, can be used to compare with the value sent in the bundle which invoked the mPOS app | CALLIN_AMOUNT_KEY |
reference | Corresponds to the reference used in the operation performed in the mPOS, can be used to compare with the value sent in the Bundle which invoked the mPOS app | CALLIN_REF |
gratuityAmount | corresponds to the amount of the gratuity in an operation performed by the SoftPOS. It can be used to compare with the amount sent in the Bundle that invoked the mPOS app | CALLIN_GRATUITY_KEY |
MB WAY client data* | Corresponds to a json with the MB WAY information used in the operation performed in the mPOS, an can be used when converting to an object MbWayCallInAppData. | CALLIN_MBWAY_CLIENT_DATA |
MB WAY client data*
The json has the following structure:
{
"fiscalIdentificationNumber": "123456789 ",
"email": “email_de_teste@sibs.com”
}
Name | Shape | Description |
---|---|---|
fiscalidentificationNumber | string | TIN |
string | Client’s email |
Below you can find a table with the Used Keys and correspondent definition.
Used keys | Key definition |
---|---|
DATA_MPOS | Corresponds to the name of the Bundle used to call the mPOS app |
PACKAGE_ID | Contains the application ID of the app which is calling the mPOS |
BASE64REFERENCE | Corresponds to the value in base 64 of the json created from the object MessageToSend with the amount and reference values populated |
REQUEST_RESPONSE | Corresponds to the flag which indicated whether the app that is invoking the mPOS requires a response |
BYPASS_INSERT_VALUE | Corresponds to the flag which indicated whether the app that is invoking the mPOS allows the change of the amount |
EDITABLE_REFERENCE | Corresponds to the flag which indicated whether the app that is invoking the mPOS allow the change of the reference |
REQUEST_KEY | Corresponds to the Int value used in the StartActivity that used the created intent |
CALLIN_ERROR_KEY | Used in case of response corresponding to the error (if any) obtained by the mPOS while performing the operation |
CALLIN_STATUS_KEY | Used in case of response and it informs the status of the operation performed by the mPOS (success, declined, etc.) |
CALLIN_AMOUNT_KEY | Used in case of response and corresponds to the amount of the operation performed in the mPOS |
CALLIN_GRATUITY_KEY | Used in case of response and corresponds to the amount of the gratuity in an operation performed in the mPOS. The value is of the String type. |
CALLIN_DATE_KEY | Used in case of response and it informs the date when the operation was performed in the mPOS |
CALLIN_REF | Used in case of response and it contains the reference used in the operation performed in the mPOS |
CALL_IN_APP_FECHO | Corresponds to the flag indicating whether the app will perform a closure (“fecho”, in Portuguese) instead of a purchase |
API_TOKEN | Used to export the authentication token of the payment app. This token is generated through the backoffice or payment app and contains the information of the User who generated it. The token generation is done through the tab “Manage API Key”. The token must be transmitted in JWT format (base64 with dot dividers, such as header.body.trailer) and is provided in the format expected by the payment application. |
API_TOKEN_ID | Key used to transport the authentication token ID. It is used to identify the token used by the partner application. The value is of the String type. |
String token= "eyJhbGciOiJFQ0RILUVTIiwiZW5jIjoiQTEyOENCQy1IUzI1NiIsImVwayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMjU2IiwieCI6IkdacEs5U0taUGxVTkpWR1JGMSswenlacVpXUGNNcUJSNmh1ODJTZVAxNGdcdTAwM2QiLCJ5IjoiQUszUjY3alpGYmQ1QTR6T013SnNLQVJ4WTY5MGo0bEJIQXdoWlZraHJrUEUiLCJleHQiOmZhbHNlfSwia2lkIjoidGVzdGVmaW5hbCJ9..122+VO2IJii+3oQhdQRgJw==.VGrKQuXL+VtCspmXVF1YXiREJvsSvivWUld+XPJjhbJWd4Fur5vVk7LQn7NK8W/+tC8P7f5mPkYTXAy374FJSA==.OFzZ03QZf/2btlJQwoAnhQ==";
String token_id ="token_test";
data.putString(API_TOKEN, token);
data.putString(API_TOKEN_ID, token_id);
The API key menu allows the configuration of Single Sign On (SSO) authentication intended to allow the User a secure login to the partner application (such as business app or invoicing apps) without the need to login to the payment application.
On accessing this menu page, the User will be shown the list of API Keys that are currently active as per the following figure:
To create a new API Key, the user should use the “Add API Key” button, available at the top of the page. Clicking on this button opens a window where the user must enter the following data to create the token:
- Key Name (optional)
- Password (mandatory)
Since the “Key name” is an optional field, it does not need to be filled in. In these cases, a name will be automatically generated by the backend. This “key name” field is to help you identify the token in use.
After entering the required data, a success message will be displayed for token creation and a file with the token and the token ID will be automatically downloaded. This file has a JSON with the following structure:
{
"authToken": "eyJhbGciOiJFQ0RILUVTIiwiZW5jIjoiQTEyOENCQy1IUzI1NiIsImVwayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMjU2IiwieCI6IkFJSFpXL3VGbXF6NlByTFp3eXNXRUgrSWh1ZUJDUWlFckFkd1lFY2NXZlRxIiwieSI6IlI2WGk3NEIxVkQ2aGR2TU0wOFkwc3MzdVVNR1ozZmJ2VWZHblpwMFRrbmdcdTAwM2QiLCJleHQiOmZhbHNlfSwia2lkIjoiN2VhMWUzY2ItZmJkMy00MGE2LTk0ODEtZjE5N2FmMDY1YzRmIn0=..yHo1ot7byeyDUn3YpDIbqQ==.7AexWSp5a129AE5NRytWzDQhxH5p7c9OG3c8CrsyCzx5ZGDDmnAHMqFLMKHdPdMJ.4P4YtpZkgglHEqGICH9QJw==",
"tokenId": "7ea1e3cb-fbd3-40a6-9481-f197af065c4f"
}
There is a validation at the “Key Name” level. If the User tries to create a token with the name of an existing key, the following error message will be displayed: “A token with the specified if already exists, each token must have a unique name.”
The key can be renewed on the “Re-generate” butting, that is, this button creates a new key for a given API Token. The next steps will be to simply enter the account password, which will trigger the automatic download of the file with the re-generated token. Since it is a token obtained with an ephemeral key, it will be different from the originally generated token.
The Delete button shall be used to revoke an existing token. This functionality will cause the selected token to be deleted, rendering it invalid. For security reasons a warning message is displayed before the User starts the token deletion process.
If the action is confirmed, the token deletion process will start, and the user sill only need to enter the password to complete the process.
Once completed, the token will be deleted, hence becoming invalid for use in any application. The deleted token shall be removed from the list of active keys and cannot be re-generated.
Once the token is created, it can be used to authenticate the partner application, through the app to app call. As long as the token is valid, the User won’t be logged out of the payment apps and all the requests will be authenticated with the token.
iOS
This section describes the steps required to perform a “app to app” call on iOS applications. The technical development itself requires 3 steps:
Step 1: Configure the application
Step 2: Create the data model to transfer to mPOS
Step 3: Get a response from mPOS
Step 1: Configure the application
To receive responses from the mPOS, the client application must configure a URL Type in the project’s Info.plist. The name (scheme) must be defined in the URL Schemes field – this is the name by which the mPOS app will make the “app to app” call to obtain the answer with the result of the operation performed in the mPOS.
In the following example, the “app-to-app” scheme must be replaced by the client application scheme:
Step 2: Create the data model to transfer to mPOS
The call to the mPOS by an iOS app is made through a data model (in json format in base64) based on the following parameters:
{
"reference" : “ABCDEFG”,
"amount" : “3284”,
"lockAmountValue" : 1,
"performAutomaticClose" : 1,
"urlScheme": @“callinapp://"
}
Below, we provide you with a table with the details of the date model briefly described:
Field | Description |
---|---|
reference | Informs the reference associated to the operation. It is of the String type, 25-character length (maximum). May contain alphanumeric values. |
amount | Contains the operation amount and is represented in cents. Example: for a €10 purchase, the value ‘amount’ must be populated with ‘1000’. This field is of the String type. |
lockAmountValue | Boolean field. If populated with ‘true’, then it is not possible to edit the amount sent to the mPOS and, as such, the mPOS starts directly on the payment method selection screen. |
performAutomaticClose: | Boolean field. If populated with ‘true’, then the mPOS app will open on the Closure screen and automatically start the closure operation without user intervention. If both this field and the field lockAmountValue are populated with ‘true’, then this operation will have priority over the purchase operation, which is ignored. |
urlScheme | This field indicates which scheme (of the client application) the mPOS app should call to send the result of the executed operation. |
The following code sample represents a “app to app” call made to mPOS by an iOS app:
(void) openAppWithScheme:(NSString*)scheme {
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
numberFormatter.numberStyle = NSNumberFormatterDecimalStyle;
int amount = [numberFormatter numberFromString:@“32,84”].floatValue * 100;
NSDictionary *paramsDic = @{@"reference" : @"ABCDEFG",
@"amount" : [NSString stringWithFormat:@"%i", amount],
@"lockAmountValue" : [NSNumber numberWithBool:YES],
@"performAutomaticClose" : [NSNumber numberWithBool:YES],
@"urlScheme": @"callinapp://"
};
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:paramsDic options:0error:nil];
NSString *jsonParms = [jsonData base64EncodedStringWithOptions:0];
NSString *url = [NSString stringWithFormat:@"%@://%@", scheme, jsonParms];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]
options:@{ UIApplicationOpenURLOptionUniversalLinksOnly: @NO} completionHandler:^(BOOL success) {
NSLog(@"URL: %@", url);
NSLog(@"Success: %@", success ? @"YES": @"NO");
}
];
}
Step 3: Get a response from mPOS
The mPOS application, upon receiving a “app to app” call processes the requested operation returning the response to the client application with the result (success or error) of the operation. This response is returned to the client application using the following data model defined in JSON in base 64
{
@"callInError" : “”,
@"callInStatus" : “APPR”,
@"callInAmount" : “3284”,
@"callInDate": “2020-05-04T11:42:38.001+01:00”,
@"callInRef": “ABCDEFG”
@"callInMBWayCustomerData": “{"fiscalIdentificationNumber": "123456789 ", "email": “email_de_teste@sibs.com”}”
}
Here is a brief description with the meaning of the different fields:
Field | Description |
---|---|
CallInError | Value corresponds to the error code (if any) obtained by the mPOS while performing the operation. The value is of the String type. |
CallInStatus | Informs the status of the operation performed by the mPOS, which can be: – DeviceError – Success – Declined – CommError – Usercancelled – UserTimeOut |
CallInAmount | Corresponds to the value used in the operation performed in the mPOS, and can be used to compare with the value sent in the call to the mPOS app. The value is of the String type. |
CallInDate | Value informs the date when the operation was performed by the mPOS. The value is of the String type. |
CallInRef | Corresponds to the reference used in the operation performed in the mPOS, and can be used to compare with the value sent in the call to the mPOS app. The value is of the String type. |
CallInMBWayCustomerData* | Corresponds to a json with the MB WAY information used in the operation performed in the mPOS – TIN and email – that can be sent as a response to a payment with QR code – Name – Shape – Description – fiscalidentificationNumber – String – TIN – String – Client’s email |
CallInMBWayCustomerData *
The json has the following structure:
{
"fiscalIdentificationNumber": "123456789 ",
"email": “email_de_teste@sibs.com”
}
Below we provide you an example of how to process an mPOS response in the AppDelegate file of the iOS project:
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options: (NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
[self parsePaymentResponse:url];
return YES;
}
-(void)parsePaymentResponse:(NSURL*_Nullable)url {
if(!url)
return;
NSString *base64Encoded = [url.absoluteString stringByReplacingOccurrencesOfString:@"callinapp://" withString:@""];
if(!base64Encoded)
return;
NSData *nsdataFromBase64String = [[NSData alloc] initWithBase64EncodedString:base64Encoded options:0];
if(!nsdataFromBase64String)
return;
NSError *error;
NSDictionary *dicParams = [NSJSONSerialization JSONObjectWithData:nsdataFromBase64String options:0 error:&error];
if(!dicParams || error)
return;
NSLog(@"%@", dicParams);
NSString *result = [NSString stringWithFormat:@"%@", dicParams];
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Resposta" message:result preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
[self.window.rootViewController presentViewController:alert animated:YES completion:nil];
}