ارائه اطلاعات حمل و نقل و تماس از یک برنامه پرداخت Android

نحوه به‌روزرسانی برنامه پرداخت Android خود برای ارائه آدرس حمل و اطلاعات تماس پرداخت‌کننده با Web Payments.

ساحل شریفی
Sahel Sharify

تاریخ انتشار: 17 جولای 2020، آخرین به روز رسانی: 27 مه 2025

وارد کردن آدرس حمل و نقل و اطلاعات تماس از طریق یک فرم وب می تواند یک تجربه دست و پا گیر برای مشتریان باشد. می تواند باعث خطا و کاهش نرخ تبدیل شود.

به همین دلیل است که API درخواست پرداخت از ویژگی درخواست آدرس ارسال و اطلاعات تماس پشتیبانی می کند. این مزایای متعددی را ارائه می دهد:

  • کاربران می توانند آدرس مناسب را تنها با چند ضربه انتخاب کنند.
  • آدرس همیشه در قالب استاندارد بازگردانده می شود.
  • احتمال ارسال آدرس نادرست کمتر است.

مرورگرها می‌توانند جمع‌آوری آدرس ارسال و اطلاعات تماس را به یک برنامه پرداخت موکول کنند تا تجربه پرداخت یکپارچه را ارائه دهند. این قابلیت تفویض اختیار نامیده می شود.

هر زمان که ممکن باشد، Chrome جمع آوری آدرس ارسال و اطلاعات تماس مشتری را به برنامه پرداخت Android فراخوانی شده واگذار می کند. هیئت نمایندگی اصطکاک را در هنگام پرداخت کاهش می دهد.

وب سایت بازرگان می تواند بسته به انتخاب مشتری از آدرس حمل و نقل و گزینه حمل، گزینه های حمل و نقل و قیمت کل را به صورت پویا به روز کند.

گزینه حمل و نقل و آدرس حمل و نقل تغییر می کند. ببینید که چگونه به صورت پویا بر گزینه های حمل و نقل و قیمت کل تأثیر می گذارد.

برای افزودن پشتیبانی نمایندگی به یک برنامه پرداخت Android موجود، مراحل زیر را اجرا کنید:

  1. هیئت های حمایت شده را اعلام کنید .
  2. موارد اضافی قصد PAY را برای گزینه های پرداخت مورد نیاز تجزیه و تحلیل کنید .
  3. در پاسخ به پرداخت اطلاعات مورد نیاز را ارائه دهید .
  4. [اختیاری] پشتیبانی از جریان پویا :
    1. تاجر را از تغییرات در روش پرداخت انتخابی کاربر، آدرس ارسال یا گزینه ارسال مطلع کنید .
    2. جزئیات پرداخت به روز شده را از تاجر دریافت کنید (به عنوان مثال، مبلغ کل تنظیم شده بر اساس هزینه گزینه حمل و نقل انتخاب شده) .

هیئت های حمایت شده را اعلام کنید

مرورگر باید لیستی از اطلاعات اضافی را که برنامه پرداخت شما می تواند ارائه دهد بداند تا بتواند مجموعه آن اطلاعات را به برنامه شما واگذار کند. نمایندگی های پشتیبانی شده را در برنامه AndroidManifest.xml به عنوان <meta-data> اعلام کنید.

<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 را برای گزینه های پرداخت مورد نیاز تجزیه و تحلیل کنید

تاجر می تواند اطلاعات مورد نیاز اضافی را با استفاده از فرهنگ لغت paymentOptions مشخص کند. Chrome فهرستی از گزینه‌های مورد نیازی را که برنامه شما می‌تواند ارائه دهد، با ارسال موارد اضافی 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 ، واحد پول هزینه حمل و نقل را به عنوان یک کد الفبای 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)

جاوا

String id = bundle.getString("id");
String label = bundle.getString("label");
Bundle amount = bundle.getBundle("amount");
Boolean selected = bundle.getBoolean("selected", false);

اطلاعات مورد نیاز را در پاسخ پرداخت ارائه دهید

برنامه شما باید اطلاعات اضافی مورد نیاز را در پاسخ به فعالیت PAY درج کند.

برای انجام این کار، پارامترهای زیر باید به عنوان Intent اضافی مشخص شوند:

  • payerName - نام کامل پرداخت کننده. وقتی paymentOptions.requestPayerName درست است، این باید یک رشته غیر خالی باشد.
  • payerPhone - شماره تلفن پرداخت کننده. وقتی paymentOptions.requestPayerPhone درست است، این باید یک رشته غیر خالی باشد.
  • payerEmail - آدرس ایمیل پرداخت کننده. زمانی که paymentOptions.requestPayerEmail درست است، باید یک رشته غیر خالی باشد.
  • shippingAddress - آدرس حمل و نقل ارائه شده توسط کاربر. وقتی paymentOptions.requestShipping درست است، این باید یک بسته غیر خالی باشد. بسته نرم افزاری باید دارای کلیدهای زیر باشد که بخش های مختلف یک آدرس فیزیکی را نشان می دهد.
    • countryCode
    • postalCode
    • sortingCode
    • region
    • city
    • dependentLocality
    • addressLine
    • organization
    • recipient
    • phone همه کلیدها به غیر از 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", "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 ، Chrome به سرویس 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 هر دو با مقادیر رشته است. 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 هنوز منتظر پاسخ تاجر به تغییر قبلی است (مانند یک رویداد تغییر مداوم).
  • شناسه گزینه حمل و نقل ارائه شده توسط برنامه پرداخت به هیچ یک از گزینه های حمل و نقل مشخص شده توسط فروشنده تعلق ندارد.

جزئیات پرداخت به روز شده را از تاجر دریافت کنید

کاتلین

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 - یک آرایه قابل بسته‌بندی از Bundles، که هر کدام دارای یک فیلد total و یک methodData است که آنها نیز Bundle هستند.

کلید غایب به این معنی است که مقدار آن تغییر نکرده است.