Dostarczanie informacji o dostawie i danych kontaktowych z aplikacji płatniczej na Androida

Jak zaktualizować aplikację płatniczą na Androida, aby podawać adres dostawy i dane kontaktowe płatnika za pomocą interfejsów API płatności internetowych.

Sahel Sharify
Sahel Sharify

Podanie adresu dostawy i informacji kontaktowych w formularzu internetowym może być uciążliwe dla klientów. Może powodować błędy i zmniejszyć liczbę konwersji stawki.

Dlatego interfejs Payment Request API ma funkcję żądania wysyłki. adres i dane kontaktowe. Zapewnia to wiele korzyści:

  • Aby wybrać właściwy adres, wystarczy kilka kliknięć.
  • Adres jest zawsze zwracany w standardowym formacie .
  • Przesłanie nieprawidłowego adresu jest mniej prawdopodobne.

Przeglądarki mogą odroczyć zbieranie adresu dostawy i danych kontaktowych do To aplikacja płatnicza, która zapewnia ujednoliconą obsługę płatności. Ta funkcja jest nazywamy przekazywaniem dostępu.

Gdy tylko jest to możliwe, Chrome przekazuje informacje o wysyłce klienta adres i dane kontaktowe do wywołanej aplikacji płatniczej na Androida. upraszcza przekazywanie dostępu.

Witryna sprzedawcy może dynamicznie aktualizować opcje dostawy i łączną cenę w zależności od wyboru adresu dostawy i sposobu wysyłki .

Zmiana opcji dostawy i adresu dostawy. Zobacz, jak dynamicznie wpływa to na opcje dostawy i cenę całkowitą.
.
.

Aby dodać obsługę przekazywania dostępu do istniejącej aplikacji płatniczej na Androida: wykonaj te czynności:

  1. Deklarowanie obsługiwanych przekazywania dostępu.
  2. Przeanalizuj dodatki do intencji PAY dla wymaganej płatności opcje.
  3. Podawanie wymaganych informacji w formie płatności .
  4. [Opcjonalnie] Dynamiczny przepływ pomocy:
    1. Powiadamianie sprzedawcy o zmianach w formie płatności wybranej przez użytkownika, adres dostawy lub dostawa .
    2. otrzymać od sprzedawcy zaktualizowane dane do płatności (na przykład dostosowanej łącznej kwoty na podstawie wybranej opcji wysyłki koszt).

Deklarowanie obsługiwanych przekazywania dostępu

Przeglądarka musi znać listę dodatkowych informacji powiązanych z płatnością dostępna w aplikacji, tak aby mogła przekazać . Zadeklaruj obsługiwane przekazania jako <meta-data> w swojej aplikacji Plik AndroidManifest.xml

<activity
  android:name=".PaymentActivity"
    <meta-data
    android:name="org.chromium.payment_supported_delegations"
    android:resource="@array/supported_delegations" />
</activity>

<resource> musi być listą ciągów wybranych spośród tych prawidłowych wartości:

[ "payerName", "payerEmail", "payerPhone", "shippingAddress" ]

W tym przykładzie można podać tylko adres dostawy i adres e-mail płatnika adresu.

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <string-array name="supported_delegations">
    <item>payerEmail</item>
    <item>shippingAddress</item>
  </string-array>
</resources>

Przeanalizuj dodatki do intencji PAY, aby uzyskać informacje o wymaganych opcjach płatności

Sprzedawca może podać dodatkowe wymagane informacje za pomocą atrybutu paymentOptions słownik. Chrome poda listę wymaganych opcji, których aplikacja może używać przekazując poniższe parametry do działania PAY jako intencji, Dodatki.

paymentOptions

paymentOptions to podzbiór opcji płatności określonych przez sprzedawcę, w przypadku których w przypadku Twojej aplikacji zadeklarowano obsługę przekazywania dostępu.

val paymentOptions: Bundle? = extras.getBundle("paymentOptions")
val requestPayerName: Boolean? = paymentOptions?.getBoolean("requestPayerName")
val requestPayerPhone: Boolean? = paymentOptions?.getBoolean("requestPayerPhone")
val requestPayerEmail: Boolean? = paymentOptions?.getBoolean("requestPayerEmail")
val requestShipping: Boolean? = paymentOptions?.getBoolean("requestShipping")
val shippingType: String? = paymentOptions?.getString("shippingType")

