Comment vérifier la disponibilité de l'offre de lancement dans iOS

Si vous utilisez des offres de lancement dans votre application d'abonnement (essai, paiement à l'utilisation ou prépaiement), avant d'afficher le prix sur l'écran de paiement, vous devez déterminer la disponibilité de l'offre de lancement pour l'utilisateur. Si l'utilisateur a déjà rédigé un essai, vous devez afficher le prix total pour celui-ci.


image


Bonjour à tous, je suis en contact avec Renat d' Apphud - un service qui simplifie le travail avec les abonnements dans les applications iOS. Aujourd'hui, je vais vous dire comment déterminer si un seul utilisateur a le droit d'activer une phrase d'introduction ou non.


L'offre de lancement est valable au sein du même groupe d'abonnement. Cela signifie que l'utilisateur peut émettre un abonnement hebdomadaire régulier sans essai, se désabonner et ensuite émettre un essai pour un abonnement mensuel.


La documentation Apple contient un diagramme montrant quand une phrase d'introduction est disponible pour l'utilisateur:



Il s'avère que l'utilisateur peut utiliser la phrase introductive si:


  • il n'avait pas utilisé une phrase introductive avant

Et


  • l'abonnement n'a pas été émis ou a expiré

Pour vérifier la disponibilité de la phrase introductive, vous devez effectuer 3 étapes:


1) Validez l'App Store-check et retirez le tableau des transactions. S'il n'y a pas de transactions, nous ne vérifions rien, une offre de lancement est disponible. S'il y a des transactions, effectuez les deux étapes suivantes.


2) Vérifiez si la phrase introductive a déjà été utilisée


3) Vérifier l'état actuel de l'abonnement


Examinons ces étapes plus en détail.


1. Validation du chèque App Store


Pour valider le chèque, vous devez envoyer une demande à Apple, en transmettant receiptData et sharedSecret . Remplacez la valeur sharedSecret par la vôtre. Si vous ne connaissez pas votre sharedSecret , il est décrit ici où l'obtenir.


 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() } 

L'exemple ci-dessus utilise la macro #if DEBUG pour déterminer le type d'abonnement: sandbox ou production . Si vous utilisez d'autres macros, vous devrez mettre à jour le code à cet endroit.

2. Vérifiez si une phrase introductive a déjà été utilisée


Après avoir reçu une réponse d'Apple, nous la traduisons en Dictionary et obtenons un éventail de transactions:


 // 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 

Nous is_trial_period le tableau des transactions et examinons les valeurs de is_trial_period et is_in_intro_offer_period . Si l'une des valeurs est true , alors l'utilisateur a déjà rédigé une phrase d'introduction. Ces valeurs se présentent sous la forme d'une chaîne, donc pour plus de fiabilité, nous allons essayer de convertir la valeur à la fois en Bool et en chaîne.


 // 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. Vérification de l'état actuel de l'abonnement


Pour connaître l'état actuel de l'abonnement, nous devons trouver la dernière date d' expires_date et comparer avec la date actuelle. Si l'abonnement n'a pas expiré, l'offre de lancement n'est pas disponible:


 // 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) } 

Vous pouvez trouver un lien vers le code complet de la méthode à la fin de l'article, cependant, il y a beaucoup de "Mais" dans cette méthode.


Pièges


  • Dans cet exemple, nous n'avons examiné que le cas d'un groupe d'abonnement. Si vous utilisez plusieurs groupes d'abonnements dans une application, vous devez transmettre l'identifiant du groupe d'abonnements à cette méthode et le vérifier par la valeur de subscription_group_identifier à la receipt .


  • Dans cet exemple, le cas du retour des abonnements n'est pas pris en compte. Pour ce faire, vérifiez la présence du champ cancellation_date :


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

  • Et ici, le délai de grâce (Billing Grace Period) n'est pas pris en compte. Si l'utilisateur est dans la période de grâce au moment où la vérification est validée, en pending_renewal_info aura le champ grace_period_expires_date . Dans ce cas, en tant que développeur, vous devez fournir des fonctionnalités premium à l'utilisateur sans afficher d'écran de paiement. Et en conséquence, cela n'a aucun sens de vérifier la disponibilité de la phrase introductive.


  • Il y a un problème avec la vérification de la date d'expiration. L'heure du système sur l'appareil iOS peut être dévissée, puis notre code donnera un résultat incorrect: l'abonnement sera considéré comme actif.


  • La validation d'une vérification sur l'appareil lui-même n'est pas recommandée par Apple. Ils en ont parlé plusieurs fois à la WWDC (à partir de 5h50) et cela est indiqué dans la documentation . Ceci n'est pas sûr car un attaquant peut intercepter des données à l'aide d'une attaque par l'homme du milieu. Apple recommande d'utiliser votre serveur pour valider les chèques.



Vérification de la disponibilité d'une offre promotionnelle


La condition de disponibilité de l'offre promotionnelle est plus simple - l'essentiel est que l'utilisateur dispose d'un abonnement actif ou expiré. Pour ce faire, recherchez la présence de pending_renewal_info pour votre groupe d'abonnement.


Comment il est implémenté dans le SDK Apphud


Il suffit d'appeler une méthode, en y passant votre product , qui vous renverra le résultat:


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

Et de même pour l'offre promotionnelle:


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

Il existe également des méthodes pour vérifier la disponibilité de plusieurs produits en une seule fois:


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

Conclusion


Le code de méthode complet peut être téléchargé ici .


Chez Apphud, nous avons déjà mis en place une vérification de la disponibilité des offres de lancement et promotionnelles dans un SDK open-source pratique. Apphud vous aide également à suivre l'état de l'abonnement, à analyser les mesures clés, à proposer automatiquement des remises aux utilisateurs non abonnés, et bien plus encore. Si vous éprouvez de la douleur en travaillant avec des abonnements, essayez gratuitement notre solution .

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


All Articles