Skip to content
Menu

Integracja app-to-app

Nasza integracja między aplikacjami umożliwia płynne połączenie między aplikacją sprzedawcy a naszą aplikacją LightPOS, zapewniając klientom szybki i bezpieczny sposób dokonywania płatności. Sprawdź szczegóły poniżej, aby rozpocząć integrację z aplikacjami na Androida i iOS.

Android

Sprawdź kroki wymagane do wykonania połączenia „app-to-app” w aplikacjach na Androida. Proces rozwoju obejmuje trzy kroki:

Krok 1: Utwórz zamiar wywołania aplikacji SoftPOS
Krok 2: Zdefiniuj klasę obiektu MessageToSend
Krok 3: Uzyskaj odpowiedź od SoftPOS
Krok 1: Utwórz zamiar wywołania aplikacji SoftPOS

Komunikacja z aplikacją SoftPOS odbywa się za pomocą intencji systemu Android. Oznacza to, że wywołanie SoftPOS przez aplikację Android odbywa się za pośrednictwem intencji, która zawiera pakiet z wymaganymi informacjami dla transakcji.

Dane wysyłane do SoftPOS można znaleźć w poniższym przykładzie kodu:

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;
}

Przykład ilustruje metodę, która ostatecznie zwraca intencję z niezbędnymi informacjami. Najpierw tworzona jest intencja, a następnie setClassName służy do konfiguracji pakietu SoftPOS i działania, które zostanie wywołane, w tym przypadku MainActivity. Nazwa Activity, która ma być używana w wywołaniu “app to app” topt.sibs.android.mpos.activities.MainActivity.

Po skonfigurowaniu intencji, jest tworzony obiekt niestandardowego typu o nazwie MessageToSend .

Ten obiekt jest używany do przechowywania wartości dla pól “reference”, “amount” i “gratuityAmount”, które są wymagane dla transakcji SoftPOS.

Po utworzeniu obiektu i wypełnieniu wartości obu pól, obiekt jest konwertowany na json, przy użyciu funkcji Gson lib , a następnie zakodować string json do Base64.

Po wypełnieniu obiektu możemy utworzyć Bundle, który zostanie przekazany wraz z Intencją. Bundle musi zawierać następujące elementy:

  • String z Application ID aplikacji, która wywołuje SoftPOS;
  • Wartości Boolean czy aplikacja wymaga odpowiedzi od SoftPOS; pozwala edytować kwotę i odniesienie; czy wykona polecenie Closure zamiast Purchase;
  • String z wartościami Base64-encoded JSON;
  • Wartość Integer w StartActivity użyje Intent stworzoną przez tą metodę.

Po utworzeniu Bundle FLAG_ACTIVITY_SINGLE_TOP jest skonfigurowany w Intent. Flaga ta jest ustawieniem konfiguracyjnym intencji, które określa, jak Activity powinno się zachowywać po uruchomieniu. Klucze użyte w the Bundle zostaną opisane w dalszej części tego przewodnika. Pakiety rozwojowe i produkcyjne zostaną udostępnione deweloperom po rozpoczęciu procesu integracji.

Info

Pakiety rozwojowe i produkcyjne zostaną udostępnione deweloperom po rozpoczęciu procesu integracji.

Krok 2: Zdefiniuj klasę obiektu MessageToSend

W tym obiekcie należy wypełnić następujące pola:

  • amount to pole zawiera kwotę operacji i jest reprezentowane w centach. Przykład: w przypadku zakupu o wartości 10 EUR kwota musi być wypełniona wartością „1000”. Ten typ pola to String;
  • reference to pole informuje o referencji związanej z operacją. Jest ono typu String, o długości do 25 znaków (maximum). Może zawierać wartości alfanumeryczne.
  • gratuityAmount to pole zawiera kwotę napiwku związanego z operacją i jest reprezentowane w centach. Przykład: dla zakupu z napiwkiem w wysokości 1 €, wartość gratuityAmount muszą być wypełnione z wartością ‘100’. To pole jest typu String.

Oto przykład Class Message do wysłania:

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;
    }
}
Krok 3: Uzyskaj odpowiedź od SoftPOS

Po wykonaniu operacji można otrzymać odpowiedź z systemu SoftPOS, jeśli flaga odpowiadająca kluczowi “REQUEST_RESPONSE” oznacza wartość true.

Poniższy przykład ilustruje, jak odczytać odpowiedź, jeśli nadejdzie ona przez on ActivityResult albo w 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());
        }
    }
}

W obu przypadkach odbierana jest intencja zawierająca Bundle wypełniony przez SoftPOS danymi odpowiedzi.

