Versand- und Kontaktdaten aus einer Android-Zahlungs-App angeben

So aktualisieren Sie Ihre Android-Zahlungs-App, um mit Web Payments APIs die Versandadresse und die Kontaktdaten des Zahlungspflichtigen anzugeben.

Sahel Sharify
Sahel Sharify

Veröffentlicht am 17. Juli 2020, zuletzt aktualisiert am 27. Mai 2025

Die Eingabe von Versandadresse und Kontaktdaten über ein Webformular kann für Kunden mühsam sein. Dies kann zu Fehlern und einer niedrigeren Conversion-Rate führen.

Aus diesem Grund unterstützt die Payment Request API eine Funktion zum Anfordern von Versandadresse und Kontaktdaten. Das bietet mehrere Vorteile:

  • Nutzer können die richtige Adresse mit nur wenigen Klicks auswählen.
  • Die Adresse wird immer im standardisierten Format zurückgegeben.
  • Es ist weniger wahrscheinlich, dass eine falsche Adresse angegeben wird.

Browser können die Erfassung von Versandadresse und Kontaktdaten an eine Zahlungs-App delegieren, um eine einheitliche Zahlung zu ermöglichen. Diese Funktion wird als Delegierung bezeichnet.

Wenn möglich, delegiert Chrome die Erfassung der Versandadresse und der Kontaktdaten eines Kunden an die aufgerufene Android-Zahlungs-App. Durch die Delegation wird die Reibung beim Bezahlvorgang verringert.

Die Versandoptionen und der Gesamtpreis können auf der Händlerwebsite dynamisch aktualisiert werden, je nachdem, welche Versandadresse und Versandoption der Kunde auswählt.

Versandoption und Versandadresse werden geändert. Sehen Sie, wie sich das dynamisch auf die Versandoptionen und den Gesamtpreis auswirkt.

So fügen Sie einer bereits vorhandenen Android-Zahlungs-App die Unterstützung für die Delegierung hinzu:

  1. Unterstützte Delegierungen deklarieren
  2. PAY-Intent-Extras für erforderliche Zahlungsoptionen parsen:
  3. Erforderliche Informationen in der Zahlungsantwort angeben:
  4. Optional: Dynamischen Ablauf unterstützen:
    1. Händler über Änderungen an der vom Nutzer ausgewählten Zahlungsmethode, Versandadresse oder Versandoption benachrichtigen:
    2. Aktualisierte Zahlungsdetails vom Händler erhalten, z. B. den angepassten Gesamtbetrag basierend auf den Kosten der ausgewählten Versandoption.

Unterstützte Delegationen deklarieren

Der Browser muss die Liste der zusätzlichen Informationen kennen, die Ihre Zahlungs-App bereitstellen kann, damit er die Erhebung dieser Informationen an Ihre App delegieren kann. Deklarieren Sie die unterstützten Delegierungen als <meta-data> in der AndroidManifest.xml Ihrer App.

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

android:resource muss auf ein <string-array> verweisen, das alle oder eine Teilmenge der folgenden Werte enthält:

  • payerName
  • payerEmail
  • payerPhone
  • shippingAddress

Im folgenden Beispiel können nur eine Versandadresse und die E-Mail-Adresse des Zahlungspflichtigen angegeben werden.

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

PAY-Intent-Extras nach erforderlichen Zahlungsoptionen parsen

Der Händler kann mit dem paymentOptions-Dictionary zusätzliche erforderliche Informationen angeben. Chrome stellt die Liste der erforderlichen Optionen bereit, die Ihre App bereitstellen kann, indem sie die paymentOptions Intent-Extras an die PAY-Aktivität übergibt.

paymentOptions

paymentOptions ist die Teilmenge der vom Händler angegebenen Zahlungsoptionen, für die in Ihrer App die Delegierungsunterstützung deklariert wurde.

Kotlin

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")

Java

Bundle paymentOptions = extras.getBundle("paymentOptions");
if (paymentOptions != null) {
    Boolean requestPayerName = paymentOptions.getBoolean("requestPayerName");
    Boolean requestPayerPhone = paymentOptions.getBoolean("requestPayerPhone");
    Boolean requestPayerEmail = paymentOptions.getBoolean("requestPayerEmail");
    Boolean requestShipping = paymentOptions.getBoolean("requestShipping");
    String shippingType = paymentOptions.getString("shippingType");
}

