रिलीज़ से पहले IAP इंटीग्रेशन टेस्टिंग के दौरान हमें एक सामान्य लेकिन बहुत भ्रमित करने वाली समस्या मिली:
- यूज़र “Continue Purchase” पर टैप करता है
- बटन “Processing” में चला जाता है
- कुछ सेकंड बाद फिर “Continue Purchase” हो जाता है
- App Store का purchase confirmation dialog दिखाई नहीं देता
इस लेख में पूरा जांच-पथ, महत्वपूर्ण लॉग, root cause और रिलीज़ से पहले लागू की जा सकने वाली fix strategy दी गई है।
1. समस्या का लक्षण
Purchase पेज पर product list सामान्य रूप से लोड हो रही थी, लेकिन खरीद बटन दबाने के बाद:
purchase()कॉल हो रहा था- कोई system dialog नहीं आ रहा था
- UI अंत में non-purchased state में लौट जा रहा था
पहली नज़र में लगा कि purchase flow शुरू ही नहीं हुआ। लेकिन logs ने अलग तस्वीर दिखाई।
2. पहली जांच: क्या purchase flow वास्तव में चल रहा है?
हमने purchase flow के सभी critical checkpoints पर logging जोड़ी:
- बटन क्लिक पैरामीटर
purchaseSelectedProduct()एंट्री औरguardbranchesproduct.purchase()से पहले/बादTransaction.updatesrefreshEntitlements()Transaction.currentEntitlementsTransaction.latest(for:)
परिणाम:
purchase()ने.successलौटाया- transaction verification सफल थी, और
transaction.finish()भी चला - लेकिन
entitledIDsखाली रहे
इसका मतलब: समस्या “purchase शुरू नहीं हुआ” नहीं थी, बल्कि “purchase के बाद entitlements पहचाने नहीं गए” थी।
3. गहराई से जांच में मिले निर्णायक संकेत
अतिरिक्त logs जोड़ने पर कुछ अहम संकेत मिले:
Transaction.currentEntitlementsका iteration count0थाTransaction.latest(for: monthly)में valid record था, लेकिन वह expired था- सबसे महत्वपूर्ण: खरीद से पहले
Transaction.unfinishedमें पुराने transactions मौजूद थे - मौजूदा
purchase()ने नया interactive purchase flow नहीं, बल्कि पुराने transaction chain का transaction लौटाया
यही वजह है कि “पॉपअप नहीं आया”:
- StoreKit पहले processable पुराना transaction लौटाता है (unfinished / historical chain)
- आपका कोड उसे
finish()कर देता है - request “successful” दिखती है, लेकिन expected नया purchase confirmation path ट्रिगर नहीं होता
4. root cause सारांश
यह single-point issue नहीं था, बल्कि दो कारणों का संयोजन था:
- unfinished transactions का purchase flow में हस्तक्षेप
- sandbox subscription chain का expired state में होना (latest transaction होने पर भी वह active entitlement हो, यह ज़रूरी नहीं)
अंतिम व्यवहार: पॉपअप नहीं, सफलता का आभास, entitlements खाली।
5. fix strategy (व्यवहार में प्रभावी)
5.1 खरीद से पहले unfinished transactions proactively साफ करें
App startup पर और खरीद से पहले Transaction.unfinished स्कैन करें, और verified transactions पर finish() चलाएँ, ताकि पुराने transactions नया purchase flow hijack न करें।
5.2 diagnostic logs बनाए रखें और मजबूत करें (लॉन्च से पहले अनुशंसित)
लॉन्च तक ये logs चालू रखना उपयोगी है:
unfinished transactionsnapshotsubscription status(state, renewal info)currentEntitlementsiteration countlatest(for:)का transaction/expiration विवरण
5.3 entitlement validation के लिए dual-path अपनाएँ (optional hardening)
यदि कुछ environments में currentEntitlements अस्थायी रूप से खाली हो, तो latest(for:) को fallback की तरह उपयोग करें (साथ में active status verify करना ज़रूरी है)।
6. pre-launch IAP checklist
- हर test से पहले sandbox account की subscription state जांचें (expired है या नहीं)
- critical paths पर
unfinishedcount log करें - तीन scenarios टेस्ट करें: first purchase / expiration के बाद renew / restore purchases
currentEntitlementsऔरlatestकी consistency जांचें- “no popup” दिखे तो पहले देखें कि पुराना transaction path hit हुआ या नहीं
7. निष्कर्ष
“खरीद पर टैप लेकिन पॉपअप नहीं” हमेशा UI या timing issue नहीं होता।
StoreKit 2 में transaction state, unfinished queue और subscription lifecycle सीधे final behavior को प्रभावित करते हैं।
लॉन्च से पहले ये logs और cleanup steps जोड़ने से ऐसे कई IAP issues कम होते हैं जो production में reproduce करना मुश्किल होता है।