रिफ़ंड पर कार्रवाई करने से पहले App Store सर्वर नोटिफ़िकेशन सत्यापित करें, क्योंकि आपके webhook URL पर कोई भी पोस्ट कर सकता है
जब तक आप इसके सिग्नेचर की जाँच नहीं करते, रिफ़ंड नोटिफ़िकेशन सिर्फ़ एक HTTPS अनुरोध है। जानिए App Store सर्वर नोटिफ़िकेशन और Google Play RTDN संदेशों को कैसे सत्यापित करें, हर स्टोर क्या साइन करता है, और जाली या गलती से अस्वीकार किया गया रिफ़ंड आपको कितना महँगा पड़ता है।

मुख्य बातें
- Apple हर version 2 App Store सर्वर नोटिफ़िकेशन को signedPayload के रूप में भेजता है, जो तीन Base64URL हिस्सों वाला JSON Web Signature है: एक header, एक payload और एक signature।
- App Store सर्वर नोटिफ़िकेशन के JWS header में तीन सर्टिफ़िकेट की x5c सर्टिफ़िकेट चेन होती है: एक signing leaf, Apple Worldwide Developer Relations एक्सटेंशन 1.2.840.113635.100.6.2.1 वाला एक Apple intermediate, और एक Apple root।
- Apple की App Store Server Library एक SignedDataVerifier से नोटिफ़िकेशन सत्यापित करती है, जो सर्टिफ़िकेट चेन, bundle ID, environment और production में appAppleId की जाँच करता है, और ऑनलाइन सर्टिफ़िकेट रद्दीकरण भी जाँच सकता है।
- Google Play Real-time developer notifications पर Google Play का सिग्नेचर नहीं होता। push subscription पर Pub/Sub, Authorization header में एक साइन किया हुआ OpenID Connect टोकन जोड़ सकता है, और आपका सर्वर उसके सिग्नेचर, audience और email claims की जाँच करता है।
- Google कहता है कि RTDN सिर्फ़ यह बताता है कि किसी खरीद की स्थिति बदली है, इसलिए किसी भी रिफ़ंड नोटिफ़िकेशन पर सुरक्षित कदम यह है कि एक्सेस रद्द करने से पहले Google Play Developer API से उसकी पुष्टि करें।
- Apple, App Store सर्वर नोटिफ़िकेशन 17.0.0.0/8 subnet से भेजता है, लेकिन IP allow list सिर्फ़ यह सीमित करती है कि आपके endpoint तक कौन पहुँच सकता है। संदेश Apple से आया है, यह सिग्नेचर ही साबित करता है।
- असली संदेशों को गलती से अस्वीकार करने वाला verifier उतना ही महँगा है जितना जाली संदेश स्वीकार करने वाला, क्योंकि छोड़े गए CONSUMPTION_REQUEST की जवाब देने की अवधि 12 घंटे है और Google Play chargeback समीक्षा की 24 घंटे।
जिसे भी आपका webhook URL पता चल जाए, वह उस पर रिफ़ंड भेज सकता है। हर App Store सर्वर नोटिफ़िकेशन और हर Google Play Real-time developer notification के पीछे यही असहज सच्चाई है: जब तक आप इसे सत्यापित नहीं करते, संदेश बस कुछ JSON वाला एक HTTPS POST है। अगर आपका सर्वर किसी अनुरोध में REFUND लिखा होने भर से subscription रद्द करता है, क्रेडिट वापस लेता है या खाता बंद करता है, तो आपने यह ताक़त हर उस व्यक्ति को दे दी है जो एक curl कमांड लिख सकता है।
दोनों स्टोर जाँच का तरीका देते हैं। Apple नोटिफ़िकेशन को खुद साइन करता है, इसलिए आप सिर्फ़ Apple के root सर्टिफ़िकेट से App Store सर्वर नोटिफ़िकेशन सत्यापित कर सकते हैं। Google Play अलग रास्ता अपनाता है। संदेश साइन नहीं होता, लेकिन Pub/Sub डिलीवरी साइन की जा सकती है, और Google वैसे भी कहता है कि हर बदलाव की पुष्टि उसकी API से करें। यहाँ बताया गया है कि हर तरीका क्या साबित करता है, और किसी भी दिशा में गलती होने पर उसकी क्या कीमत चुकानी पड़ती है।
हर स्टोर वास्तव में क्या साइन करता है
| प्रश्न | App Store Server Notifications V2 | Google Play RTDN |
|---|---|---|
| क्या संदेश खुद साइन होता है? | हाँ, signedPayload एक JWS है | नहीं, data फ़ील्ड base64-encoded JSON है |
| भेजने वाले को क्या साबित करता है | Apple root तक x5c सर्टिफ़िकेट चेन | push पर Pub/Sub OIDC टोकन, या आपका अपना authenticated pull |
| अंदर के साइन किए गए ऑब्जेक्ट | signedTransactionInfo और signedRenewalInfo, हर एक अपना JWS | कोई नहीं |
| आपके ऐप से मिलाने वाले फ़ील्ड | bundleId, appAppleId, environment | packageName |
| स्रोत नेटवर्क | 17.0.0.0/8, sandbox और production | Google Cloud Pub/Sub |
| कार्रवाई से पहले पुष्टि | वैकल्पिक, साइन किया हुआ डेटा ही रिकॉर्ड है | ज़रूरी, Google कहता है Developer API कॉल करें |
| ट्रांसपोर्ट | HTTPS, TLS 1.2 या बाद का | HTTPS push, या client library pull |
App Store सर्वर नोटिफ़िकेशन कैसे सत्यापित करें
Apple के दस्तावेज़ signedPayload को बिंदुओं से अलग किए गए तीन Base64URL-encoded हिस्सों की स्ट्रिंग बताते हैं: एक header, एक payload और एक signature, जो JSON Web Signature specification के अनुसार साइन होती है। payload को decode करना आसान है। उस पर भरोसा करने के लिए चार जाँचें चाहिए।
- decode किए गए header से x5c array पढ़ें। Apple क्रम बताता है: पहले signing key वाला सर्टिफ़िकेट, फिर एक Apple intermediate सर्टिफ़िकेट, फिर एक Apple root सर्टिफ़िकेट।
- उस चेन को उस Apple root के विरुद्ध सत्यापित करें जो आपने खुद Apple की PKI साइट से डाउनलोड किया है, व्यवहार में Apple Root CA - G3। संदेश के अंदर आए root पर कभी भरोसा न करें, क्योंकि जालसाज़ वहाँ कोई भी सर्टिफ़िकेट रख सकता है।
- पुष्टि करें कि intermediate में Apple Worldwide Developer Relations एक्सटेंशन 1.2.840.113635.100.6.2.1 है, फिर leaf सर्टिफ़िकेट की public key से JWS सिग्नेचर सत्यापित करें।
- decode किए गए डेटा को अपने ऐप से मिलाएँ: bundleId, production में appAppleId, और environment। किसी दूसरे डेवलपर के ऐप पर, या आपके production endpoint पर आई sandbox खरीद पर, Apple का वैध सिग्नेचर भी आपका रिफ़ंड नहीं है।
फिर अंदर की सामग्री के लिए यही दोबारा करें। data ऑब्जेक्ट में signedTransactionInfo और signedRenewalInfo होते हैं, और हर एक अपनी x5c चेन वाला अलग JWS है। जो REFUND handler लिफ़ाफ़े को सत्यापित करता है लेकिन transaction को बिना सत्यापित किए पढ़ लेता है, उसने बीच में एक छेद छोड़ दिया है।
खुद लिखने के बजाय Apple की library इस्तेमाल करें
Apple, Swift, Java, Python और Node के लिए App Store Server Library प्रकाशित करता है। इसका SignedDataVerifier आपके root सर्टिफ़िकेट, एक online-checks flag, environment, आपका bundle ID और production के लिए आपका appAppleId लेता है। Node का source दिखाता है कि यह क्या लागू करता है: चेन में ठीक तीन सर्टिफ़िकेट, Apple leaf एक्सटेंशन 1.2.840.113635.100.6.11.1 और intermediate एक्सटेंशन, सर्टिफ़िकेट की वैधता की तारीखें, और मेल खाते bundle ID, app ID और environment। online checks चालू होने पर यह OCSP responder से यह भी पूछता है कि leaf और intermediate सर्टिफ़िकेट रद्द तो नहीं हुए।

