सर्वर साइड में एंड्रॉइड ऐप के लिए खरीदारी कैसे सत्यापित करें (ऐप बिलिंग v3 में Google Play)


96

मेरे पास एक सरल ऐप है (खाते के साथ उपयोगकर्ता लॉगिन की आवश्यकता है)। मैं भुगतान किए गए उपयोगकर्ताओं के लिए कुछ प्रीमियम सुविधाएँ प्रदान करता हूं, जैसे अधिक समाचार सामग्री।

मुझे यह रिकॉर्ड करने की आवश्यकता है कि क्या उपयोगकर्ता ने मेरे सर्वर डेटाबेस में इस आइटम को खरीदा है। जब मैं उपयोगकर्ता की डिवाइस को डेटा सामग्री प्रदान करता हूं, तो मैं उपयोगकर्ता की स्थिति की जांच कर सकता हूं, और भुगतान किए गए उपयोगकर्ता के लिए विभिन्न सामग्री प्रदान कर सकता हूं।

मैंने Google द्वारा प्रदान किए गए आधिकारिक ट्रिवियलड्राइव नमूने की जांच की, यह सर्वर-साइड सत्यापन के लिए कोई नमूना कोड प्रदान नहीं करता है, यहां मेरे प्रश्न हैं।

  1. मैंने पाया कि खरीदारी को सत्यापित करने के लिए नमूना मेरे ऐप की सार्वजनिक कुंजी का उपयोग करता है, यह अच्छा नहीं लगता है, मुझे लगता है कि मैं बस उपयोगकर्ता लॉगिन क्रेडेंशियल के साथ संयुक्त रूप से सत्यापन प्रक्रिया को आगे बढ़ा सकता हूं, यह देखने के लिए कि उपयोगकर्ता खरीद पूरी हुई, और फिर डेटाबेस को अपडेट करें।
  2. इसके अलावा खरीद एपीआई मैं क्वेरी करने के लिए उपयोग कर सकते हैं, मैं क्या जरूरत है उपयोगकर्ता की खरीद के सर्वर में पारित करने के लिए है।

मुझे यकीन नहीं है कि उपयोगकर्ता की खरीद को सत्यापित करने के लिए मुझे क्या तरीका अपनाना चाहिए, और अपने डेटाबेस में उपयोगकर्ता की स्थिति को चिह्नित करना चाहिए, शायद दोनों?

और मुझे डर है कि एक स्थिति है, अगर किसी उपयोगकर्ता ने Google Play से इस आइटम को खरीदा है, लेकिन किसी कारण से, बस उस समय में, जब मेरे ऐप ने मेरे सर्वर पर सत्यापन शुरू किया, तो नेटवर्क कनेक्शन नीचे है या मेरा अपना सर्वर डाउन है , उपयोगकर्ता ने Google Play में केवल पैसे का भुगतान किया है लेकिन मैंने अपने सर्वर में खरीदारी रिकॉर्ड नहीं की है? मुझे क्या करना चाहिए, मैं इस स्थिति से कैसे निपट सकता हूं।


आपको संभवतः इस प्रश्न से आईओएस ध्वज को हटा देना चाहिए।
गुस्तावो ग्वेरा

जवाबों:


160

यह लगता है कि आप जो खोज रहे हैं वह यह जांचने का एक तरीका है कि क्या उपयोगकर्ता के पास अपने खाते पर प्रीमियम सुविधाएँ सक्षम हैं, इसलिए यह वह जगह है जहाँ मैं शुरू करूँगा;

सुनिश्चित करें कि आपके डेटाबेस पर किसी प्रकार का एक झंडा है जो यह दर्शाता है कि उपयोगकर्ता के पास प्रीमियम सुविधाएँ हैं और इसमें खाता जानकारी का अनुरोध करते समय एपीआई प्रतिक्रिया पेलोड में शामिल हैं। यह ध्वज "प्रीमियम सुविधाओं" के लिए आपका प्राथमिक अधिकार होगा।

जब कोई उपयोगकर्ता इन-ऐप खरीदारी करता है, तो क्लाइंट पर स्थानीय रूप से विवरण (टोकन, ऑर्डर आईडी और उत्पाद आईडी) कैश करें (यानी ऐप) तो इसे अपने एपीआई में भेजें।

