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

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

पेमेंट रिक्वेस्ट एपीआई, वेब ब्राउज़र पर आधारित एक इंटरफ़ेस है जो पहले से मौजूद है. इसकी मदद से लोग, पेमेंट करने के लिए ज़रूरी पेमेंट कर सकते हैं जानकारी मिलती है. एपीआई, प्लैटफ़ॉर्म के हिसाब से पेमेंट करने की सुविधा भी शुरू कर सकता है दिखाई देता है.

ब्राउज़र सहायता

  • Chrome: 60. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
  • एज: 15. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
  • Firefox: किसी झंडे के पीछे.
  • Safari: 11.1. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है

सोर्स

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

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

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

किसी Android भुगतान ऐप्लिकेशन में वेब भुगतान लागू करने के लिए चार चरणों की आवश्यकता है:

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

वेब भुगतान को कार्य करते देखने के लिए, यहां देखें android-web-payment डेमो.

पहला चरण: कारोबारियों या कंपनियों को अपना पेमेंट ऐप्लिकेशन खोजने की सुविधा देना

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

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

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

कारोबारी, 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 सेवा के लिए एपीआई की जानकारी एआईडीएल में दी गई है. दो एआईडीएल बनाएं फ़ाइलें जिनमें यह कॉन्टेंट है:

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 देता है, ये पेमेंट ऐप्लिकेशन हैं विशिष्ट और ब्राउज़र के लिए अपारदर्शी. ब्राउज़र details को कन्वर्ट करता है स्ट्रिंग को JSON डीसीरियलाइज़ेशन के ज़रिए व्यापारी के लिए 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

व्यापारी/कंपनी के सर्टिफ़िकेट की चेन (टॉप लेवल की सर्टिफ़िकेट चेन ब्राउज़िंग कॉन्टेक्स्ट). डिस्क पर लोकलहोस्ट और फ़ाइल के लिए शून्य, जो दोनों सुरक्षित हैं बिना एसएसएल सर्टिफ़िकेट के. हर 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 फ़ील्ड ऐप्लिकेशन को लेन-देन की स्थिति के बारे में ज़्यादा जानें. कारोबारी या कंपनी की वेबसाइटें इस फ़ील्ड का इस्तेमाल, &quot;push-payment&quot; एक बैंड से बाहर के लेन-देन की स्थिति के लिए ऐप्लिकेशन.

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

जवाब

गतिविधि setResult के ज़रिए RESULT_OK के ज़रिए अपना जवाब वापस भेज सकती है.

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

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

चौथा चरण: कॉल करने वाले (कॉलर) के साइनिंग सर्टिफ़िकेट की पुष्टि करें

कॉल करने वाले (कॉलर) के पैकेज का नाम Binder.getCallingUid() से चेक किया जा सकता है IS_READY_TO_PAY और 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) } }