איך מעדכנים את אפליקציית התשלומים ב-Android כדי לספק כתובת למשלוח ואת הפרטים ליצירת קשר של המשלם באמצעות ממשקי Web Payments API.
הזנת כתובת למשלוח ופרטים ליצירת קשר באמצעות טופס אינטרנט יכולה להיות חוויה מסורבלת ללקוחות. הוא עלול לגרום לשגיאות ולירידה במספר ההמרות מחיר.
לכן ב-Payment Request API יש תמיכה בתכונה שמאפשרת לבקש משלוח כתובת ופרטים ליצירת קשר. יש לכך כמה יתרונות:
- המשתמשים יכולים לבחור את הכתובת הנכונה בכמה הקשות פשוטות.
- הכתובת תמיד מוחזרת בשדה הסטנדרטי .
- יש סיכוי נמוך יותר לשלוח כתובת שגויה.
דפדפנים יכולים לדחות את האיסוף של כתובות למשלוח ופרטים ליצירת קשר למשך אפליקציית תשלומים כדי לספק חוויית תשלום אחידה. הפונקציונליות הזו שנקראת הענקת גישה.
כשהדבר מתאפשר, Chrome מאציל את איסוף פרטי המשלוח של הלקוח הכתובת והפרטים ליצירת קשר אל אפליקציית התשלומים ב-Android שהופעלה. הענקת גישה מפחיתה את הקושי במהלך התשלום בקופה.
אתר המוכר יכול לעדכן באופן דינמי את אפשרויות המשלוח ואת המחיר הכולל בהתאם לבחירת הלקוח בכתובת למשלוח ובמשלוח כאפשרות.
כדי להוסיף תמיכה בהענקת גישה לאפליקציית תשלומים קיימת ב-Android: לבצע את השלבים הבאים:
- להצהיר על הענקת גישה נתמכת
- ניתוח של
PAY
תוספות כוונה לתשלום עבור התשלום הנדרש . - איך מספקים את המידע הנדרש לתשלום תשובה.
- [אופציונלי] תמיכה בתהליך דינמי:
הצהרה על הקצאות נתמכות
הדפדפן צריך לדעת מהי רשימת הפרטים הנוספים שהתשלום שלך
אפליקציה יכולה לספק כדי להאציל את איסוף המידע הזה
אפליקציה. יש להצהיר על הענקת הגישה שנתמכת בתור <meta-data>
בישות של האפליקציה
AndroidManifest.xml.
<activity
android:name=".PaymentActivity"
…
<meta-data
android:name="org.chromium.payment_supported_delegations"
android:resource="@array/supported_delegations" />
</activity>
הערך <resource>
חייב להיות רשימה של מחרוזות שנבחרות מהערכים החוקיים הבאים:
[ "payerName", "payerEmail", "payerPhone", "shippingAddress" ]
בדוגמה הבאה אפשר לציין רק כתובת למשלוח ואת כתובת האימייל של המשלם address.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="supported_delegations">
<item>payerEmail</item>
<item>shippingAddress</item>
</string-array>
</resources>
ניתוח של PAY
תוספות Intent עבור אפשרויות התשלום הנדרשות
המוכר יכול לציין מידע נדרש נוסף באמצעות
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
מציג את המטבע של עלות המשלוח, בתור הפורמט ISO4217 תקין קוד אלפביתי בן 3 אותיות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
הוא True.shippingAddress
- הכתובת למשלוח שסופקה על ידי המשתמש. הוא צריך להיות חבילה שאינה ריקה אם הערך שלpaymentOptions.requestShipping
הוא True. החבילה הם צריכים להכיל את המפתחות הבאים שמייצגים חלקים שונים ב address.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")
}
}
אופציונלי: זרימה דינמית של תמיכה
לפעמים העלות הכוללת של עסקה עולה, למשל כשהמשתמש בוחר באפשרות של משלוח אקספרס, או כשיש רשימה של אפשרויות המשלוח הזמינות או המחירים שלהן משתנים כשהמשתמש בוחר משלוח בינלאומי address. אם האפליקציה מספקת את הכתובת או האפשרות למשלוח שנבחרו על ידי המשתמש, צריכה להיות אפשרות להודיע למוכר על כל כתובת או אפשרות למשלוח משתנה ולהראות למשתמש את פרטי התשלום המעודכנים (מסופקים על ידי סוחר).
AIDL
כדי להודיע למוכר על שינויים חדשים, צריך להשתמש ב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
שמשמש לכוונת ההתחלה של השירות יכול לכלול אחד מהבאים
את הערכים הבאים, בהתאם לדפדפן שביצע את התשלום
בקשה.
ערוץ Chrome | שם חבילה |
---|---|
אורווה |
"com.android.chrome"
|
בטא |
"com.chrome.beta"
|
פיתוח |
"com.chrome.dev"
|
האיים הקנריים |
"com.chrome.canary"
|
Chromium |
"org.chromium.chrome"
|
תיבת חיפוש מהיר של Google (כלי להטמיע WebLayer) |
"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
מודיע למוכר על שינויים בכתובת למשלוח שסופקה על ידי המשתמש. כרום
המערכת תבדוק אם יש חבילת shippingAddress
לא ריקה עם ערך countryCode
תקין
ולשלוח updatePaymentDetails
עם הודעת השגיאה הבאה דרך
callback.updateWith
אם האימות נכשל.
'Payment app returned invalid shipping address in response.'
הודעת שגיאה לגבי מצב לא חוקי
אם Chrome נתקל במצב לא חוקי בעת קבלת בקשות שינוי
היא תקרא callback.updateWith
עם updatePaymentDetails
מצונזר
חבילה. החבילה תכלול רק את המפתח 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
- המערך המפרק של shipping אפשרויותerror
- מחרוזת שמכילה הודעת שגיאה כללית (למשל, המאפייןchangeShippingOption
לא מספק מזהה חוקי של אפשרות משלוח)stringifiedPaymentMethodErrors
– מחרוזת JSON שמייצגת אימות שגיאות באמצעי התשלוםaddressErrors
– חבילה עם מפתחות אופציונליים שזהים למשלוח כתובת ומחרוזת ערכים. כל מפתח מייצג שגיאת אימות שקשורה לערך חלק מהכתובת למשלוח.
אם מפתח חסר, המשמעות היא שהערך שלו לא השתנה.