Es kann die folgenden Parameter enthalten:

  • requestPayerName: Der boolesche Wert, der angibt, ob der Name des Zahlungspflichtigen erforderlich ist.
  • requestPayerPhone: Der boolesche Wert, der angibt, ob die Telefonnummer des Zahlungspflichtigen erforderlich ist.
  • requestPayerEmail: Der boolesche Wert, der angibt, ob die E-Mail-Adresse des Zahlungspflichtigen erforderlich ist.
  • requestShipping: Der boolesche Wert, der angibt, ob Versandinformationen erforderlich sind.
  • shippingType: Der String, der den Versandtyp angibt. Der Versandtyp kann "shipping", "delivery" oder "pickup" sein. Ihre App kann diesen Hinweis in der Benutzeroberfläche verwenden, wenn sie nach der Adresse des Nutzers oder der Auswahl der Versandoptionen fragt.

shippingOptions

shippingOptions ist das Parcelable-Array der vom Händler angegebenen Versandoptionen. Dieser Parameter ist nur vorhanden, wenn paymentOptions.requestShipping == true.

Kotlin

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

Java

Parcelable[] shippingOptions = extras.getParcelableArray("shippingOptions");
for (Parcelable it : shippingOptions) {
  if (it != null && it instanceof Bundle) {
    Bundle shippingOption = (Bundle) it;
  }
}

Jede Versandoption ist ein Bundle mit den folgenden Schlüsseln.

  • id: Die ID der Versandoption.
  • label: Das Label der Versandoption, das dem Nutzer angezeigt wird.
  • amount: Das Versandkosten-Bundle mit den Schlüsseln currency und value mit String-Werten.
    • currency gibt die Währung für die Versandkosten als wohlgeformten dreistelligen alphabetischen ISO4217-Code an.
    • value zeigt den Wert der Versandkosten als gültigen Dezimalwert an.
  • selected: Gibt an, ob die Versandoption ausgewählt werden soll, wenn die Zahlungs-App die Versandoptionen anzeigt.

Alle Schlüssel außer selected haben String-Werte. selected hat einen booleschen Wert.

Kotlin

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)

Java

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

Erforderliche Informationen in einer Zahlungsantwort angeben

Ihre App sollte die erforderlichen zusätzlichen Informationen in ihrer Antwort auf die Aktivität PAY enthalten.

Dazu müssen die folgenden Parameter als Intent-Extras angegeben werden:

  • payerName: Der vollständige Name des Zahlungspflichtigen. Dies sollte ein nicht leerer String sein, wenn paymentOptions.requestPayerName „wahr“ ist.
  • payerPhone: Die Telefonnummer des Zahlungspflichtigen. Dies sollte ein nicht leerer String sein, wenn paymentOptions.requestPayerPhone „wahr“ ist.
  • payerEmail: Die E-Mail-Adresse des Zahlungspflichtigen. Dies sollte ein nicht leerer String sein, wenn paymentOptions.requestPayerEmail „true“ ist.
  • shippingAddress: Die vom Nutzer angegebene Versandadresse. Dies sollte ein nicht leeres Bundle sein, wenn paymentOptions.requestShipping „wahr“ ist. Das Bundle sollte die folgenden Schlüssel enthalten, die verschiedene Teile einer physischen Adresse darstellen.
    • countryCode
    • postalCode
    • sortingCode
    • region
    • city
    • dependentLocality
    • addressLine
    • organization
    • recipient
    • phone Alle Schlüssel außer addressLine haben String-Werte. addressLine ist ein Array von Strings.
  • shippingOptionId: Die Kennung der vom Nutzer ausgewählten Versandoption. Dies sollte ein nicht leerer String sein, wenn paymentOptions.requestShipping „wahr“ ist.

Zahlungsantwort validieren

Wenn das Aktivitätsergebnis einer Zahlungsantwort, die von der aufgerufenen Zahlungs-App empfangen wurde, auf RESULT_OK festgelegt ist, prüft Chrome die Extras auf erforderliche zusätzliche Informationen. Wenn die Validierung fehlschlägt, gibt Chrome ein abgelehntes Promise von request.show() mit einer der folgenden Fehlermeldungen für Entwickler zurück:

'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".'

Das folgende Codebeispiel zeigt eine gültige Antwort:

Kotlin

fun Intent.populateRequestedPaymentOptions() {
    if (requestPayerName) {
        putExtra("payerName", "John Smith")
    }
    if (requestPayerPhone) {
        putExtra("payerPhone", "5555555555")
    }
    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", "5555555555")
        putExtra("shippingAddress", address)
        putExtra("shippingOptionId", "standard")
    }
}