आपका एपीआई तो भेजना चाहिए purchaseTokenकरने के लिए Google Play डेवलपर API सत्यापन के लिए।

यहाँ से कुछ चीजें हो सकती हैं:

  1. रसीद मान्य है, आपका एपीआई क्लाइंट को 200 ओके स्टेटस कोड के साथ प्रतिक्रिया देता है
  2. रसीद अमान्य है, आपका एपीआई क्लाइंट के साथ 400 खराब अनुरोध स्थिति कोड का जवाब देता है
  3. Google Play API नीचे है, आपका API 502 खराब गेटवे स्थिति कोड के साथ प्रतिक्रिया करता है

1. या 2. (2xx या 4xx स्टेटस कोड) के मामले में आपके क्लाइंट ने खरीद विवरण का कैश क्लियर कर दिया है क्योंकि इसे अब इसकी आवश्यकता नहीं है क्योंकि एपीआई ने संकेत दिया है कि यह प्राप्त हो चुका है।

एक सफल सत्यापन (केस 1) पर, आपको premiumउपयोगकर्ता के लिए ध्वज को सही पर सेट करना चाहिए ।

3. (5xx स्थिति कोड) या नेटवर्क टाइमआउट के मामले में ग्राहक को तब तक कोशिश करते रहना चाहिए जब तक कि वह आपके एपीआई से 2xx या 4xx स्थिति कोड प्राप्त न कर ले।

अपनी आवश्यकताओं के आधार पर, आप फिर से भेजने से पहले कुछ सेकंड प्रतीक्षा कर सकते हैं या बस अपने एपीआई को विवरण भेज सकते हैं जब कभी ऐप फिर से लॉन्च किया जाता है या ऐप कैश पर खरीद विवरण मौजूद होने पर पृष्ठभूमि से बाहर आता है।

इस दृष्टिकोण को नेटवर्क टाइमआउट, सर्वर अनुपलब्ध होने आदि का ध्यान रखना चाहिए।

अब कुछ प्रश्न हैं जिन पर आपको विचार करने की आवश्यकता है:

खरीदारी के तुरंत बाद क्या होना चाहिए? ऐप को तब तक इंतजार करना चाहिए जब तक प्रीमियम सामग्री प्रदान करने से पहले सत्यापन सफल न हो या इसे अस्थायी रूप से पहुंच प्रदान करना चाहिए और यदि सत्यापन विफल हो जाता है तो इसे हटा देना चाहिए?

प्रीमियम सुविधाओं के लिए अस्थायी पहुँच प्रदान करने से आपके अधिकांश उपयोगकर्ताओं के लिए प्रक्रिया सुचारू हो जाती है, लेकिन आप बहुत से धोखेबाज़ उपयोगकर्ताओं तक पहुँच प्रदान करेंगे, जबकि आपका एपीआई मान्य करता है purchaseToken

इसे दूसरे तरीके से रखने के लिए: खरीद वैध धोखाधड़ी या वैध होने तक मान्य है; वैध साबित होने तक धोखाधड़ी?

आदेश यदि उपयोगकर्ता अभी भी एक वैध सदस्यता है जब उनकी सदस्यता अवधि नवीकरण के लिए आता है की पहचान करने के लिए, आप पर एक फिर से सत्यापन का समय निर्धारित करने की आवश्यकता होगी purchaseTokenपर चलाने के लिए expiryTimeMillisहै कि में वापस आ गया था परिणाम

यदि expiryTimeMillisअतीत में है, तो आप premiumध्वज को झूठे पर सेट कर सकते हैं । यदि यह भविष्य में है, तो इसे नए के लिए फिर से शेड्यूल करें expiryTimeMillis

अंत में, यह सुनिश्चित करने के लिए कि उपयोगकर्ता के पास प्रीमियम एक्सेस (या नहीं) है, आपके ऐप को ऐप लॉन्च पर या पृष्ठभूमि से बाहर आने पर उपयोगकर्ताओं के विवरण के लिए अपने एपीआई को क्वेरी करना चाहिए।


भुगतान किए गए ऐप के लिए, मुझे Google से रसीद कैसे मिलेगी?
मेरिन जो

