كيفية التحقق من توفر العرض التمهيدي في نظام التشغيل iOS

إذا كنت تستخدم العروض التمهيدية في تطبيق الاشتراك الخاص بك (النسخة التجريبية أو الدفع عند استخدامك أو الدفع المسبق) ، فقبل تحديد السعر على شاشة الدفع ، يتعين عليك تحديد مدى توفر العرض التمهيدي للمستخدم. إذا كان المستخدم قد قام بالفعل بوضع نسخة تجريبية ، فيجب عليك عرض السعر الكامل لها.


صورة


مرحبًا بالجميع ، أنا على اتصال بـ Renat من Apphud - وهي خدمة تعمل على تبسيط العمل بالاشتراكات في تطبيقات iOS. سأخبرك اليوم عن كيفية تحديد ما إذا كان لمستخدم واحد الحق في تنشيط جملة تمهيدية أم لا.


العرض التمهيدي صالح في نفس مجموعة الاشتراك. هذا يعني أنه يمكن للمستخدم إصدار اشتراك أسبوعي منتظم دون محاكمة ، وإلغاء الاشتراك وإصدار تجربة لاحقة للاشتراك الشهري.


تحتوي وثائق Apple على مخطط يوضح متى تكون الجملة التمهيدية متاحة للمستخدم:



اتضح أنه يمكن للمستخدم استخدام الجملة التمهيدية إذا:


  • لم يستخدم جملة تمهيدية من قبل

و


  • لم يتم إصدار الاشتراك أو انتهت صلاحيته

للتحقق من توفر الجملة التمهيدية ، تحتاج إلى تنفيذ 3 خطوات:


1) تحقق من صحة متجر التطبيقات ، واسحب مجموعة المعاملات. إذا لم تكن هناك معاملات ، فإننا لا نتحقق من أي شيء ، فهناك حكم تمهيدي متاح. إذا كانت هناك معاملات ، فقم بتنفيذ الخطوتين التاليتين.


2) تحقق مما إذا كانت الجملة التمهيدية قد استخدمت من قبل


3) التحقق من حالة الاشتراك الحالية


لننظر في هذه الخطوات بمزيد من التفصيل.


1. التحقق من صحة متجر التطبيقات


