सभी लेख
Deep diveपढ़ने में 7 मिनट

Apple का Send Consumption Information अब 12 नहीं, 5 फ़ील्ड माँगता है, और यहाँ हर एक फ़ील्ड दी गई है

जब कोई ग्राहक Apple से रिफ़ंड माँगता है, तो Send Consumption Information payload आपका जवाब होता है। Apple ने इसे 12 फ़ील्ड से घटाकर 5 कर दिया है, 3 अनिवार्य और 2 वैकल्पिक। यहाँ हर फ़ील्ड है, हर एक जो मान स्वीकार करती है, और वह 12-घंटे की समय-सीमा जिसमें आप इसे भेजते हैं।

एक स्मार्टफ़ोन जिसके बगल में कागज़ के फ़ॉर्म का एक पतला ढेर है जिसके ज़्यादातर पन्ने फाड़ दिए गए हैं, जो Apple के Send Consumption Information payload के 12 फ़ील्ड से घटकर 5 होने को दर्शाता है

मुख्य बातें

  • Apple का Send Consumption Information payload अब 5 फ़ील्ड रखता है, जो पहले 12 था। 3 अनिवार्य हैं, customerConsented, deliveryStatus, और sampleContentProvided, और 2 वैकल्पिक हैं, consumptionPercentage और refundPreference।
  • customerConsented एक सख़्त गेट है। Apple का अपना मार्गदर्शन यह है कि अगर ग्राहक ने consumption डेटा साझा करने के लिए सहमति नहीं दी, तो आप payload बिलकुल न भेजें।
  • deliveryStatus आपका सबसे मज़बूत संकेत रखता है। DELIVERED कहता है कि खरीद काम कर गई, और चार UNDELIVERED मान Apple को बताते हैं कि ग्राहक को कभी कोई काम करने वाला उत्पाद नहीं मिला।
  • consumptionPercentage ने पुराने चार-चरण वाले consumptionStatus enum की जगह milliunits में एक सटीक संख्या ले ली है, जहाँ 100,000 milliunits का मतलब है कि आइटम पूरी तरह उपभोग हो गया।
  • refundPreference अब एक string है, संख्या नहीं। तीन मान हैं DECLINE, GRANT_FULL, और GRANT_PRORATED, और यह एक प्राथमिकता बताता है, फ़ैसला नहीं। फ़ैसला अब भी Apple ही करता है।
  • आप payload को transaction id के आधार पर Send Consumption Information endpoint पर PUT के ज़रिए भेजते हैं, और Apple खाली body के साथ 202 Accepted लौटाता है। समय-सीमा CONSUMPTION_REQUEST के बाद 12 घंटे है।
  • ऑटो-रिन्यूएबल सब्सक्रिप्शन के लिए Apple बीते समय से खुद ही उपभोग की गणना करता है, इसलिए consumptionPercentage उपभोग-योग्य और नॉन-रिन्यूइंग खरीदों के लिए है।

जब कोई ग्राहक रिफ़ंड चाहता है तब Apple आपसे जो तथ्य माँगता है उनकी सूची काफ़ी छोटी हो गई है। Send Consumption Information payload, वह एक जवाब जो कोई डेवलपर App Store के रिफ़ंड फ़ैसले में भेज पाता है, पहले 12 फ़ील्ड रखता था। अब इसमें 5 हैं। Apple ने इसे WWDC24 के आसपास छाँटा और पुराने account-profiling सवालों में से ज़्यादातर को दो सरल सवालों और एक संख्या में समेट दिया। कम फ़ील्ड कोई छोटा बदलाव नहीं है। यह बदलता है कि Apple किन सबूतों को तौलता है, और यह बदलता है कि किन फ़ील्ड को गलत भरने का जोखिम आप नहीं उठा सकते।

यह क्यों आपके ध्यान के योग्य है और केवल एक schema नोट भर नहीं, यह रहा। यह payload Apple के रिफ़ंड में वह एकमात्र पल है जहाँ आपकी तरफ़ की कहानी फ़ैसले तक पहुँचती है। एक उपभोग-योग्य रिफ़ंड उस राजस्व को पलट देता है जिसे पहुँचाने में आप पहले ही असली पैसा खर्च कर चुके हैं, और ये 5 फ़ील्ड ही वह तरीका हैं जिससे आप Apple को बताते हैं कि उत्पाद पहुँचाया और इस्तेमाल किया गया। 12-घंटे की समय-सीमा चूक जाएँ या कोई फ़ील्ड गलत भरें, और Apple अकेले ग्राहक के दावे पर फ़ैसला करता है।

