Android पेमेंट ऐप्लिकेशन डेवलपर गाइड

अपने Android पेमेंट ऐप्लिकेशन को वेब पेमेंट के साथ काम करने के लिए अडैप्ट करने और ग्राहकों को बेहतर उपयोगकर्ता अनुभव देने का तरीका जानें.

पब्लिश किया गया: 5 मई, 2020, पिछली बार अपडेट किया गया: 25 मार्च, 2025

Payment Request API, वेब पर ब्राउज़र पर काम करने वाला एक इंटरफ़ेस उपलब्ध कराता है. इसकी मदद से, उपयोगकर्ता पेमेंट के लिए ज़रूरी जानकारी को पहले से ज़्यादा आसानी से डाल सकते हैं. एपीआई, प्लैटफ़ॉर्म के हिसाब से पेमेंट ऐप्लिकेशन भी चालू कर सकता है.

Browser Support

  • Chrome: 60.
  • Edge: 15.
  • Firefox: behind a flag.
  • Safari: 11.1.

Source

वेब पेमेंट का इस्तेमाल करने वाले, प्लैटफ़ॉर्म के हिसाब से Google Pay ऐप्लिकेशन के साथ चेकआउट फ़्लो.

सिर्फ़ Android इंटेंट का इस्तेमाल करने की तुलना में, वेब पेमेंट की सुविधा से ब्राउज़र, सुरक्षा, और उपयोगकर्ता अनुभव के साथ बेहतर इंटिग्रेशन की सुविधा मिलती है:

  • पेमेंट ऐप्लिकेशन को व्यापारी/कंपनी की वेबसाइट के संदर्भ में, मॉडल के तौर पर लॉन्च किया जाता है.
  • इसे लागू करने से, आपके मौजूदा पेमेंट ऐप्लिकेशन को बेहतर बनाने में मदद मिलेगी. साथ ही, आपको अपने उपयोगकर्ताओं का फ़ायदा पाने में भी मदद मिलेगी.
  • साइडलोडिंग को रोकने के लिए, पेमेंट ऐप्लिकेशन के हस्ताक्षर की जांच की जाती है.
  • पेमेंट ऐप्लिकेशन में, पेमेंट के कई तरीके इस्तेमाल किए जा सकते हैं.
  • क्रिप्टो करंसी, बैंक ट्रांसफ़र वगैरह जैसे पेमेंट के किसी भी तरीके को इंटिग्रेट किया जा सकता है. Android डिवाइसों पर मौजूद पेमेंट ऐप्लिकेशन, ऐसे तरीकों को भी इंटिग्रेट कर सकते हैं जिनके लिए डिवाइस पर मौजूद हार्डवेयर चिप का ऐक्सेस ज़रूरी होता है.

Android के पेमेंट ऐप्लिकेशन में वेब पेमेंट की सुविधा लागू करने के लिए, चार चरण पूरे करने होंगे:

  1. कारोबारियों या कंपनियों को अपना पेमेंट ऐप्लिकेशन दिखाएं.
  2. व्यापारी/कंपनी को बताएं कि ग्राहक के पास रजिस्टर किया गया कोई ऐसा पेमेंट कार्ड है या नहीं जिससे पेमेंट किया जा सकता है.
  3. ग्राहक को पेमेंट करने की अनुमति दें.
  4. कॉलर के हस्ताक्षर वाले सर्टिफ़िकेट की पुष्टि करें.

वेब पेमेंट की सुविधा को इस्तेमाल करते हुए देखने के लिए, android-web-payment के डेमो को देखें.

पहला चरण: व्यापारियों/कंपनियों को अपने पेमेंट ऐप्लिकेशन के बारे में बताना

पेमेंट का तरीका सेट अप करना में दिए गए निर्देशों के मुताबिक, वेब ऐप्लिकेशन मेनिफ़ेस्ट में related_applications प्रॉपर्टी सेट करें.