Po sprawdzeniu, czy intencja istnieje i zawiera pakiet, uzyskane zostaną wartości każdego Key, jeśli są obecne.

Odpowiedź zwraca 6 wartości, wyszczególnionych w poniższych tabelach:

WartośćOpisTyp String
errorCodeOdpowiada kodowi błędu (jeśli istnieje) uzyskanemu przez SoftPOS podczas wykonywania operacji.CALLIN_ERROR_KEY
statusInformuje o statusie operacji wykonywanej przez SoftPOS, którą może być:
DeviceError
Success
Declined
CommError
Usercancelled
UserTimeOut
Missing Credentials
CALLIN_STATUS_KEY
dateInformuje o dacie wykonania operacji przez system SoftPOS.CALLIN_DATE_KEY
amountOdpowiada wartości użytej w operacji wykonanej w SoftPOS, może być użyta do porównania z wartością wysłaną w pakiecie, który wywołał aplikację SoftPOS.CALLIN_AMOUNT_KEY
referenceOdpowiada referencji użytej w operacji wykonanej w aplikacji SoftPOS, może być użyta do porównania z wartością wysłaną w pakiecie, który wywołał aplikację SoftPOS.CALLIN_REF
gratuityAmountOdpowiada kwocie napiwku w operacji wykonanej przez aplikację SoftPOS. Można jej użyć do porównania z kwotą wysłaną w Bundle, który wywołał aplikację SoftPOS.CALLIN_GRATUITY_KEY

Below you can find a table with the Used Keys and correspondent definition:

Klucze UseraDefinicje Key
DATA_MPOSOdpowiada nazwie Bundle używanego do wywoływania aplikacji SoftPOS.
PACKAGE_IDZawiera application ID aplikacji, która wywołuje SoftPOS.
BASE64REFERENCEOdpowiada wartości w base 64 pliku json utworzonego z obiektu MessageToSend z wypełnionymi wartościami amount i reference.
REQUEST_RESPONSEOdpowiada znacznikowi (fladze), czy aplikacja wywołująca SoftPOS wymaga odpowiedzi.
BYPASS_INSERT_VALUEOdpowiada znacznikowi wskazującemu, czy aplikacja wywołująca SoftPOS zezwala na zmianę kwoty.
EDITABLE_REFERENCEOdpowiada znacznikowi wskazującemu, czy aplikacja wywołująca SoftPOS zezwala na zmianę odniesienia.
REQUEST_KEYOdpowiada wartości Int użytej w StartActivity, która użyła utworzonej intencji.
CALLIN_ERROR_KEYUżywany w przypadku odpowiedzi odpowiadającej błędowi (jeśli występuje) uzyskanemu przez SoftPOS podczas wykonywania operacji.
CALLIN_STATUS_KEYUżywany w przypadku odpowiedzi i informuje o statusie operacji wykonanej przez SoftPOS (zaakceptowana, odrzucona itp.).
CALLIN_AMOUNT_KEYUżywany w przypadku odpowiedzi i odpowiada kwocie operacji wykonanej w systemie SoftPOS.
CALLIN_GRATUITY_KEYUżywana w przypadku odpowiedzi i odpowiada kwocie napiwku w operacji wykonywanej w SoftPOS. Wartość jest typu String
CALLIN_DATE_KEYUżywany w przypadku odpowiedzi i informuje o dacie wykonania operacji w systemie SoftPOS.
CALLIN_REFUżywany w przypadku odpowiedzi i zawiera odniesienie użyte w operacji wykonanej w SoftPOS.
CALL_IN_APP_FECHOOdpowiada fladze wskazującej, czy aplikacja wykona zamknięcie („fecho”, po portugalsku) zamiast zakupu.

iOS

Sprawdź kroki wymagane do wykonania połączenia „app-to-app” w aplikacjach iOS. Proces rozwoju obejmuje trzy kroki:

Krok 1: Konfiguracja aplikacji
Krok 2: Tworzenie modelu danych do przeniesienia do SoftPOS
Krok 3: Uzyskaj odpowiedź od SoftPOS
Krok 1: Konfiguracja aplikacji

Aby otrzymywać odpowiedzi z systemu SoftPOS, aplikacja kliencka musi skonfigurować typ adresu URL w polu projektu Info.plist. Nazwa (scheme) musi być zdefiniowane w polu URL Schemes – jest to nazwa, pod którą SoftPOS app stworzy połączenie “app to app” aby uzyskać odpowiedź z wynikiem operacji wykonanej w SoftPOS.

W poniższym przykładzie schemat „app-to-app” musi zostać zastąpiony schematem aplikacji klienckiej:

