Web Payments API'leriyle gönderim adresini ve ödeme yapan kişinin iletişim bilgilerini sağlamak için Android ödeme uygulamanızı güncelleme.
Gönderim adresini ve iletişim bilgilerini bir web formu aracılığıyla girmek müşteriler için zahmetli bir deneyim olabilir. Bu durum hatalara ve dönüşüm oranının düşmesine neden olabilir.
Bu nedenle Payment Request API, kargo adresi ve iletişim bilgilerini isteme özelliğini destekler. Bunun birden çok avantajı vardır:
- Kullanıcılar yalnızca birkaç dokunuşla doğru adresi seçebilir.
- Adres her zaman standartlaştırılmış biçimde döndürülür.
- Yanlış adres gönderme olasılığı daha düşüktür.
Tarayıcılar, birleşik bir ödeme deneyimi sunmak için gönderim adresi ve iletişim bilgilerinin toplanmasını bir ödeme uygulamasına erteleyebilir. Bu işleve yetki verme adı verilir.
Chrome, mümkün olduğunda müşterinin gönderim adresi ve iletişim bilgilerinin toplanmasını çağrılan Android ödeme uygulamasına devreder. Bu yetkilendirme, ödeme sırasındaki zorlukları azaltır.
Satıcı web sitesi, müşterinin gönderim adresi ve gönderim seçeneğine bağlı olarak gönderim seçeneklerini ve toplam fiyatı dinamik olarak güncelleyebilir.
Mevcut bir Android ödeme uygulamasına yetkilendirme desteği eklemek için aşağıdaki adımları uygulayın:
- Desteklenen yetkilendirmeleri beyan edin.
- Zorunlu ödeme seçenekleri için
PAY
intent ekstralarını ayrıştırın. - Ödeme yanıtında gerekli bilgileri sağlayın.
- [İsteğe bağlı] Dinamik akışı destekleyin:
Desteklenen yetkilendirmeleri bildirme
Tarayıcının, ödeme uygulamanızın sağlayabileceği ek bilgilerin listesini bilmesi gerekir. Böylece, bu bilgilerin toplanması için uygulamanıza yetki
verilebilir. Uygulamanızın AndroidManifest.xml dosyasında, desteklenen yetkileri <meta-data>
olarak beyan edin.
<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 bir dize listesi olmalıdır:
[ "payerName", "payerEmail", "payerPhone", "shippingAddress" ]
Aşağıdaki örnekte yalnızca gönderim adresi ve ödeme yapan kullanıcının e-posta adresi sağlanabilir.
<?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ü kullanarak gerekli ek bilgileri belirtebilir. Chrome, aşağıdaki parametreleri PAY
etkinliğine Amaç ekstraları olarak ileterek uygulamanızın sağlayabileceği gerekli seçeneklerin listesini sağlar.
paymentOptions
paymentOptions
, uygulamanızın yetkilendirme desteğini beyan ettiği, satıcı tarafından belirtilen ödeme seçeneklerinin alt kümesidir.
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
: Ödemeyi yapan kişinin adının gerekli olup olmadığını belirten boole değeri.requestPayerPhone
: Ödeyenin telefonunun gerekli olup olmadığını belirten boole değeri.requestPayerEmail
: Ödeyenin e-posta adresinin gerekli olup olmadığını belirten boole değeri.requestShipping
: Kargo bilgilerinin gerekli olup olmadığını gösteren boole değeri.shippingType
: Gönderim türünü gösteren dize. Gönderim türü"shipping"
,"delivery"
veya"pickup"
olabilir. Uygulamanız, kullanıcının adresini veya kargo seçeneklerini sorarken kullanıcı arayüzünde bu ipucunu kullanabilir.
shippingOptions
shippingOptions
, satıcı tarafından belirtilen kargo seçeneklerinin paketlenebilir dizisidir. 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
öğesidir.
id
: Gönderim seçeneği tanımlayıcısı.label
: Kullanıcıya gösterilen gönderim seçeneği etiketi.amount
- Dize değerlerine sahipcurrency
vevalue
anahtarlarını içeren kargo maliyeti paketi.currency
, gönderim maliyetinin para birimini ISO4217'ye uygun, doğru biçimlendirilmiş 3 harfli alfabetik kod olarak gösterir.value
, kargo maliyetinin değerini geçerli bir ondalık parasal değer olarak gösterir
selected
: Ödeme uygulaması kargo seçeneklerini gösterdiğinde kargo seçeneğinin seçilip seçilmeyeceği.
selected
dışındaki tüm anahtarların dize değerleri vardır. selected
, bir boole değerine sahip.
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, PAY
etkinliğine verdiği yanıtta gerekli ek bilgileri içermelidir.
Bunun için aşağıdaki parametreler Intent ekstraları olarak belirtilmelidir:
payerName
: Ödemeyi yapanın tam adı.paymentOptions.requestPayerName
doğru olduğunda bu, boş olmayan bir dize olmalıdır.payerPhone
: Ödeyenin telefon numarası.paymentOptions.requestPayerPhone
doğru olduğunda bu, boş olmayan bir dize olmalıdır.payerEmail
: Ödeyenin e-posta adresi.paymentOptions.requestPayerEmail
doğru olduğunda bu, boş olmayan bir dize olmalıdır.shippingAddress
: Kullanıcı tarafından sağlanan gönderim adresi.paymentOptions.requestShipping
doğru olduğunda bu, boş olmayan bir paket olmalıdır. Pakette, fiziksel adresteki farklı bölümleri temsil eden aşağıdaki anahtarlar bulunmalıdır.city
countryCode
dependentLocality
organization
phone
postalCode
recipient
region
sortingCode
addressLine
addressLine
dışındaki tüm anahtarların dize değerleri vardır.addressLine
, bir dizi dizedir.
shippingOptionId
- Kullanıcı tarafından seçilen gönderim seçeneğinin tanımlayıcısı.paymentOptions.requestShipping
doğru olduğunda bu dize boş olmamalıdır.
Ödeme yanıtını doğrulama
Çağrılan ödeme uygulamasından alınan bir ödeme yanıtının etkinlik sonucu RESULT_OK
olarak ayarlanırsa Chrome, ekstralarında gerekli ek bilgileri kontrol eder. Doğrulama başarısız olursa Chrome, request.show()
kaynağından reddedilmiş bir söz döndürür ve geliştiricilere yönelik aşağıdaki hata mesajlarından birini gösterir:
'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ı hızlı kargo seçeneğini tercih ettiğinde veya uluslararası bir kargo adresi seçtiğinde mevcut kargo seçeneklerinin listesi ya da fiyatları değişebilir. Uygulamanız, kullanıcı tarafından seçilen gönderim adresini veya seçeneğini sağladığında satıcıyı gönderim adresi ya da seçenek değişiklikleri hakkında bilgilendirebilmeli ve kullanıcıya güncellenmiş ödeme ayrıntılarını (satıcı tarafından sağlanır) gösterebilmelidir.
AIDL
Satıcıyı yeni değişiklikler hakkında bilgilendirmek için Chrome'un AndroidManifest.xml dosyasında bildirilen PaymentDetailsUpdateService
hizmetini kullanın. Bu hizmeti kullanmak için aşağıdaki içeriğe sahip iki AIDL dosyası oluşturun:
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 kargo seçeneğindeki değişiklikler hakkında satıcıyı bilgilendirme
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
, ödeme isteğini başlatan tarayıcıya bağlı olarak aşağıdaki değerlerden birine sahip olabilir.
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 (WebLayer yerleştirici) |
"com.google.android.googlequicksearchbox"
|
changePaymentMethod
Satıcıyı, kullanıcı tarafından seçilen ödeme yöntemindeki değişiklikler hakkında bilgilendirir. paymentHandlerMethodData
paketi, hem dize değerlerine sahip methodName
hem de isteğe bağlı details
anahtarları içerir. Chrome, boş olmayan bir methodName
içeren boş olmayan bir paket olup olmadığını kontrol eder ve doğrulama başarısız olursa callback.updateWith
üzerinden aşağıdaki hata mesajlarından birini içeren bir updatePaymentDetails
gönderir.
'Method data required.'
'Method name required.'
changeShippingOption
Satıcıyı, kullanıcı tarafından seçilen gönderim seçeneğinde yapılan değişiklikler hakkında bilgilendirir.
shippingOptionId
, satıcı tarafından belirtilen gönderim seçeneklerinden birinin tanımlayıcısıdır. Doğrulama başarısız olursa Chrome, boş olmayan bir shippingOptionId
olup olmadığını kontrol edecek ve callback.updateWith
aracılığıyla updatePaymentDetails
aracılığıyla aşağıdaki hata mesajını gönderecektir.
'Shipping option identifier required.'
changeShippingAddress
Satıcıyı, kullanıcı tarafından sağlanan gönderim adresindeki değişiklikler hakkında bilgilendirir. Chrome, geçerli bir countryCode
içeren boş olmayan bir shippingAddress
paketi olup olmadığını kontrol eder ve doğrulama başarısız olursa callback.updateWith
üzerinden aşağıdaki hata mesajını içeren bir updatePaymentDetails
gönderir.
'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 callback.updateWith
uygulamasını, çıkartılmış bir updatePaymentDetails
paketiyle çağırır. Pakette yalnızca "Invalid state"
ile error
anahtarı bulunur.
Geçersiz durum örnekleri:
- Chrome, satıcının önceki bir değişikliğe (ör. devam eden bir değişiklik etkinliği) karşı yanıtını beklerken hâlâ bekleme aşamasındadır.
- Ödeme uygulaması tarafından sağlanan gönderim seçeneği tanımlayıcısı, satıcı tarafından belirtilen gönderim seçeneklerinden hiçbirine ait değil.
Satıcıdan güncellenmiş ö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üğüne eşdeğer olan pakettir (modifiers
alanının çıkartılmasından sonra) ve aşağıdaki isteğe bağlı anahtarları içerir:
total
:currency
vevalue
anahtarlarını içeren bir paket. Her iki anahtarın da dize değerleri vardır.shippingOptions
- Paketlenebilir gönderim seçenekleri dizisierror
: Genel bir hata mesajı içeren bir dize (ör.changeShippingOption
geçerli bir gönderim seçeneği tanımlayıcısı sağlamadığında)stringifiedPaymentMethodErrors
: Ödeme yöntemiyle ilgili doğrulama hatalarını temsil eden bir JSON dizesiaddressErrors
: Gönderim adresi ve dize değerleriyle aynı olan isteğe bağlı anahtarları içeren bir paket. Her anahtar, gönderim adresinin karşılık gelen kısmıyla ilgili bir doğrulama hatasını temsil eder.
Anahtar yoksa değeri değişmemiştir.