للتحقق من صحة التحقق ، تحتاج إلى إرسال طلب إلى Apple ، ويمر على receiptData و sharedSecret . استبدل قيمة sharedSecret بالقيمة الخاصة بك. إذا كنت لا تعرف sharedSecret ، ثم هو موضح هنا من أين تحصل عليه.


 func isEligibleForIntroductory(callback: @escaping (Bool) -> Void){ guard let receiptUrl = Bundle.main.appStoreReceiptURL else { callback(true) return } #if DEBUG let urlString = "https://sandbox.itunes.apple.com/verifyReceipt" #else let urlString = "https://buy.itunes.apple.com/verifyReceipt" #endif let receiptData = try? Data(contentsOf: receiptUrl).base64EncodedString() let sharedSecret = "YOUR_SHARED_SECRET" let requestData = ["receipt-data" : receiptData ?? "", "password" : sharedSecret, "exclude-old-transactions" : false] as [String : Any] var request = URLRequest(url: URL(string: urlString)!) request.httpMethod = "POST" request.setValue("Application/json", forHTTPHeaderField: "Content-Type") let httpBody = try? JSONSerialization.data(withJSONObject: requestData, options: []) request.httpBody = httpBody URLSession.shared.dataTask(with: request) { (data, response, error) in // continue here }.resume() } 

يستخدم المثال أعلاه الماكرو #if DEBUG لتحديد نوع الاشتراك: sandbox أو production . إذا كنت تستخدم وحدات ماكرو أخرى ، فستحتاج إلى تحديث الكود في هذا المكان.

2. تحقق مما إذا كانت الجملة التمهيدية قد استخدمت من قبل


بعد تلقي استجابة من Apple ، نقوم بترجمتها إلى Dictionary والحصول على مجموعة من المعاملات:


 // paste this code after "continue here" comment guard let data = data, let json = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String : AnyHashable], let receipts_array = json["latest_receipt_info"] as? [[String : AnyHashable]] else { callback(true) return } // continue here 

نذهب إلى مجموعة المعاملات وننظر إلى قيم is_trial_period و is_in_intro_offer_period . إذا كانت إحدى القيم true ، فقد قام المستخدم بالفعل بوضع جملة تمهيدية. هذه القيم تأتي كسلسلة ، لذلك من أجل الموثوقية ، سنحاول تحويل القيمة في كل من Bool و string.


 // paste this code after "continue here" comment var latestExpiresDate = Date(timeIntervalSince1970: 0) let formatter = DateFormatter() for receipt in receipts_array { let used_trial : Bool = receipt["is_trial_period"] as? Bool ?? false || (receipt["is_trial_period"] as? NSString)?.boolValue ?? false let used_intro : Bool = receipt["is_in_intro_offer_period"] as? Bool ?? false || (receipt["is_in_intro_offer_period"] as? NSString)?.boolValue ?? false if used_trial || used_intro { callback(false) return } // continue here 

3. التحقق من الوضع الحالي للاشتراك


لمعرفة الحالة الحالية للاشتراك ، نحتاج إلى العثور على أحدث تاريخ انتهاء الصلاحية ومقارنته مع التاريخ الحالي. إذا لم ينته الاشتراك ، فلن يكون العرض التمهيدي متاحًا:


 // paste this code after "continue here" comment formatter.dateFormat = "yyyy-MM-dd HH:mm:ss VV" if let expiresDateString = receipt["expires_date"] as? String, let date = formatter.date(from: expiresDateString) { if date > latestExpiresDate { latestExpiresDate = date } } } if latestExpiresDate > Date() { callback(false) } else { callback(true) } 

يمكنك العثور على رابط للرمز الكامل للطريقة في نهاية المقالة ، ولكن هناك الكثير من "لكن" في هذه الطريقة.


المزالق


  • في هذا المثال ، نظرنا فقط في حالة مجموعة اشتراك واحدة. إذا كنت تستخدم أكثر من مجموعة اشتراك واحدة في أحد التطبيقات ، فيجب عليك تمرير معرف مجموعة الاشتراك إلى هذه الطريقة والتحقق من ذلك بواسطة قيمة subscription_group_identifier في receipt .


  • في هذا المثال ، لا تؤخذ حالة إرجاع الاشتراكات في الاعتبار. للقيام بذلك ، تحقق من وجود الحقل cancellation_date :


     if receipt["cancellation_date"] != nil{ // if user made a refund, no need to check for eligibility callback(false) return } 

  • وهنا لا تؤخذ فترة السماح (فترة سماح الفوترة) في الاعتبار. إذا كان المستخدم في فترة السماح في الوقت الذي تم التحقق من صحة التحقق ، grace_period_expires_date حقل grace_period_expires_date . في هذه الحالة ، يتعين عليك كمطور أن توفر وظيفة مميزة للمستخدم دون عرض شاشة دفع. وبناءً على ذلك ، لا معنى للتحقق من توفر الجملة التمهيدية.


  • هناك مشكلة في التحقق من تاريخ انتهاء الصلاحية. يمكن إلغاء وقت النظام على جهاز iOS ومن ثم سيعطي رمزنا نتيجة غير صحيحة: سيتم اعتبار الاشتراك نشطًا.


  • لا توصي شركة Apple بالتحقق من صحة الفحص على الجهاز نفسه. تحدثوا عن هذا عدة مرات في WWDC (من 5:50) وهذا موضح في الوثائق . هذا غير آمن لأن أي مهاجم يمكنه اعتراض البيانات باستخدام هجوم رجل في المنتصف. توصي Apple باستخدام الخادم الخاص بك للتحقق من صحة الشيكات.



التحقق من توافر عرض ترويجي


شرط توفر العرض الترويجي أبسط - الشيء الرئيسي هو أن المستخدم لديه اشتراك نشط أو منتهي الصلاحية. للقيام بذلك ، ابحث عن وجود pending_renewal_info لمجموعة الاشتراك الخاصة بك.


كيف يتم تنفيذه في Apphud SDK


يكفي استدعاء طريقة واحدة ، لتمرير product الخاص بك إلى داخلها ، مما سيعيد لك النتيجة:


 Apphud.checkEligibilityForIntroductoryOffer(product: myProduct) { result in if result { // User is eligible to purchase introductory offer } } 

وبالمثل بالنسبة للعرض الترويجي:


 Apphud.checkEligibilityForPromotionalOffer(product: myProduct) { result in if result { // User is eligible to purchase promotional offer } } 

هناك أيضًا طرق للتحقق من توفر العديد من المنتجات مرة واحدة في مكالمة واحدة:


 func checkEligibilitiesForIntroductoryOffers(products: [SKProduct], callback: ApphudEligibilityCallback) func checkEligibilitiesForPromotionalOffers(products: [SKProduct], callback: ApphudEligibilityCallback) 

استنتاج


يمكن تنزيل رمز الطريقة الكاملة هنا .


لقد قمنا في Apphud بالفعل بتنفيذ فحص حول توفر العروض التمهيدية والترويجية في SDK مريحة ومفتوحة المصدر. يساعدك Apphud أيضًا على تتبع حالة الاشتراك ، وتحليل المقاييس الأساسية ، وتقديم خصومات تلقائيًا للمستخدمين غير المشتركين ، وغير ذلك الكثير. إذا كنت تعاني من الألم أثناء العمل مع الاشتراكات ، فجرّب حلنا مجانًا.

Source: https://habr.com/ru/post/ar471492/


All Articles