Krok 2: Tworzenie modelu danych do przeniesienia do SoftPOS

Wywołanie SoftPOS przez aplikację iOS odbywa się za pośrednictwem modelu danych (w formacie json w base64) w oparciu o następujące parametry:

{
    "reference" : “ABCDEFG”,
    "amount" : “3284”,
    "lockAmountValue" : 1,
    "performAutomaticClose" : 1,
    "urlScheme": @“callinapp://"
}

Poniżej przedstawiamy tabelę ze szczegółowym opisem modelu daty:

PoleOpis
referenceInformuje o referencji związanej z operacją. Jest to typ String o maksymalnej długości 25 znaków. Może zawierać wartości alfanumeryczne.
amountZawiera kwotę operacji i jest reprezentowana w centach. Przykład: w przypadku zakupu za 10 EUR wartość „amount” musi być wypełniona wartością „1000”. To pole jest typu String.
lockAmountValuePole Boolean . Jeśli wypełniona zostanie wartość „true”, nie będzie można edytować kwoty wysłanej do systemu SoftPOS i w związku z tym system SoftPOS uruchomi się bezpośrednio na ekranie wyboru metody płatności.
performAutomaticClose:Pole Boolean . Jeśli pole ma wartość „true”, aplikacja SoftPOS otworzy się na ekranie zamknięcia i automatycznie rozpocznie operację zamknięcia bez interwencji użytkownika. Jeśli zarówno to pole, jak i pole lockAmountValue mają wartość „true”, wówczas ta operacja będzie miała pierwszeństwo przed operacją zakupu, która jest ignorowana.
urlSchemeTo pole wskazuje, który schemat (aplikacji klienckiej) aplikacja SoftPOS powinna wywołać, aby wysłać wynik wykonanej operacji.

Poniższa próbka kodu reprezentuje połączenie „aplikacja do aplikacji” wykonane do SoftPOS przez aplikację iOS:

(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");
        }
    ];
}
Krok 3: Uzyskaj odpowiedź od SoftPOS

Aplikacja SoftPOS po otrzymaniu wywołania „app to app” przetwarza żądaną operację, zwracając odpowiedź do aplikacji klienckiej z wynikiem (sukces lub błąd) operacji. Ta odpowiedź jest zwracana do aplikacji klienckiej przy użyciu następującego modelu danych zdefiniowanego w JSON w base 64

{
    @"callInError" : “”,
    @"callInStatus" : “APPR”,
    @"callInAmount" : “3284”,
    @"callInDate": “2020-05-04T11:42:38.001+01:00”,
    @"callInRef": “ABCDEFG”}”
}

Poniżej znajduje się krótki opis znaczenia poszczególnych pól:

PoleOpis
CallInErrorWartość odpowiada kodowi błędu (jeśli występuje) uzyskanemu przez SoftPOS podczas wykonywania operacji. Wartość jest typu String.
CallInStatusInformuje o statusie operacji wykonywanej przez SoftPOS, którą może być:
– DeviceError
– Success
– Declined
– CommError
– Usercancelled
– UserTimeOut
CallInAmountOdpowiada wartości użytej w operacji wykonanej w aplikacji SoftPOS i może być użyta do porównania z wartością wysłaną w wywołaniu do aplikacji SoftPOS. Wartość jest typu String.
CallInDateWartość informuje o dacie wykonania operacji przez SoftPOS. Wartość jest typu String.
CallInRefOdpowiada referencji użytej w operacji wykonanej w aplikacji SoftPOS i może być użyta do porównania z wartością wysłaną w wywołaniu do aplikacji SoftPOS. Wartość jest typu String.

Poniżej przedstawiamy przykład przetwarzania odpowiedzi SoftPOS w pliku AppDelegate  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];

}
Przegląd prywatności

Ta strona korzysta z ciasteczek, aby zapewnić Ci najlepszą możliwą obsługę. Informacje o ciasteczkach są przechowywane w przeglądarce i wykonują funkcje takie jak rozpoznawanie Cię po powrocie na naszą stronę internetową i pomaganie naszemu zespołowi w zrozumieniu, które sekcje witryny są dla Ciebie najbardziej interesujące i przydatne.

Ściśle niezbędne ciasteczka

Niezbędne ciasteczka powinny być zawsze włączone, abyśmy mogli zapisać twoje preferencje dotyczące ustawień ciasteczek.

Jeśli wyłączysz to ciasteczko, nie będziemy mogli zapisać twoich preferencji. Oznacza to, że za każdym razem, gdy odwiedzasz tę stronę, musisz ponownie włączyć lub wyłączyć ciasteczka.