2
नमस्ते! Google पर सदस्यता इतिहास तक पहुंचने का कोई तरीका नहीं है? तथ्य यह है कि अगर पहले से ही खरीदे गए शावक को खरीद के मामले में खोने से कैसे रोका जाए तो ऐप स्टोर करने के क्षण में दुर्घटनाग्रस्त हो जाता है?
स्काइथारैगन

2
मुझे भी इसी तरह की समस्या है .. एप को टोकन भेजने के बजाय एपि को और अधिक विश्वसनीय बनाने के लिए, Google डेवलपर सर्वर को मेरी पुश अपी के लिए सीधे धक्का अधिसूचना के साथ ऐसा करने का निर्देश देने के लिए अधिक विश्वसनीय है?
गियानलुका घेटिनी

Google Play Developer API को रद्द किए जाने वाले सदस्यता के लिए , रद्द करने के बाद भी 200 वापस आ जाएंगे, अगर वही पुरानी खरीद टोकन सत्यापन के लिए उपयोग की जाती है।
Cezar Cobuz

तो एक सदस्यता के लिए, आप सुझाव दे रहे हैं कि सर्वर पर पहली कॉल के बाद, हम खरीद टोकन, और उत्पाद आईडी को स्टोर करते हैं, और एक्सपायरीटाइममिल्स होने पर एक अन्य सत्यापन कॉल (उसी अनुरोध को फिर से चलाते हैं) को शेड्यूल करते हैं? क्या हम सदस्यता वैधता को सत्यापित करने वाले हैं? क्या ऐसा करने के लिए एंड्रॉइड से कोई दिशानिर्देश हैं? Apple को इसके बारे में एक WWDC वीडियो मिला, जो इसके अच्छे अभ्यास के बारे में स्पष्ट रूप से बताता है, लेकिन Play Store के बारे में अधिक जानकारी नहीं पा सकता है।
शंशांक

26

इस पर प्रलेखन भ्रामक है और अजीब तरह से उन चीजों के साथ क्रिया करता है जो वास्तव में महत्वपूर्ण दस्तावेज को लगभग अप्रकाशित और खोजने के लिए कठिन होने के दौरान लगभग असंगत हैं। यह सबसे लोकप्रिय सर्वर प्लेटफॉर्म पर बहुत अच्छा काम करना चाहिए, जो अन्य लोगों के साथ-साथ जावा, पायथन, .नेट और नॉडजेएस सहित गूगल एपीआई क्लाइंट लाइब्रेरी चला सकता है। नोट: मैंने केवल पायथन एपीआई क्लाइंट का परीक्षण किया है जैसा कि नीचे दिखाया गया है।

आवश्यक कदम:

  1. अपने Google Play कंसोल में API एक्सेस लिंक से, एपीआई प्रोजेक्ट बनाएं

  2. एक नया सेवा खाता बनाएं, जो JSON निजी कुंजी उत्पन्न करता है उसे सहेजें । आपको इस फ़ाइल को अपने सर्वर पर ले जाना होगा।

  3. ताज़ा करने के लिए प्ले कंसोल के सर्विस अकाउंट सेक्शन में प्रेस करें और फिर सर्विस अकाउंट तक पहुँच प्रदान करें

  4. Https://developers.google.com/api-client-library से अपने सर्वर प्लेटफॉर्म के लिए एक Google एपि क्लाइंट लाइब्रेरी प्राप्त करें

  5. सेवा इंटरफ़ेस बनाने के लिए अपने विशेष प्लेटफ़ॉर्म के क्लाइंट लाइब्रेरी का उपयोग करें और सीधे अपने खरीद सत्यापन का परिणाम पढ़ें।

आपको ऑथराइजेशन स्कोप्स से परेशान होने की जरूरत नहीं है, कस्टम रिक्वेस्ट कॉल करना, एक्सेस टोकन को रीफ्रेश करना आदि एपि क्लायंट लाइब्रेरी हर चीज का ख्याल रखती है। सदस्यता को सत्यापित करने के लिए यहां एक अजगर पुस्तकालय उपयोग उदाहरण है:

सबसे पहले, इस तरह से अपने pipenv में गूगल एपीआई क्लाइंट स्थापित करें:

