چگونه برنامه پرداخت اندروید خود را بهروزرسانی کنید تا آدرس ارسال و اطلاعات تماس پرداختکننده را با APIهای پرداخت وب ارائه دهد.
منتشر شده: ۱۷ ژوئیه ۲۰۲۰، آخرین بهروزرسانی: ۲۷ مه ۲۰۲۵
وارد کردن آدرس ارسال و اطلاعات تماس از طریق فرم وب میتواند برای مشتریان یک تجربه دست و پا گیر باشد. این میتواند باعث خطا و کاهش نرخ تبدیل شود.
به همین دلیل است که API درخواست پرداخت از قابلیتی برای درخواست آدرس ارسال و اطلاعات تماس پشتیبانی میکند. این امر مزایای متعددی را ارائه میدهد:
- کاربران میتوانند تنها با چند لمس، آدرس صحیح را انتخاب کنند.
- آدرس همیشه در قالب استاندارد برگردانده میشود.
- احتمال ارسال آدرس نادرست کمتر است.
مرورگرها میتوانند جمعآوری آدرس ارسال و اطلاعات تماس را به یک برنامه پرداخت موکول کنند تا یک تجربه پرداخت یکپارچه ارائه دهند. این قابلیت، واگذاری اختیار (delegation) نامیده میشود.
در صورت امکان، کروم جمعآوری آدرس ارسال و اطلاعات تماس مشتری را به برنامه پرداخت اندروید فراخوانیشده واگذار میکند. این واگذاری، اصطکاک را در حین پرداخت کاهش میدهد.
وبسایت فروشگاه میتواند بسته به انتخاب مشتری از آدرس ارسال و گزینه ارسال، گزینههای ارسال و قیمت کل را به صورت پویا بهروزرسانی کند.
برای افزودن پشتیبانی از واگذاری اختیار به یک برنامه پرداخت اندروید موجود، مراحل زیر را اجرا کنید:
- هیئتهای نمایندگی مورد حمایت خود را اعلام کنید .
- موارد اضافی مربوط به قصد
PAY
intent) را برای گزینههای پرداخت مورد نیاز تجزیه و تحلیل کنید . - اطلاعات لازم را در پاسخ پرداخت ارائه دهید .
- اختیاری: پشتیبانی از جریان پویا :
هیئتهای نمایندگی مورد حمایت را اعلام کنید
مرورگر باید فهرست اطلاعات اضافی که برنامه پرداخت شما میتواند ارائه دهد را بداند تا بتواند جمعآوری آن اطلاعات را به برنامه شما واگذار کند. وکالتنامههای پشتیبانیشده را به عنوان یک <meta-data>
در AndroidManifest.xml برنامه خود اعلام کنید.
<activity
android:name=".PaymentActivity"
…
<meta-data
android:name="org.chromium.payment_supported_delegations"
android:resource="@array/chromium_payment_supported_delegations" />
</activity>
android:resource
باید به یک <string-array>
اشاره کند که شامل تمام یا زیرمجموعهای از مقادیر زیر است:
-
payerName
-
payerEmail
-
payerPhone
-
shippingAddress
مثال زیر فقط میتواند آدرس ارسال و آدرس ایمیل پرداختکننده را ارائه دهد.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="chromium_payment_supported_delegations">
<item>payerEmail</item>
<item>shippingAddress</item>
</string-array>
</resources>
موارد اضافی PAY
intent را برای گزینههای پرداخت مورد نیاز تجزیه کنید
فروشنده میتواند اطلاعات مورد نیاز اضافی را با استفاده از دیکشنری paymentOptions
مشخص کند. کروم فهرست گزینههای مورد نیازی را که برنامه شما میتواند ارائه دهد، با ارسال موارد اضافی paymentOptions
Intent به فعالیت PAY
ارائه میدهد.
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")
جاوا
Bundle paymentOptions = extras.getBundle("paymentOptions");
if (paymentOptions != null) {
Boolean requestPayerName = paymentOptions.getBoolean("requestPayerName");
Boolean requestPayerPhone = paymentOptions.getBoolean("requestPayerPhone");
Boolean requestPayerEmail = paymentOptions.getBoolean("requestPayerEmail");
Boolean requestShipping = paymentOptions.getBoolean("requestShipping");
String shippingType = 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)
}
جاوا
Parcelable[] shippingOptions = extras.getParcelableArray("shippingOptions");
for (Parcelable it : shippingOptions) {
if (it != null && it instanceof Bundle) {
Bundle shippingOption = (Bundle) it;
}
}
هر گزینه ارسال، یک Bundle
با کلیدهای زیر است.
-
id
- شناسه گزینه ارسال. -
label
- برچسب گزینه ارسال که به کاربر نشان داده میشود. -
amount
- بسته هزینه ارسال شامل کلیدهایcurrency
وvalue
با مقادیر رشتهای.-
currency
واحد پول هزینه حمل و نقل را به صورت یک کد سه حرفی خوشفرم 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)
جاوا
String id = bundle.getString("id");
String label = bundle.getString("label");
Bundle amount = bundle.getBundle("amount");
Boolean selected = bundle.getBoolean("selected", false);
اطلاعات لازم را در پاسخ پرداخت ارائه دهید
برنامه شما باید اطلاعات اضافی مورد نیاز را در پاسخ به فعالیت PAY
درج کند.
برای انجام این کار، پارامترهای زیر باید به عنوان Intent extras مشخص شوند:
-
payerName
- نام کامل پرداختکننده. این باید یک رشته غیر خالی باشد وقتیpaymentOptions.requestPayerName
برابر با true باشد. -
payerPhone
- شماره تلفن پرداختکننده. این شماره باید یک رشته غیر خالی باشد وقتیpaymentOptions.requestPayerPhone
برابر با true باشد. -
payerEmail
- آدرس ایمیل پرداختکننده. این باید یک رشته غیر خالی باشد وقتیpaymentOptions.requestPayerEmail
برابر با true باشد. -
shippingAddress
- آدرس ارسال ارائه شده توسط کاربر. این باید یک بسته غیر خالی باشد وقتیpaymentOptions.requestShipping
برابر با true باشد. بسته باید دارای کلیدهای زیر باشد که نشان دهنده بخشهای مختلف در یک آدرس فیزیکی هستند.-
countryCode
-
postalCode
-
sortingCode
-
region
-
city
-
dependentLocality
-
addressLine
-
organization
-
recipient
-
phone
همه کلیدها به غیر ازaddressLine
دارای مقادیر رشتهای هستند.addressLine
آرایهای از رشتهها است.
-
-
shippingOptionId
- شناسهی گزینهی حمل و نقل انتخاب شده توسط کاربر. این باید یک رشتهی غیر خالی باشد وقتیpaymentOptions.requestShipping
برابر با true باشد.
اعتبارسنجی پاسخ پرداخت
اگر نتیجه فعالیت پاسخ پرداخت دریافتی از برنامه پرداخت فراخوانی شده روی RESULT_OK
تنظیم شده باشد، کروم اطلاعات اضافی مورد نیاز را در موارد اضافی خود بررسی میکند. اگر اعتبارسنجی با شکست مواجه شود، کروم یک promise رد شده از 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", "5555555555")
}
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", "5555555555")
putExtra("shippingAddress", address)
putExtra("shippingOptionId", "standard")
}
}
جاوا
private Intent populateRequestedPaymentOptions() {
Intent result = new Intent();
if (requestPayerName) {
result.putExtra("payerName", "John Smith");
}
if (requestPayerPhone) {
presult.utExtra("payerPhone", "5555555555");
}
if (requestPayerEmail) {
result.putExtra("payerEmail", "john.smith@gmail.com");
}
if (requestShipping) {
Bundle address = new Bundle();
address.putExtra("countryCode", "CA");
address.putExtra("postalCode", "M5H2G4");
address.putExtra("region", "Ontario");
address.putExtra("city", "Toronto");
String[] addressLines = new String[] {"111 Richmond st. West"};
address.putExtra("addressLines", addressLines);
address.putExtra("recipient", "John Smith");
address.putExtra("phone", "5555555555");
result.putExtra("shippingAddress", address);
result.putExtra("shippingOptionId", "standard");
}
return result;
}
اختیاری: پشتیبانی از جریان پویا
گاهی اوقات هزینه کل یک تراکنش افزایش مییابد، مانند زمانی که کاربر گزینه ارسال سریع را انتخاب میکند، یا زمانی که لیست گزینههای ارسال موجود یا قیمتهای آنها با انتخاب آدرس ارسال بینالمللی توسط کاربر تغییر میکند. وقتی برنامه شما آدرس یا گزینه ارسال انتخاب شده توسط کاربر را ارائه میدهد، باید بتواند هرگونه تغییر آدرس یا گزینه ارسال را به فروشنده اطلاع دهد و جزئیات پرداخت بهروز شده (ارائه شده توسط فروشنده) را به کاربر نشان دهد.
برای اطلاعرسانی به فروشنده در مورد تغییرات جدید، رابط IPaymentDetailsUpdateServiceCallback
را پیادهسازی کنید و آن را در AndroidManifest.xml
خود با فیلتر UPDATE_PAYMENT_DETAILS
اعلان کنید.
بلافاصله پس از فراخوانی هدف PAY
، کروم به سرویس UPDATE_PAYMENT_DETAILS
(در صورت وجود) در همان بسته هدف PAY
متصل میشود و setPaymentDetailsUpdateService(service)
را فراخوانی میکند تا نقطه پایانی IPaymentDetailsUpdateService
را برای برنامه پرداخت شما فراهم کند تا در مورد تغییرات در روش پرداخت کاربر، گزینه ارسال یا آدرس ارسال اطلاعرسانی کند.
هنگام دریافت ارتباط بین فرآیندی (IPC) از packageManager.getPackagesForUid(Binder.getCallingUid())
استفاده کنید تا تأیید کنید که برنامهای که قصد PAY
را فراخوانی کرده است، نام بسته یکسانی با برنامهای دارد که متدهای IPaymentDetailsUpdateServiceCallback
فراخوانی کرده است.
آیدل
دو فایل AIDL با محتوای زیر ایجاد کنید:
org/chromium/components/payments/IPaymentDetailsUpdateServiceCallback.aidl
package org.chromium.components.payments;
import android.os.Bundle;
import org.chromium.components.payments.IPaymentDetailsUpdateService;
interface IPaymentDetailsUpdateServiceCallback {
oneway void updateWith(in Bundle updatedPaymentDetails);
oneway void paymentDetailsNotUpdated();
oneway void setPaymentDetailsUpdateService(IPaymentDetailsUpdateService service);
}
org/chromium/components/payments/IPaymentDetailsUpdateService.aidl
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);
}
خدمات
سرویس IPaymentDetailsUpdateServiceCallback
را پیادهسازی کنید.
کاتلین
class SampleUpdatePaymentDetailsCallbackService : Service() {
private val binder = object : IPaymentDetailsUpdateServiceCallback.Stub() {
override fun updateWith(updatedPaymentDetails: Bundle) {}
override fun paymentDetailsNotUpdated() {}
override fun setPaymentDetailsUpdateService(service: IPaymentDetailsUpdateService) {}
}
override fun onBind(intent: Intent?): IBinder? {
return binder
}
}
جاوا
import org.chromium.components.paymsnts.IPaymentDetailsUpdateServiceCallback;
public class SampleUpdatePaymentDetailsCallbackService extends Service {
private final IPaymentDetailsUpdateServiceCallback.Stub mBinder =
new IPaymentDetailsUpdateServiceCallback.Stub() {
@Override
public void updateWith(Bundle updatedPaymentDetails) {}
@Override
public void paymentDetailsNotUpdated() {}
@Override
public void setPaymentDetailsUpdateService(IPaymentDetailsUpdateService service) {}
};
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}
AndroidManifest.xml
سرویس را برای IPaymentDetailsUpdateServiceCallback
در AndroidManifest.xml
خود نمایش دهید.
<service
android:name=".SampleUpdatePaymentDetailsCallbackService"
android:exported="true">
<intent-filter>
<action android:name="org.chromium.intent.action.UPDATE_PAYMENT_DETAILS" />
</intent-filter>
</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
}
جاوا
if (service == null) {
return;
}
try {
if (isOptionChange) {
service.changeShippingOption(selectedOptionId, callback);
} else (isAddressChange) {
service.changeShippingAddress(selectedAddress, callback);
} else {
service.changePaymentMethod(methodData, callback);
}
} catch (RemoteException e) {
// Handle the remote exception
}
changePaymentMethod
به فروشنده در مورد تغییرات در روش پرداخت انتخاب شده توسط کاربر اطلاع میدهد. بسته paymentHandlerMethodData
شامل کلیدهای methodName
و details
اختیاری است که هر دو دارای مقادیر رشتهای هستند. کروم بستهای غیر خالی با methodName
غیر خالی را بررسی میکند و در صورت عدم موفقیت اعتبارسنجی، با استفاده از callback.updateWith
، یک updatePaymentDetails
به همراه یکی از پیامهای خطای زیر ارسال میکند.
'Method data required.'
'Method name required.'
changeShippingOption
به فروشنده در مورد تغییرات در گزینه حمل و نقل انتخاب شده توسط کاربر اطلاع میدهد. shippingOptionId
باید شناسه یکی از گزینههای حمل و نقل مشخص شده توسط فروشنده باشد. کروم shippingOptionId
غیر خالی را بررسی میکند و در صورت عدم موفقیت اعتبارسنجی، با استفاده از callback.updateWith
، یک updatePaymentDetails
با پیام خطای زیر ارسال میکند.
'Shipping option identifier required.'
changeShippingAddress
به فروشنده در مورد تغییرات در آدرس ارسال ارائه شده توسط کاربر اطلاع میدهد. کروم بسته shippingAddress
غیر خالی با countryCode
معتبر را بررسی میکند و در صورت عدم موفقیت اعتبارسنجی، با استفاده از callback.updateWith
، یک updatePaymentDetails
با پیام خطای زیر ارسال میکند.
'Payment app returned invalid shipping address in response.'
پیام خطای وضعیت نامعتبر
اگر کروم هنگام دریافت هر یک از درخواستهای تغییر با وضعیت نامعتبر مواجه شود، تابع callback.updateWith
را با یک بستهی ویرایششدهی updatePaymentDetails
فراخوانی میکند. این بسته فقط شامل کلید error
با "Invalid state"
خواهد بود. نمونههایی از وضعیت نامعتبر عبارتند از:
- وقتی کروم هنوز منتظر پاسخ فروشنده به تغییر قبلی (مانند یک رویداد تغییر در حال انجام) است.
- شناسه گزینه ارسال ارائه شده توسط برنامه پرداخت، به هیچ یک از گزینههای ارسال مشخص شده توسط فروشنده تعلق ندارد.
جزئیات پرداخت بهروز شده را از فروشنده دریافت کنید
کاتلین
override fun updateWith(updatedPaymentDetails: Bundle) {}
override fun paymentDetailsNotUpdated() {}
جاوا
@Override
public void updateWith(Bundle updatedPaymentDetails) {}
@Override
public void paymentDetailsNotUpdated() {}
updatedPaymentDetails
معادل بستهی دیکشنری PaymentRequestDetailsUpdate
WebIDL است و شامل کلیدهای اختیاری زیر است:
-
total
- یک بسته شامل کلیدهایcurrency
وvalue
، هر دو کلید دارای مقادیر رشتهای هستند. -
shippingOptions
- آرایهای از گزینههای ارسال قابل بستهبندی -
error
- رشتهای حاوی یک پیام خطای عمومی (مثلاً وقتیchangeShippingOption
شناسه گزینه حمل و نقل معتبری ارائه نمیدهد) -
stringifiedPaymentMethodErrors
- یک رشته JSON که خطاهای اعتبارسنجی برای روش پرداخت را نشان میدهد. -
addressErrors
- یک بسته با کلیدهای اختیاری مشابه آدرس ارسال و مقادیر رشتهای. هر کلید نشاندهنده یک خطای اعتبارسنجی مربوط به بخش مربوطه از آدرس ارسال است. -
modifiers
- آرایهای قابل تقسیم از Bundleها، که هر کدام دارای یکtotal
و یک فیلدmethodData
هستند که آنها نیز Bundle هستند.
یک کلید غایب به این معنی است که مقدار آن تغییر نکرده است.