Android ödeme uygulamasından gönderim ve iletişim bilgileri sağlama

Web Payments API'leriyle gönderim adresini ve ödeyen iletişim bilgilerini sağlamak için Android ödeme uygulamanızı güncelleme.

Sahel Sharify
Sahel Sharify

Bir web formu aracılığıyla gönderim adresi ve iletişim bilgilerini girmek külfetli bir deneyim haline geldi. Hatalara ve dönüşümün azalmasına neden olabilir oranıdır.

Bu nedenle Payment Request API, kargo isteğinde bulunma özelliğini destekler. ve iletişim bilgilerinizi girin. Bunun birden çok avantajı vardır:

Tarayıcılar, gönderim adresinin ve iletişim bilgilerinin toplanmasını birleştirilmiş bir ödeme deneyimi sunan bir ödeme uygulamasıdır. Bu işlev delegasyon olarak adlandırılır.

Mümkün olduğunda Chrome, müşterinin kargolarının teslim alınması için yetki verir çağrılan Android ödeme uygulamasına adres ve iletişim bilgileri gönderilir. İlgili içeriği oluşturmak için kullanılan ödeme sırasında karşılaşılan zorlukları azaltır.

Satıcı web sitesi, kargo seçeneklerini ve toplam fiyatı dinamik olarak güncelleyebilir. Müşterinin gönderim adresi seçimine ve seçeneğini belirleyin.

Geçerli gönderim seçeneği ve gönderim adresi değişikliği. Bu durumun kargo seçeneklerini ve toplam fiyatı nasıl etkilediğini dinamik olarak görün.
ziyaret edin.
'nı inceleyin.

Mevcut bir Android ödeme uygulamasına yetki desteği eklemek için: şu adımları uygulayın:

  1. Desteklenen yetkileri beyan edin.
  2. Gerekli ödeme için PAY intent ekstralarını ayrıştırın seçenekleri bulabilirsiniz.
  3. Ödeme sırasında gerekli bilgileri sağlama yanıt ekleyin.
  4. [İsteğe bağlı] Dinamik akışı destekleyin:
    1. Kullanıcının seçtiği ödeme yöntemindeki değişiklikler hakkında satıcıya bilgi verme, kargo adresi veya kargo seçeneği sunulur.
    2. Satıcıdan güncel ödeme ayrıntılarını alın (örneğin, toplam tutar, belirlenen gönderim seçeneğinin maliyeti).

Desteklenen yetkileri bildirme

Tarayıcının, ödemeniz gereken ek bilgilerin listesini bilmesi gerekir. bu uygulamanın, bu bilgileri toplama yetkisini başka bir uygulama tarafından uygulamasını indirin. Desteklenen yetkileri uygulamanızda <meta-data> olarak beyan edin AndroidManifest.xml dosyası.

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

<resource>, aşağıdaki geçerli değerlerden seçilen dizelerden oluşan bir liste olmalıdır:

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

Aşağıdaki örnekte yalnızca bir gönderim adresi ve ödemeyi yapanın e-posta adresi yer alabilir girin.

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

Gerekli ödeme seçenekleri için PAY intent ekstralarını ayrıştır

Satıcı, paymentOptions sözlüğünüzden yararlanırsınız. Chrome, uygulamanızın indirebileceği gerekli seçeneklerin listesini sağlar aşağıdaki parametreleri PAY etkinliğine Intent olarak ileterek sağlayın. ekstralar.

paymentOptions

paymentOptions, satıcı tarafından belirtilen ödeme seçeneklerinin alt kümesidir. uygulamanız yetki desteği beyan etti.

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

Aşağıdaki parametreleri içerebilir:

  • requestPayerName - Ödeyen adının olup olmadığını gösteren boole gereklidir.
  • requestPayerPhone: Ödeyenin telefonunun olup olmadığını gösteren boole gereklidir.
  • requestPayerEmail: Ödeyenin e-posta adresinin olup olmadığını gösteren boole gereklidir.
  • requestShipping: Gönderim bilgilerinin olup olmadığını gösteren boole gereklidir.
  • shippingType: Kargo türünü gösteren dize. Gönderim türü: "shipping", "delivery" veya "pickup". Uygulamanız bu ipucunu Kullanıcının adresini veya kargo seçenekleri seçimini isteyen kullanıcı arayüzü.

shippingOptions

shippingOptions, satıcı tarafından belirtilen kargo bilgilerinin ayrıştırılabilir dizisidir seçenekleri vardır. Bu parametre yalnızca paymentOptions.requestShipping == true olduğunda mevcut olur.

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

Her gönderim seçeneği, aşağıdaki anahtarlara sahip bir Bundle şeklindedir.

  • id: Gönderim seçeneği tanımlayıcısı.
  • label: Kullanıcıya gösterilen gönderim seçeneği etiketi.
  • amount - Şunları içeren currency ve value anahtarlarını içeren kargo maliyeti paketi: dize değerleri.
  • selected - Kargo seçeneğinin belirlenmesi için kargo seçeneklerini gösteren bir ödeme uygulaması görürsünüz.

selected dışındaki tüm anahtarların dize değerleri var. selected bir boole değeri içeriyor değer.

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)

Ödeme yanıtında gerekli bilgileri sağlama

Uygulamanız, şuna yanıt verirken gerekli ek bilgileri içermelidir: PAY etkinliği.

