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

हर App Store खरीद के साथ एक appAccountToken जोड़ें, वरना आप रिफंड का बचाव नहीं कर पाएंगे

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

एक गहरे रंग की बहीखाता पर रखी एक नंबर वाली पीतल की चाबी, बगल में एक स्मार्टफोन जो खरीद रसीद दिखा रहा है, यह दर्शाता है कि कैसे एक appAccountToken किसी App Store खरीद को उपयोगकर्ता खाते से जोड़ता है

मुख्य बातें

  • appAccountToken एक UUID है जिसे आप किसी App Store खरीद के साथ जोड़ते हैं ताकि परिणामी ट्रांज़ैक्शन आपके अपने सिस्टम में ठीक उसी उपयोगकर्ता की ओर इशारा करे। Apple इसे ट्रांज़ैक्शन पर संग्रहीत करता है और हर जगह लौटाता है जहां वह ट्रांज़ैक्शन दिखाई देता है।
  • फ़ॉर्मेटिंग का एकमात्र नियम जो Apple लागू करता है वह यह है कि मान एक वैध UUID हो। कुछ और भेजें, कोई id, कोई ईमेल, या जोड़ी गई स्ट्रिंग, तो StoreKit उसे चुपचाप हटा देता है और appAccountToken को nil के रूप में लौटाता है।
  • StoreKit 2 में आप इसे एक ही खरीद विकल्प, Product.PurchaseOption.appAccountToken(_:), से सेट करते हैं, उस खाते के लिए आपके द्वारा बनाए और संग्रहीत किए गए एक स्थिर UUID का उपयोग करते हुए।
  • इसे मूल खरीद पर एक बार सेट करें और Apple उसी टोकन को सब्सक्रिप्शन श्रृंखला में हर नवीनीकरण, बिलिंग पुनः प्रयास और अपग्रेड में साथ ले जाता है।
  • 2025 से, Set App Account Token एंडपॉइंट आपके सर्वर को आपके ऐप के बाहर की गई खरीदों में टोकन जोड़ने देता है, जैसे ऑफ़र कोड रिडेम्पशन और प्रमोटेड खरीदें, जिन तक इन-ऐप फ़्लो कभी नहीं पहुंच सकता था।
  • appAccountToken ही Apple के CONSUMPTION_REQUEST को उत्तर देने योग्य बनाता है। इसके बिना आप रिफंड को उस ग्राहक से नहीं जोड़ सकते जिसके उपयोग का वर्णन आपको 12-घंटे की विंडो के भीतर करना होता है।
  • जिस रिफंड की पहचान आप नहीं कर सकते, उसका बचाव भी आप नहीं कर सकते। आप उन खरीदों पर पैसा लौटा देते हैं जिन्हें रखने के लिए आपके पास सबूत था, साथ ही वह कंप्यूट, API कॉल और भुगतान भी जो आप उन्हें पहुंचाने में पहले ही खर्च कर चुके थे।

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

appAccountToken एक UUID है जिसे आप किसी खरीद के साथ जोड़ते हैं ताकि परिणामी App Store ट्रांज़ैक्शन आपके सिस्टम में ठीक उसी उपयोगकर्ता की ओर एक पॉइंटर ले जाए। इसे सेट करें, और उस ग्राहक के बारे में Apple जो भी रिफंड सवाल पूछेगा, वह उसकी पहचान के साथ आएगा। इसे छोड़ दें, और आप अनुमान लगाते रहेंगे। यहां बताया गया है कि यह फ़ील्ड क्या है, इसे कैसे सेट करें, वह नया एंडपॉइंट जो आपके ऐप के बाहर की गई खरीदों को बचाता है, और जब रिफंड आता है तो यह गायब कड़ी असल में कितनी महंगी पड़ती है।

appAccountToken असल में क्या है

appAccountToken एक अपारदर्शी UUID है जिसे आप बनाते हैं और खरीद के क्षण में StoreKit को भेजते हैं। Apple इसे ट्रांज़ैक्शन पर संग्रहीत करता है और उस खरीद की ट्रांज़ैक्शन जानकारी में लौटाता है, और यह वहीं रहता है। Apple के शब्दों में, यह "वह UUID है जो ट्रांज़ैक्शन को आपकी अपनी सेवा पर उपयोगकर्ता के खाते से जोड़ता है।" फ़ॉर्मेटिंग का एकमात्र नियम यह है कि इसे UUID होना चाहिए। Apple इसे पढ़ता नहीं, यह किससे जुड़ता है इसकी पुष्टि नहीं करता, और आपके पक्ष में इसका क्या अर्थ है इसकी परवाह नहीं करता। यह एक कड़ी है जिसे आप नियंत्रित करते हैं।

