如何更新 Android 付款應用程式,以便使用 Web Payments API 提供運送地址和付款人聯絡資訊。
透過網路表單輸入運送地址和聯絡資訊可以是 帶給客戶麻煩這可能會造成錯誤並降低轉換 頻率。
因此,Payment Request API 支援要求運送服務的功能 地址和聯絡資訊這麼做有許多好處:
- 使用者只要輕觸幾下,就能選擇正確的地址。
- 系統一律會以標準化形式傳回地址 格式。
- 提交錯誤的地址較不容易。
瀏覽器可以將運送地址和聯絡資訊延遲收集, 付款應用程式,提供整合式付款體驗。這項功能 稱為「委派」。
Chrome 在可能的情況下,會委派消費者的運送作業 傳送地址和聯絡資訊給叫用的 Android 付款應用程式。 委派功能可減少結帳程序。
商家網站可以動態更新運送選項和總價 視消費者選擇的運送地址和運送包裹而定 如果有需要 SQL 指令的分析工作負載 則 BigQuery 可能是最佳選擇
如要為既有的 Android 付款應用程式新增委派支援,請按照下列步驟操作: 實作下列步驟:
宣告支援的委派
瀏覽器必須取得您付款的其他資訊清單
應用程式可以提供,以便將這些資訊的收集委派給
應用程式。在應用程式的函式中,將支援的委派宣告宣告為 <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" ]
以下範例只能提供運送地址和付款人的電子郵件地址 讓我們看看 DNS 解析 進一步探索內部和外部位址
<?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 會提供必要選項清單,讓您的應用程式可以
將下列參數以 Intent 當做 IntentPAY
額外項目。
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
:運送選項 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
活動。
方法是將下列參數指定為意圖額外項目:
payerName
- 付款人的全名。這應該是非空白字串,paymentOptions.requestPayerName
為 true。payerPhone
- 付款人的電話號碼。這應該是非空白字串,paymentOptions.requestPayerPhone
為 true。payerEmail
- 付款人的電子郵件地址。這必須是非空白字串 當paymentOptions.requestPayerEmail
為 true 時。shippingAddress
- 使用者提供的運送地址。這應為 非空白套裝組合。paymentOptions.requestShipping
套裝組合 應具備下列代表實體物件中不同部分的鍵 電子郵件地址。city
countryCode
dependentLocality
organization
phone
postalCode
recipient
region
sortingCode
addressLine
addressLine
以外的所有索引鍵都有字串值。addressLine
是字串陣列。
shippingOptionId
:使用者所選運送選項的 ID。這個 當paymentOptions.requestShipping
為 true 時,應該是非空白字串。
驗證付款回應
如果所叫用付款收到的付款回應活動結果
應用程式已設為「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")
}
}
選用:支援動態流程
有時交易的總費用會增加,例如使用者 選擇快速出貨選項,或選擇運送清單時 選項或其價格會在使用者選擇國際運送時變更 讓我們看看 DNS 解析 進一步探索內部和外部位址應用程式向使用者提供的運送地址或選項時, 應該要能通知商家任何運送地址或選項 並向使用者顯示更新後的付款資料 ( 商家)。
AIDL
如要通知商家有新的變更,請使用 PaymentDetailsUpdateService
服務。如要使用這項服務,請建立兩個
含有以下內容的 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"
|
Beta 版 |
"com.chrome.beta"
|
開發 |
"com.chrome.dev"
|
Canary 版 |
"com.chrome.canary"
|
鉻 |
"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
應為商家指定的其中一項 ID
運送選項。Chrome 會檢查 shippingOptionId
是否為空白,然後傳送
updatePaymentDetails
附帶下列錯誤訊息:
callback.updateWith
表示驗證失敗。
'Shipping option identifier required.'
changeShippingAddress
在使用者提供的運送地址有變動時通知商家。Chrome
會檢查是否有包含有效 countryCode
的非空白 shippingAddress
組合
然後透過以下方式傳送含有以下錯誤訊息的 updatePaymentDetails
:
callback.updateWith
表示驗證失敗。
'Payment app returned invalid shipping address in response.'
無效的狀態錯誤訊息
如果 Chrome 在收到任何變更請求時進入無效狀態
系統會呼叫 callback.updateWith
並顯示遮蓋的 updatePaymentDetails
軟體包。組合只會包含有 "Invalid state"
的 error
鍵。
無效狀態的例子包括:
- Chrome 仍在等待商家回應先前變更的時間 (例如進行中的變更事件)。
- 付款應用程式提供的運送選項 ID 不屬於 商家指定的運送選項
接收商家更新的付款資料
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
未提供有效的運送選項 ID)stringifiedPaymentMethodErrors
- 代表驗證的 JSON 字串 付款方式錯誤addressErrors
- 包含選用金鑰與運送相同 address 和字串 輕鬆分配獎金每個金鑰都代表一個與其相對應的驗證錯誤相關的驗證錯誤 。
如果缺少索引鍵,則代表該值未變更。