कारोबारी या कंपनी को आपके पेमेंट ऐप्लिकेशन का इस्तेमाल करने के लिए, Payment Request API का इस्तेमाल करना होगा. साथ ही, पेमेंट के तरीके के आइडेंटिफ़ायर का इस्तेमाल करके, पेमेंट के उस तरीके के बारे में बताना होगा जिसका इस्तेमाल आपके ऐप्लिकेशन में किया जा सकता है.

अगर आपके पास पेमेंट के तरीके का ऐसा आइडेंटिफ़ायर है जो आपके पेमेंट ऐप्लिकेशन के लिए यूनीक है, तो आपके पास अपना पेमेंट के तरीके का मेनिफ़ेस्ट सेट अप करने का विकल्प है. इससे ब्राउज़र आपके ऐप्लिकेशन को खोज पाएंगे.

दूसरा चरण: व्यापारी/कंपनी को यह बताना कि खरीदार के पास रजिस्टर किया गया कोई ऐसा पेमेंट कार्ड है जिससे पेमेंट किया जा सकता है

व्यापारी/कंपनी hasEnrolledInstrument() को कॉल करके, यह पूछ सकती है कि ग्राहक पेमेंट कर सकता है या नहीं. इस क्वेरी का जवाब देने के लिए, IS_READY_TO_PAY को Android सेवा के तौर पर लागू किया जा सकता है.

AndroidManifest.xml

ऐक्शन org.chromium.intent.action.IS_READY_TO_PAY के साथ इंटेंट फ़िल्टर की मदद से, अपनी सेवा का एलान करें.

<service
  android:name=".SampleIsReadyToPayService"
  android:exported="true">
  <intent-filter>
    <action android:name="org.chromium.intent.action.IS_READY_TO_PAY" />
  </intent-filter>
</service>

IS_READY_TO_PAY सेवा का इस्तेमाल करना ज़रूरी नहीं है. अगर पेमेंट ऐप्लिकेशन में ऐसा कोई इंटेंट हैंडलर नहीं है, तो वेब ब्राउज़र यह मान लेता है कि ऐप्लिकेशन कभी भी पेमेंट कर सकता है.

एआईडीएल

IS_READY_TO_PAY सेवा के लिए एपीआई, AIDL में तय किया गया है. यहां दिए गए कॉन्टेंट के साथ दो AIDL फ़ाइलें बनाएं:

app/src/main/aidl/org/chromium/IsReadyToPayServiceCallback.aidl

package org.chromium;
interface IsReadyToPayServiceCallback {
    oneway void handleIsReadyToPay(boolean isReadyToPay);
}

app/src/main/aidl/org/chromium/IsReadyToPayService.aidl

package org.chromium;
import org.chromium.IsReadyToPayServiceCallback;

interface IsReadyToPayService {
    oneway void isReadyToPay(IsReadyToPayServiceCallback callback);
}

IsReadyToPayService लागू करना

IsReadyToPayService को लागू करने का सबसे आसान तरीका, यहां दिए गए उदाहरण में दिखाया गया है:

class SampleIsReadyToPayService : Service() {
  private val binder = object : IsReadyToPayService.Stub() {
    override fun isReadyToPay(callback: IsReadyToPayServiceCallback?) {
      callback?.handleIsReadyToPay(true)
    }
  }

  override fun onBind(intent: Intent?): IBinder? {
    return binder
  }
}

जवाब

सेवा, handleIsReadyToPay(Boolean) तरीके से अपना जवाब भेज सकती है.

callback?.handleIsReadyToPay(true)

अनुमति

Binder.getCallingUid() का इस्तेमाल करके, यह देखा जा सकता है कि कॉल करने वाला व्यक्ति कौन है. ध्यान दें कि आपको isReadyToPay तरीके से ऐसा करना होगा, न कि onBind तरीके से.

