Como atualizar seu app de pagamento Android para fornecer o endereço de entrega e os dados de contato do pagador com as APIs Web Payments.
Digitar endereço de entrega e informações de contato por meio de um formulário da Web pode ser uma uma experiência complicada para os clientes. Isso pode causar erros e reduzir conversões e a taxa de conversão.
É por isso que a API Payment Request é compatível com um recurso para solicitar frete endereço e dados de contato. Isso oferece vários benefícios:
- Os usuários podem escolher o endereço certo com apenas alguns toques.
- O endereço é sempre retornado na configuração padrão formato.
- É menos provável que envie um endereço incorreto.
Os navegadores podem adiar a coleta do endereço de entrega e dos dados de contato para um aplicativo de pagamento para proporcionar uma experiência de pagamento unificada. Essa funcionalidade chamado delegação.
Sempre que possível, o Chrome delega a coleta dos dados de envio de um cliente e os dados de contato para o app de pagamento para Android invocado. A a delegação reduz o atrito na finalização da compra.
O site do comerciante pode atualizar dinamicamente as opções de frete e o preço total. dependendo do endereço de entrega e do frete que o cliente é a melhor opção.
Para adicionar suporte à delegação a um app de pagamento já existente no Android, faça o seguinte: implemente as seguintes etapas:
- Declare as delegações compatíveis.
- Analisar os extras da intent
PAY
para o pagamento necessário de controle de acesso. - Forneça as informações necessárias no pagamento resposta.
- [Opcional] Suporte ao fluxo dinâmico:
Declarar delegações compatíveis
O navegador precisa saber a lista de informações adicionais que seu pagamento
que o app pode fornecer para delegar a coleta dessas informações à sua
app. Declare as delegações com suporte como um <meta-data>
no arquivo
AndroidManifest.xml (link em inglês).
<activity
android:name=".PaymentActivity"
…
<meta-data
android:name="org.chromium.payment_supported_delegations"
android:resource="@array/supported_delegations" />
</activity>
<resource>
precisa ser uma lista de strings escolhidas entre os seguintes valores válidos:
[ "payerName", "payerEmail", "payerPhone", "shippingAddress" ]
O exemplo a seguir fornece apenas um endereço de entrega e o e-mail do pagador endereço IP.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="supported_delegations">
<item>payerEmail</item>
<item>shippingAddress</item>
</string-array>
</resources>
Analisar os extras da intent PAY
para as opções de pagamento necessárias
O comerciante pode especificar informações adicionais necessárias usando o
paymentOptions
dicionário. O Chrome vai fornecer a lista de opções necessárias que o app pode
fornecem passando os seguintes parâmetros para a atividade PAY
como Intent
extras.
paymentOptions
paymentOptions
é o subconjunto de opções de pagamento especificadas pelo comerciante em que
o app declarou suporte à delegação.
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")
Ele pode incluir os seguintes parâmetros:
requestPayerName
: o booleano que indica se o nome do pagador é obrigatório.requestPayerPhone
: o booleano que indica se o smartphone do pagador é obrigatório.requestPayerEmail
: o booleano que indica se o e-mail do pagador é obrigatório.requestShipping
: o booleano que indica se as informações de frete são ou não é obrigatório.shippingType
: a string que mostra o tipo de frete. O tipo de frete pode ser"shipping"
,"delivery"
ou"pickup"
. Seu app pode usar essa dica IU ao solicitar o endereço do usuário ou a escolha das opções de envio.
shippingOptions
shippingOptions
é a matriz fracionável do frete especificado pelo comerciante.
. Esse parâmetro só existe quando paymentOptions.requestShipping ==
true
.
val shippingOptions: List<ShippingOption>? =
extras.getParcelableArray("shippingOptions")?.mapNotNull {
p -> from(p as Bundle)
}
Cada opção de envio é um Bundle
com as chaves a seguir.
id
: identificador da opção de envio.label
: o rótulo da opção de envio mostrado ao usuário.amount
: o pacote de custo de frete que contém as chavescurrency
evalue
com valores de string.currency
mostra a moeda do custo de frete, como uma ISO4217 bem formado Código do alfabeto de três letrasvalue
mostra o valor do custo de frete, como um valor monetário decimal válido valor
selected
: se a opção de envio deve ser selecionada ou não quando o o app de pagamento mostra as opções de envio.
Todas as chaves, exceto selected
, têm valores de string. selected
tem um booleano
.
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)
Fornecer as informações necessárias na resposta ao pagamento
Seu aplicativo deve incluir as informações adicionais necessárias em resposta a
a atividade PAY
.
Para fazer isso, os seguintes parâmetros precisam ser especificados como extras de intent:
payerName
: o nome completo do pagador. Precisa ser uma string que não esteja vazia quandopaymentOptions.requestPayerName
é verdadeiro.payerPhone
: número de telefone do pagador. Precisa ser uma string que não esteja vazia quandopaymentOptions.requestPayerPhone
é verdadeiro.payerEmail
: endereço de e-mail do pagador. Precisa ser uma string que não esteja vazia quandopaymentOptions.requestPayerEmail
for verdadeiro.shippingAddress
: o endereço de entrega fornecido pelo usuário. Ele deve ser pacote não vazio quandopaymentOptions.requestShipping
for verdadeiro. O pacote deve ter as seguintes chaves que representam diferentes partes de uma física endereço IP.city
countryCode
dependentLocality
organization
phone
postalCode
recipient
region
sortingCode
addressLine
Todas as chaves, excetoaddressLine
, têm valores de string. OaddressLine
é uma matriz de strings.
shippingOptionId
: o identificador da opção de envio selecionada pelo usuário. Isso precisa ser uma string não vazia quandopaymentOptions.requestShipping
for verdadeiro.
Validar resposta de pagamento
Se o resultado da atividade de uma resposta de pagamento recebida do pagamento invocado
app está definido como RESULT_OK
, o Chrome verificará se existem
nos extras. Se a validação falhar, o Chrome retornará uma mensagem
promessa de request.show()
com um dos seguintes erros voltados ao desenvolvedor
mensagens:
'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".'
O exemplo de código a seguir mostra uma resposta válida:
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")
}
}
Opcional: suporte ao fluxo dinâmico
Às vezes, o custo total de uma transação aumenta, como quando o usuário escolha a opção de frete expresso ou quando a lista de opções ou os preços mudam quando o usuário escolhe uma opção de envio endereço IP. Quando o app fornece o endereço ou a opção de entrega selecionada pelo usuário, precisa notificar o comerciante sobre qualquer endereço ou opção de entrega alterações e mostrar ao usuário os detalhes de pagamento atualizados (fornecidos pelo comerciante).
AIDL
Para notificar o comerciante sobre novas mudanças, use o PaymentDetailsUpdateService
declarado no AndroidManifest.xml do Chrome. Para usar esse serviço, crie dois
Arquivos AIDL com o seguinte conteúdo:
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);
}
Notificar o comerciante sobre mudanças na forma de pagamento, endereço de entrega ou opção de envio selecionada pelo usuário
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
}
}
}
O callingPackageName
usado para a intent de inicialização do serviço pode ter uma das
valores a seguir, dependendo do navegador que iniciou o pagamento
solicitação.
Canal do Chrome | Nome do pacote |
---|---|
Estável |
"com.android.chrome"
|
Beta |
"com.chrome.beta"
|
Dev |
"com.chrome.dev"
|
Canary |
"com.chrome.canary"
|
Chromium |
"org.chromium.chrome"
|
Caixa de pesquisa rápida do Google (um incorporador da WebLayer) |
"com.google.android.googlequicksearchbox"
|
changePaymentMethod
Notifica o comerciante sobre mudanças na forma de pagamento selecionada pelo usuário. A
O pacote paymentHandlerMethodData
contém methodName
e details
opcional
chaves com valores de string. O Chrome verificará se há um pacote que não esteja vazio com uma
methodName
não vazio e enviar um updatePaymentDetails
com um dos
mensagens de erro a seguir via callback.updateWith
se a validação falhar.
'Method data required.'
'Method name required.'
changeShippingOption
Notifica o comerciante sobre mudanças na opção de envio selecionada pelo usuário.
shippingOptionId
deve ser o identificador de um dos endereços especificados pelo comerciante
opções de envio. O Chrome vai verificar se há um shippingOptionId
não vazio e enviar
um updatePaymentDetails
com a seguinte mensagem de erro via
callback.updateWith
se a validação falhar.
'Shipping option identifier required.'
changeShippingAddress
Notifica o comerciante sobre mudanças no endereço de entrega fornecido pelo usuário. Google Chrome
vai procurar um pacote de shippingAddress
não vazio com um parâmetro countryCode
válido
e envie uma updatePaymentDetails
com a seguinte mensagem de erro via
callback.updateWith
se a validação falhar.
'Payment app returned invalid shipping address in response.'
Mensagem de erro de estado inválido
Se o Chrome encontrar um estado inválido ao receber qualquer uma das solicitações de mudança
ele vai chamar callback.updateWith
com uma updatePaymentDetails
encoberta;
feixe. O pacote conterá apenas a chave error
com "Invalid state"
.
Exemplos de um estado inválido:
- Quando o Chrome ainda está aguardando a resposta do comerciante a uma alteração anterior (como um evento de alteração contínua).
- O identificador da opção de envio fornecido pelo aplicativo de pagamento não pertence a nenhum as opções de envio especificadas pelo comerciante.
Receber detalhes de pagamento atualizados do comerciante
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
é o pacote equivalente ao
PaymentRequestDetailsUpdate
dicionário WebIDL (depois de encobrir o
modifiers
) e contém as seguintes chaves opcionais:
total
: um pacote contendo as chavescurrency
evalue
, ambas as chaves têm valores de stringshippingOptions
: a matriz fracionável de frete opçõeserror
: uma string que contém uma mensagem de erro genérica (por exemplo, quandochangeShippingOption
não fornece um identificador de opção de envio válido)stringifiedPaymentMethodErrors
: uma string JSON que representa a validação erros na forma de pagamentoaddressErrors
: um pacote com chaves opcionais idênticas a shipping [frete] address e string e a distribuição dos valores dos dados. Cada chave representa um erro de validação relacionado ao parte do endereço de entrega.
Uma chave ausente significa que o valor não foi alterado.