क्या IP allow list काफ़ी है?
नहीं। Apple कहता है कि अगर आपके सर्वर को allow list चाहिए, तो 17.0.0.0/8 subnet जोड़ें, और यह sandbox और production दोनों पर लागू होता है। इससे शोर कम होता है। यह साबित नहीं करता कि संदेश असली है, और जैसे ही Apple का नेटवर्क किसी ऐसे तरीके से बदलता है जिसकी आपको खबर नहीं मिली, यह टूट जाता है। असली दरवाज़ा सिग्नेचर जाँच को ही रखें।
Google Play रिफ़ंड नोटिफ़िकेशन कैसे सत्यापित करें
Google Play, RTDN संदेशों को आपके अपने Pub/Sub topic पर प्रकाशित करता है, और उस पर Pub/Sub Publisher भूमिका सिर्फ़ google-play-developer-notifications@system.gserviceaccount.com service account के पास होनी चाहिए। फिर आपकी subscription दो में से किसी एक तरीके से संदेश पहुँचाती है, और हर तरीके का अपना प्रमाण है।
- Pull subscription: आपका सर्वर Pub/Sub से एक authenticated कनेक्शन खोलता है और संदेश लाता है। कोई सार्वजनिक endpoint नहीं है, इसलिए किसी अजनबी के पास पोस्ट करने के लिए कुछ नहीं है।
- authentication चालू वाली Push subscription: Pub/Sub एक JSON Web Token साइन करता है और उसे Authorization header में Bearer टोकन के रूप में भेजता है। Google की गाइड कहती है कि टोकन के सिग्नेचर को सत्यापित करें और जाँचें कि उसके email और audience claims आपकी कॉन्फ़िगर की गई वैल्यू से मेल खाते हैं, और उसका sample code यह भी माँगता है कि email_verified true हो। टोकन एक घंटे तक पुराना हो सकता है।
- authentication के बिना Push subscription: जो कुछ भी URL तक पहुँच सकता है, वह RTDN जैसा दिखने वाला संदेश भेज सकता है।
Google क्यों चाहता है कि आप API से पुष्टि करें
पूरी तरह authenticated RTDN में भी पूरी कहानी नहीं होती। Google की setup गाइड साफ़ कहती है कि ये नोटिफ़िकेशन सिर्फ़ इतना बताते हैं कि किसी खरीद की स्थिति बदली है, और पूरी स्थिति जानने के लिए आपको Google Play Developer API कॉल करनी होगी। voidedPurchaseNotification के लिए इसका मतलब है कि कुछ भी रद्द करने से पहले Voided Purchases API में खरीद खोजें, या उसकी मौजूदा स्थिति लाएँ। API कॉल आपके अपने service account से authenticated होती है, इसलिए उसका जवाब ऐसा है जिसे कोई जालसाज़ नकली नहीं बना सकता।
जाली या अस्वीकार किए गए रिफ़ंड की पैसों में कीमत
जिस जाली रिफ़ंड नोटिफ़िकेशन पर आप भरोसा करते हैं, उसकी कीमत एक भुगतान करने वाला ग्राहक है। आप ऐसे व्यक्ति को बाहर कर देते हैं जिसका पैसा अभी भी आपके पास है, वह support ticket खोलता है, और कुछ लोग स्टोर जाकर वही रिफ़ंड माँगेंगे जो आपके सिस्टम ने देने का दिखावा पहले ही कर दिया था। जाली खरीद या renewal की कीमत उल्टी दिशा में पड़ती है: आप ऐसी आमदनी के बदले GPU compute, सशुल्क third-party API कॉल, storage और creator payouts देते हैं जो कभी थी ही नहीं।
उल्टी विफलता शांत होती है और अक्सर बड़ी। जो verifier गलत appAppleId, production में sandbox सेटिंग या पुराने root सर्टिफ़िकेट की वजह से असली संदेश अस्वीकार करता है, वह ठीक वे दो रिफ़ंड प्रक्रियाएँ गिरा देता है जहाँ आपके सबूत मायने रखते हैं। Apple, CONSUMPTION_REQUEST के 12 घंटे के भीतर consumption डेटा माँगता है। Google, orders.reviewrefund के ज़रिए chargeback समीक्षा का जवाब देने के लिए 24 घंटे देता है, और August 3, 2026 के बाद दिए गए ऑर्डर पर हारा हुआ Google Play chargeback आपको खरीद मूल्य में से Play की सेवा फ़ीस घटाकर, साथ में खरीदार के बैंक की फ़ीस जितना पड़ता है।
| विफलता | क्या होता है | इसकी कीमत |
|---|---|---|
| जाली REFUND स्वीकार | एक भुगतान करने वाला ग्राहक एक्सेस खो देता है | support का समय और एक असली रिफ़ंड अनुरोध जिसे आपने खुद बुलाया |
| जाली खरीद स्वीकार | सशुल्क फ़ीचर तक मुफ़्त एक्सेस | बिना आमदनी के compute, API कॉल, storage और payouts |
| असली CONSUMPTION_REQUEST अस्वीकार | Apple आपके डेटा के बिना फ़ैसला करता है | बिक्री, और उसे देने में पहले से खर्च हुआ सब कुछ |
| असली chargeback समीक्षा अस्वीकार | Google आपके सबूत के बिना फ़ैसला करता है | August 3, 2026 के बाद के ऑर्डर पर खरीद मूल्य और बैंक फ़ीस |
सत्यापन के बग को समय-सीमा न निगलने दें
- सत्यापित करने से पहले raw अनुरोध सहेजें, ताकि अस्वीकार किया गया संदेश कभी सचमुच खो न जाए।
- हर सत्यापन विफलता पर अलर्ट करें। एक जाली संदेश शोर है। एक साथ हर संदेश का विफल होना आपका अपना बग है।
- Apple पर, आप अस्वीकार किए गए संदेश दोबारा चला सकते हैं। Get Notification History पिछले 180 दिनों का मूल signedPayload लौटाता है, इसलिए verifier ठीक करें और सहेजे या वापस पाए गए payloads को उससे फिर से गुज़ारें।
- Google पर, लंबित chargeback समीक्षा सिर्फ़ अपने नोटिफ़िकेशन में होती है, इसलिए गलत कॉन्फ़िगर push audience का मतलब एक छूटी हुई समीक्षा है। हर बदलाव के बाद Play Console में Send Test Message से इसकी जाँच करें।
RefundHalt दोनों स्टोर के नोटिफ़िकेशन सत्यापित करता है, कुछ भी बदलने से पहले स्टोर की APIs से रिफ़ंड की पुष्टि करता है, और CONSUMPTION_REQUEST और chargeback समीक्षाओं का जवाब उनकी समय-सीमा के भीतर देता है, ताकि कोई नकली संदेश आपसे ग्राहक न छीन सके और कोई असली संदेश छूट न जाए।
अक्सर पूछे जाने वाले सवाल
- मैं App Store सर्वर नोटिफ़िकेशन कैसे सत्यापित करूँ?
- signedPayload को JSON Web Signature के रूप में सत्यापित करें। उसके header से x5c सर्टिफ़िकेट चेन पढ़ें, उसे Apple की PKI साइट से डाउनलोड किए गए Apple root सर्टिफ़िकेट के विरुद्ध सत्यापित करें, leaf सर्टिफ़िकेट की key से सिग्नेचर सत्यापित करें, फिर जाँचें कि bundleId, appAppleId और environment आपके ऐप से मेल खाते हैं। Apple की App Store Server Library यह सब अपने SignedDataVerifier में करती है।
- App Store सर्वर नोटिफ़िकेशन सत्यापित करने के लिए मैं कौन-सी key इस्तेमाल करूँ?
- आपको App Store Connect से कोई key नहीं चाहिए। public key, JWS header के अंदर x5c चेन के पहले सर्टिफ़िकेट में होती है, और आप उस पर तभी भरोसा करते हैं जब चेन को खुद हासिल किए गए Apple root सर्टिफ़िकेट तक सत्यापित कर लें। आपकी In-App Purchase key, Apple की APIs कॉल करने के लिए है, नोटिफ़िकेशन जाँचने के लिए नहीं।
- क्या Google Play Real-time developer notifications साइन होते हैं?
- नहीं, Google Play खुद RTDN संदेश को साइन नहीं करता। authenticated push subscription पर Pub/Sub, Authorization header में एक साइन किया हुआ OpenID Connect टोकन भेजता है जिसे आप सत्यापित करते हैं, और Google कहता है कि खरीद की पूरी स्थिति जानने के लिए हर नोटिफ़िकेशन के बाद Google Play Developer API कॉल करें।
- जब कोई नोटिफ़िकेशन सत्यापन में विफल हो, तो क्या मेरे सर्वर को error लौटानी चाहिए?
- पहले raw अनुरोध सहेजें, फिर फ़ैसला करें। Apple, 40x या 50x जवाब के बाद version 2 नोटिफ़िकेशन को पिछले प्रयास के 1, 12, 24, 48 और 72 घंटे बाद दोबारा भेजता है। अगर विफलता आपके अपने कॉन्फ़िगरेशन की है, तो Get Notification History से आप 180 दिनों तक मूल signedPayload वापस पा सकते हैं और ठीक करने के बाद उसे फिर से सत्यापित कर सकते हैं।
- अगर मैं सिर्फ़ Apple की IP range की अनुमति देता हूँ, तो क्या मुझे फिर भी नोटिफ़िकेशन सत्यापित करने होंगे?
- हाँ। Apple, allow list वाले सर्वरों से 17.0.0.0/8 subnet स्वीकार करने को कहता है, जो सीमित करता है कि कौन कनेक्ट कर सकता है, लेकिन यह साबित नहीं करता कि संदेश असली है। JWS सिग्नेचर ही वह जाँच है जो नोटिफ़िकेशन को Apple और आपके ऐप से जोड़ती है।
स्रोत और आगे की जानकारी
- Apple Developer: signedPayload
- Apple Developer: JWSDecodedHeader
- Apple Developer: Enabling App Store Server Notifications
- Apple Developer: Responding to App Store Server Notifications
- Apple on GitHub: App Store Server Library (Node)
- Android Developers: Get ready (Real-time developer notifications setup)
- Google Cloud: Authentication for push subscriptions
- Play Console Help: Updates to refund protection and chargeback cost responsibility
RefundHalt
App Store और Google Play के लिए refund ऑटोपायलट
आगे पढ़ें
ज़्यादा रिफ़ंड अनुरोध आपको रिफ़ंड से भी महंगे पड़ सकते हैं, क्योंकि दोनों ऐप स्टोर इन्हें क्वालिटी का संकेत मानते हैं
Apple की गाइडलाइन 5.6.4 ज़्यादा रिफ़ंड अनुरोधों को इस बात का संकेत बताती है कि ऐप क्वालिटी के मानकों पर खरा नहीं उतर रहा, और Google का डिस्ट्रिब्यूशन एग्रीमेंट नए डेवलपर्स के ऐप रिफ़ंड दर के आधार पर हटाने की अनुमति देता है। जानिए हर स्टोर क्या कहता है, ऐप हटने की कीमत क्या है और इससे कैसे बचें।
छूटे हुए रिफ़ंड नोटिफ़िकेशन आपसे वही रिफ़ंड छीन सकते हैं जिन्हें आप चुनौती दे सकते हैं, और समय रहते देखें तो दोनों स्टोर इन्हें वापस पाने देते हैं
जब आपका सर्वर कोई रिफ़ंड नोटिफ़िकेशन चूक जाता है, तो आपके सबूत माँगने वाले दोनों रिफ़ंड फ़्लो आपके बिना बंद हो जाते हैं। जानिए Apple और Google Play कैसे दोबारा कोशिश करते हैं, छूटे हुए रिफ़ंड नोटिफ़िकेशन कितने पीछे तक वापस मिल सकते हैं, और रिकवरी में कहाँ कमियाँ हैं।