चूंकि यह ट्रांज़ैक्शन पर रहता है, यह हर उस जगह लौटता है जहां ट्रांज़ैक्शन लौटता है। सर्वर सूचना में साइन किया गया ट्रांज़ैक्शन, App Store Server API की Get Transaction Info प्रतिक्रिया, और किसी सब्सक्रिप्शन श्रृंखला में हर नवीनीकरण, सभी वही टोकन ले जाते हैं यदि आपने इसे मूल खरीद पर सेट किया है। एक UUID, एक बार जोड़ा गया, रिश्ते के पूरे जीवनकाल तक ग्राहक की बिलिंग का पीछा करता है।

इसे एक असली UUID होना चाहिए, वरना यह चुपचाप गायब हो जाता है

Apple जो एकमात्र नियम लागू करता है वह है फ़ॉर्मेट। StoreKit 2 को एक RFC 4122 UUID चाहिए। यदि आप एक जोड़ी गई स्ट्रिंग, एक पूर्णांक id, या एक ईमेल पता भेजते हैं, तो StoreKit कोई त्रुटि नहीं फेंकता। यह मान को हटा देता है और ट्रांज़ैक्शन appAccountToken के nil पर सेट होकर लौटता है। डेवलपर लगातार इससे टकराते हैं, और लक्षण हमेशा एक ही होता है, Apple के अपने फ़ोरम पर "appAccountToken ट्रांज़ैक्शन पेलोड में गायब है" का कोई न कोई रूप, लगभग हमेशा इसलिए क्योंकि भेजा गया मान एक वैध UUID नहीं था। सर्वर-साइड पर एक असली UUID बनाएं, इसे खाते के विरुद्ध संग्रहीत करें, और StoreKit को कभी कुछ और न सौंपें।

इसे खरीद के समय कैसे सेट करें

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

सिग्नेचर Product.PurchaseOption.appAccountToken(_ token: UUID) है, और एक खरीद ऐसी दिखती है try await product.purchase(options: [.appAccountToken(token)])। जब ट्रांज़ैक्शन लौटता है, चाहे App Store Server API के माध्यम से सत्यापित हो या किसी सर्वर सूचना द्वारा पहुंचाया गया हो, वह उस UUID को ले जाता है, और आपका सर्वर एक ही क्वेरी में ग्राहक को खोज लेता है।

प्रति खाता एक स्थिर टोकन का उपयोग करें

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

वह एंडपॉइंट जो ऐप के बाहर की खरीदों को बचाता है

2025 तक एक छेद था। यदि कोई ग्राहक ऑफ़र कोड रिडीम करता या App Store से सीधे कोई प्रमोटेड इन-ऐप खरीद करता, तो आपका ऐप कभी खरीद फ़्लो नहीं चलाता, इसलिए appAccountToken सेट करने की कोई जगह नहीं थी। वे ट्रांज़ैक्शन गुमनाम आते और वैसे ही रह जाते।

WWDC 2025 ने Set App Account Token एंडपॉइंट से इस खाई को बंद कर दिया। आपका सर्वर App Store Server API पर बॉडी में UUID के साथ PUT /inApps/v1/transactions/{originalTransactionId}/appAccountToken कॉल करता है, और Apple उस ट्रांज़ैक्शन पर टोकन सेट कर देता है। यह हर उत्पाद प्रकार के लिए काम करता है, यह ऑफ़र कोड रिडेम्पशन और प्रमोटेड खरीदों को कवर करता है, और आपके द्वारा भेजा गया मान ट्रांज़ैक्शन पर पहले से मौजूद किसी भी टोकन को ओवरराइड कर देता है। अब आप एक खरीद को बाद में, अपने सर्वर से, बिना उसे कभी अपने ऐप से गुज़ारे, जोड़ सकते हैं।

एक गहरे रंग की मेज़ पर कागज़ी बिक्री रसीदों का एक ढेर जिसमें ग्राहक नाम की पंक्ति खाली छोड़ी गई है, एक गर्म स्पॉटलाइट से रोशन, यह दर्शाता है कि एक App Store खरीद बिना appAccountToken के आती है जो खरीदार की पहचान कर सके
खरीद चैनलआप appAccountToken कहां सेट करते हैंनोट्स
इन-ऐप खरीदखरीद के समय StoreKit खरीद विकल्पProduct.PurchaseOption.appAccountToken(UUID)
ऑफ़र कोड रिडेम्पशनSet App Account Token एंडपॉइंट, सर्वर-साइडजोड़ने के लिए कोई इन-ऐप फ़्लो नहीं, इसलिए इसे बाद में सेट करें
App Store से प्रमोटेड इन-ऐप खरीदSet App Account Token एंडपॉइंट, सर्वर-साइडखरीद आपके ऐप के बाहर होती है
सब्सक्रिप्शन नवीनीकरणकुछ नहीं करना हैमूल खरीद से स्वतः आगे ले जाया गया