Bunun için aşağıdaki parametreler Intent ekstraları olarak belirtilmelidir:

  • payerName - Ödemeyi yapan kişinin tam adı. Bu, aşağıdaki durumlarda boş olmayan bir dize olmalıdır: paymentOptions.requestPayerName doğru.
  • payerPhone - Ödemeyi yapan kullanıcının telefon numarası. Bu, aşağıdaki durumlarda boş olmayan bir dize olmalıdır: paymentOptions.requestPayerPhone doğru.
  • payerEmail - Ödeyenin e-posta adresi. Bu, boş olmayan bir dize olmalıdır paymentOptions.requestPayerEmail doğru olduğunda.
  • shippingAddress: Kullanıcı tarafından sağlanan gönderim adresi. Bu, paymentOptions.requestShipping doğru olduğunda boş olmayan paket gösterilir. Paket fiziksel bir çalışmada farklı bölümleri temsil eden aşağıdaki anahtarlara sahip olmalıdır: girin.
    • city
    • countryCode
    • dependentLocality
    • organization
    • phone
    • postalCode
    • recipient
    • region
    • sortingCode
    • addressLine. addressLine dışındaki tüm anahtarların dize değerleri var. addressLine bir dize dizisidir.
  • shippingOptionId - Kullanıcı tarafından seçilen gönderim seçeneğinin tanımlayıcısı. Bu paymentOptions.requestShipping doğru olduğunda boş olmayan bir dize olmalıdır.

Ödeme yanıtını doğrula

Çağrılan ödemeden alınan bir ödeme yanıtının etkinlik sonucu uygulama RESULT_OK olarak ayarlanırsa Chrome, bilgileri de kapsayabilir. Doğrulama başarısız olursa Chrome reddedilen bir uyarı döndürür. request.show() tarafından geliştiriciye yönelik aşağıdaki hatalardan birini içeren bir vaat mesajlar:

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

Aşağıdaki kod örneği geçerli bir yanıt örneğidir:

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

İsteğe bağlı: Dinamik akışı destekleme

Bazen bir işlemin toplam maliyeti artar. Örneğin, kullanıcı Kullanıcı ekspres kargo seçeneğini belirlediğinde veya Kullanıcı uluslararası bir kargo seçtiğinde seçeneklerin veya fiyatlarının değişmesi girin. Uygulamanızda kullanıcı tarafından seçilen kargo adresi veya seçeneği sunulduğunda satıcıya herhangi bir gönderim adresi veya seçeneği ile ilgili bilgi ve kullanıcıya güncellenen ödeme ayrıntılarını ( satıcı).

AIDL

Satıcıyı yeni değişiklikler hakkında bilgilendirmek için PaymentDetailsUpdateService özelliğini kullanın . Bu hizmeti kullanmak için iki hesap oluşturun Aşağıdaki içeriğe sahip AIDL dosyaları:

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

Kullanıcının seçtiği ödeme yöntemi, gönderim adresi veya gönderim seçeneğinde yapılan değişiklikler hakkında satıcıya bilgi verme

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

Hizmetin başlangıç amacı için kullanılan callingPackageName şunlardan birine sahip olabilir: ödemeyi başlatan tarayıcıya bağlı olarak aşağıdaki değerler gösterilir isteğinde bulunabilirsiniz.

Chrome Kanalı Paket Adı
Kararlı "com.android.chrome"
Beta "com.chrome.beta"
Dev "com.chrome.dev"
Canary "com.chrome.canary"
Chromium "org.chromium.chrome"
Google Hızlı Arama Kutusu (bir WebKatman yerleştirme aracı) "com.google.android.googlequicksearchbox"

changePaymentMethod

Satıcıyı, kullanıcı tarafından seçilen ödeme yöntemindeki değişiklikler hakkında bilgilendirir. İlgili içeriği oluşturmak için kullanılan paymentHandlerMethodData paketi, methodName ve isteğe bağlı details içeriyor anahtarların her ikisi de dize değerleriyle gösterilir. Chrome, boş olmayan bir paket olup olmadığını kontrol eder boş olmayan methodName veupdatePaymentDetails doğrulama başarısız olursa callback.updateWith aracılığıyla aşağıdaki hata mesajları gösterilir.

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

changeShippingOption

Satıcıyı, kullanıcı tarafından belirlenen gönderim seçeneğindeki değişiklikler hakkında bilgilendirir. shippingOptionId, satıcı tarafından belirtilen satıcılardan birinin tanımlayıcısı olmalıdır kargo seçeneklerini de belirleyebilirsiniz. Chrome, boş olmayan bir shippingOptionId olup olmadığını kontrol eder ve updatePaymentDetails üzerinden şu hata mesajını içeren bir updatePaymentDetails Doğrulama başarısız olursa callback.updateWith.

'Shipping option identifier required.'

changeShippingAddress

Satıcıyı, kullanıcı tarafından sağlanan gönderim adresindeki değişiklikler hakkında bilgilendirir. Krom boş olmayan, geçerli bir countryCode içeren shippingAddress paketi olup olmadığını kontrol eder ve şu hata mesajını içeren bir updatePaymentDetails gönderin: Doğrulama başarısız olursa callback.updateWith.

'Payment app returned invalid shipping address in response.'

Geçersiz durum hata mesajı

Chrome, değişiklik isteklerinden herhangi birini aldıktan sonra geçersiz bir durumla karşılaşırsa çıkartılmış updatePaymentDetails ile callback.updateWith çağıracak paket. Paket yalnızca "Invalid state" içeren error anahtarını içerecek. Geçersiz durum örnekleri şunlardır:

  • Chrome, satıcının önceki bir değişiklikle ilgili yanıtını beklerken (örneğin, sürekli bir değişim olayı).
  • Ödeme uygulaması tarafından sağlanan gönderim seçeneği tanımlayıcısı, Satıcı tarafından belirtilen gönderim seçenekleri.

Satıcıdan güncel ödeme ayrıntılarını alma

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, PaymentRequestDetailsUpdate WebIDL sözlüğü ( modifiers alanına) ve şu isteğe bağlı anahtarları içerir:

Anahtarın eksik olması, değerinin değişmediği anlamına gelir.