অ্যান্ড্রয়েড পেমেন্ট অ্যাপ ডেভেলপার গাইড

ওয়েব পেমেন্টের সাথে কাজ করার জন্য আপনার Android পেমেন্ট অ্যাপটিকে কীভাবে মানিয়ে নিতে হয় এবং গ্রাহকদের জন্য আরও ভাল ব্যবহারকারীর অভিজ্ঞতা প্রদান করতে হয় তা জানুন।

প্রকাশিত: মে 5, 2020, শেষ আপডেট: মে 27, 2025

পেমেন্ট রিকোয়েস্ট API ওয়েবে একটি অন্তর্নির্মিত ব্রাউজার-ভিত্তিক ইন্টারফেস নিয়ে আসে যা ব্যবহারকারীদের প্রয়োজনীয় অর্থপ্রদানের তথ্য আগের চেয়ে সহজে প্রবেশ করতে দেয়। এপিআই প্ল্যাটফর্ম-নির্দিষ্ট অর্থপ্রদানের অ্যাপ্লিকেশনগুলিকেও আহ্বান করতে পারে।

Browser Support

  • ক্রোম: 60।
  • প্রান্ত: 15।
  • ফায়ারফক্স: একটি পতাকার পিছনে।
  • সাফারি: 11.1।

Source

প্ল্যাটফর্ম-নির্দিষ্ট Google Pay অ্যাপের সাথে চেকআউট প্রবাহ যা ওয়েব পেমেন্ট ব্যবহার করে।

শুধুমাত্র অ্যান্ড্রয়েড ইন্টেন্ট ব্যবহার করার তুলনায়, ওয়েব পেমেন্ট ব্রাউজার, নিরাপত্তা এবং ব্যবহারকারীর অভিজ্ঞতার সাথে আরও ভাল একীকরণের অনুমতি দেয়:

  • পেমেন্ট অ্যাপটি বণিক ওয়েবসাইটের পরিপ্রেক্ষিতে একটি মডেল হিসেবে চালু করা হয়েছে।
  • বাস্তবায়ন আপনার বিদ্যমান পেমেন্ট অ্যাপের পরিপূরক, যা আপনাকে আপনার ব্যবহারকারী বেসের সুবিধা নিতে সক্ষম করে।
  • সাইডলোডিং এড়াতে পেমেন্ট অ্যাপের স্বাক্ষর চেক করা হয়।
  • পেমেন্ট অ্যাপ একাধিক পেমেন্ট পদ্ধতি সমর্থন করতে পারে।
  • যেকোনো অর্থপ্রদানের পদ্ধতি, যেমন ক্রিপ্টোকারেন্সি, ব্যাঙ্ক ট্রান্সফার এবং আরও অনেক কিছু একত্রিত করা যেতে পারে। অ্যান্ড্রয়েড ডিভাইসে অর্থপ্রদানের অ্যাপ্লিকেশনগুলি এমনকি এমন পদ্ধতিগুলিকে একীভূত করতে পারে যেগুলির জন্য ডিভাইসে হার্ডওয়্যার চিপে অ্যাক্সেস প্রয়োজন৷

একটি অ্যান্ড্রয়েড পেমেন্ট অ্যাপে ওয়েব পেমেন্ট বাস্তবায়ন করতে চারটি ধাপ লাগে:

  1. ব্যবসায়ীদের আপনার পেমেন্ট অ্যাপ আবিষ্কার করতে দিন।
  2. একজন বণিককে জানান যে একজন গ্রাহকের কাছে একটি নথিভুক্ত যন্ত্র (যেমন ক্রেডিট কার্ড) আছে যা অর্থপ্রদানের জন্য প্রস্তুত।
  3. একজন গ্রাহককে অর্থপ্রদান করতে দিন।
  4. কলারের স্বাক্ষরকারী শংসাপত্র যাচাই করুন।

ওয়েব পেমেন্টগুলি কার্যকর দেখতে, অ্যান্ড্রয়েড-ওয়েব-পেমেন্ট ডেমো দেখুন।

ধাপ 1: ব্যবসায়ীদের আপনার পেমেন্ট অ্যাপ আবিষ্কার করতে দিন

একটি অর্থপ্রদানের পদ্ধতি সেট আপ করার নির্দেশাবলী অনুসারে ওয়েব অ্যাপ ম্যানিফেস্টে related_applications বৈশিষ্ট্য সেট করুন।

একজন বণিক আপনার অর্থপ্রদানের অ্যাপ ব্যবহার করার জন্য, তাদের অর্থপ্রদানের অনুরোধ API ব্যবহার করতে হবে এবং অর্থপ্রদানের পদ্ধতি শনাক্তকারী ব্যবহার করে আপনি যে অর্থপ্রদানের পদ্ধতি সমর্থন করেন তা নির্দিষ্ট করতে হবে।