गायब कड़ी आपको कहां पैसा गंवाती है

टोकन का उद्देश्य साफ़-सुथरे रिकॉर्ड नहीं हैं। उद्देश्य यह है कि डेवलपर के लिए Apple का एकमात्र रिफंड सवाल, CONSUMPTION_REQUEST, केवल तभी उत्तर देने योग्य होता है जब आप उस ग्राहक को खोज सकें जिसके बारे में वह है।

जब कोई खरीदार किसी उपभोग्य या गैर-नवीनीकरण योग्य सब्सक्रिप्शन पर रिफंड का अनुरोध करता है, तो Apple आपके सर्वर को एक CONSUMPTION_REQUEST सूचना भेजता है और आपको Send Consumption Information के साथ जवाब देने के लिए बारह घंटे देता है। आपका जवाब उस विशिष्ट ग्राहक के बारे में डेटा है: उसने उत्पाद का कितना उपभोग किया, उसके खाते की अवधि, उसका आजीवन खर्च, उसकी डिलीवरी स्थिति। appAccountToken स्वयं उस अनुरोध के फ़ील्ड में से एक है, और अधिक महत्वपूर्ण बात, यही वह तरीका है जिससे सूचना का ट्रांज़ैक्शन उस खाते से जुड़ता है जिसके उपयोग का वर्णन आप करने वाले हैं। कोई टोकन नहीं, कोई खोज नहीं, कोई सटीक जवाब नहीं।

खाली जवाब असल में कितना महंगा पड़ता है

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

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

वही विचार Android पर मौजूद है, दूसरे नाम से

Google Play उसी समस्या को setObfuscatedAccountId से हल करता है, जो किसी खरीद के साथ एक खाता पहचानकर्ता जोड़ता है ताकि orders.reviewrefund के माध्यम से Google की चार्जबैक समीक्षा का जवाब किसी असली उपयोगकर्ता के विरुद्ध दिया जा सके। अलग स्टोर, अलग यांत्रिकी, वही सबक: खरीद के समय पहचान जोड़ें वरना आप बाद में विवाद का बचाव नहीं कर सकते। App Store पर, वह उपकरण appAccountToken है, और इसे एक UUID होना चाहिए।

तीन आदतें जो टोकन को अपनी जगह पर बनाए रखती हैं

  • प्रति खाता एक UUID बनाएं और इसे संग्रहीत करें। प्रति ग्राहक एक स्थिर टोकन, जब वे साइन अप करते हैं या पहले चेकआउट पर बनाया गया, उनके रिकॉर्ड पर सहेजा गया और हर खरीद के लिए पुनः उपयोग किया गया।
  • इसे भेजने से पहले सत्यापित करें। अपने खरीद कोड में पुष्टि करें कि मान एक असली UUID है, ताकि कोई विकृत id ट्रांज़ैक्शन पर चुपचाप एक nil टोकन कभी न बन सके।
  • ऐप के बाहर की खरीदों को बैकफ़िल करें। जब किसी ऑफ़र कोड रिडेम्पशन या बिना टोकन वाली प्रमोटेड खरीद के लिए कोई सर्वर सूचना आती है, तो सही टोकन जोड़ने के लिए Set App Account Token एंडपॉइंट को कॉल करें।

ये तीनों करें और Apple आपको जो भी ट्रांज़ैक्शन भेजे, रिफंड अनुरोध सहित, वह पहले से ही उस ग्राहक से बंधा हुआ आता है जिसका वह है।

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

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