Java

private Intent populateRequestedPaymentOptions() {
    Intent result = new Intent();
    if (requestPayerName) {
        result.putExtra("payerName", "John Smith");
    }
    if (requestPayerPhone) {
        presult.utExtra("payerPhone", "5555555555");
    }
    if (requestPayerEmail) {
        result.putExtra("payerEmail", "john.smith@gmail.com");
    }
    if (requestShipping) {
        Bundle address = new Bundle();
        address.putExtra("countryCode", "CA");
        address.putExtra("postalCode", "M5H2G4");
        address.putExtra("region", "Ontario");
        address.putExtra("city", "Toronto");
        String[] addressLines = new String[] {"111 Richmond st. West"};
        address.putExtra("addressLines", addressLines);
        address.putExtra("recipient", "John Smith");
        address.putExtra("phone", "5555555555");
        result.putExtra("shippingAddress", address);
        result.putExtra("shippingOptionId", "standard");
    }
    return result;
}

Optional: Dynamischen Ablauf unterstützen

Manchmal steigen die Gesamtkosten einer Transaktion, z. B. wenn der Nutzer die Option für den Expressversand auswählt oder wenn sich die Liste der verfügbaren Versandoptionen oder deren Preise ändert, wenn der Nutzer eine internationale Versandadresse auswählt. Wenn Ihre App die vom Nutzer ausgewählte Versandadresse oder ‑option bereitstellt, sollte sie den Händler über Änderungen an der Versandadresse oder ‑option benachrichtigen und dem Nutzer die aktualisierten Zahlungsdetails (die vom Händler bereitgestellt werden) anzeigen können.

Wenn Sie den Händler über neue Änderungen benachrichtigen möchten, implementieren Sie die IPaymentDetailsUpdateServiceCallback-Schnittstelle und deklarieren Sie sie in Ihrem AndroidManifest.xml mit dem Intent-Filter UPDATE_PAYMENT_DETAILS.

Unmittelbar nach dem Aufrufen des PAY-Intents stellt Chrome eine Verbindung zum UPDATE_PAYMENT_DETAILS-Dienst (falls vorhanden) im selben Paket wie der PAY-Intent her und ruft setPaymentDetailsUpdateService(service) auf, um Ihrer Zahlungs-App den IPaymentDetailsUpdateService-Endpunkt zur Verfügung zu stellen, über den Änderungen an der Zahlungsmethode, Versandoption oder Versandadresse des Nutzers mitgeteilt werden.

Verwenden Sie packageManager.getPackagesForUid(Binder.getCallingUid()) beim Empfang der Inter-Process Communication (IPC), um zu prüfen, ob die App, die den PAY-Intent aufgerufen hat, denselben Paketnamen hat wie die App, die die IPaymentDetailsUpdateServiceCallback-Methoden aufgerufen hat.

AIDL

Erstellen Sie zwei AIDL-Dateien mit folgendem Inhalt:

org/chromium/components/payments/IPaymentDetailsUpdateServiceCallback.aidl

package org.chromium.components.payments;

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

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

    oneway void paymentDetailsNotUpdated();

    oneway void setPaymentDetailsUpdateService(IPaymentDetailsUpdateService service);
}

org/chromium/components/payments/IPaymentDetailsUpdateService.aidl

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

Dienst

Implementieren Sie den IPaymentDetailsUpdateServiceCallback-Dienst.

Kotlin

class SampleUpdatePaymentDetailsCallbackService : Service() {
    private val binder = object : IPaymentDetailsUpdateServiceCallback.Stub() {
        override fun updateWith(updatedPaymentDetails: Bundle) {}

        override fun paymentDetailsNotUpdated() {}

        override fun setPaymentDetailsUpdateService(service: IPaymentDetailsUpdateService) {}
    }

    override fun onBind(intent: Intent?): IBinder? {
        return binder
    }
}

Java

import org.chromium.components.paymsnts.IPaymentDetailsUpdateServiceCallback;

public class SampleUpdatePaymentDetailsCallbackService extends Service {
    private final IPaymentDetailsUpdateServiceCallback.Stub mBinder =
        new IPaymentDetailsUpdateServiceCallback.Stub() {
            @Override
            public void updateWith(Bundle updatedPaymentDetails) {}

            @Override
            public void paymentDetailsNotUpdated() {}

            @Override
            public void setPaymentDetailsUpdateService(IPaymentDetailsUpdateService service) {}
        };

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
}

AndroidManifest.xml