আপনার যদি একটি পেমেন্ট পদ্ধতি শনাক্তকারী থাকে যা আপনার পেমেন্ট অ্যাপের জন্য অনন্য, আপনি আপনার নিজস্ব অর্থপ্রদানের পদ্ধতি মেনিফেস্ট সেট আপ করতে পারেন যাতে ব্রাউজারগুলি আপনার অ্যাপটি আবিষ্কার করতে পারে।

ধাপ 2: একজন বণিককে জানান যে একজন গ্রাহকের একটি নথিভুক্ত যন্ত্র আছে যা অর্থ প্রদানের জন্য প্রস্তুত

গ্রাহক পেমেন্ট করতে সক্ষম কিনা তা জানতে ব্যবসায়ী hasEnrolledInstrument() এ কল করতে পারেন। আপনি এই প্রশ্নের উত্তর দিতে একটি Android পরিষেবা হিসাবে IS_READY_TO_PAY প্রয়োগ করতে পারেন৷

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 পরিষেবার API AIDL-এ সংজ্ঞায়িত করা হয়েছে। নিম্নলিখিত বিষয়বস্তু সহ দুটি 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 এর সহজতম বাস্তবায়ন নিম্নলিখিত উদাহরণে দেখানো হয়েছে:

কোটলিন

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) পদ্ধতি ব্যবহার করে তার প্রতিক্রিয়া পাঠাতে পারে।

কোটলিন

callback?.handleIsReadyToPay(true)

জাভা

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

অনুমতি

কলকারী কে তা পরীক্ষা করতে আপনি Binder.getCallingUid() ব্যবহার করতে পারেন। মনে রাখবেন যে আপনাকে এটি isReadyToPay পদ্ধতিতে করতে হবে, onBind পদ্ধতিতে নয়, কারণ Android OS পরিষেবা সংযোগটি ক্যাশে এবং পুনরায় ব্যবহার করতে পারে, যা onBind() পদ্ধতিটিকে ট্রিগার করে না।

কোটলিন

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());
        // ...

ইন্টার-প্রসেস কমিউনিকেশন (IPC) কলগুলি গ্রহণ করার সময় সর্বদা 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 WebView এবং নন-https ওয়েবসাইটগুলিতে null যা সাধারণত স্থানীয় পরীক্ষার জন্য ব্যবহৃত হয়, যেমন http://localhost

ধাপ 3: একজন গ্রাহককে অর্থপ্রদান করতে দিন

পেমেন্ট অ্যাপ চালু করতে মার্চেন্ট কল show() যাতে গ্রাহক পেমেন্ট করতে পারেন। অর্থপ্রদানের অ্যাপটি ইনটেন্ট প্যারামিটারে লেনদেনের তথ্য সহ একটি অ্যান্ড্রয়েড ইন্টেন্ট PAY ব্যবহার করে আহ্বান করা হয়েছে।

অর্থপ্রদান অ্যাপটি methodName এবং details সহ প্রতিক্রিয়া জানায়, যা পেমেন্ট অ্যাপ নির্দিষ্ট এবং ব্রাউজারে অস্বচ্ছ। ব্রাউজার JSON স্ট্রিং ডিসিরিয়ালাইজেশন ব্যবহার করে বণিকের জন্য details স্ট্রিংটিকে একটি জাভাস্ক্রিপ্ট অভিধানে রূপান্তর করে, কিন্তু এর বাইরে কোনো বৈধতা প্রয়োগ করে না। ব্রাউজার details পরিবর্তন করে না; সেই প্যারামিটারের মান সরাসরি বণিকের কাছে পাঠানো হয়।

AndroidManifest.xml

PAY অভিপ্রায় ফিল্টারের সাথে কার্যকলাপে একটি <meta-data> ট্যাগ থাকা উচিত যা অ্যাপটির জন্য ডিফল্ট অর্থপ্রদানের পদ্ধতি শনাক্তকারীকে চিহ্নিত করে

একাধিক অর্থপ্রদানের পদ্ধতি সমর্থন করতে, একটি <string-array> সংস্থান সহ একটি <meta-data> ট্যাগ যোগ করুন।

<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 অবশ্যই স্ট্রিংগুলির একটি তালিকা হতে হবে, যার প্রত্যেকটি একটি বৈধ, পরম URL হতে হবে একটি HTTPS স্কিম সহ এখানে দেখানো হয়েছে৷

<?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

কোটলিন

val extras: Bundle? = getIntent()?.extras

জাভা

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

পদ্ধতির নাম

ব্যবহৃত পদ্ধতির নাম। উপাদানগুলি methodData অভিধানের কী। পেমেন্ট অ্যাপ সমর্থন করে এই পদ্ধতিগুলি।

কোটলিন

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

জাভা

List<String> methodNames = extras.getStringArrayList("methodNames");