Send Consumption Information क्या है

Send Consumption Information वह App Store Server API endpoint है जिसे आप तब कॉल करते हैं जब Apple आपके सर्वर को CONSUMPTION_REQUEST नोटिफ़िकेशन भेजता है। उस नोटिफ़िकेशन का मतलब है कि किसी ग्राहक ने किसी in-app purchase पर Apple से रिफ़ंड माँगा है और Apple फ़ैसला करने से पहले आपकी राय चाहता है। आप endpoint पर एक छोटा JSON body, यानी ConsumptionRequest, PUT करके जवाब देते हैं। Apple इसे पढ़ता है, ग्राहक के इतिहास के मुक़ाबले तौलता है, और फ़ैसला करता है। रिफ़ंड का फ़ैसला आप कभी नहीं करते। आप तथ्य देते हैं।

body ही पूरा इंटरफ़ेस है। कोई अलग फ़ॉर्म नहीं, कोई अपील नहीं, और कोई दूसरा सबमिशन नहीं जो गिना जाए। उस एक payload में आप जो भी भेजते हैं वही आपका पूरा पक्ष है, इसलिए हर फ़ील्ड का अर्थ फ़ील्ड की संख्या से कहीं ज़्यादा मायने रखता है।

अब Apple जो 5 फ़ील्ड माँगता है

मौजूदा ConsumptionRequest में 5 सदस्य हैं। 3 अनिवार्य हैं और 2 वैकल्पिक। ग्राहक के account, उनकी अवधि, उनके जीवनकाल के खर्च, उनके जीवनकाल के रिफ़ंड, उनके play time के बारे में Apple जो कुछ पूछा करता था, वह सब आप जो भेजते हैं उसमें से हटा दिया गया है।

फ़ील्डअनिवार्यप्रकारयह क्या रखती है
customerConsentedहाँBooleanक्या ग्राहक Apple के साथ consumption डेटा साझा करने पर सहमत हुआ
deliveryStatusहाँStringक्या आपके ऐप ने काम करने वाला उत्पाद पहुँचाया
sampleContentProvidedहाँBooleanक्या आपने खरीद से पहले मुफ़्त सैंपल या ट्रायल दिया
consumptionPercentageनहींIntegerखरीद का कितना हिस्सा उपभोग हुआ, milliunits में
refundPreferenceनहींStringरिफ़ंड अनुरोध के लिए आपका पसंदीदा परिणाम

customerConsented ही गेट है

customerConsented एक Boolean है, और यही वह फ़ील्ड है जो तय करती है कि आप कुछ भी भेजते हैं या नहीं। यह दर्ज करती है कि क्या ग्राहक ने आपको Apple के साथ consumption डेटा साझा करने की अनुमति दी। Apple का मार्गदर्शन सीधा है, अगर ग्राहक ने सहमति नहीं दी, तो consumption information न भेजें। इसलिए यह कोई ऐसी फ़ील्ड नहीं है जिसे आप अपना पक्ष मज़बूत करने के लिए true कर दें। यह एक असली हाँ-या-नहीं को दर्शाती है जो आपके पास पहले से होनी चाहिए, और यहाँ false का मतलब है कि बाकी payload नहीं भेजा जाना चाहिए।

deliveryStatus वही फ़ील्ड है जो रिफ़ंड को प्रभावित करती है

deliveryStatus एक string enum है, और यह आपके पास सबसे मज़बूत ज़रिया है। यह Apple को बताती है कि आपके ऐप ने वाकई कोई काम करने वाला in-app purchase पहुँचाया या नहीं। एक मान हाँ कहता है। बाकी चार नहीं कहते हैं, हर एक अलग कारण से, और हर एक Apple को बताता है कि ग्राहक की शिकायत जायज़ है।

मानयह Apple को क्या बताती है
DELIVEREDऐप ने काम करने वाला in-app purchase पहुँचाया
UNDELIVERED_QUALITY_ISSUEगुणवत्ता की समस्या के कारण खरीद नहीं पहुँचाई गई
UNDELIVERED_WRONG_ITEMग्राहक को गलत आइटम मिला
UNDELIVERED_SERVER_OUTAGEसर्वर के बंद होने से पहुँचाना रुक गया
UNDELIVERED_OTHERखरीद किसी अन्य कारण से नहीं पहुँचाई गई

sampleContentProvided एक निष्पक्षता के सवाल का जवाब देती है

