Android ödeme uygulamanızı Web Ödemeleri ile çalışacak şekilde nasıl uyarlayacağınızı ve müşterilere daha iyi bir kullanıcı deneyimi nasıl sunacağınızı öğrenin.
Payment Request API, web, kullanıcıların gereken ödeme tutarını girmelerine olanak tanıyan yerleşik bir tarayıcı tabanlı arayüzdür. hiç olmadığı kadar kolay hale geldi. API, platforma özel ödeme yöntemini de çağırabilir.
Web Ödemeleri, yalnızca Android Intent'leri kullanmaya kıyasla daha iyi entegrasyon sağlar tarayıcı, güvenlik ve kullanıcı deneyimi ile:
- Ödeme uygulaması, satıcının web sitesi bağlamında kalıcı olarak kullanıma sunulur.
- Bu uygulama, mevcut ödeme uygulamanıza ek olarak gelir elde etmenizi sağlar. yararlanabilmeniz için çok iyi bir fırsattır.
- Bu sorunu önlemek için ödeme uygulamasının imzası kontrol edilir. başka cihazdan yükleme.
- Ödeme uygulamaları birden fazla ödeme yöntemini destekleyebilir.
- Kripto para ve banka havalesi gibi tüm ödeme yöntemleri entegre edilmiştir. Android cihazlardaki ödeme uygulamaları cihazdaki donanım çipine erişmesi gerekir.
Bir Android ödeme uygulamasında Web Ödemeleri'ni uygulamak için dört adım gerekir:
- Satıcıların ödeme uygulamanızı keşfetmesine izin verin.
- Müşterinin kayıtlı bir aracını (ör. kredi) satıcıya bildirin kartı) ödeme yapabilirsiniz.
- Müşterinin ödeme yapmasına izin verin.
- Arayanın imza sertifikasını doğrulayın.
Web Ödemelerinin işleyiş şeklini görmek için şu sayfaya göz atın: android-web-payment demomuz var.
1. Adım: Satıcıların ödeme uygulamanızı keşfetmesine izin verin
Bir satıcının ödeme uygulamanızı kullanabilmesi için Ödeme Request API ve ödeme yöntemini kullanarak desteklediğiniz ödeme yöntemini belirtin tanımlayıcı'yı kullanabilirsiniz.
Ödeme uygulamanıza özgü bir ödeme yöntemi tanımlayıcınız varsa kendi ödeme yönteminizi ayarlayabilirsiniz manifesto'yu indirin. uygulamanızı keşfedin.
2. Adım: Müşterinin ödeme yapmaya hazır bir kayıtlı aracının olup olmadığını satıcıya bildirin
Satıcı, müşterinin müşterininhasEnrolledInstrument()
ödeme yapabiliyor olması gerekir. Şunları yapabilirsiniz:
Bu sorguyu yanıtlamak için IS_READY_TO_PAY
uygulamasını Android hizmeti olarak uygulayın.
AndroidManifest.xml
Hizmetinizi intent filtresiyle bildirin
org.chromium.intent.action.IS_READY_TO_PAY
<service
android:name=".SampleIsReadyToPayService"
android:exported="true">
<intent-filter>
<action android:name="org.chromium.intent.action.IS_READY_TO_PAY" />
</intent-filter>
</service>
IS_READY_TO_PAY
hizmeti isteğe bağlıdır. Android'de böyle bir intent işleyici yoksa
ödeme uygulaması söz konusu olduğunda, web tarayıcısı uygulamanın her zaman
ödeme.
AIDL
IS_READY_TO_PAY
hizmetinin API'si AIDL'de tanımlanmıştır. İki AIDL oluşturun
şu içeriğe sahip dosyaları:
app/src/main/aidl/org/chromium/IsReadyToPayServiceCallback.aidl
package org.chromium;
interface IsReadyToPayServiceCallback {
oneway void handleIsReadyToPay(boolean isReadyToPay);
}
app/src/main/aidl/org/chromium/IsReadyToPayService.aidl
package org.chromium;
import org.chromium.IsReadyToPayServiceCallback;
interface IsReadyToPayService {
oneway void isReadyToPay(IsReadyToPayServiceCallback callback);
}
IsReadyToPayService
kullanımı
IsReadyToPayService
etiketinin en basit uygulaması aşağıda gösterilmiştir
örnek:
class SampleIsReadyToPayService : Service() {
private val binder = object : IsReadyToPayService.Stub() {
override fun isReadyToPay(callback: IsReadyToPayServiceCallback?) {
callback?.handleIsReadyToPay(true)
}
}
override fun onBind(intent: Intent?): IBinder? {
return binder
}
}
Yanıt
Hizmet, yanıtını handleIsReadyToPay(Boolean)
yöntemiyle gönderebilir.
callback?.handleIsReadyToPay(true)
İzin
Arayanın kim olduğunu kontrol etmek için Binder.getCallingUid()
hizmetini kullanabilirsiniz. Lütfen
bunu onBind
yönteminde değil, isReadyToPay
yönteminde yapmanız gerekir.
override fun isReadyToPay(callback: IsReadyToPayServiceCallback?) {
try {
val callingPackage = packageManager.getNameForUid(Binder.getCallingUid())
// …
Nasıl yapıldığını öğrenmek için Arayanın imzalama sertifikasını doğrulama başlıklı makaleye göz atın. .
3. Adım: Müşterinin ödeme yapmasına izin verin
Satıcı, ödemeyi başlatmak için show()
adlı satıcıyı arar
uygulama
Böylece müşterinin ödeme yapmasını sağlayabilirsiniz. Ödeme uygulaması Android üzerinden çağrılır
intent parametrelerinde işlem bilgileriyle PAY
.
Ödeme uygulaması, ödeme uygulaması olan methodName
ve details
ile yanıt veriyor.
ve tarayıcı için opak olmalıdır. Tarayıcı, details
öğesini dönüştürür
dizeyi, JSON seri dışı hale getirme aracılığıyla satıcı için bir JavaScript nesnesine yazar, ancak
bunun dışında herhangi bir geçerliliği yoktur. Tarayıcı,
details
; bu parametrenin değeri doğrudan satıcıya aktarılır.
AndroidManifest.xml
PAY
intent filtresine sahip etkinlikte, <meta-data>
birincil ödeme yöntemi tanımlayıcısını
uygulamasını indirin.
Birden fazla ödeme yöntemini desteklemek için<meta-data>
<string-array>
kaynak.
<activity
android:name=".PaymentActivity"
android:theme="@style/Theme.SamplePay.Dialog">
<intent-filter>
<action android:name="org.chromium.intent.action.PAY" />
</intent-filter>
<meta-data
android:name="org.chromium.default_payment_method_name"
android:value="https://bobbucks.dev/pay" />
<meta-data
android:name="org.chromium.payment_method_names"
android:resource="@array/method_names" />
</activity>
resource
, her biri geçerli bir dize olmak üzere dizelerin listesi olmalıdır.
Burada gösterildiği gibi bir HTTPS şemasına sahip mutlak URL'niz olmalıdır.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="method_names">
<item>https://alicepay.com/put/optional/path/here</item>
<item>https://charliepay.com/put/optional/path/here</item>
</string-array>
</resources>
Parametreler
Aşağıdaki parametreler etkinliğe Intent ekstraları olarak aktarılır:
methodNames
methodData
topLevelOrigin
topLevelCertificateChain
paymentRequestOrigin
total
modifiers
paymentRequestId
val extras: Bundle? = intent?.extras
methodNames
Kullanılan yöntemlerin adları. Öğeler,
methodData
sözlüğü. Bunlar, ödeme uygulamasının desteklediği yöntemlerdir.
val methodNames: List<String>? = extras.getStringArrayList("methodNames")
methodData
Her bir methodNames
öğesinden,
methodData
val methodData: Bundle? = extras.getBundle("methodData")
merchantName
Satıcının ödeme sayfasındaki <title>
HTML etiketinin içeriği
tarayıcının üst düzey göz atma bağlamı).
val merchantName: String? = extras.getString("merchantName")
topLevelOrigin
Satıcının şema içermeyen kökeni (
göz atma bağlamı). Örneğin, https://mystore.com/checkout
mystore.com
olarak geçti.
val topLevelOrigin: String? = extras.getString("topLevelOrigin")
topLevelCertificateChain
Satıcının sertifika zinciri (Üst düzey sertifika zincirinin sertifika zinciri)
göz atma bağlamı). Güvenli olan localhost ve diskteki dosya için null
bağlamları SSL sertifikasız. Her Parcelable
bir Pakettir:
certificate
anahtarı ve bir bayt dizisi değeri.
val topLevelCertificateChain: Array<Parcelable>? =
extras.getParcelableArray("topLevelCertificateChain")
val list: List<ByteArray>? = topLevelCertificateChain?.mapNotNull { p ->
(p as Bundle).getByteArray("certificate")
}
paymentRequestOrigin
JavaScript'te new
PaymentRequest(methodData, details, options)
oluşturucuyu çağıran iframe göz atma bağlamının şemasız kaynağı. Öğe
oluşturucu üst düzey bağlamdan çağrılmıştır; ardından bu çağrının değeri
parametresi, topLevelOrigin
parametresinin değerine eşit.
val paymentRequestOrigin: String? = extras.getString("paymentRequestOrigin")
total
İşlemin toplam tutarını temsil eden JSON dizesi.
val total: String? = extras.getString("total")
Aşağıda, dizenin örnek bir içeriği belirtilmiştir:
{"currency":"USD","value":"25.00"}
modifiers
details.modifiers
olan JSON.stringify(details.modifiers)
çıkışı
yalnızca supportedMethods
ve total
içerir.
paymentRequestId
"push-payment" işlemi yapılan PaymentRequest.id
alanı şununla ilişkilendirilmesi gerekir:
işlem durumu. Satıcı web siteleri,
"push-payment" uygulamaların bant dışı durumunu kontrol edin.
val paymentRequestId: String? = extras.getString("paymentRequestId")
Yanıt
Etkinlik, RESULT_OK
üzerinden setResult
üzerinden yanıtını geri gönderebilir.
setResult(Activity.RESULT_OK, Intent().apply {
putExtra("methodName", "https://bobbucks.dev/pay")
putExtra("details", "{\"token\": \"put-some-data-here\"}")
})
finish()
Intent ekstraları olarak iki parametre belirtmeniz gerekir:
methodName
: Kullanılan yöntemin adı.details
: Satıcının şunları yapması için gerekli bilgileri içeren JSON dizesi: tamamlanması gerekir. Başarıtrue
isedetails
olmalıdır öylesine yapılandırılmıştır kiJSON.parse(details)
başarılı olacaktır.
İşlemRESULT_CANCELED
ödeme uygulaması (örneğin, kullanıcı e-posta adresi için doğru PIN kodunu
ödeme uygulamasında kullanabilir. Tarayıcı, kullanıcının
başka bir ödeme uygulaması.
setResult(RESULT_CANCELED)
finish()
Çağrılan ödemeden alınan bir ödeme yanıtının etkinlik sonucu
uygulama RESULT_OK
olarak ayarlanırsa Chrome, boş olmayan methodName
ve
Ekstra özellikleri details
. Doğrulama başarısız olursa Chrome reddedilen bir uyarı döndürür.
aşağıdaki geliştiriciden kaynaklanan hatadan biriyle ilgili söz (request.show()
)
mesajlar:
'Payment app returned invalid response. Missing field "details".'
'Payment app returned invalid response. Missing field "methodName".'
İzin
Etkinlik, arayanı getCallingPackage()
yöntemiyle kontrol edebilir.
val caller: String? = callingPackage
Son adım, arayanın imza sertifikasını doğrulamak için arayanın imza sertifikasının doğru imzaya sahip olduğundan emin olun.
4. Adım: Arayanın imza sertifikasını doğrulayın
Arayanın paket adını Binder.getCallingUid()
ile kontrol edebilirsiniz:
IS_READY_TO_PAY
ve Activity.getCallingPackage()
ile PAY
içinde. Bu amaçla
arayanın aklınızdaki tarayıcı olduğunu doğruladığınızda,
imzalama sertifikasını kontrol edin ve sertifikanın doğru sertifikayla eşleştiğinden emin olun
değer.
API düzeyi 28 ve üstünü hedefliyorsanız ve bir tarayıcıyla entegrasyon yapıyorsanız
varsa tek bir imzalama sertifikası varsa
PackageManager.hasSigningCertificate()
val packageName: String = … // The caller's package name
val certificate: ByteArray = … // The correct signing certificate.
val verified = packageManager.hasSigningCertificate(
callingPackage,
certificate,
PackageManager.CERT_INPUT_SHA256
)
Tek sertifika için PackageManager.hasSigningCertificate()
tercih edilir
çünkü sertifika rotasyonunu doğru şekilde işler. (Chrome'un bir
tek imzalı sertifika.) Birden fazla imzalama sertifikası olan uygulamalar
döndürebilirsiniz.
27 ve önceki eski API düzeylerini desteklemeniz gerekiyorsa veya
birden fazla imzalama sertifikası bulunan tarayıcılarda
PackageManager.GET_SIGNATURES
val packageName: String = … // The caller's package name
val certificates: Set<ByteArray> = … // The correct set of signing certificates
val packageInfo = getPackageInfo(packageName, PackageManager.GET_SIGNATURES)
val sha256 = MessageDigest.getInstance("SHA-256")
val signatures = packageInfo.signatures.map { sha256.digest(it.toByteArray()) }
val verified = signatures.size == certificates.size &&
signatures.all { s -> certificates.any { it.contentEquals(s) } }