Android पेमेंट ऐप्लिकेशन से शिपिंग और संपर्क जानकारी देना

Web Payments API के ज़रिए शिपिंग पता और पैसे चुकाने वाले की संपर्क जानकारी देने के लिए, Android पेमेंट ऐप्लिकेशन को अपडेट करने का तरीका.

Sahel Sharify
Sahel Sharify

वेब फ़ॉर्म की मदद से शिपिंग का पता और संपर्क जानकारी डालना, ग्राहकों के लिए मुश्किल हो सकता है. इससे गड़बड़ियां हो सकती हैं और कन्वर्ज़न रेट में गिरावट आ सकती है.

इसलिए, पेमेंट रिक्वेस्ट एपीआई में शिपिंग पते और संपर्क जानकारी का अनुरोध करने की सुविधा है. इससे कई फ़ायदे मिलते हैं:

  • उपयोगकर्ता, सिर्फ़ कुछ टैप करके सही पता चुन सकते हैं.
  • पता हमेशा स्टैंडर्ड फ़ॉर्मैट में दिखाया जाता है.
  • गलत पता सबमिट करने की संभावना कम होती है.

ब्राउज़र, शिपिंग पते और संपर्क जानकारी को इकट्ठा करने की प्रोसेस को पेमेंट ऐप्लिकेशन पर भेज सकते हैं, ताकि एक ही जगह से पेमेंट किया जा सके. इस सुविधा को अधिकार सौंपना कहा जाता है.

जब भी मुमकिन हो, 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/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 गतिविधि में ये पैरामीटर पास करके, ये विकल्प उपलब्ध करा सकता है.

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 के मुताबिक, तीन अक्षरों वाले अंग्रेज़ी वर्णमाला के कोड के तौर पर दिखती है
    • 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 के 'सही' होने पर, यह एक स्ट्रिंग होनी चाहिए.
  • 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")
   
}
}

ज़रूरी नहीं: डाइनैमिक फ़्लो की सुविधा

कभी-कभी लेन-देन की कुल कीमत बढ़ जाती है. जैसे, जब कोई उपयोगकर्ता एक्सप्रेस शिपिंग का विकल्प चुनता है या जब कोई उपयोगकर्ता अंतरराष्ट्रीय शिपिंग पता चुनता है, तो शिपिंग के उपलब्ध विकल्पों की सूची या उनकी कीमतें बदल जाती हैं. जब आपका ऐप्लिकेशन, उपयोगकर्ता का चुना गया शिपिंग पता या विकल्प उपलब्ध कराता है, तो वह व्यापारी/कंपनी/कारोबारी को शिपिंग पते या विकल्प में होने वाले बदलावों के बारे में बता सकता है. साथ ही, उसे पेमेंट के तरीके की अपडेट की गई जानकारी (व्यापारी/कंपनी की ओर से दी गई) दिखानी चाहिए.

एआईडीएल

व्यापारी/कंपनी को नए बदलावों की सूचना देने के लिए, Chrome की AndroidManifest.xml में बताई गई 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"
बीटा "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 के साथ किसी ऐसे बंडल की जांच करेगा जिसमें कोई डेटा हो. अगर पुष्टि नहीं हो पाती है, तो callback.updateWith के ज़रिए गड़बड़ी के इनमें से किसी एक मैसेज के साथ updatePaymentDetails भेजा जाएगा.

'Method data required.'
'Method name required.'

changeShippingOption

उपयोगकर्ता के चुने गए शिपिंग के विकल्प में हुए बदलावों के बारे में व्यापारी/कंपनी/कारोबारी को सूचना देता है. shippingOptionId, व्यापारी/कंपनी/कारोबारी के बताए गए शिपिंग के विकल्पों में से किसी एक का आइडेंटिफ़ायर होना चाहिए. अगर पुष्टि नहीं हो पाती है, तो Chrome ऐसे shippingOptionId की जांच करेगा जो खाली नहीं है और callback.updateWith के ज़रिए इस गड़बड़ी के मैसेज के साथ updatePaymentDetails भेजेगा.

'Shipping option identifier required.'

changeShippingAddress

उपयोगकर्ता के दिए गए शिपिंग पते में हुए बदलावों के बारे में व्यापारी/कंपनी/कारोबारी को सूचना देता है. Chrome, मान्य countryCode के साथ, खाली नहीं होने वाले shippingAddress बंडल की जांच करेगा. अगर पुष्टि नहीं हो पाती है, तो callback.updateWith के ज़रिए गड़बड़ी का यह मैसेज भेजकर updatePaymentDetails भेजा जाएगा.

'Payment app returned invalid shipping address in response.'

अमान्य स्थिति की गड़बड़ी का मैसेज

अगर Chrome को बदलाव का कोई अनुरोध मिलने पर, अमान्य स्थिति मिलती है, तो वह updatePaymentDetails बंडल के साथ callback.updateWith को कॉल करेगा. बंडल में सिर्फ़ "Invalid state" वाली error कुंजी होगी. अमान्य स्थिति के उदाहरण यहां दिए गए हैं:

  • जब 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, modifiers फ़ील्ड को हटाने के बाद, PaymentRequestDetailsUpdate WebIDL डिक्शनरी के बराबर का बंडल होता है. इसमें ये वैकल्पिक कुंजियां शामिल होती हैं:

  • total - currency और value बटन वाला बंडल, दोनों बटन की वैल्यू स्ट्रिंग है
  • shippingOptions - शिपिंग के विकल्पों का पैकेज किया जा सकने वाला ऐरे
  • error - ऐसी स्ट्रिंग जिसमें गड़बड़ी का सामान्य मैसेज होता है. उदाहरण के लिए, जब changeShippingOption शिपिंग के विकल्प का मान्य आइडेंटिफ़ायर नहीं देता है
  • stringifiedPaymentMethodErrors - पेमेंट के तरीके की पुष्टि करने से जुड़ी गड़बड़ियों को दिखाने वाली JSON स्ट्रिंग
  • addressErrors - शिपिंग के पते और स्ट्रिंग की वैल्यू से मिलती-जुलती वैकल्पिक कुंजियों वाला बंडल. हर कुंजी, शिपिंग पते के उस हिस्से से जुड़ी पुष्टि से जुड़ी गड़बड़ी दिखाती है जिससे वह जुड़ी है.

अगर कोई कुंजी मौजूद नहीं है, तो इसका मतलब है कि उसकी वैल्यू नहीं बदली है.