bu Ödeme Talebi API’sı web’e, kullanıcıların gerekli ödeme bilgilerini her zamankinden daha kolay girmelerini sağlayan yerleşik bir tarayıcı tabanlı arayüz getiriyor. API, platforma özel ödeme uygulamalarını da çalıştırabilir.
- Chrome 60, Desteklenir 60
- Firefox 55, Bir bayrağın arkasında
- Kenar 15, Desteklenen 15
- Safari 11.1, Desteklenir 11.1
Yalnızca Android Amaçlarını kullanmakla karşılaştırıldığında, Web Ödemeleri tarayıcı, güvenlik ve kullanıcı deneyimi ile daha iyi entegrasyon sağlar:
- Ödeme uygulaması, satıcı web sitesi bağlamında bir model olarak başlatılır.
- Uygulama, mevcut ödeme uygulamanızı tamamlar ve kullanıcı tabanınızdan yararlanmanıza olanak tanır.
- Önlemek için ödeme uygulamasının imzası kontrol edilir. Yan yükleme.
- Ödeme uygulamaları birden fazla ödeme yöntemini destekleyebilir.
- Kripto para birimi, banka havaleleri ve daha fazlası gibi herhangi bir ödeme yöntemi entegre edilebilir. Android cihazlardaki ödeme uygulamaları, cihazdaki donanım çipine erişim gerektiren yöntemleri bile entegre edebilir.
Bir Android ödeme uygulamasında Web Payments’ı uygulamak için dört adım gerekir:
- Satıcıların ödeme uygulamanızı keşfetmesine izin verin.
- Müşterinin ödemeye hazır kayıtlı bir enstrümanı (kredi kartı gibi) olup olmadığını satıcıya bildirin.
- Bir müşterinin ödeme yapmasına izin verin.
- Arayanın imza sertifikasını doğrulayın.
Web Payments’ı çalışırken görmek için şuraya göz atın: android-web-ödeme gösteri.
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 Talebi API’sı kullanarak desteklediğiniz ödeme yöntemini belirtin. ödeme yöntemi tanımlayıcısı.
Ödeme uygulamanıza özel bir ödeme yöntemi tanımlayıcınız varsa kendi kimliğinizi oluşturabilirsiniz. ödeme yöntemi bildirimi böylece tarayıcılar uygulamanızı keşfedebilir.
2. Adım: Müşterinin ödemeye hazır kayıtlı bir aracı olup olmadığını satıcıya bildirin #
tüccar arayabilir hasEnrolledInstrument()
Müşterinin ödeme yapıp yapamayacağını sorgulamak için. uygulayabilirsiniz IS_READY_TO_PAY
Bu sorguyu yanıtlamak için bir Android hizmeti olarak.
AndroidManifest.xml
#
Eylem ile bir niyet filtresi ile hizmetinizi 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>
bu IS_READY_TO_PAY
servis isteğe bağlıdır. Ödeme uygulamasında böyle bir niyet işleyici yoksa web tarayıcısı, uygulamanın her zaman ödeme yapabileceğini varsayar.
AIDL #
için API IS_READY_TO_PAY
hizmet AIDL’de tanımlanmıştır. Aşağıdaki içeriğe sahip iki AIDL dosyası oluşturun:
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);
}
uygulama IsReadyToPayService
#
En basit uygulama IsReadyToPayService
aşağıdaki örnekte gösterilmiştir:
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
}
}
Cevap #
Hizmet, yanıtını şu yolla gönderebilir: handleIsReadyToPay(Boolean)
yöntem.
callback?.handleIsReadyToPay(true)
İzin #
Kullanabilirsiniz Binder.getCallingUid()
Arayanın kim olduğunu kontrol etmek için. Bunu yapmanız gerektiğini unutmayın. isReadyToPay
yöntemde değil, onBind
yöntem.
override fun isReadyToPay(callback: IsReadyToPayServiceCallback?) {
try {
val callingPackage = packageManager.getNameForUid(Binder.getCallingUid())
// …
Görmek Arayanın imza sertifikasını doğrulayın çağıran paketin doğru imzaya sahip olduğunun nasıl doğrulanacağı hakkında.
3. Adım: Bir müşterinin ödeme yapmasına izin verin #
Tüccar arar show()
Müşterinin ödeme yapabilmesi için ödeme uygulamasını başlatmak. Ödeme uygulaması, bir Android amacı aracılığıyla çağrılır PAY
niyet parametrelerinde işlem bilgileri ile.
Ödeme uygulaması şununla yanıt verir: methodName
Ve details
, ödeme uygulamasına özeldir ve tarayıcı için opaktır. tarayıcı dönüştürür details
dizesini JSON serisini kaldırma yoluyla satıcı için bir JavaScript nesnesine dönüştürür, ancak bunun ötesinde herhangi bir geçerliliği zorlamaz. Tarayıcı değiştirmez details
; bu parametrenin değeri doğrudan satıcıya iletilir.
AndroidManifest.xml
#
ile aktivite PAY
niyet filtresinin bir <meta-data>
uygulama için varsayılan ödeme yöntemi tanımlayıcısını tanımlayan etiket.
Birden çok ödeme yöntemini desteklemek için bir <meta-data>
ile etiketle <string-array>
kaynak.
activity
android:name=".PaymentActivity"
android:theme="FrancyStyle/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>
bu resource
her biri burada gösterildiği gibi bir HTTPS şemasına sahip geçerli, mutlak bir URL 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, aktiviteye Intent ekstraları olarak iletilir:
methodNames
methodData
topLevelOrigin
topLevelCertificateChain
paymentRequestOrigin
total
modifiers
paymentRequestId
val extras: Bundle? = intent?.extras
yöntem İsimleri #
Kullanılan yöntemlerin adları. Öğeler, içindeki anahtarlardır. methodData
sözlük. Bunlar, ödeme uygulamasının desteklediği yöntemlerdir.
val methodNames: ListString>? = extras.getStringArrayList("methodNames")
methodData
#
Her birinden bir eşleme methodNames
için methodData
.
val methodData: Bundle? = extras.getBundle("methodData")
Tüccar Adı #
içindekiler <title>
Satıcının ödeme sayfasının HTML etiketi (tarayıcının en üst düzey tarama bağlamı).
val merchantName: String? = extras.getString("merchantName")
topLevelOrigin
#
Şema olmadan tüccarın menşei (Üst düzey göz atma bağlamının şemasız menşei). Örneğin, olarak geçilir
mystore.com
.
val topLevelOrigin: String? = extras.getString("topLevelOrigin")
topLevelCertificateChain
#
Satıcının sertifika zinciri (Üst düzey göz atma bağlamının sertifika zinciri). Her ikisi de SSL sertifikaları olmayan güvenli bağlamlar olan localhost ve file on disk için null. Her biri Parcelable
içeren bir Pakettir certificate
anahtar ve bir bayt dizi değeri.
val topLevelCertificateChain: ArrayParcelable>? =
extras.getParcelableArray("topLevelCertificateChain")
val list: ListByteArray>? = topLevelCertificateChain?.mapNotNull { p ->
(p as Bundle).getByteArray("certificate")
}
paymentRequestOrigin
#
başlatan iframe tarama bağlamının şemasız kaynağı new PaymentRequest(methodData, details, options)
JavaScript’te yapıcı. Yapıcı üst düzey bağlamdan çağrıldıysa, bu parametrenin değeri şu değere eşittir: topLevelOrigin
parametre.
val paymentRequestOrigin: String? = extras.getString("paymentRequestOrigin")
total
#
İşlemin toplam tutarını temsil eden JSON dizesi.
val total: String? = extras.getString("total")
İşte dizenin bir örnek içeriği:
{"currency":"USD","value":"25.00"}
modifiers
#
çıktısı JSON.stringify(details.modifiers)
Neresi details.modifiers
sadece içerir supportedMethods
Ve total
.
paymentRequestId
#
bu PaymentRequest.id
“anında ödeme” uygulamalarının işlem durumuyla ilişkilendirmesi gereken alan. Satıcı web siteleri, bant dışı işlemin durumu için “anında ödeme” uygulamalarını sorgulamak için bu alanı kullanır.
val paymentRequestId: String? = extras.getString("paymentRequestId")
Cevap #
Etkinlik, yanıtını şu şekilde geri gönderebilir: setResult
ile RESULT_OK
.
setResult(Activity.RESULT_OK, Intent().apply {
putExtra("methodName", ")
putExtra("details", "{\"token\": \"put-some-data-here\"}")
})
finish()
Intent ekstraları olarak iki parametre belirtmelisiniz:
methodName
: Kullanılan yöntemin adı.details
: Satıcının işlemi tamamlaması için gerekli bilgileri içeren JSON dizesi. başarı isetrue
Daha sonradetails
şekilde inşa edilmelidir.JSON.parse(details)
başaracak
Geçebilirsin RESULT_CANCELED
örneğin ödeme uygulamasında işlem tamamlanmadıysa, örneğin kullanıcı ödeme uygulamasında hesabı için doğru PIN kodunu girmediyse. Tarayıcı, kullanıcının farklı bir ödeme uygulaması seçmesine izin verebilir.
setResult(RESULT_CANCELED)
finish()
Çağrılan ödeme uygulamasından alınan bir ödeme yanıtının etkinlik sonucu şu şekilde ayarlanmışsa: RESULT_OK
ardından Chrome boş olup olmadığını kontrol edecek methodName
Ve details
ekstralarında. Doğrulama başarısız olursa Chrome, reddedilen bir söz döndürür. request.show()
aşağıdaki geliştiricilerden biri hata mesajlarıyla karşılaşıyor:
'Payment app returned invalid response. Missing field "details".'
'Payment app returned invalid response. Missing field "methodName".'
İzin #
Etkinlik, arayan kişiyi kontrol edebilir. getCallingPackage()
yöntem.
val caller: String? = callingPackage
Son adım, arayan paketin doğru imzaya sahip olduğunu doğrulamak için arayanın imzalama sertifikasını doğrulamaktır.
4. Adım: Arayanın imza sertifikasını doğrulayın #
Arayanın paket adını şununla kontrol edebilirsiniz: Binder.getCallingUid()
içinde IS_READY_TO_PAY
Ve birlikte Activity.getCallingPackage()
içinde PAY
. Arayanın aklınızdaki tarayıcı olduğunu gerçekten doğrulamak için imzalama sertifikasını kontrol etmeli ve doğru değerle eşleştiğinden emin olmalısınız.
API düzeyi 28 ve üzerini hedefliyorsanız ve tek imzalama sertifikasına sahip bir tarayıcıyla entegrasyon gerçekleştiriyorsanız, 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
)
PackageManager.hasSigningCertificate()
sertifika rotasyonunu doğru bir şekilde işlediği için tek sertifika tarayıcıları için tercih edilir. (Chrome’un tek bir imzalama sertifikası vardır.) Birden çok imzalama sertifikasına sahip uygulamalar bunları döndüremez.
27 ve altındaki eski API düzeylerini desteklemeniz gerekiyorsa veya birden çok imzalama sertifikasına sahip tarayıcıları kullanmanız gerekiyorsa, şunu kullanabilirsiniz: PackageManager.GET_SIGNATURES
.
val packageName: String = … // The caller's package name
val certificates: SetByteArray> = … // The correct set of signing certificatesval 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) } }