نحوه بهروزرسانی برنامه پرداخت Android خود برای ارائه آدرس حمل و اطلاعات تماس پرداختکننده با Web Payments.
وارد کردن آدرس حمل و نقل و اطلاعات تماس از طریق یک فرم وب می تواند یک تجربه دست و پا گیر برای مشتریان باشد. می تواند باعث خطا و کاهش نرخ تبدیل شود.
به همین دلیل است که API درخواست پرداخت از ویژگی درخواست آدرس ارسال و اطلاعات تماس پشتیبانی می کند. این مزایای متعددی را به همراه دارد:
- کاربران می توانند آدرس مناسب را تنها با چند ضربه انتخاب کنند.
- آدرس همیشه در قالب استاندارد بازگردانده می شود.
- ارسال آدرس نادرست احتمال کمتری دارد.
مرورگرها میتوانند جمعآوری آدرس ارسال و اطلاعات تماس را به یک برنامه پرداخت موکول کنند تا تجربه پرداخت یکپارچه را ارائه دهند. این قابلیت تفویض اختیار نامیده می شود.
هر زمان که ممکن باشد، Chrome جمع آوری آدرس ارسال و اطلاعات تماس مشتری را به برنامه پرداخت Android فراخوانی شده واگذار می کند. هیئت نمایندگی اصطکاک را در هنگام پرداخت کاهش می دهد.
وب سایت بازرگان می تواند بسته به انتخاب مشتری از آدرس حمل و نقل و گزینه حمل، گزینه های حمل و نقل و قیمت کل را به صورت پویا به روز کند.
برای افزودن پشتیبانی نمایندگی به یک برنامه پرداخت Android موجود، مراحل زیر را اجرا کنید:
- هیئت های حمایت شده را اعلام کنید .
- موارد اضافی قصد
PAY
را برای گزینه های پرداخت مورد نیاز تجزیه و تحلیل کنید . - در پاسخ به پرداخت اطلاعات مورد نیاز را ارائه دهید .
- [اختیاری] پشتیبانی از جریان پویا :
هیئت های حمایت شده را اعلام کنید
مرورگر باید لیستی از اطلاعات اضافی را که برنامه پرداخت شما می تواند ارائه دهد بداند تا بتواند مجموعه آن اطلاعات را به برنامه شما واگذار کند. نمایندگی های پشتیبانی شده را در برنامه AndroidManifest.xml به عنوان <meta-data>
اعلام کنید.
<activity
android:name=".PaymentActivity"
…
<meta-data
android:name="org.chromium.payment_supported_delegations"
android:resource="@array/supported_delegations" />
</activity>
<resource>
باید لیستی از رشته ها باشد که از مقادیر معتبر زیر انتخاب شده اند:
[ "payerName", "payerEmail", "payerPhone", "shippingAddress" ]
مثال زیر فقط می تواند آدرس حمل و نقل و آدرس ایمیل پرداخت کننده را ارائه دهد.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="supported_delegations">
<item>payerEmail</item>
<item>shippingAddress</item>
</string-array>
</resources>
موارد اضافی قصد PAY
را برای گزینه های پرداخت مورد نیاز تجزیه و تحلیل کنید
تاجر می تواند اطلاعات مورد نیاز اضافی را با استفاده از فرهنگ لغت paymentOptions
مشخص کند. Chrome فهرستی از گزینههای مورد نیازی را که برنامه شما میتواند ارائه دهد، با ارسال پارامترهای زیر به فعالیت PAY
به عنوان موارد اضافی Intent ارائه میکند.
paymentOptions
paymentOptions
زیرمجموعهای از گزینههای پرداخت مشخصشده توسط فروشنده است که برنامه شما از آنها پشتیبانی نمایندگی را اعلام کرده است.
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")
می تواند شامل پارامترهای زیر باشد:
-
requestPayerName
- بولی که نشان می دهد نام پرداخت کننده مورد نیاز است یا خیر. -
requestPayerPhone
- بولین نشان می دهد که آیا تلفن پرداخت کننده مورد نیاز است یا خیر. -
requestPayerEmail
- بولی که نشان می دهد ایمیل پرداخت کننده مورد نیاز است یا خیر. -
requestShipping
- بولی که نشان می دهد اطلاعات حمل و نقل مورد نیاز است یا خیر. -
shippingType
- رشته ای که نوع حمل و نقل را نشان می دهد. نوع حمل و نقل می تواند"shipping"
،"delivery"
یا"pickup"
باشد. برنامه شما میتواند از این راهنمایی در رابط کاربری خود هنگام درخواست آدرس کاربر یا انتخاب گزینههای ارسال استفاده کند.
shippingOptions
shippingOptions
مجموعه ای از گزینه های حمل و نقل مشخص شده توسط فروشنده است. این پارامتر فقط زمانی وجود خواهد داشت که paymentOptions.requestShipping == true
.
val shippingOptions: List<ShippingOption>? =
extras.getParcelableArray("shippingOptions")?.mapNotNull {
p -> from(p as Bundle)
}
هر گزینه حمل و نقل یک Bundle
با کلیدهای زیر است.
-
id
- شناسه گزینه حمل و نقل. -
label
- برچسب گزینه حمل و نقل که به کاربر نشان داده می شود. -
amount
- بسته هزینه حمل و نقل حاوی کلیدهایcurrency
وvalue
با مقادیر رشته ای.-
currency
واحد پول هزینه حمل و نقل را به عنوان یک کد الفبای 3 حرفی ISO4217 نشان می دهد. -
value
ارزش هزینه حمل و نقل را به عنوان یک ارزش پولی اعشاری معتبر نشان می دهد
-
-
selected
- وقتی برنامه پرداخت گزینه های حمل و نقل را نمایش می دهد، گزینه ارسال باید انتخاب شود یا خیر.
همه کلیدهای غیر از selected
دارای مقادیر رشته هستند. selected
دارای یک مقدار بولی است.
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)
اطلاعات مورد نیاز را در پاسخ پرداخت ارائه دهید
برنامه شما باید اطلاعات اضافی مورد نیاز را در پاسخ به فعالیت PAY
درج کند.
برای انجام این کار، پارامترهای زیر باید به عنوان Intent اضافی مشخص شوند:
-
payerName
- نام کامل پرداخت کننده. وقتیpaymentOptions.requestPayerName
درست است، این باید یک رشته غیر خالی باشد. -
payerPhone
- شماره تلفن پرداخت کننده. وقتیpaymentOptions.requestPayerPhone
درست است، این باید یک رشته غیر خالی باشد. -
payerEmail
- آدرس ایمیل پرداخت کننده. زمانی کهpaymentOptions.requestPayerEmail
درست است، باید یک رشته غیر خالی باشد. -
shippingAddress
- آدرس حمل و نقل ارائه شده توسط کاربر. وقتیpaymentOptions.requestShipping
درست است، این باید یک بسته غیر خالی باشد. بسته نرم افزاری باید دارای کلیدهای زیر باشد که بخش های مختلف یک آدرس فیزیکی را نشان می دهد.-
city
-
countryCode
-
dependentLocality
-
organization
-
phone
-
postalCode
-
recipient
-
region
-
sortingCode
-
addressLine
همه کلیدها به غیر ازaddressLine
دارای مقادیر رشته هستند.addressLine
آرایه ای از رشته ها است.
-
-
shippingOptionId
- شناسه گزینه حمل و نقل انتخاب شده توسط کاربر. زمانی کهpaymentOptions.requestShipping
درست است، باید یک رشته غیر خالی باشد.
تایید پاسخ پرداخت
اگر نتیجه فعالیت یک پاسخ پرداخت دریافتی از برنامه پرداخت فراخوانی شده روی RESULT_OK
تنظیم شود، Chrome اطلاعات اضافی مورد نیاز را در موارد اضافی آن بررسی میکند. اگر اعتبارسنجی ناموفق باشد، Chrome یک وعده رد شده از request.show()
را با یکی از پیامهای خطای زیر برمیگرداند:
'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".'
نمونه کد زیر نمونه ای از پاسخ معتبر است:
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")
}
}
اختیاری: پشتیبانی از جریان پویا
گاهی اوقات هزینه کل یک تراکنش افزایش می یابد، مانند زمانی که کاربر گزینه حمل و نقل سریع را انتخاب می کند، یا زمانی که کاربر یک آدرس حمل و نقل بین المللی را انتخاب می کند، لیست گزینه های حمل و نقل موجود یا قیمت آنها تغییر می کند. وقتی برنامه شما آدرس یا گزینه ارسال انتخابی توسط کاربر را ارائه میکند، باید بتواند تاجر را در مورد هر گونه آدرس حمل و نقل یا تغییر گزینه مطلع کند و جزئیات پرداخت بهروز شده (ارائه شده توسط تاجر) را به کاربر نشان دهد.
ایدل
برای اطلاع دادن به تاجر در مورد تغییرات جدید، از سرویس PaymentDetailsUpdateService
اعلام شده در AndroidManifest.xml Chrome استفاده کنید. برای استفاده از این سرویس دو فایل AIDL با محتوای زیر ایجاد کنید:
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);
}
در مورد تغییرات در روش پرداخت انتخابی کاربر، آدرس حمل و نقل یا گزینه ارسال، به تاجر اطلاع دهید
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
}
}
}
callingPackageName
که برای هدف شروع سرویس استفاده میشود، بسته به مرورگری که درخواست پرداخت را آغاز کرده است، میتواند یکی از مقادیر زیر را داشته باشد.
کانال کروم | نام بسته |
---|---|
پایدار | "com.android.chrome" |
بتا | "com.chrome.beta" |
توسعه دهنده | "com.chrome.dev" |
قناری | "com.chrome.canary" |
کروم | "org.chromium.chrome" |
جعبه جستجوی سریع Google (یک جاسازی لایه Web) | "com.google.android.googlequicksearchbox" |
changePaymentMethod
تغییرات در روش پرداخت انتخابی کاربر را به تاجر اطلاع می دهد. بسته paymentHandlerMethodData
حاوی methodName
و کلیدهای اختیاری details
هر دو با مقادیر رشته است. Chrome یک بسته غیر خالی را با methodName
غیر خالی بررسی میکند و در صورتی که اعتبارسنجی ناموفق باشد updatePaymentDetails
با یکی از پیامهای خطای زیر از طریق callback.updateWith
ارسال میکند.
'Method data required.'
'Method name required.'
changeShippingOption
به تاجر در مورد تغییرات در گزینه حمل و نقل انتخاب شده توسط کاربر اطلاع می دهد. shippingOptionId
باید شناسه یکی از گزینه های حمل و نقل مشخص شده توسط فروشنده باشد. Chrome یک shippingOptionId
غیرخالی را بررسی میکند و در صورت عدم تأیید اعتبار، یک updatePaymentDetails
با پیام خطای زیر از طریق callback.updateWith
ارسال میکند.
'Shipping option identifier required.'
changeShippingAddress
به تاجر در مورد تغییرات در آدرس حمل و نقل ارائه شده توسط کاربر اطلاع می دهد. Chrome بستهای غیرخالی shippingAddress
را با countryCode
معتبر بررسی میکند و در صورت عدم تأیید اعتبار، یک updatePaymentDetails
با پیام خطای زیر از طریق callback.updateWith
ارسال میکند.
'Payment app returned invalid shipping address in response.'
پیام خطای وضعیت نامعتبر
اگر Chrome با دریافت هر یک از درخواستهای تغییر با وضعیت نامعتبر مواجه شود، با یک بسته updatePaymentDetails
ویرایششده، callback.updateWith
فراخوانی میکند. بسته فقط حاوی کلید error
با "Invalid state"
. نمونه هایی از حالت نامعتبر عبارتند از:
- وقتی Chrome هنوز منتظر پاسخ تاجر به تغییر قبلی است (مانند یک رویداد تغییر مداوم).
- شناسه گزینه حمل و نقل ارائه شده توسط برنامه پرداخت به هیچ یک از گزینه های حمل و نقل مشخص شده توسط فروشنده تعلق ندارد.
جزئیات پرداخت به روز شده را از تاجر دریافت کنید
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 است (پس از ویرایش فیلد modifiers
) و حاوی کلیدهای اختیاری زیر است:
-
total
- یک بسته حاوی کلیدهایcurrency
وvalue
، هر دو کلید دارای مقادیر رشته هستند -
shippingOptions
- آرایه قابل بسته بندی از گزینه های حمل و نقل -
error
- رشته ای حاوی یک پیام خطای عمومی (مثلاً وقتیchangeShippingOption
یک شناسه گزینه حمل و نقل معتبر ارائه نمی دهد) -
stringifiedPaymentMethodErrors
- یک رشته JSON که خطاهای اعتبارسنجی روش پرداخت را نشان می دهد -
addressErrors
- یک بسته با کلیدهای اختیاری مشابه آدرس ارسال و مقادیر رشته. هر کلید نشان دهنده یک خطای اعتبارسنجی مربوط به قسمت مربوطه آن از آدرس حمل و نقل است.
کلید غایب به این معنی است که مقدار آن تغییر نکرده است.