$ pipenv install google-api-python-client

फिर आप सेवा खाते को प्रमाणित करने के लिए निजी कुंजी json फ़ाइल का उपयोग करके एपीआई क्लाइंट क्रेडेंशियल्स सेट कर सकते हैं।

credentials = service_account.Credentials.from_service_account_file("service_account.json")

अब आप सीधे पुस्तकालय का उपयोग करके सदस्यता खरीद या उत्पाद खरीद को सत्यापित कर सकते हैं।

#Build the "service" interface to the API you want
service = googleapiclient.discovery.build("androidpublisher", "v3", credentials=credentials)

#Use the token your API got from the app to verify the purchase
result = service.purchases().subscriptions().get(packageName="your.app.package.id", subscriptionId="sku.name", token="token-from-app").execute()
#result is a python object that looks like this ->
# {'kind': 'androidpublisher#subscriptionPurchase', 'startTimeMillis': '1534326259450', 'expiryTimeMillis': '1534328356187', 'autoRenewing': False, 'priceCurrencyCode': 'INR', 'priceAmountMicros': '70000000', 'countryCode': 'IN', 'developerPayload': '', 'cancelReason': 1, 'orderId': 'GPA.1234-4567-1234-1234..5', 'purchaseType': 0}

प्ले डेवलपर एपीआई के लिए प्लेटफ़ॉर्म सेवा इंटरफ़ेस के लिए प्रलेखन आसान तरीके से जुड़ा हुआ नहीं है, कुछ के लिए यह खोजने के लिए बिल्कुल कठिन है । यहाँ लोकप्रिय प्लेटफ़ॉर्म के लिंक दिए गए हैं:

अजगर | जावा | .NET | PHP | NodeJS (Github TS) | गो (जीतूब जानसन)


5
सहमत हूँ, दस्तावेज़ीकरण भयानक है ... फायरबैस (फायरस्टार) और क्लाउड के साथ बैकेंड के रूप में कार्य करने का कोई विचार?
जेफ पडगेट

यदि आपके क्लाउड फ़ंक्शन NodeJS में हैं, तो आप शायद API क्लाइंट लाइब्रेरी को काम करने के लिए ऊपर दिए गए NodeJS लिंक का उपयोग कर सकते हैं?
धीरज गुप्ता

17

PHP के लिए Google API क्लाइंट लाइब्रेरी का उपयोग करने का पूरा उदाहरण :

  1. अपने Google प्रोजेक्ट को सेट करें और मार्क के उत्तर में वर्णित https://stackoverflow.com/a/35138885/1046909 के अनुसार अपने सेवा खाते के लिए Google Play पर पहुंचें ।

  2. लाइब्रेरी स्थापित करें: https://developers.google.com/api-client-library/php/start/installation

  3. अब आप निम्नलिखित तरीके से अपनी रसीद सत्यापित कर सकते हैं:

    $client = new \Google_Client();
    $client->setAuthConfig('/path/to/service/account/credentials.json');
    $client->addScope('https://www.googleapis.com/auth/androidpublisher');
    $service = new \Google_Service_AndroidPublisher($client);
    $purchase = $service->purchases_subscriptions->get($packageName, $productId, $token);

    इसके बाद $ खरीद Google_Service_AndroidPublisher_SubscriptionPurchase का उदाहरण है

    $purchase->getAutoRenewing();
    $purchase->getCancelReason();
    ...

यह काम नहीं कर रहा है, मैं बार आ रही है (401) प्रवेश आवश्यक और setAuthConfig does not को सेवा खाता क्रेडेंशियल json स्वीकार
Raulnd

