Fournir des coordonnées et des informations de livraison depuis une application de paiement Android

Mettre à jour votre application de paiement Android afin d'indiquer l'adresse de livraison et les coordonnées du payeur avec les API de paiement Web

Sahel Sharify
Sahel Sharify

La saisie d'une adresse de livraison et de coordonnées via un formulaire Web peut être une expérience utilisateur fastidieuse. Cela peut provoquer des erreurs et réduire le nombre de conversions taux de conversion.

C'est pourquoi l'API Payment Request accepte une fonctionnalité de demande d'expédition. votre adresse postale et vos coordonnées. Cela offre plusieurs avantages:

  • Les utilisateurs peuvent sélectionner la bonne adresse en quelques gestes.
  • L'adresse est toujours renvoyée au format standardisé de sortie.
  • Il est moins probable que l'adresse indiquée soit incorrecte.

Les navigateurs peuvent reporter la collecte de l'adresse de livraison et des coordonnées à une application de paiement pour offrir une expérience de paiement unifiée. Cette fonctionnalité est appelée délégation.

Dans la mesure du possible, Chrome délègue la collecte des données d'expédition du client. votre adresse e-mail et vos coordonnées à l'application de paiement Android invoquée. La la délégation facilite le processus de paiement.

Le site Web du marchand peut mettre à jour de façon dynamique les options de livraison et le prix total en fonction de l'adresse de livraison choisie par le client et de l'adresse de livraison .

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">.
Modification de l'option de livraison et de l'adresse de livraison. Découvrez son impact sur les options de livraison et le prix total de façon dynamique.

Pour ajouter la fonctionnalité de délégation à une application de paiement Android existante, procédez comme suit : procédez comme suit:

  1. Déclarez les délégations compatibles.
  2. Analyser les extras d'intent PAY pour le paiement requis options.
  3. Fournir les informations requises lors du paiement réponse.
  4. [Facultatif] Compatibilité avec le flux dynamique: <ph type="x-smartling-placeholder">
      </ph>
    1. Informer le marchand des modifications apportées au mode de paiement sélectionné par l'utilisateur l'adresse de livraison l'option.
    2. Recevez des informations de paiement mises à jour de la part du marchand (par exemple, montant total ajusté en fonction de l'option de livraison (coût total).

Déclarer les délégations compatibles

Le navigateur a besoin de connaître la liste des informations supplémentaires que votre paiement l'application peut fournir afin de déléguer la collecte de ces informations à votre l'application. Déclarez les délégations compatibles en tant que <meta-data> dans le fichier AndroidManifest.xml.

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

<resource> doit être une liste de chaînes choisies parmi les valeurs valides suivantes:

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

L'exemple suivant ne peut indiquer qu'une adresse de livraison et l'adresse e-mail du payeur adresse e-mail.

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

Analyser les extras d'intent PAY pour les options de paiement requises

Le marchand peut spécifier les informations supplémentaires requises à l'aide des paymentOptions dictionnaire. Chrome vous fournira la liste des options requises pour votre application en transmettant les paramètres suivants à l'activité PAY en tant qu'intent extras.

paymentOptions

paymentOptions est le sous-ensemble d'options de paiement spécifiées par le marchand pour lesquelles votre application a déclaré la prise en charge de la délégation.

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

Il peut inclure les paramètres suivants:

  • requestPayerName : valeur booléenne indiquant si le nom du payeur est obligatoire.
  • requestPayerPhone : valeur booléenne indiquant si le numéro de téléphone du payeur est obligatoire.
  • requestPayerEmail : valeur booléenne indiquant si l'adresse e-mail du payeur est obligatoire.
  • requestShipping : booléen indiquant si des informations de livraison sont fournies ou non est obligatoire.
  • shippingType : chaîne indiquant le type de livraison. Le type de livraison peut être "shipping", "delivery" ou "pickup". Votre application peut utiliser cet indice dans son UI demandant l'adresse de l'utilisateur ou le choix d'options de livraison

shippingOptions

shippingOptions correspond au tableau des informations de livraison spécifiées par le marchand. options. Ce paramètre n'existe que lorsque paymentOptions.requestShipping == true.

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

Chaque option de livraison est un Bundle avec les clés suivantes.

  • id : identifiant de l'option de livraison.
  • label : étiquette de l'option de livraison présentée à l'utilisateur.
  • amount : lot de frais de port contenant currency et value clés avec des valeurs de chaîne.
    • currency indique la devise des frais de port sous forme de Format ISO4217 correctement formé Code alphabétique à trois lettres
    • value indique la valeur des frais de port sous forme de nombre décimal valide. valeur
  • selected : indique si l'option de livraison doit être sélectionnée lorsque l'attribut de paiement affiche les options de livraison.

Toutes les clés autres que selected ont des valeurs de chaîne. selected comporte une valeur booléenne .

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)

Fournir les informations requises dans une réponse au paiement

Votre application doit inclure les informations supplémentaires requises dans sa réponse à l'activité PAY.