Może zawierać takie parametry:

  • requestPayerName – wartość logiczna wskazująca, czy nazwa płatnika jest czy nie. jest wymagane.
  • requestPayerPhone – wartość logiczna wskazująca, czy telefon płatnika jest czy nie. jest wymagane.
  • requestPayerEmail – wartość logiczna wskazująca, czy adres e-mail płatnika jest czy nie. jest wymagane.
  • requestShipping – wartość logiczna wskazująca, czy informacje o dostawie są prawidłowe. jest wymagane.
  • shippingType – ciąg tekstowy wskazujący typ dostawy. Typ dostawy może być "shipping", "delivery" lub "pickup". Aplikacja może użyć tej podpowiedzi w swoich Interfejs, w którym pojawia się pytanie o adres użytkownika lub wybór opcji wysyłki.

shippingOptions

shippingOptions to tablica parowalna określająca dostawę określoną przez sprzedawcę . Ten parametr będzie istnieć tylko wtedy, gdy paymentOptions.requestShipping == true.

val shippingOptions: List<ShippingOption>? =
    extras.getParcelableArray("shippingOptions")?.mapNotNull {
        p -> from(p as Bundle)
    }

Każda opcja dostawy to Bundle z poniższymi kluczami.

  • id – identyfikator opcji dostawy.
  • label – etykieta opcji wysyłki widoczna dla użytkownika.
  • amount – pakiet kosztów dostawy zawierający klucze currency i value oraz ciągów znaków.
  • selected – określa, czy należy wybrać opcję dostawy, gdy w aplikacji płatniczej widoczne są opcje wysyłki.

Wszystkie klucze poza selected zawierają ciągi znaków. selected zawiera wartość logiczną .

val id: String = bundle.getString("id")
val label: String = bundle.getString("label")
val amount: Bundle = bundle.getBundle("amount")
val selected: Boolean = bundle.getBoolean("selected", false)

Podawanie wymaganych informacji w odpowiedzi na płatność

W odpowiedzi na swoją aplikację musisz podać wymagane dodatkowe informacje. aktywność w usłudze PAY.

W tym celu jako dodatki intencji należy określić te parametry:

  • payerName – pełna nazwa płatnika. Ciąg nie może być pusty, gdy: paymentOptions.requestPayerName to prawda.
  • payerPhone – numer telefonu płatnika. Ciąg nie może być pusty, gdy: paymentOptions.requestPayerPhone to prawda.
  • payerEmail – adres e-mail płatnika. Pole nie może być puste gdy paymentOptions.requestPayerEmail to prawda.
  • shippingAddress – adres dostawy podany przez użytkownika. Powinien to być niepusty pakiet, gdy paymentOptions.requestShipping ma wartość prawda. Pakiet powinien mieć następujące klucze reprezentujące różne części w fizycznym brzmieniu
    • city
    • countryCode
    • dependentLocality
    • organization
    • phone
    • postalCode
    • recipient
    • region
    • sortingCode
    • addressLine Wszystkie klucze poza addressLine zawierają ciągi znaków. addressLine jest tablicą ciągów znaków.
  • shippingOptionId – identyfikator opcji dostawy wybranej przez użytkownika. Ten nie może być pustym ciągiem znaków, jeśli paymentOptions.requestShipping ma wartość prawda.

Sprawdź odpowiedź dotyczącą płatności

Jeśli wynikiem działania na płatność jest otrzymana odpowiedź z wywołanej płatności aplikacja ma ustawienie RESULT_OK, Chrome sprawdzi wymagane dodatkowe zawarte w nich informacje. Jeśli weryfikacja się nie powiedzie, Chrome zwróci błąd obietnica od request.show() z jednym z tych błędów programistycznych wiadomości:

'Payment app returned invalid response. Missing field "payerEmail".'
'Payment app returned invalid response. Missing field "payerName".'
'Payment app returned invalid response. Missing field "payerPhone".'
'Payment app returned invalid shipping address in response.'
'... is not a valid CLDR country code, should be 2 upper case letters [A-Z]'
'Payment app returned invalid response. Missing field "shipping option".'