इसने मेरे लिए putenv ('GOOGLE_APPLICATION_CREDENTIALS = क्रेडेंशियल्स' 'काम किया); $ ग्राहक = नया Google_Client (); $ ग्राहक> useApplicationDefaultCredentials (); $ ग्राहक-> addScope (' googleapis.com/auth/androidpublisher' ); $ सेवा = नया Google_Service_AndroidPublisher ($ ग्राहक); $ खरीद = $ सेवा-> खरीद_प्रोडक्ट-> प्राप्त ($ पैकेजनाम, $ productId, $ टोकन); var_dump ($ खरीद);
राऊंड

यह बात अनुचित बिलिंग के मामले में है। क्या होगा यदि मैं अपने डेटाबेस में ऑर्डर प्राप्त करना चाहता हूं जब भी उपयोगकर्ता अनुपयुक्त के बजाय प्ले स्टोर से मेरा ऐप खरीदता है?
अंकेश कुमार जयसंसारिया

stackoverflow.com/questions/48662787/… कृपया इस प्रश्न को देखें। मैं इस सवाल का जवाब ढूंढ रहा हूं। यह सक्रिय इनाम भी है
अंकेश कुमार जयसंसारिया

@MingalevME क्या होगा अगर टोकन प्रारूप अमान्य है और PHP को एक घातक त्रुटि मिलती है, तो मैं इस त्रुटि को कैसे पकड़ सकता हूं?
एलेक्सएक्स ०१ Jul६

12

आप Purchase.subsults का उपयोग करके कोशिश कर सकते हैं : सर्वर-साइड प्राप्त करें। यह पैरामनेटर के रूप में पैकेजनाम, सबस्क्राइब और टोकन लेता है और प्राधिकरण की आवश्यकता होती है ।

यह जांचता है कि उपयोगकर्ता की सदस्यता खरीद वैध है या नहीं और उसका समय समाप्त हो जाता है।

यदि यह सफल है, तो यह विधि प्रतिक्रिया निकाय में एक खरीद। सदस्यता संसाधन लौटाती है ।


9
मुझे प्राधिकरण के काम करने में गंभीर समस्याएं हो रही हैं।

8
गंभीरता से। कुछ ऐप्स के लिए महत्वपूर्ण खरीदारी कितनी महत्वपूर्ण है, इसके लिए समर्थन और प्रलेखन अपर्याप्त है। यह आपको सर्वर पर करने की आवश्यकता है: github.com/google/… । यहाँ अधिक जानकारी: stackoverflow.com/questions/35127086/…
उपयोगकर्ता

0

मैं इस चिंता का जवाब देता हूं

नेटवर्क कनेक्शन डाउन हो गया है या मेरा अपना सर्वर डाउन हो गया है, उपयोगकर्ता ने केवल Google Play में पैसे का भुगतान किया है लेकिन मैंने अपने सर्वर में खरीदारी रिकॉर्ड नहीं की है? मुझे क्या करना चाहिए, मैं इस स्थिति से कैसे निपट सकता हूं।

स्थिति यह है:

उपयोगकर्ता Google Play सेवा का उपयोग करके 'abc' आइटम खरीदता है -> ठीक है -> कुछ कारणों के लिए सर्वर से सत्यापित करने में विफल रहता है जैसे कि कोई इंटरनेट कनेक्शन नहीं।

समाधान है:

क्लाइंट की ओर से, 'Google वॉलेट' बटन दिखाने से पहले, आप जांच लें कि क्या 'एबीसी' आइटम पहले से ही स्वामित्व में है।

  • यदि हाँ, फिर से सर्वर से सत्यापित करें
  • यदि नहीं, तो 'Google वॉलेट' बटन दिखाएं।

क्रय खरीद = mInventory.getPurchase ('abc');

if (purchase != null) // Verify with server 

else // show Google Wallet button

https://developer.android.com/google/play/billing/billing_reference.html#getSkuDetails


4
मुझे नहीं लगता कि सर्वर पर सत्यापन करना ऐप पर मान्य होने से अधिक सुरक्षित है। दिन के अंत में यह ऐप है जो सुविधाओं को अनलॉक करता है इसलिए ऐप में कोड को निकालना या पलटना संभव है जो यह जांचता है कि क्या सर्वर प्रतिक्रिया "ओके" है
गियानलुका गेथिनी

2
@GianlucaGhettini क्योंकि, कभी-कभी सर्वर वह है जो खरीदी गई सेवा को ऐप के अलावा नहीं प्रदान करता है, ऐप को रिवर्स इंजीनियर किया जा सकता है और फिर कुछ संघर्ष के साथ सत्यापन प्रक्रिया को हैक किया जा सकता है।
मोहियादीन अलाउद्दीन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.