App Store में appAccountToken क्या है?
appAccountToken एक UUID है जिसे आप बनाते हैं और StoreKit के माध्यम से किसी खरीद के साथ जोड़ते हैं ताकि परिणामी App Store ट्रांज़ैक्शन आपके अपने सिस्टम में किसी विशिष्ट उपयोगकर्ता खाते की ओर वापस इशारा करे। Apple इसे ट्रांज़ैक्शन पर संग्रहीत करता है और ट्रांज़ैक्शन जानकारी, सर्वर सूचनाओं, और उसी श्रृंखला में हर नवीनीकरण में लौटाता है, जो आपको किसी भी भविष्य की घटना को, रिफंड अनुरोध सहित, सही ग्राहक से जोड़ने देता है।
मेरा appAccountToken nil या गायब क्यों है?
लगभग हमेशा इसलिए क्योंकि आपके द्वारा भेजा गया मान एक वैध UUID नहीं था। StoreKit 2 को एक RFC 4122 UUID चाहिए और यह बाकी सब कुछ चुपचाप हटा देता है, इसलिए एक जोड़ी गई स्ट्रिंग, एक पूर्णांक id, या एक ईमेल appAccountToken के रूप में nil लौटाता है जबकि खरीद फिर भी सफल हो जाती है। दूसरा आम कारण आपके ऐप के बाहर की गई खरीद है, जैसे ऑफ़र कोड रिडेम्पशन, जहां टोकन सेट करने के लिए कोई इन-ऐप फ़्लो नहीं चला।
क्या मैं ऑफ़र कोड के लिए खरीद के बाद appAccountToken सेट कर सकता हूं?
हां, 2025 से। App Store Server API पर Set App Account Token एंडपॉइंट आपके सर्वर को किसी मौजूदा ट्रांज़ैक्शन पर टोकन जोड़ने या अधिलेखित करने देता है, बॉडी में UUID के साथ PUT /inApps/v1/transactions/{originalTransactionId}/appAccountToken कॉल करके। यह हर उत्पाद प्रकार के लिए काम करता है और आपके ऐप के बाहर की गई खरीदों के लिए बनाया गया है, जैसे ऑफ़र कोड रिडेम्पशन और प्रमोटेड इन-ऐप खरीदें।
क्या appAccountToken का UUID होना ज़रूरी है?
हां। Apple जो एकमात्र फ़ॉर्मेटिंग नियम लागू करता है वह यह है कि मान एक वैध UUID हो। यह अन्यथा अपारदर्शी है, इसलिए यह आपके पक्ष में जिस भी खाता कुंजी से चाहें जुड़ सकता है, लेकिन यदि यह UUID नहीं है तो StoreKit इसे संग्रहीत नहीं करेगा और ट्रांज़ैक्शन appAccountToken के nil पर सेट होकर लौटता है।
appAccountToken रिफंड में कैसे मदद करता है?
जब कोई ग्राहक रिफंड का अनुरोध करता है, तो Apple एक CONSUMPTION_REQUEST भेजता है और आपको उस विशिष्ट खरीदार के बारे में डेटा के साथ जवाब देने के लिए बारह घंटे देता है। appAccountToken ही वह तरीका है जिससे आप सूचना के ट्रांज़ैक्शन को उस खाते से मिलाते हैं जिसके उपयोग की रिपोर्ट आपको देनी है, और यह उपभोग अनुरोध में ही फ़ील्ड में से एक है। इसके बिना आप असली उपयोग के साथ जवाब नहीं दे सकते, इसलिए Apple उन रिफंड को देने की ओर झुकता है जिनका बचाव करने का सबूत आपके पास था।
क्या appAccountToken हर खरीद के लिए अलग होना चाहिए?
नहीं। प्रति खाता एक स्थिर UUID का उपयोग करें और उस उपयोगकर्ता की हर खरीद के लिए इसे पुनः उपयोग करें। Apple टोकन को किसी सब्सक्रिप्शन श्रृंखला में नवीनीकरण और अपग्रेड के पार ले जाता है, इसलिए एक स्थिर टोकन आपको समय के साथ एक साफ़ कड़ी देता है। हर खरीद पर बदलने वाला टोकन उस कड़ी को तोड़ देता है और ट्रांज़ैक्शन को उसी ग्राहक से जोड़ना कठिन बना देता है।

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

RefundHalt

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

आगे पढ़ें

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

अगर आपने Google Play खरीद को तीन दिनों के भीतर स्वीकार नहीं किया तो Google उसे रिफंड कर देता है, और यह आपको क्या कीमत चुकवाता है

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

Playbookपढ़ने में 8 मिनट

सीरियल refund का दुरुपयोग आपको दोहरी चोट देता है, यहाँ बताया गया है कि स्टोर आपको जवाबी लड़ाई का मौका कैसे देते हैं

जो ग्राहक बार-बार refund लेता है वह कोई इत्तेफाक नहीं है। refund का दुरुपयोग आपको पैसा वापस देने पर तो नुकसान देता ही है, साथ ही वह compute भी छीन लेता है जो आप पहले ही खर्च कर चुके हैं, और दोनों स्टोर आपको इस पैटर्न को जोड़ने के लिए एक पहचान संकेत देते हैं, Apple का appAccountToken और Google का obfuscated account ID।

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

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