एक ऐसा endpoint है जो किसी ग्राहक का पूरा App Store रिफ़ंड इतिहास लौटाता है, और यहाँ बताया गया है कि यह क्या देता है
Apple का Get Refund History endpoint किसी ग्राहक का पूरा App Store रिफ़ंड इतिहास signed transactions के रूप में लौटाता है। यहाँ हर फ़ील्ड है, revision token कैसे पेज बनाता है, यह प्रति ऐप नहीं बल्कि प्रति ग्राहक क्यों है, और जो रिफ़ंड आप चूक जाते हैं उसकी क्या कीमत चुकानी पड़ती है।

मुख्य बातें
- Get Refund History एक App Store Server API endpoint है जो आपके ऐप के लिए किसी ग्राहक की रिफ़ंड की गई in-app खरीदारियों को signed transactions की सूची के रूप में लौटाता है, ताकि आप रिफ़ंड का मिलान कर सकें और पहुँच रद्द कर सकें, भले ही कोई notification आप तक कभी न पहुँची हो।
- आप उस ग्राहक की किसी भी transaction id के साथ GET /inApps/v2/refund/lookup/{transactionId} कॉल करते हैं, और Apple आपके ऐप में हर खरीदारी प्रकार के लिए उनके रिफ़ंड लौटाता है, सिर्फ़ वही नहीं जिसके बारे में आपने पूछा।
- प्रतिक्रिया में तीन फ़ील्ड होते हैं: signedTransactions, प्रति पेज अधिकतम 20 JWS transactions जो सबसे पुराने रिफ़ंड को पहले क्रम में रखते हैं, साथ ही पेजिंग के लिए एक revision token और एक hasMore boolean।
- अंतिम revision token को संग्रहित करें। अगली बार इसे वापस पास करें और Apple केवल उस बिंदु से नए रिफ़ंड लौटाता है, जो हर बार पूरे इतिहास के डंप को नई पंक्तियों की एक छोटी सूची में बदल देता है।
- प्रत्येक decoded transaction में revocationDate और revocationReason होता है। revocationReason का 1 होना मतलब ग्राहक ने आपके ऐप में किसी वास्तविक या कथित समस्या के कारण रिफ़ंड लिया, और 0 का मतलब कोई अन्य कारण है जैसे कि गलती से की गई खरीदारी।
- यह endpoint प्रति ग्राहक है, प्रति ऐप नहीं। ऐसी कोई एक कॉल नहीं है जो आपके पूरे ऐप के हर रिफ़ंड को सूचीबद्ध करे, इसलिए आप एक transaction id से प्रति खाता मिलान करते हैं, या ऐप-व्यापी दृश्य के लिए अपने REFUND notification फ़ीड को पढ़ते हैं।
- इसे जोड़ने का कारण पैसा है। जो रिफ़ंड आप कभी नहीं पकड़ते वह एक खाते को चालू रखता है, और आप एक ऐसे ग्राहक के लिए compute, model API calls, storage और payouts का भुगतान करते रहते हैं जिसे App Store पहले ही भरपाई दे चुका है।
Apple आपके ऐप के लिए किसी ग्राहक के खाते पर दिए गए हर रिफ़ंड का एक क्वेरी करने योग्य रिकॉर्ड रखता है, और एक कॉल उसे लौटा देती है। यह endpoint Get Refund History है, App Store Server API का हिस्सा, और यह आपको उस ग्राहक का पूरा App Store रिफ़ंड इतिहास signed transactions की सूची के रूप में सौंपता है। आप एक transaction id पास करते हैं, आपको वह मिलता है जो Apple ने रिफ़ंड किया, और आप उसका मिलान उससे करते हैं जो आपने अभी भी चालू रखा है।
यहाँ बताया गया है कि आप इसकी परवाह क्यों करेंगे। जो रिफ़ंड आप कभी नहीं देखते वह एक ऐसा रिफ़ंड है जिसके लिए आप भुगतान करते रहते हैं। पैसा तो जा चुका है, लेकिन खाता चालू रहता है, और हर घंटे जब तक यह चालू है आप compute, model API calls, storage और उस ग्राहक से जुड़े किसी भी payout पर खर्च करते रहते हैं। आपकी रिफ़ंड notifications का मकसद इसे उसी पल पकड़ना है जब यह होता है। Get Refund History तब के लिए बैकस्टॉप है जब वे नहीं पकड़तीं, किसी आउटेज के बाद, किसी ऐसे deploy के बाद जिसने webhook गिरा दिया, या किसी सपोर्ट केस में जहाँ आपको एक ही कॉल में पूरी तस्वीर चाहिए।
App Store रिफ़ंड इतिहास endpoint क्या लौटाता है
आप App Store Server API के विरुद्ध GET /inApps/v2/refund/lookup/{transactionId} कॉल करते हैं, उसी JWT से हस्ताक्षरित जिसका उपयोग आप उसकी हर दूसरी कॉल के लिए करते हैं। पथ में transaction id उस ग्राहक का कोई भी transaction हो सकता है। Apple इसे एक पहचान के रूप में पढ़ता है, फ़िल्टर के रूप में नहीं, और आपके पूरे ऐप में उस ग्राहक की रिफ़ंड की गई खरीदारियाँ लौटाता है: consumables, non-consumables, auto-renewable और non-renewing subscriptions, सभी। इस endpoint का पुराना V1 एक ही प्रतिक्रिया में अधिकतम 50 रिफ़ंड लौटाता था और अब बंद हो चुका है। वर्तमान संस्करण पेज बनाता है, ताकि आप लंबे इतिहास वाले ग्राहकों को एक विशाल payload के बिना संभाल सकें।
प्रतिक्रिया में तीन फ़ील्ड हैं
| फ़ील्ड | यह क्या रखता है |
|---|---|
| signedTransactions | इस ग्राहक के लिए अधिकतम 20 रिफ़ंड की गई transactions, प्रत्येक एक signed JWS जिसे आप सत्यापित और decode करते हैं। revocationDate के अनुसार सबसे पुराने रिफ़ंड को पहले क्रम में। खाली array का मतलब ग्राहक के आपके ऐप में कोई रिफ़ंड नहीं हैं |
| revision | एक पेजिंग टोकन। अगला पेज पाने के लिए इसे वापस पास करें, और अगली बार केवल नए रिफ़ंड लाने के लिए अंतिम को रखें |
| hasMore | True तब जब Apple के पास इस पेज में लौटाए गए से अधिक रिफ़ंड की गई transactions हों, इसलिए आप revision के साथ फिर से कॉल करें |
एक रिफ़ंड की गई transaction आपको क्या बताती है
signedTransactions में प्रत्येक प्रविष्टि एक JWS है। इसे Apple की certificate chain के विरुद्ध सत्यापित करें, इसे decode करें, और आपके पास रिफ़ंड फ़ील्ड भरे हुए एक सामान्य transaction payload होता है। यहाँ वही मायने रखते हैं।
| फ़ील्ड | यह आपको क्या बताता है |
|---|---|
| transactionId | रिफ़ंड की गई transaction की id, आपकी दर्ज की गई खरीदारी से वापस जोड़ने की कुंजी |
| originalTransactionId | श्रृंखला की पहली खरीदारी की id, यह कि आप एक subscription के नवीनीकरणों को एक साथ कैसे बांधते हैं |
| productId | वह उत्पाद जो रिफ़ंड किया गया था, ताकि आप सही entitlement रद्द करें और कुछ और नहीं |
| revocationDate | वह UNIX समय, मिलीसेकंड में, जब Apple ने transaction रिफ़ंड किया |
| revocationReason | Apple ने इसे क्यों रिफ़ंड किया। 1 का मतलब आपके ऐप में एक वास्तविक या कथित समस्या, 0 का मतलब कोई अन्य कारण जैसे कि गलती से की गई खरीदारी |
| price, currency | राशि, milliunits में, और उसका ISO 4217 मुद्रा कोड, ताकि आप लौटाए गए पैसे का कुल जोड़ सकें |
| appAccountToken | वह UUID जो आपने खरीद पर जोड़ा था, किसी रिफ़ंड को अपने उपयोगकर्ता से वापस जोड़ने का सबसे साफ़ तरीका |
revision token वह तरीका है जिससे आप पूरी सूची को दोबारा पढ़ना बंद करते हैं
इस endpoint का उपयोग करने का भोला तरीका है हर बार एक ग्राहक को देखना और हर पेज पर चलना। यह काम करता है, और पचास रिफ़ंड वाले ग्राहक पर यह पचास पंक्तियाँ हैं जिन्हें आप पहले से जानते थे, साथ ही वह एक नई पंक्ति। revision token उस बर्बादी को खत्म करने के लिए मौजूद है। प्रत्येक प्रतिक्रिया में एक revision होता है। जब hasMore true हो, तो अगला पेज पाने के लिए इसे वापस पास करें। जब आप अंत तक पहुँचें, तो आपने देखा अंतिम revision रखें।
यह endpoint क्या नहीं करेगा
इस पर निर्माण करने से पहले एक अपेक्षा छोड़ देनी है। Get Refund History प्रति ग्राहक है, प्रति ऐप नहीं। आप इससे पिछले हफ़्ते आपके ऐप को मिले हर रिफ़ंड के लिए नहीं पूछ सकते। यह एक सवाल का जवाब देता है, इस खाते के पास कौन से रिफ़ंड हैं, और इसे पूछने के लिए आपको उस खाते की एक transaction id के साथ आना होगा। डेवलपर्स लगातार इस दीवार से टकराते हैं और एक पूरे-ऐप रिफ़ंड endpoint की तलाश में जाते हैं जो मौजूद नहीं है।
ऐप-व्यापी दृश्य कहीं और रहता है। आपका App Store Server Notifications फ़ीड हर रिफ़ंड के मंज़ूर होते ही एक REFUND notification भेजता है, और Get Notification History आपको उस फ़ीड को एक तिथि सीमा में रिफ़ंड प्रकारों तक फ़िल्टर करके फिर से चलाने देता है। तो विभाजन साफ़ है। Notifications और उनका इतिहास आपको ऐप-व्यापी धारा देते हैं। Get Refund History आपको एक खाते की आधिकारिक सूची देता है, माँग पर, जो वही है जो आप किसी सपोर्ट डेस्क पर या किसी आउटेज के बाद चाहते हैं।