sampleContentProvided एक Boolean है। यह दर्ज करती है कि क्या आपने ग्राहक को खरीदने से पहले मुफ़्त सैंपल, कोई ट्रायल, या यह साफ़ जानकारी दी कि खरीद क्या करती है। यहाँ true एक छोटा निष्पक्षता का संकेत है, ग्राहक के पास यह जानने का मौका था कि वे क्या खरीद रहे हैं। यह अपने आप कुछ तय नहीं करती, पर यह केवल 3 अनिवार्य फ़ील्ड में से एक है, इसलिए Apple स्पष्ट रूप से इसे हर जवाब में चाहता है।

consumptionPercentage अब एक संख्या है, कोई status नहीं

यही वह फ़ील्ड है जो सबसे ज़्यादा बदली। पुराने payload में consumptionStatus था, एक चार-चरण वाला enum, UNDECLARED, NOT_CONSUMED, PARTIALLY_CONSUMED, FULLY_CONSUMED। नया payload इसकी जगह consumptionPercentage रखता है, milliunits में मापा गया एक integer। 100,000 milliunits का मतलब है कि आइटम पूरी तरह उपभोग हो गया, तो 50,000 आधा है और 0 अछूता। एक सटीक संख्या चार-तरफ़ा बकेट से बेहतर है, क्योंकि यह आपको यह कहने देती है कि किसी ग्राहक ने क्रेडिट पैक का 90 प्रतिशत खर्च कर दिया, बजाय इसके कि इसे घटाकर partially consumed मान लिया जाए।

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

एक स्मार्टफ़ोन जो एक गोलाकार प्रोग्रेस रिंग दिखाता है जो लगभग दो-तिहाई भरी है, जो milliunits में मापे गए consumptionPercentage को दर्शाता है जहाँ 100,000 का मतलब पूरी तरह उपभोग है

refundPreference एक प्राथमिकता बताता है, कोई फ़ैसला नहीं

refundPreference एक वैकल्पिक string है, और यहीं आप Apple को बताते हैं कि आप कौन-सा परिणाम पसंद करेंगे। इसका रूप भी बदला। पुरानी फ़ील्ड एक संख्या थी जिसमें prefer-grant, prefer-decline, और no-preference जैसे मान थे। नई एक नामित string है जिसमें 3 मान हैं।

मानआप क्या माँग रहे हैं
GRANT_FULLआप चाहेंगे कि Apple पूरा रिफ़ंड दे
GRANT_PRORATEDआप जितना इस्तेमाल हुआ उसके अनुसार आंशिक रिफ़ंड चाहेंगे
DECLINEआप चाहेंगे कि Apple रिफ़ंड अस्वीकार करे

Apple ने क्या हटाया, और यह क्यों मायने रखता है

पुराने ConsumptionRequest में 12 फ़ील्ड थीं। उनमें से 7 अब आप जो भेजते हैं उसमें से चली गई हैं। accountTenure, lifetimeDollarsPurchased, lifetimeDollarsRefunded, playTime, userStatus, platform, और appAccountToken payload का account-profiling वाला आधा हिस्सा थीं, वे फ़ील्ड जो आपसे कहती थीं कि किसी ग्राहक को इस आधार पर बाँटें कि उनका account कितने समय से है, उन्होंने कितना खर्च किया, उन्हें कितना रिफ़ंड मिला, और उन्होंने ऐप को कितने समय तक इस्तेमाल किया।

Apple ने इन्हें एक ऐसे कारण से हटाया जिस पर ध्यान देना ज़रूरी है। वे फ़ील्ड डेवलपर्स से ग्राहक की एक प्रोफ़ाइल सौंपने को कहती थीं, और ज़्यादातर डेवलपर या तो उन्हें अघोषित छोड़ देते या अनुमान लगाते। जो 5 बची हैं वे खरीद और डिलीवरी के बारे में हैं, ऐसे तथ्य जिन्हें आप वाकई अपने सिस्टम से सत्यापित कर सकते हैं। बदलाव यह है कि ग्राहक कौन है से हटकर इस विशेष खरीद के साथ क्या हुआ पर आ गया है।

पुराना payloadमौजूदा payload
कुल फ़ील्ड125
अनिवार्य फ़ील्डव्यावहारिक रूप से कोई लागू नहीं3
उपभोग संकेतconsumptionStatus, चार बकेटconsumptionPercentage, सटीक milliunits
रिफ़ंड प्राथमिकतासंख्यात्मक enumनामित string, 3 मान
Account profilingअवधि, जीवनकाल खर्च, रिफ़ंड, play time, statusहटा दिया गया

endpoint और घड़ी