override fun isReadyToPay(callback: IsReadyToPayServiceCallback?) {
  try {
    val callingPackage = packageManager.getNameForUid(Binder.getCallingUid())
    // …

कॉल करने वाले के हस्ताक्षर वाले सर्टिफ़िकेट की पुष्टि करना लेख पढ़ें. इसमें, कॉल करने वाले पैकेज पर सही हस्ताक्षर होने की पुष्टि करने का तरीका बताया गया है.

तीसरा चरण: ग्राहक को पेमेंट करने की सुविधा देना

व्यापारी/कंपनी, पेमेंट ऐप्लिकेशन को लॉन्च करने के लिए show() को कॉल करती है, ताकि खरीदार पेमेंट कर सके. पेमेंट ऐप्लिकेशन को Android इंटेंट PAY की मदद से चालू किया जाता है. इसमें इंटेंट पैरामीटर में लेन-देन की जानकारी होती है.

पेमेंट ऐप्लिकेशन, methodName और details के साथ जवाब देता है. ये पेमेंट ऐप्लिकेशन के हिसाब से होते हैं और ब्राउज़र के लिए साफ़ तौर पर नहीं दिखते. ब्राउज़र, JSON डेसरियलाइज़ेशन की मदद से details स्ट्रिंग को व्यापारी/कंपनी/कारोबारी के लिए JavaScript ऑब्जेक्ट में बदल देता है. हालांकि, वह इसके अलावा किसी भी तरह की पुष्टि नहीं करता. ब्राउज़र, details में बदलाव नहीं करता. इस पैरामीटर की वैल्यू, सीधे व्यापारी/कंपनी/कारोबारी को भेजी जाती है.

AndroidManifest.xml

PAY इंटेंट फ़िल्टर वाली गतिविधि में <meta-data> टैग होना चाहिए. यह टैग, ऐप्लिकेशन के लिए पैसे चुकाने के डिफ़ॉल्ट तरीके के आइडेंटिफ़ायर की पहचान करता है.

पेमेंट के एक से ज़्यादा तरीकों का इस्तेमाल करने के लिए, <meta-data> टैग के साथ <string-array> संसाधन जोड़ें.

<activity
  android:name=".PaymentActivity"
  android:theme="@style/Theme.SamplePay.Dialog">
  <intent-filter>
    <action android:name="org.chromium.intent.action.PAY" />
  </intent-filter>

  <meta-data
    android:name="org.chromium.default_payment_method_name"
    android:value="https://bobbucks.dev/pay" />
  <meta-data
    android:name="org.chromium.payment_method_names"
    android:resource="@array/method_names" />
</activity>

resource, स्ट्रिंग की सूची होनी चाहिए. हर स्ट्रिंग, एचटीटीपीएस स्कीम वाला मान्य और एब्सोल्यूट यूआरएल होनी चाहिए, जैसा कि यहां दिखाया गया है.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="method_names">
        <item>https://alicepay.com/put/optional/path/here</item>
        <item>https://charliepay.com/put/optional/path/here</item>
    </string-array>
</resources>

पैरामीटर

यहां दिए गए पैरामीटर, गतिविधि में इंटेंट एक्स्ट्रा के तौर पर पास किए जाते हैं:

  • methodNames
  • methodData
  • topLevelOrigin
  • topLevelCertificateChain
  • paymentRequestOrigin
  • total
  • modifiers
  • paymentRequestId
val extras: Bundle? = intent?.extras

methodNames

इस्तेमाल किए जा रहे तरीकों के नाम. एलिमेंट, methodData डिक्शनरी में मौजूद कुंजियां होती हैं. पेमेंट ऐप्लिकेशन में ये तरीके काम करते हैं.

val methodNames: List<String>? = extras.getStringArrayList("methodNames")

methodData

हर methodNames से methodData तक की मैपिंग.

val methodData: Bundle? = extras.getBundle("methodData")

merchantName

व्यापारी/कंपनी/कारोबारी के चेकआउट पेज (ब्राउज़र के टॉप-लेवल ब्राउज़िंग कॉन्टेक्स्ट) के <title> एचटीएमएल टैग का कॉन्टेंट.

val merchantName: String? = extras.getString("merchantName")

topLevelOrigin

स्कीम के बिना व्यापारी/कंपनी/कारोबारी का ऑरिजिन (टॉप-लेवल ब्राउज़िंग कॉन्टेक्स्ट का स्कीम-लेस ऑरिजिन). उदाहरण के लिए, https://mystore.com/checkout को mystore.com के तौर पर पास किया जाता है.

val topLevelOrigin: String? = extras.getString("topLevelOrigin")

topLevelCertificateChain

कारोबारी/कंपनी/कारोबारी की सर्टिफ़िकेट चेन (टॉप-लेवल ब्राउज़िंग कॉन्टेक्स्ट की सर्टिफ़िकेट चेन). localhost और डिस्क पर मौजूद फ़ाइल के लिए शून्य, जो दोनों ही एसएसएल सर्टिफ़िकेट के बिना सुरक्षित कॉन्टेक्स्ट हैं. हर Parcelable एक बंडल होता है, जिसमें एक certificate कुंजी और एक बाइट कलेक्शन वैल्यू होती है.

val topLevelCertificateChain: Array<Parcelable>? =
    extras.getParcelableArray("topLevelCertificateChain")
val list: List<ByteArray>? = topLevelCertificateChain?.mapNotNull { p ->
  (p as Bundle).getByteArray("certificate")
}

paymentRequestOrigin

iframe ब्राउज़िंग कॉन्टेक्स्ट का स्कीम-लेस ऑरिजिन, जिसने JavaScript में new PaymentRequest(methodData, details, options) कन्स्ट्रक्टर को ट्रिगर किया. अगर कॉन्स्ट्रक्टर को टॉप-लेवल कॉन्टेक्स्ट से शुरू किया गया था, तो इस पैरामीटर की वैल्यू, topLevelOrigin पैरामीटर की वैल्यू के बराबर होगी.

val paymentRequestOrigin: String? = extras.getString("paymentRequestOrigin")

total

लेन-देन की कुल रकम दिखाने वाली JSON स्ट्रिंग.

val total: String? = extras.getString("total")

यहां स्ट्रिंग का एक उदाहरण दिया गया है:

{"currency":"USD","value":"25.00"}

modifiers

JSON.stringify(details.modifiers) का आउटपुट, जहां details.modifiers में सिर्फ़ supportedMethods और total शामिल हैं.

paymentRequestId

PaymentRequest.id फ़ील्ड, जिसे "पुश-पेमेंट" ऐप्लिकेशन को लेन-देन की स्थिति से जोड़ना चाहिए. व्यापारी/कंपनी/कारोबारी की वेबसाइटें, इस फ़ील्ड का इस्तेमाल करके, "पुश-पेमेंट" ऐप्लिकेशन से लेन-देन की स्थिति के बारे में जानकारी हासिल करेंगी.

val paymentRequestId: String? = extras.getString("paymentRequestId")

जवाब

ऐक्टिविटी, RESULT_OK की मदद से setResult के ज़रिए अपना जवाब वापस भेज सकती है.

setResult(Activity.RESULT_OK, Intent().apply {
  putExtra("methodName", "https://bobbucks.dev/pay")
  putExtra("details", "{\"token\": \"put-some-data-here\"}")
})
finish()

आपको दो पैरामीटर, इंटेंट एक्स्ट्रा के तौर पर बताने होंगे:

  • methodName: इस्तेमाल किए जा रहे तरीके का नाम.
  • details: JSON स्ट्रिंग, जिसमें लेन-देन पूरा करने के लिए व्यापारी/कंपनी के लिए ज़रूरी जानकारी होती है. अगर सफलता true है, तो details को इस तरह से बनाया जाना चाहिए कि JSON.parse(details) सफल हो.

अगर पेमेंट ऐप्लिकेशन में लेन-देन पूरा नहीं हुआ है, तो RESULT_CANCELED को पास किया जा सकता है. उदाहरण के लिए, अगर उपयोगकर्ता ने पेमेंट ऐप्लिकेशन में अपने खाते के लिए सही पिन कोड नहीं डाला है. ब्राउज़र, उपयोगकर्ता को कोई दूसरा पेमेंट ऐप्लिकेशन चुनने की अनुमति दे सकता है.

setResult(RESULT_CANCELED)
finish()

अगर इस्तेमाल किए गए पेमेंट ऐप्लिकेशन से मिले पेमेंट रिस्पॉन्स की गतिविधि का नतीजा RESULT_OK पर सेट है, तो Chrome अपने एक्सट्रा में methodName और details के खाली न होने की जांच करेगा. अगर पुष्टि नहीं हो पाती है, तो Chrome request.show() से अस्वीकार किए गए प्रॉमिस के साथ, डेवलपर को गड़बड़ी का यह मैसेज दिखाएगा:

'Payment app returned invalid response. Missing field "details".'
'Payment app returned invalid response. Missing field "methodName".'

अनुमति

गतिविधि, getCallingPackage() तरीके से कॉलर की पहचान कर सकती है.

val caller: String? = callingPackage

आखिरी चरण में, कॉल करने वाले के हस्ताक्षर वाले सर्टिफ़िकेट की पुष्टि की जाती है. इससे यह पक्का किया जाता है कि कॉलिंग पैकेज में सही हस्ताक्षर है.

चौथा चरण: कॉल करने वाले व्यक्ति के हस्ताक्षर करने वाले सर्टिफ़िकेट की पुष्टि करना

कॉलर के पैकेज का नाम देखने के लिए, IS_READY_TO_PAY में Binder.getCallingUid() और PAY में Activity.getCallingPackage() पर क्लिक करें. यह पुष्टि करने के लिए कि कॉल करने वाला ब्राउज़र वही है जिसे आपको कॉल करना है, आपको उसके हस्ताक्षर वाले सर्टिफ़िकेट की जांच करनी चाहिए. साथ ही, यह पक्का करना चाहिए कि वह सही वैल्यू से मेल खाता हो.

अगर एपीआई लेवल 28 और उसके बाद के वर्शन को टारगेट किया जा रहा है और किसी ऐसे ब्राउज़र के साथ इंटिग्रेट किया जा रहा है जिसमें एक साइनिंग सर्टिफ़िकेट है, तो PackageManager.hasSigningCertificate() का इस्तेमाल किया जा सकता है.

val packageName: String =  // The caller's package name
val certificate: ByteArray =  // The correct signing certificate.
val verified = packageManager.hasSigningCertificate(
  callingPackage,
  certificate,
  PackageManager.CERT_INPUT_SHA256
)

एक सर्टिफ़िकेट ब्राउज़र के लिए, PackageManager.hasSigningCertificate() को प्राथमिकता दी जाती है, क्योंकि यह सर्टिफ़िकेट रोटेशन को सही तरीके से मैनेज करता है. (Chrome के पास एक सिग्निंग सर्टिफ़िकेट होता है.) जिन ऐप्लिकेशन के पास साइन करने के लिए एक से ज़्यादा सर्टिफ़िकेट हैं वे उनका रोटेशन नहीं कर सकते.

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

val packageName: String =  // The caller's package name
val certificates: Set<ByteArray> =  // The correct set of signing certificates

val packageInfo = getPackageInfo(packageName, PackageManager.GET_SIGNATURES)
val sha256 = MessageDigest.getInstance("SHA-256")
val signatures = packageInfo.signatures.map { sha256.digest(it.toByteArray()) }
val verified = signatures.size == certificates.size &&
    signatures.all { s -> certificates.any { it.contentEquals(s) } }