Machen Sie den Dienst für IPaymentDetailsUpdateServiceCallback in Ihrer AndroidManifest.xml verfügbar.

<service
    android:name=".SampleUpdatePaymentDetailsCallbackService"
    android:exported="true">
    <intent-filter>
        <action android:name="org.chromium.intent.action.UPDATE_PAYMENT_DETAILS" />
    </intent-filter>
</service>

Den Händler über Änderungen an der vom Nutzer ausgewählten Zahlungsmethode, Versandadresse oder Versandoption informieren

Kotlin

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
}

Java

if (service == null) {
  return;
}

try {
    if (isOptionChange) {
        service.changeShippingOption(selectedOptionId, callback);
    } else (isAddressChange) {
        service.changeShippingAddress(selectedAddress, callback);
    } else {
        service.changePaymentMethod(methodData, callback);
    }
} catch (RemoteException e) {
    // Handle the remote exception
}

changePaymentMethod

Benachrichtigt den Händler über Änderungen an der vom Nutzer ausgewählten Zahlungsmethode. Das paymentHandlerMethodData-Bundle enthält die Schlüssel methodName und optional details, die beide Stringwerte haben. Chrome prüft, ob das Bundle nicht leer ist und ob methodName nicht leer ist. Wenn die Validierung fehlschlägt, wird mit callback.updateWith eine updatePaymentDetails mit einer der folgenden Fehlermeldungen gesendet.

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

changeShippingOption

Benachrichtigt den Händler über Änderungen an der vom Nutzer ausgewählten Versandoption. shippingOptionId sollte die Kennung einer der vom Händler angegebenen Versandoptionen sein. Chrome prüft, ob shippingOptionId nicht leer ist, und sendet bei einem Validierungsfehler eine updatePaymentDetails mit der folgenden Fehlermeldung über callback.updateWith.

'Shipping option identifier required.'

changeShippingAddress

Benachrichtigt den Händler über Änderungen an der vom Nutzer angegebenen Versandadresse. Chrome prüft, ob ein nicht leeres shippingAddress-Bundle mit einem gültigen countryCode vorhanden ist, und sendet bei einem Validierungsfehler eine updatePaymentDetails mit der folgenden Fehlermeldung über callback.updateWith.

'Payment app returned invalid shipping address in response.'

Fehlermeldung „Ungültiger Status“

Wenn in Chrome beim Empfang einer der Änderungsanfragen ein ungültiger Status festgestellt wird, wird callback.updateWith mit einem gekürzten updatePaymentDetails-Bundle aufgerufen. Das Set enthält nur den error-Schlüssel mit "Invalid state". Beispiele für einen ungültigen Status:

  • Chrome wartet noch auf die Antwort des Händlers auf eine vorherige Änderung, z. B. auf ein laufendes Änderungsereignis.
  • Die vom Zahlungs-App-Anbieter bereitgestellte Kennung für die Versandoption gehört zu keiner der vom Händler angegebenen Versandoptionen.

Aktualisierte Zahlungsdetails vom Händler erhalten

Kotlin

override fun updateWith(updatedPaymentDetails: Bundle) {}

override fun paymentDetailsNotUpdated() {}

Java

@Override
public void updateWith(Bundle updatedPaymentDetails) {}

@Override
public void paymentDetailsNotUpdated() {}

updatedPaymentDetails ist das Bundle-Äquivalent zum PaymentRequestDetailsUpdate-Wörterbuch WebIDL und enthält die folgenden optionalen Schlüssel:

  • total: Ein Bundle mit den Schlüsseln currency und value. Beide Schlüssel haben String-Werte.
  • shippingOptions: Das Parcelable-Array der Versandoptionen
  • error: Ein String mit einer allgemeinen Fehlermeldung (z.B. wenn changeShippingOption keine gültige Kennung für eine Versandoption enthält)
  • stringifiedPaymentMethodErrors: Ein JSON-String, der Validierungsfehler für die Zahlungsmethode darstellt.
  • addressErrors: Ein Bundle mit optionalen Schlüsseln, die mit shipping address identisch sind, und Stringwerten. Jeder Schlüssel steht für einen Validierungsfehler, der sich auf den entsprechenden Teil der Versandadresse bezieht.
  • modifiers: Ein parcelable-Array von Bundles, die jeweils ein total- und ein methodData-Feld enthalten, die ebenfalls Bundles sind.

Wenn ein Schlüssel fehlt, bedeutet das, dass sich sein Wert nicht geändert hat.