Poniższa próbka kodu to przykład prawidłowej odpowiedzi:

fun Intent.populateRequestedPaymentOptions() {
    if (requestPayerName) {
        putExtra("payerName", "John Smith")
    }
    if (requestPayerPhone) {
        putExtra("payerPhone", "4169158200")
    }
    if (requestPayerEmail) {
        putExtra("payerEmail", "john.smith@gmail.com")
    }
    if(requestShipping) {
        val address: Bundle = Bundle()
        address.putString("countryCode", "CA")
        val addressLines: Array<String> =
                arrayOf<String>("111 Richmond st. West")
        address.putStringArray("addressLines", addressLines)
        address.putString("region", "Ontario")
        address.putString("city", "Toronto")
        address.putString("postalCode", "M5H2G4")
        address.putString("recipient", "John Smith")
        address.putString("phone", "4169158200")
        putExtra("shippingAddress", address)
        putExtra("shippingOptionId", "standard")
    }
}

Opcjonalnie: obsługa dynamicznego przepływu

Czasami całkowity koszt transakcji wzrasta, np. gdy użytkownik wybierze opcję szybkiej dostawy lub gdy lista dostępnych opcji dostawy opcje wysyłki lub ich ceny zmienią się, gdy użytkownik wybierze dostawę międzynarodową adresu. Gdy aplikacja poda adres lub opcję dostawy wybrany przez użytkownika, powinien mieć możliwość powiadomienia sprzedawcy o dowolnym adresie lub opcji wysyłki zmian i wyświetlą użytkownikowi zaktualizowane dane do płatności (dostarczone przez sprzedawcy).

AIDL

Aby powiadomić sprzedawcę o nowych zmianach, użyj PaymentDetailsUpdateService zadeklarowaną w pliku AndroidManifest.xml w Chrome. Aby korzystać z tej usługi, utwórz dwie Pliki AIDL z następującą zawartością:

app/src/main/aidl/org/chromium/components/payments/IPaymentDetailsUpdateService

package org.chromium.components.payments;
import android.os.Bundle;

interface IPaymentDetailsUpdateServiceCallback {
    oneway void updateWith(in Bundle updatedPaymentDetails);

    oneway void paymentDetailsNotUpdated();
}

app/src/main/aidl/org/chromium/components/payments/IPaymentDetailsUpdateServiceCallback

package org.chromium.components.payments;
import android.os.Bundle;
import org.chromium.components.payments.IPaymentDetailsUpdateServiceCallback;

interface IPaymentDetailsUpdateService {
    oneway void changePaymentMethod(in Bundle paymentHandlerMethodData,
            IPaymentDetailsUpdateServiceCallback callback);

    oneway void changeShippingOption(in String shippingOptionId,
            IPaymentDetailsUpdateServiceCallback callback);

    oneway void changeShippingAddress(in Bundle shippingAddress,
            IPaymentDetailsUpdateServiceCallback callback);
}

Powiadom sprzedawcę o zmianach w wybranej przez użytkownika formie płatności, adresie dostawy lub opcji dostawy

private fun bind() {
    // The action is introduced in Chrome version 92, which supports the service in Chrome
    // and other browsers (e.g., WebLayer).
    val newIntent = Intent("org.chromium.intent.action.UPDATE_PAYMENT_DETAILS")
        .setPackage(callingBrowserPackage)
    if (packageManager.resolveService(newIntent, PackageManager.GET_RESOLVED_FILTER) == null) {
        // Fallback to Chrome-only approach.
        newIntent.setClassName(
            callingBrowserPackage,
            "org.chromium.components.payments.PaymentDetailsUpdateService")
        newIntent.action = IPaymentDetailsUpdateService::class.java.name
    }
    isBound = bindService(newIntent, connection, Context.BIND_AUTO_CREATE)
}

private val connection = object : ServiceConnection {
    override fun onServiceConnected(className: ComponentName, service: IBinder) {
        val service = IPaymentDetailsUpdateService.Stub.asInterface(service)
        try {
            if (isOptionChange) {
                service?.changeShippingOption(selectedOptionId, callback)
            } else (isAddressChange) {
                service?.changeShippingAddress(selectedAddress, callback)
            } else {
                service?.changePaymentMethod(methodData, callback)
            }
        } catch (e: RemoteException) {
            // Handle the remote exception
        }
    }
}

