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

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

पब्लिश किया गया: 5 मई, 2020, पिछली बार अपडेट किया गया: 27 मई, 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 फ़ाइलें बनाएं:

org/chromium/IsReadyToPayServiceCallback.aidl

package org.chromium;

interface IsReadyToPayServiceCallback {
    oneway void handleIsReadyToPay(boolean isReadyToPay);
}

org/chromium/IsReadyToPayService.aidl

package org.chromium;

import org.chromium.IsReadyToPayServiceCallback;

interface IsReadyToPayService {
    oneway void isReadyToPay(IsReadyToPayServiceCallback callback, in Bundle parameters);
}

IsReadyToPayService लागू करना

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

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

    override fun onBind(intent: Intent?): IBinder? {
        return binder
    }
}
import org.chromium.IsReadyToPayService;

public class SampleIsReadyToPayService extends Service {
    private final IsReadyToPayService.Stub mBinder =
        new IsReadyToPayService.Stub() {
            @Override
            public void isReadyToPay(IsReadyToPayServiceCallback callback, Bundle parameters) {
                if (callback != null) {
                    callback.handleIsReadyToPay(true);
                }
            }
        };

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
}

जवाब

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

KotlinJava
callback?.handleIsReadyToPay(true)
if (callback != null) {
    callback.handleIsReadyToPay(true);
}

अनुमति

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

KotlinJava
override fun isReadyToPay(callback: IsReadyToPayServiceCallback?, parameters: Bundle?) {
    try {
        val untrustedPackageName = parameters?.getString("packageName")
        val actualPackageNames = packageManager.getPackagesForUid(Binder.getCallingUid())
        // ...
@Override
public void isReadyToPay(IsReadyToPayServiceCallback callback, Bundle parameters) {
    try {
        String untrustedPackageName = parameters != null
                ? parameters.getString("packageName")
                : null;
        String[] actualPackageNames = packageManager.getPackagesForUid(Binder.getCallingUid());
        // ...

इंटर-प्रोसेस कम्यूनिकेशन (आईपीसी) कॉल मिलने पर, null के इनपुट पैरामीटर हमेशा देखें. यह जानकारी खास तौर पर इसलिए ज़रूरी है, क्योंकि Android OS के अलग-अलग वर्शन या फ़ॉर्क, अनचाहे तरीके से काम कर सकते हैं. साथ ही, अगर इनका ध्यान नहीं रखा जाता है, तो गड़बड़ियां हो सकती हैं.

आम तौर पर, packageManager.getPackagesForUid() एक एलिमेंट दिखाता है. हालांकि, आपके कोड को उस असामान्य स्थिति को भी मैनेज करना चाहिए जहां कॉलर कई पैकेज के नाम का इस्तेमाल करता है. इससे यह पक्का होता है कि आपका ऐप्लिकेशन बेहतर तरीके से काम करता रहे.

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

पैरामीटर

parameters बंडल को Chrome 139 में जोड़ा गया था. इसकी जांच हमेशा null के साथ की जानी चाहिए.

parameters बंडल में, सेवा को ये पैरामीटर भेजे जाते हैं:

  • packageName
  • methodNames
  • methodData
  • topLevelOrigin
  • paymentRequestOrigin
  • topLevelCertificateChain

packageName को Chrome 138 में जोड़ा गया था. इस पैरामीटर की वैल्यू का इस्तेमाल करने से पहले, आपको Binder.getCallingUid() के साथ इसकी पुष्टि करनी होगी. यह पुष्टि करना ज़रूरी है, क्योंकि parameters बंडल पर कॉल करने वाले का पूरा कंट्रोल होता है, जबकि Binder.getCallingUid() पर Android OS का कंट्रोल होता है.

topLevelCertificateChain, वेबव्यू और ऐसी वेबसाइटों पर null होता है जो आम तौर पर लोकल टेस्टिंग के लिए इस्तेमाल की जाती हैं. जैसे, http://localhost.

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

व्यापारी/कंपनी, पेमेंट ऐप्लिकेशन को लॉन्च करने के लिए show() को कॉल करती है, ताकि ग्राहक पेमेंट कर सके. पेमेंट ऐप्लिकेशन को Android Intent 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/chromium_payment_method_names" />
</activity>

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

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

पैरामीटर

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

  • methodNames
  • methodData
  • merchantName
  • topLevelOrigin
  • topLevelCertificateChain
  • paymentRequestOrigin
  • total
  • modifiers
  • paymentRequestId
  • paymentOptions
  • shippingOptions

KotlinJava
val extras: Bundle? = getIntent()?.extras
Bundle extras = getIntent() != null ? getIntent().getExtras() : null;

methodNames

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

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

methodData

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

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

merchantName

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

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

topLevelOrigin

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

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

topLevelCertificateChain

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

KotlinJava
val topLevelCertificateChain: Array<Parcelable>? =
        extras.getParcelableArray("topLevelCertificateChain")
val list: List<ByteArray>? = topLevelCertificateChain?.mapNotNull { p ->
    (p as Bundle).getByteArray("certificate")
}
Parcelable[] topLevelCertificateChain =
        extras.getParcelableArray("topLevelCertificateChain");
if (topLevelCertificateChain != null) {
    for (Parcelable p : topLevelCertificateChain) {
        if (p != null && p instanceof Bundle) {
            ((Bundle) p).getByteArray("certificate");
        }
    }
}

paymentRequestOrigin

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

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

total

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

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

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

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

modifiers

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

paymentRequestId

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

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

जवाब

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

KotlinJava
setResult(Activity.RESULT_OK, Intent().apply {
    putExtra("methodName", "https://bobbucks.dev/pay")
    putExtra("details", "{\"token\": \"put-some-data-here\"}")
})
finish()
Intent result = new Intent();
Bundle extras = new Bundle();
extras.putString("methodName", "https://bobbucks.dev/pay");
extras.putString("details", "{\"token\": \"put-some-data-here\"}");
result.putExtras(extras);
setResult(Activity.RESULT_OK, result);
finish();

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

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

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

KotlinJava
setResult(Activity.RESULT_CANCELED)
finish()
setResult(Activity.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() तरीके से कॉलर की पहचान कर सकती है.

KotlinJava
val caller: String? = callingPackage
String caller = getCallingPackage();

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

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

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

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

KotlinJava
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
)
String packageName =  // The caller's package name
byte[] certificate =  // The correct signing certificate
boolean verified = packageManager.hasSigningCertificate(
        callingPackage,
        certificate,
        PackageManager.CERT_INPUT_SHA256);

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

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

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

val packageInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES)
val sha256 = MessageDigest.getInstance("SHA-256")
val actual = packageInfo.signatures.map {
    SerializeByteArrayToString(sha256.digest(it.toByteArray()))
}
val verified = actual.equals(expected)
String packageName  =  // The caller's package name
Set<String> expected =  // The correct set of signing certificates

PackageInfo packageInfo =
        packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
Set<String> actual = new HashSet<>();
for (Signature it : packageInfo.signatures) {
    actual.add(SerializeByteArrayToString(sha256.digest(it.toByteArray())));
}
boolean verified = actual.equals(expected);

डीबग

गड़बड़ियों या जानकारी देने वाले मैसेज देखने के लिए, यह कमांड इस्तेमाल करें:

adb logcat | grep -i pay