एक चूका हुआ रिफ़ंड आपको पैसे में क्या पड़ता है
यह endpoint प्लंबिंग है। बिल वह कारण है जिससे आप पाइप बिछाते हैं। उस सूची में हर रिफ़ंड पहले ही लौटाया गया पैसा है, और आपके नियंत्रण में बचा एकमात्र चर यह है कि आप एक ऐसे खाते पर कब तक खर्च करते रहते हैं जो अब भुगतान नहीं करता।
आप एक रिफ़ंड किए गए खाते की सेवा के लिए भुगतान करते रहते हैं
Apple के रिफ़ंड मंज़ूर करते ही खरीद मूल्य चला जाता है। जो चलता रहता है वह डिलीवरी की लागत है। एक ऐसे ऐप के लिए जो प्रति उपयोगकर्ता वास्तविक काम करता है, वह है compute, model API calls, storage, और उनके उपयोग से जुड़ा कोई भी creator या partner payout। एक रिफ़ंड किया गया ग्राहक जिसकी पहुँच आप कभी नहीं काटते, एक ऐसी subscription है जिसे आप अपनी जेब से चलाते हैं। Get Refund History के विरुद्ध मिलान करना और जो आप पाते हैं उस पर रद्द करना ही वह तरीका है जिससे आप उस मीटर को बंद करते हैं जब कोई notification छूट जाती है।
1 का रिफ़ंड कारण भेस में एक खामी रिपोर्ट है
revocationReason आपको दोगुना पड़ता है अगर आप इसे अनदेखा करते हैं। पहली लागत रिफ़ंड ही है। दूसरी उसी कारण से हर भविष्य का रिफ़ंड है। जब कोई उत्पाद revocationReason 1 के साथ बार-बार लौटता रहता है, आपके ऐप में एक वास्तविक या कथित समस्या, तो Apple आपको इस बात का एक लेबल किया गया नमूना सौंप रहा है कि किस चीज़ से ग्राहक अपना पैसा वापस माँगते हैं। इसे उत्पाद के अनुसार रुझान में डालें और आप एक-एक रिफ़ंड चुकाने के बजाय रिसाव को ठीक कर सकते हैं।
इसे देर से पकड़ना फिर भी न पकड़ने से बेहतर है
एक chargeback बैंक के साथ अंतिम होता है और, दूसरे स्टोर पर, अब एक शुल्क लेकर आता है जिसे डेवलपर वहन करता है। एक App Store रिफ़ंड वह नहीं है। यह निपट चुका है, लेकिन entitlement आपका है रद्द करने के लिए जिस पल आप जानते हैं। तो एक रिफ़ंड भी जो आप इस endpoint के ज़रिए दिनों बाद पाते हैं, पाने लायक है। आप पैसा वापस नहीं छीन सकते, लेकिन आप उस खर्च को रोक सकते हैं जो अभी भी उसके पीछे चल रहा था।
यह notifications के साथ, और Google के साथ कैसे फ़िट होता है
टुकड़ों को एक प्रणाली के रूप में सोचें। REFUND notification जीवंत संकेत है, जैसे ही Apple निर्णय लेता है आपके सर्वर पर पुश किया जाता है। Get Refund History किसी एक ग्राहक के लिए सत्य का पुल-आधारित स्रोत है, वह कॉल जो आप तब करते हैं जब पुश विफल हो गया हो या जब किसी इंसान को पूरा खाता अपने सामने चाहिए हो। Google Play की ओर आकार अलग नामों के साथ वही विचार है: एक VoidedPurchaseNotification वास्तविक समय में पुश करता है, और Voided Purchases API वह सूची है जिसे आप खींचते हैं। दोनों स्टोर आपको एक धारा और एक बहीखाता देते हैं। गलती केवल धारा पर भरोसा करना है, क्योंकि धाराएँ गिरती हैं।
इसे RefundHalt तरीके से जोड़ना
एक बार हर टुकड़ा जगह पर होने के बाद लूप छोटा है। एक REFUND notification को ट्रिगर के रूप में लें। Get Refund History के विरुद्ध मिलान करें ताकि एक गिरा हुआ webhook कभी किसी रिफ़ंड किए गए खाते को चालू न छोड़े। प्रत्येक transaction को decode करें, इसे appAccountToken या transactionId पर अपने उपयोगकर्ता से वापस जोड़ें, revocationReason पढ़ें ताकि एक खामी वाला रिफ़ंड चिह्नित हो न कि केवल फ़ाइल किया जाए, और पूरे खाते के बजाय ठीक-ठीक entitlement रद्द करें। revision token के साथ पेज करें ताकि आप नए रिफ़ंड पढ़ें, पुराने नहीं।
यह वह हिस्सा है जो RefundHalt आपके लिए चलाता है। यह रिफ़ंड notifications को सुनता है, जब उसे आधिकारिक सूची चाहिए होती है तो Get Refund History पर वापस गिरता है, हर signed transaction को सत्यापित करता है, ठीक-ठीक खरीदारी को रद्द करता है, और revision को रखता है ताकि हर पास केवल वही पढ़े जो बदला। आपको सेकंडों में पहुँच कटी हुई मिलती है और इसका एक साफ़ रिकॉर्ड कि किसे रिफ़ंड किया गया, किसके लिए, और क्यों, बिना खुद polling और JWS सत्यापन खड़ा किए।
अक्सर पूछे जाने वाले सवाल
- मैं सिर्फ़ एक ग्राहक नहीं, बल्कि अपने पूरे ऐप में हर रिफ़ंड कैसे देखूँ?
- Get Refund History से आप नहीं देख सकते, क्योंकि यह प्रति ग्राहक है और उस खाते के लिए एक transaction id की ज़रूरत है जिसके बारे में आप पूछ रहे हैं। ऐप-व्यापी दृश्य के लिए, अपने App Store Server Notifications फ़ीड का उपयोग करें, जो Apple के हर रिफ़ंड मंज़ूर करते ही उसके लिए एक REFUND notification भेजता है, और उस फ़ीड को एक तिथि सीमा में रिफ़ंड प्रकारों तक फ़िल्टर करके फिर से चलाने के लिए Get Notification History।
- Get Refund History endpoint कितने रिफ़ंड लौटाता है?
- वर्तमान संस्करण प्रति पेज अधिकतम 20 रिफ़ंड की गई transactions लौटाता है, सबसे पुराने रिफ़ंड को पहले क्रम में, और जब hasMore true हो तो एक revision token के साथ बाकी में से पेज बनाता है। बंद हो चुका V1 endpoint एक ही प्रतिक्रिया में अधिकतम 50 लौटाता था। कुल पर कोई सीमा नहीं है, इसलिए लंबे इतिहास वाला ग्राहक बस अधिक पेजों में फैलता है।
- revision token किस लिए है?
- यह वह तरीका है जिससे आप पेज बनाते हैं और जिससे आप हर बार किसी ग्राहक के पूरे इतिहास को दोबारा पढ़ने से बचते हैं। हर प्रतिक्रिया में एक revision शामिल होता है। अगला पेज लाने के लिए आप इसे वापस पास करते हैं, और अंतिम को संग्रहित करते हैं ताकि आपकी अगली खोज केवल उस बिंदु से नए रिफ़ंड लौटाए। यह एक निर्धारित मिलान को नई पंक्तियों की एक छोटी सूची तक सीमित रखता है।
- एक रिफ़ंड की गई transaction में revocationReason का क्या मतलब है?
- यह वह है कि Apple ने transaction को क्यों रिफ़ंड किया। 1 का मान मतलब ग्राहक ने आपके ऐप के भीतर किसी वास्तविक या कथित समस्या के कारण रिफ़ंड लिया, और 0 का मतलब कोई अन्य कारण, जैसे कि गलती से की गई खरीदारी। revocationDate आपको बताता है कि रिफ़ंड कब हुआ, UNIX मिलीसेकंड में। revocationReason पढ़ने से आप एक उत्पाद खामी को एक बार के पछतावे वाले रिफ़ंड से अलग कर सकते हैं।
- अगर मैं पहले से REFUND notifications संभालता हूँ तो क्या मुझे अब भी इसकी ज़रूरत है?
- हाँ, एक बैकस्टॉप के रूप में। Notifications जीवंत संकेत हैं, लेकिन किसी आउटेज, एक ख़राब deploy, या एक webhook बदलाव के दौरान एक पुश आने में विफल हो सकता है, और एक चूका हुआ रिफ़ंड एक रिफ़ंड किए गए खाते को चालू और आपको पैसे में पड़ता हुआ छोड़ देता है। Get Refund History सत्य का पुल-आधारित स्रोत है जिसके विरुद्ध आप मिलान करते हैं ताकि कुछ भी चालू न रहे जिसे Apple पहले ही रिफ़ंड कर चुका है।
स्रोत और आगे की जानकारी
- Apple Developer: Get Refund History (App Store Server API)
- Apple Developer: RefundHistoryResponse
- Apple Developer: JWSTransactionDecodedPayload (revocationDate, revocationReason)
- Apple Developer: Get Refund History V1 (deprecated)
- Apple Developer: App Store Server Notifications V2 notificationType (REFUND)
- Apple Developer: Support customers and handle refunds (WWDC21)
RefundHalt
App Store और Google Play के लिए refund ऑटोपायलट
आगे पढ़ें
आपका ऐप इन-ऐप रिफ़ंड रिक्वेस्ट शीट दिखा सकता है, और ग्राहक के सबमिट दबाने के बाद Apple क्या करता है
Apple की इन-ऐप रिफ़ंड रिक्वेस्ट ग्राहक को आपका ऐप छोड़े बिना रिफ़ंड माँगने देती है, एक ऐसी शीट पर जिसे Apple बनाता और समीक्षा करता है. यहाँ बताया गया है कि beginRefundRequest क्या लौटाता है, यह आपके सर्वर पर कौन-सी CONSUMPTION_REQUEST और 48 घंटे की घड़ियाँ शुरू करता है, और क्या यह बटन शिप करने लायक है.
जब Google Play की कोई खरीद रिफंड या चार्जबैक होती है, तो Voided Purchases API ही वह जरिया है जिससे आपको पता चलता है
जब कोई खरीद रिफंड या चार्जबैक होती है, तो Google Play उसे चुपचाप रद्द कर देता है। Voided Purchases API उन्हीं ऑर्डरों की सूची है, ताकि आप एक्सेस वापस ले सकें। यहाँ हर फ़ील्ड, 30 दिन की विंडो, वह रिवोक विकल्प जो ऑर्डर छिपा देता है, और इसकी लागत बताई गई है।