Pour ce faire, les paramètres suivants doivent être spécifiés en tant qu'extras d'intent:

  • payerName : nom complet du payeur. Cette chaîne ne doit pas être vide lorsque paymentOptions.requestPayerName est vrai.
  • payerPhone : numéro de téléphone du payeur. Cette chaîne ne doit pas être vide lorsque paymentOptions.requestPayerPhone est vrai.
  • payerEmail : adresse e-mail du payeur. Cette chaîne ne doit pas être vide Lorsque paymentOptions.requestPayerEmail est vrai.
  • shippingAddress : adresse de livraison fournie par l'utilisateur. Il doit s'agir groupe non vide lorsque paymentOptions.requestShipping est défini sur "true". L'offre groupée doivent disposer des clés suivantes, qui représentent différentes parties d'une adresse.
    • city
    • countryCode
    • dependentLocality
    • organization
    • phone
    • postalCode
    • recipient
    • region
    • sortingCode
    • addressLine Toutes les clés autres que addressLine ont des valeurs de chaîne. addressLine est un tableau de chaînes.
  • shippingOptionId : identifiant de l'option de livraison sélectionnée par l'utilisateur. Ce doit être une chaîne non vide lorsque paymentOptions.requestShipping a la valeur "true".

Valider la réponse au paiement

Si le résultat d'activité d'une réponse de paiement reçue du paiement invoqué l'application est définie sur RESULT_OK, Chrome recherche les paramètres les informations dans leurs extras. Si la validation échoue, Chrome renvoie une erreur promesse de request.show() avec l'une des erreurs suivantes signalées par les développeurs messages:

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

L'exemple de code suivant est un exemple de réponse valide:

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

Facultatif: prendre en charge le flux dynamique

Parfois, le coût total d'une transaction augmente, par exemple lorsque l'utilisateur choisit l'option de livraison express, ou lorsque la liste des options de livraison ou leurs prix changent lorsque l'utilisateur choisit une livraison internationale. adresse e-mail. Lorsque votre application fournit l'adresse ou l'option de livraison sélectionnée par l'utilisateur, doit pouvoir indiquer au marchand toute adresse ou option de livraison et présentent à l'utilisateur les détails du mode de paiement mis à jour (fournis par le marchand).

AIDL

Pour informer le marchand des nouvelles modifications, utilisez l'PaymentDetailsUpdateService déclaré dans le fichier AndroidManifest.xml de Chrome. Pour utiliser ce service, créez deux AIDL avec le contenu suivant:

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

Informer le marchand des modifications apportées au mode de paiement, à l'adresse de livraison ou à l'option de livraison sélectionnés par l'utilisateur

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

Le callingPackageName utilisé pour l'intent de démarrage du service peut avoir l'un des Les valeurs suivantes varient en fonction du navigateur à l'origine du paiement requête.

Version de Chrome Nom du package
Stable "com.android.chrome"
Bêta "com.chrome.beta"
Dév "com.chrome.dev"
Canary "com.chrome.canary"
Chrome "org.chromium.chrome"
Champ de recherche rapide Google (intégrateur WebLayer) "com.google.android.googlequicksearchbox"

changePaymentMethod

Informe le marchand des modifications apportées au mode de paiement sélectionné par l'utilisateur. La Le pack paymentHandlerMethodData contient methodName et un details facultatif les deux avec des valeurs de chaîne. Chrome recherchera un bundle non vide avec un methodName non vide et envoyer un updatePaymentDetails avec l'une des les messages d'erreur suivants via callback.updateWith si la validation échoue.

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

changeShippingOption

Informe le marchand des modifications apportées à l'option de livraison sélectionnée par l'utilisateur. shippingOptionId doit correspondre à l'identifiant de l'un des types options de livraison. Chrome recherchera un shippingOptionId non vide et enverra une updatePaymentDetails avec le message d'erreur suivant via callback.updateWith si la validation échoue.

'Shipping option identifier required.'

changeShippingAddress

Informe le marchand des modifications apportées à l'adresse de livraison fournie par l'utilisateur. Chrome recherche un bundle shippingAddress non vide avec un countryCode valide et envoyez une updatePaymentDetails avec le message d'erreur suivant via callback.updateWith si la validation échoue.

'Payment app returned invalid shipping address in response.'

Message d'erreur indiquant un état non valide

Si Chrome rencontre un état non valide à la réception de l'une des demandes de modification Elle appellera callback.updateWith avec un updatePaymentDetails masqué d'un bundle. Le bundle ne contiendra que la clé error avec "Invalid state". Exemples d'états non valides:

  • Lorsque Chrome attend toujours la réponse du marchand à une modification précédente (par exemple, un événement de modification en cours).
  • L'identifiant de l'option de livraison fourni par l'application de paiement n'appartient à aucune des les options de livraison spécifiées par le marchand.

Recevoir des informations de paiement mises à jour de la part du marchand

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 est le bundle équivalent à PaymentRequestDetailsUpdate Dictionnaire WebIDL (après avoir masqué la section modifiers) et contient les clés facultatives suivantes:

  • total : un bundle contenant currency et value clés. Les deux clés ont valeurs de chaîne
  • shippingOptions : tableau parcelable de shipping d'assistance
  • error : chaîne contenant un message d'erreur générique (par exemple, quand changeShippingOption ne fournit pas d'identifiant d'option de livraison valide)
  • stringifiedPaymentMethodErrors : chaîne JSON représentant la validation Erreurs liées au mode de paiement
  • addressErrors : un lot avec des clés facultatives identiques à la livraison adresse et la chaîne valeurs. Chaque clé représente une erreur de validation liée à de l'adresse de livraison.

Une clé absente signifie que sa valeur n'a pas changé.