आप payload को विवादित खरीद की transaction id के आधार पर Send Consumption Information endpoint पर HTTP PUT के ज़रिए भेजते हैं, PUT /inApps/v1/transactions/consumption/{transactionId}। सफलता पर 202 Accepted लौटता है, और response body खाली होती है। वह खाली जवाब अपेक्षित है, कोई बग नहीं। यह पुष्टि करता है कि Apple ने आपका डेटा क़तार में लगा लिया, और यह आपको अंतिम परिणाम के बारे में कुछ नहीं बताता, जो बाद में REFUND या REFUND_DECLINED नोटिफ़िकेशन के रूप में आता है।

घड़ी वह हिस्सा है जिसे आप खींच नहीं सकते। Apple आपको जवाब देने के लिए CONSUMPTION_REQUEST से 12 घंटे देता है। केवल आपका पहला जवाब इस्तेमाल होता है, इसलिए पहला payload ही पूरा और सही होना चाहिए। Apple एक ही खरीद के लिए CONSUMPTION_REQUEST एक से ज़्यादा बार भेज सकता है, पर हर एक की समय-सीमा तय है, और एक मैनुअल समीक्षा समय-क्षेत्रों और सप्ताहांतों के बीच 12 घंटे में शायद ही समा पाती है।

एक गलत तरीके से संभाली फ़ील्ड की आपको क्या क़ीमत चुकानी पड़ती है

रिफ़ंड से पहले ही पैसा हाथ से निकल चुका होता है

एक उपभोग-योग्य रिफ़ंड कोई साफ़-सुथरी वापसी नहीं है। जब तक कोई ग्राहक क्रेडिट के एक पैक या AI जनरेशन के एक बैच पर अपना पैसा वापस माँगता है, तब तक आप उसे पहुँचाने में खर्च कर चुके होते हैं, हर अनुरोध पर GPU inference, प्रति टोकन बिल होने वाली तीसरे पक्ष की model API कॉल, आपने जो भी बनाया उसका storage, और उस उपयोग से जुड़ा कोई भी creator या partner भुगतान। स्टोर की क़ीमत ग्राहक के पास वापस चली जाती है। आपकी डिलीवरी की लागत आपके पास वापस नहीं आती। इसलिए एक रिफ़ंड जिसे आप चुनौती दे सकते थे कोई बराबरी वाली घटना नहीं है, यह उन सबका शुद्ध नुकसान है जो आपने उस account की सेवा में चुकाया।

ये 5 फ़ील्ड ही वह तरीका हैं जिससे आप दो बार चुकाने से बचते हैं

deliveryStatus को DELIVERED पर सेट करना और एक ऊँचा consumptionPercentage, ये दो तथ्य Apple को बताते हैं कि ग्राहक को उत्पाद मिला और उन्होंने उसका इस्तेमाल किया। ये आपका सबूत हैं कि compute, API कॉल, और storage सबने अपना काम किया। payload न भेजें और Apple यह कभी नहीं सुनता। यह ग्राहक के दावे से फ़ैसला करता है, रिफ़ंड के पास होने की संभावना ज़्यादा होती है, और आप पलटे गए राजस्व और उसके पीछे की डिलीवरी लागत दोनों झेलते हैं।

चार्जबैक और भी बुरा दरवाज़ा हैं, और चुप्पी उसी की ओर इशारा करती है

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

RefundHalt इसे कैसे संभालता है

ये 5 फ़ील्ड तब तक सरल दिखती हैं जब तक आपको उन्हें सही ढंग से, 12 घंटे के भीतर, हर CONSUMPTION_REQUEST पर, सही transaction से जोड़कर भरना न पड़े। RefundHalt नोटिफ़िकेशन पकड़ता है, उस खरीद के लिए आपके अपने डिलीवरी और उपयोग रिकॉर्ड पढ़ता है, और समय-सीमा बंद होने से पहले payload अपने आप भेज देता है। deliveryStatus वही दर्शाता है जो आपके logs वाकई दिखाते हैं, consumptionPercentage अनुमान के बजाय असली उपयोग से आता है, और refundPreference उस नीति का पालन करता है जिसे आप एक बार सेट करते हैं। आपको वह चुनौती-योग्य रिफ़ंड सबूत के साथ समीक्षित मिलता है, न कि चूकी हुई समय-सीमा और आपके बिना लिया गया फ़ैसला।

अक्सर पूछे जाने वाले सवाल

