Our app-to-app integration enables a seamless connection between your merchant app and our LightPOS app, providing customers with a quick and secure way to complete their payments. Check out the details below to get started with the integration for both Android and iOS apps.
Android
Check out the steps required to perform an “app-to-app” call on Android applications. The development process involves three steps:
Step 1: Create an intent to call SoftPOS
Step 2: Define the object class MessageToSend
Step 3: Get a response from SoftPOS
Step 1: Create an intent to call SoftPOS
Communication with the SoftPOS application is done by using Android intents. This means that the call to the SoftPOS 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 SoftPOS 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.stargatePaytelQLY”,”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 SoftPOS 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 SoftPOS 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 SoftPOS;
- Boolean values indicating whether the app requires a response from the SoftPOS; 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 SoftPOS
After the execution of the operation, a response can be received from the SoftPOS, 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 = "";
// 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+" \n Error: "+errorCode+" \n Amount: "+ amount + " \n Date: "+date+ " \n Reference: "+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 gratuity = "";
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+" \n Error: "+errorcode+" \n Amount: "+ amount + " \n Gratuity: "+ gratuity +" \n Date: "+date+" \n Reference: "+reference, Toast.LENGTH LONG.show());
}
}
}
In either case, an Intent is received containing a Bundle filled by the SoftPOS 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 SoftPOS while performing the operation | CALLIN_ERROR_KEY |
status | Informs the status of the operation performed by the SoftPOS, 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 SoftPOS | CALLIN_DATE_KEY |
amount | Corresponds to the value used in the operation performed in SoftPOS, can be used to compare with the value sent in the bundle which invoked the SoftPOS app | CALLIN_AMOUNT_KEY |
reference | Corresponds to the reference used in the operation performed in the SoftPOS, can be used to compare with the value sent in the Bundle which invoked the SoftPOS 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 SoftPOS app | CALLIN_GRATUITY_KEY |
Below you can find a table with the Used Keys and correspondent definition:
User keys | Key definition |
---|---|
DATA_MPOS | Corresponds to the name of the Bundle used to call the SoftPOS app |
PACKAGE_ID | Contains the application ID of the app which is calling the SoftPOS |
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 SoftPOS requires a response |
BYPASS_INSERT_VALUE | Corresponds to the flag which indicated whether the app that is invoking the SoftPOS allows the change of the amount |
EDITABLE_REFERENCE | Corresponds to the flag which indicated whether the app that is invoking the SoftPOS 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 SoftPOS while performing the operation |
CALLIN_STATUS_KEY | Used in case of response and it informs the status of the operation performed by the SoftPOS (success, declined, etc.) |
CALLIN_AMOUNT_KEY | Used in case of response and corresponds to the amount of the operation performed in the SoftPOS |
CALLIN_GRATUITY_KEY | Used in case of response and corresponds to the amount of the gratuity in an operation performed in the SoftPOS. 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 SoftPOS |
CALLIN_REF | Used in case of response and it contains the reference used in the operation performed in the SoftPOS |
CALL_IN_APP_FECHO | Corresponds to the flag indicating whether the app will perform a closure (“fecho”, in Portuguese) instead of a purchase |
iOS
Check out the steps required to perform an “app-to-app” call on iOS applications. The development process involves three steps:
Step 1: Configure the application
Step 2: Create the data model to transfer to SoftPOS
Step 3: Get a response from SoftPOS
Step 1: Configure the application
To receive responses from the SoftPOS, 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 SoftPOS app will make the “app to app” call to obtain the answer with the result of the operation performed in the SoftPOS.
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 SoftPOS
The call to the SoftPOS 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 SoftPOS and, as such, the SoftPOS starts directly on the payment method selection screen. |
performAutomaticClose: | Boolean field. If populated with ‘true’, then the SoftPOS 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 SoftPOS app should call to send the result of the executed operation. |
The following code sample represents a “app to app” call made to SoftPOS 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 SoftPOS
The SoftPOS 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”}”
}
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 SoftPOS while performing the operation. The value is of the String type. |
CallInStatus | Informs the status of the operation performed by the SoftPOS, which can be: – DeviceError – Success – Declined – CommError – Usercancelled – UserTimeOut |
CallInAmount | Corresponds to the value used in the operation performed in the SoftPOS, and can be used to compare with the value sent in the call to the SoftPOS app. The value is of the String type. |
CallInDate | Value informs the date when the operation was performed by the SoftPOS. The value is of the String type. |
CallInRef | Corresponds to the reference used in the operation performed in the SoftPOS, and can be used to compare with the value sent in the call to the SoftPOS app. The value is of the String type. |
Below we provide you an example of how to process an SoftPOS 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];
}