Pole callingPackageName używane dla intencji uruchomienia usługi może mieć jedną z tych wartości: następujące wartości w zależności od przeglądarki, która zainicjowała płatność użytkownika.

Kanał Chrome Nazwa pakietu
Stabilny "com.android.chrome"
Beta "com.chrome.beta"
Dla programistów "com.chrome.dev"
Canary "com.chrome.canary"
Chromium "org.chromium.chrome"
Okno szybkiego wyszukiwania Google (osadzający komponent WebLayer) "com.google.android.googlequicksearchbox"

changePaymentMethod

Powiadamia sprzedawcę o zmianach w formie płatności wybranej przez użytkownika. Pakiet paymentHandlerMethodData zawiera methodName i opcjonalny details klucze o wartości ciągu znaków. Chrome sprawdzi, czy nie ma niepustego pakietu ze znakiem niepuste pola methodName i wyślij updatePaymentDetails z jednym z następujące komunikaty o błędach za pomocą callback.updateWith, jeśli weryfikacja się nie powiedzie.

'Method data required.'
'Method name required.'

changeShippingOption

Powiadamia sprzedawcę o zmianach w opcji dostawy wybranej przez użytkownika. shippingOptionId powinien być identyfikatorem jednego z określonych przez sprzedawcę opcje wysyłki. Chrome sprawdzi, czy plik shippingOptionId nie jest pusty, i wyśle updatePaymentDetails z następującym komunikatem o błędzie za pośrednictwem: callback.updateWith, jeśli weryfikacja się nie powiedzie.

'Shipping option identifier required.'

changeShippingAddress

Powiadamia sprzedawcę o zmianach w adresie dostawy podanym przez użytkownika. Chrome, sprawdzi niepusty pakiet shippingAddress z prawidłową wartością countryCode i wyślij updatePaymentDetails z następującym komunikatem o błędzie przez callback.updateWith, jeśli weryfikacja się nie powiedzie.

'Payment app returned invalid shipping address in response.'

Komunikat o błędzie informujący o nieprawidłowym stanie

Jeśli po otrzymaniu żądania zmiany Chrome wykryje nieprawidłowy stan spowoduje wywołanie callback.updateWith z usuniętym updatePaymentDetails w pakiecie. Pakiet będzie zawierał tylko klucz error z "Invalid state". Przykłady nieprawidłowego stanu:

  • Gdy Chrome nadal czeka na odpowiedź sprzedawcy na poprzednią zmianę (np. trwające zdarzenie zmiany).
  • Identyfikator opcji dostawy podany w aplikacji płatności nie należy do żadnego z z opcjami wysyłki określonymi przez sprzedawcę.

Jak otrzymać zaktualizowane dane do płatności od sprzedawcy

private fun unbind() {
    if (isBound) {
        unbindService(connection)
        isBound = false
    }
}

private val callback: IPaymentDetailsUpdateServiceCallback =
    object : IPaymentDetailsUpdateServiceCallback.Stub() {
        override fun paymentDetailsNotUpdated() {
            // Payment request details have not changed.
            unbind()
        }

        override fun updateWith(updatedPaymentDetails: Bundle) {
            newPaymentDetails = updatedPaymentDetails
            unbind()
        }
    }

updatePaymentDetails to pakiet odpowiednika PaymentRequestDetailsUpdate. słownik WebIDL (po usunięciu wartości modifiers) i zawiera te klucze opcjonalne:

  • total – pakiet zawierający klucze currency i value, oba klucze ciągi znaków
  • shippingOptions – tablica przesyłki shipping opcje
  • error – ciąg tekstowy zawierający ogólny komunikat o błędzie (np. changeShippingOption nie zawiera prawidłowego identyfikatora opcji dostawy)
  • stringifiedPaymentMethodErrors – ciąg znaków JSON reprezentujący weryfikację. błędy formy płatności
  • addressErrors – pakiet z opcjonalnymi kluczami identyczny z dostawą address i ciąg znaków . Każdy klucz reprezentuje błąd weryfikacji związany z odpowiadającemu mu w adresie dostawy.

Brak klucza oznacza, że jego wartość się nie zmieniła.