Apple के Send Consumption Information में अब कितनी फ़ील्ड हैं?
5। 3 अनिवार्य हैं, customerConsented, deliveryStatus, और sampleContentProvided, और 2 वैकल्पिक हैं, consumptionPercentage और refundPreference। payload के पिछले संस्करण में 12 फ़ील्ड थीं, और Apple ने accountTenure, lifetimeDollarsPurchased, और userStatus जैसी account-profiling वाली फ़ील्ड हटा दीं।
किसी consumption request में deliveryStatus का क्या मतलब है?
deliveryStatus Apple को बताती है कि आपके ऐप ने काम करने वाला in-app purchase पहुँचाया या नहीं। DELIVERED का मतलब है कि पहुँचाया। चार UNDELIVERED मान, UNDELIVERED_QUALITY_ISSUE, UNDELIVERED_WRONG_ITEM, UNDELIVERED_SERVER_OUTAGE, और UNDELIVERED_OTHER, हर एक एक बताए गए कारण से कहता है कि नहीं पहुँचाया। यह payload में सबसे मज़बूत संकेत है, इसलिए यह आपके अपने logs से मेल खाना चाहिए।
क्या consumptionPercentage एक प्रतिशत है या एक कच्ची संख्या?
यह milliunits में मापा गया एक integer है, कोई सादा प्रतिशत नहीं। 100,000 milliunits का मतलब है कि ग्राहक ने खरीद पूरी तरह उपभोग की, तो 50,000 आधा है और 0 अछूता। इसने पुराने consumptionStatus enum की जगह ली, जिसमें उपभोग-नहीं से पूरी-तरह-उपभोग तक केवल चार बकेट थे।
क्या refundPreference को DECLINE पर सेट करना रिफ़ंड रोक देता है?
नहीं। refundPreference आपका पसंदीदा परिणाम बताता है, यह कुछ तय नहीं करता। DECLINE Apple को बताता है कि आप चाहेंगे कि वह रिफ़ंड न करे, और GRANT_FULL या GRANT_PRORATED इसका उलटा बताते हैं, पर Apple आपकी प्राथमिकता को ग्राहक के इतिहास और अपनी नीति के मुक़ाबले तौलता है और अंतिम फ़ैसला करता है।
अगर ग्राहक ने consumption डेटा साझा करने की सहमति नहीं दी तो क्या?
तो आपको payload नहीं भेजना चाहिए। customerConsented एक अनिवार्य Boolean है, और Apple का मार्गदर्शन यह है कि अगर ग्राहक ने consumption डेटा साझा करने के लिए सहमति नहीं दी, तो आप CONSUMPTION_REQUEST का जवाब बिलकुल न दें। सहमति एक असली हाँ-या-नहीं है जो आपके पास पहले से होनी चाहिए, न कि कोई मान जिसे आप अपना पक्ष मज़बूत करने के लिए true कर दें।
मेरे पास consumption information भेजने के लिए कितना समय है?
जब से Apple CONSUMPTION_REQUEST नोटिफ़िकेशन भेजता है तब से 12 घंटे। आप Send Consumption Information endpoint पर PUT के ज़रिए जवाब देते हैं, और सफलता पर खाली body के साथ 202 Accepted लौटता है। केवल आपका पहला जवाब इस्तेमाल होता है, इसलिए पहला payload पूरा होना चाहिए, और एक मैनुअल प्रक्रिया समय-सीमा में शायद ही समाती है।

स्रोत और आगे की जानकारी

RefundHalt

App Store और Google Play के लिए refund ऑटोपायलट

आगे पढ़ें

Deep diveपढ़ने में 7 मिनट

एक ऐसा endpoint है जो किसी ग्राहक का पूरा App Store रिफ़ंड इतिहास लौटाता है, और यहाँ बताया गया है कि यह क्या देता है

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

Deep diveपढ़ने में 7 मिनट

आपका ऐप इन-ऐप रिफ़ंड रिक्वेस्ट शीट दिखा सकता है, और ग्राहक के सबमिट दबाने के बाद Apple क्या करता है

Apple की इन-ऐप रिफ़ंड रिक्वेस्ट ग्राहक को आपका ऐप छोड़े बिना रिफ़ंड माँगने देती है, एक ऐसी शीट पर जिसे Apple बनाता और समीक्षा करता है. यहाँ बताया गया है कि beginRefundRequest क्या लौटाता है, यह आपके सर्वर पर कौन-सी CONSUMPTION_REQUEST और 48 घंटे की घड़ियाँ शुरू करता है, और क्या यह बटन शिप करने लायक है.

अगला refund अनुरोध पहले ही रास्ते में है.

RefundHalt को उतने समय में सेटअप करें, जितने में आप उस refund के बारे में एक और सपोर्ट ईमेल पढ़ते हैं जिस पर आपत्ति नहीं कर पाए.