methodData

প্রতিটি methodNames থেকে methodData ডেটাতে একটি ম্যাপিং।

কোটলিন

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

জাভা

Bundle methodData = extras.getBundle("methodData");

merchantName

বণিকের চেকআউট পৃষ্ঠার <title> HTML ট্যাগের বিষয়বস্তু (ব্রাউজারের শীর্ষ-স্তরের ব্রাউজিং প্রসঙ্গ)।

কোটলিন

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

জাভা

String merchantName = extras.getString("merchantName");

topLevelOrigin

স্কিম ছাড়াই বণিকের উৎপত্তি (টপ-লেভেল ব্রাউজিং প্রসঙ্গের স্কিম-লেস অরিজিন)। উদাহরণস্বরূপ, https://mystore.com/checkout mystore.com হিসাবে পাস করা হয়েছে।

কোটলিন

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

জাভা

String topLevelOrigin = extras.getString("topLevelOrigin");

topLevelCertificateChain

বণিকের শংসাপত্রের চেইন (শীর্ষ-স্তরের ব্রাউজিং প্রসঙ্গের শংসাপত্রের চেইন)। ওয়েবভিউ, লোকালহোস্ট বা ডিস্কের একটি ফাইলের জন্য মানটি null । প্রতিটি Parcelable হল একটি certificate কী এবং একটি বাইট অ্যারে মান সহ একটি বান্ডিল।

কোটলিন

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

আইফ্রেম ব্রাউজিং প্রসঙ্গের স্কিম-লেস মূল যা JavaScript-এ new PaymentRequest(methodData, details, options) কনস্ট্রাক্টরকে আমন্ত্রণ জানিয়েছে। যদি কনস্ট্রাক্টরকে শীর্ষ-স্তরের প্রসঙ্গ থেকে আহ্বান করা হয়, তাহলে এই প্যারামিটারের মান topLevelOrigin প্যারামিটারের মানের সমান।

কোটলিন

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

জাভা

String paymentRequestOrigin = extras.getString("paymentRequestOrigin");

total

JSON স্ট্রিং লেনদেনের মোট পরিমাণ প্রতিনিধিত্ব করে।

কোটলিন

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 ক্ষেত্র যা "পুশ-পেমেন্ট" অ্যাপগুলিকে লেনদেনের অবস্থার সাথে যুক্ত করা উচিত। বণিক ওয়েবসাইটগুলি ব্যান্ডের বাইরে লেনদেনের অবস্থার জন্য "পুশ-পেমেন্ট" অ্যাপগুলি জিজ্ঞাসা করতে এই ক্ষেত্রটি ব্যবহার করবে৷

কোটলিন

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

জাভা

String paymentRequestId = 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()

জাভা

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) সফল হয়৷ যদি এমন কোনো ডেটা না থাকে যা ফেরত দিতে হবে, তাহলে এই স্ট্রিংটি হতে পারে "{}" , যা বণিক ওয়েবসাইট একটি খালি জাভাস্ক্রিপ্ট অভিধান হিসেবে পাবে৷

আপনি RESULT_CANCELED পাস করতে পারেন যদি পেমেন্ট অ্যাপে লেনদেন সম্পূর্ণ না হয়, উদাহরণস্বরূপ, ব্যবহারকারী যদি পেমেন্ট অ্যাপে তাদের অ্যাকাউন্টের জন্য সঠিক পিন কোড টাইপ করতে ব্যর্থ হন। ব্রাউজার ব্যবহারকারীকে একটি ভিন্ন অর্থপ্রদানের অ্যাপ বেছে নিতে দিতে পারে।

কোটলিন

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() পদ্ধতির মাধ্যমে কলকারীকে পরীক্ষা করতে পারে।

কোটলিন

val caller: String? = callingPackage

জাভা

String caller = getCallingPackage();

কলিং প্যাকেজে সঠিক স্বাক্ষর আছে কিনা তা নিশ্চিত করতে কলারের স্বাক্ষর করার শংসাপত্র যাচাই করা চূড়ান্ত পদক্ষেপ।

ধাপ 4: কলার স্বাক্ষরকারী শংসাপত্র যাচাই করুন

আপনি IS_READY_TO_PAYBinder.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
)

জাভা

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-এর একটি একক স্বাক্ষর শংসাপত্র রয়েছে।) যে অ্যাপগুলির একাধিক স্বাক্ষর শংসাপত্র রয়েছে সেগুলিকে ঘোরাতে পারে না৷

আপনি যদি API স্তর 27 এবং তার আগের সমর্থন করতে চান, বা একাধিক সাইনিং শংসাপত্র সহ ব্রাউজারগুলি পরিচালনা করতে চান তবে আপনি PackageManager.GET_SIGNATURES ব্যবহার করতে পারেন।

কোটলিন

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