Transactions et vérification dans Xamarin.iOS
Restauration des transactions passées
Si votre application prend en charge les types de produits qui peuvent être restaurés, vous devez inclure certains éléments d’interface utilisateur pour permettre aux utilisateurs de restaurer ces achats. Cette fonctionnalité permet à un client d’ajouter le produit à d’autres appareils ou de restaurer le produit sur le même appareil après avoir été réinitialisation propre ou la suppression et la réinstallation de l’application. Les types de produits suivants peuvent être restaurés :
- Produits non consommables
- Abonnements renouvelables automatiquement
- Abonnements gratuits
Le processus de restauration doit mettre à jour les enregistrements que vous conservez sur l’appareil pour traiter vos produits. Le client peut choisir de restaurer à tout moment, sur l’un de ses appareils. Le processus de restauration renvoie à nouveau toutes les transactions précédentes pour cet utilisateur ; le code de l’application doit ensuite déterminer l’action à entreprendre avec ces informations (par exemple, vérifier s’il existe déjà un enregistrement de cet achat sur l’appareil et, dans le cas contraire, créer un enregistrement de l’achat et activer le produit pour l’utilisateur).
Implémentation de la restauration
Le bouton Restaurer de l’interface utilisateur appelle la méthode suivante, qui déclenche RestoreCompletedTransactions sur le SKPaymentQueue
.
public void Restore()
{
// theObserver will be notified of when the restored transactions start arriving <- AppStore
SKPaymentQueue.DefaultQueue.RestoreCompletedTransactions();
}
StoreKit enverra la demande de restauration aux serveurs d’Apple de manière asynchrone.
Étant donné que le est inscrit en tant qu’observateur de transactions, il reçoit des CustomPaymentObserver
messages lorsque les serveurs d’Apple répondent. La réponse contiendra toutes les transactions que cet utilisateur a jamais effectuées dans cette application (sur tous ses appareils). Le code effectue une boucle dans chaque transaction, détecte l’état Restauré et appelle la méthode pour la UpdatedTransactions
traiter comme indiqué ci-dessous :
// called when the transaction status is updated
public override void UpdatedTransactions (SKPaymentQueue queue, SKPaymentTransaction[] transactions)
{
foreach (SKPaymentTransaction transaction in transactions)
{
switch (transaction.TransactionState)
{
case SKPaymentTransactionState.Purchased:
theManager.CompleteTransaction(transaction);
break;
case SKPaymentTransactionState.Failed:
theManager.FailedTransaction(transaction);
break;
case SKPaymentTransactionState.Restored:
theManager.RestoreTransaction(transaction);
break;
default:
break;
}
}
}
S’il n’existe aucun produit pouvant être restauré pour l’utilisateur, UpdatedTransactions
n’est pas appelé.
Le code le plus simple possible pour restaurer une transaction donnée dans l’exemple effectue les mêmes actions que lors d’un achat, sauf que la OriginalTransaction
propriété est utilisée pour accéder à l’ID de produit :
public void RestoreTransaction (SKPaymentTransaction transaction)
{
// Restored Transactions always have an 'original transaction' attached
var productId = transaction.OriginalTransaction.Payment.ProductIdentifier;
// Register the purchase, so it is remembered for next time
PhotoFilterManager.Purchase(productId); // it's as though it was purchased again
FinishTransaction(transaction, true);
}
Une implémentation plus sophistiquée peut case activée d’autres transaction.OriginalTransaction
propriétés, telles que la date d’origine et le numéro de reçu. Ces informations seront utiles pour certains types de produits (tels que les abonnements).
Fin de la restauration
a CustomPaymentObserver
deux méthodes supplémentaires qui seront appelées par StoreKit lorsque le processus de restauration est terminé (avec succès ou avec un échec), comme indiqué ci-dessous :
public override void PaymentQueueRestoreCompletedTransactionsFinished (SKPaymentQueue queue)
{
Console.WriteLine(" ** RESTORE Finished ");
}
public override void RestoreCompletedTransactionsFailedWithError (SKPaymentQueue queue, NSError error)
{
Console.WriteLine(" ** RESTORE FailedWithError " + error.LocalizedDescription);
}
Dans l’exemple, ces méthodes ne font rien, mais une application réelle peut choisir d’implémenter un message à l’utilisateur ou d’autres fonctionnalités.
Sécurisation des achats
Les deux exemples de ce document utilisent NSUserDefaults
pour suivre les achats :
Consommables : le « solde » des achats à crédit est une valeur entière simple NSUserDefaults
incrémentée à chaque achat.
Non consommables : chaque achat de filtre photo est stocké sous la forme d’une paire clé-valeur dans NSUserDefaults
.
L’utilisation NSUserDefaults
conserve l’exemple de code simple, mais n’offre pas une solution très sécurisée, car il peut être possible pour les utilisateurs techniquement soucieux de mettre à jour les paramètres (en contournant le mécanisme de paiement).
Remarque : Les applications réelles doivent adopter un mécanisme sécurisé pour stocker le contenu acheté qui ne fait pas l’objet d’une falsification de l’utilisateur. Cela peut impliquer le chiffrement et/ou d’autres techniques, y compris l’authentification de serveur distant.
Le mécanisme doit également être conçu pour tirer parti des fonctionnalités intégrées de sauvegarde et de récupération d’iOS, d’iTunes et d’iCloud. Cela garantit qu’une fois qu’un utilisateur a restauré une sauvegarde, ses achats précédents seront immédiatement disponibles.
Pour plus d’instructions spécifiques à iOS, reportez-vous au Guide de codage sécurisé d’Apple.
Vérification des reçus et produits Server-Delivered
Jusqu’à présent, les exemples de ce document consistaient uniquement en la communication directe de l’application avec les serveurs App Store pour effectuer des transactions d’achat, ce qui déverrouille les fonctionnalités ou les fonctionnalités déjà codées dans l’application.
Apple offre un niveau supplémentaire de sécurité d’achat en autorisant la vérification indépendante des reçus d’achat par un autre serveur, ce qui peut être utile pour valider une demande avant de livrer du contenu numérique dans le cadre d’un achat (par exemple, un livre numérique ou un magazine).
Produits intégrés : comme dans les exemples de ce document, le produit acheté existe en tant que fonctionnalité fournie avec l’application. Un achat dans l’application permet à l’utilisateur d’accéder à la fonctionnalité. Les ID de produit sont codés en dur.
Produits livrés par serveur : le produit se compose de contenu téléchargeable stocké sur un serveur distant jusqu’à ce qu’une transaction réussie entraîne le téléchargement du contenu. Les exemples peuvent inclure des livres ou des problèmes de magazine. Les ID de produit proviennent généralement d’un serveur externe (où le contenu du produit est également hébergé). Les applications doivent implémenter un moyen robuste d’enregistrement lorsqu’une transaction est terminée, afin qu’en cas d’échec du téléchargement du contenu, elle puisse être tentée à nouveau sans confondre l’utilisateur.
produits Server-Delivered
Le contenu de certains produits, tels que des livres et des magazines (ou même un niveau de jeu), doit être téléchargé à partir d’un serveur distant pendant le processus d’achat. Cela signifie qu’un serveur supplémentaire est nécessaire pour stocker et remettre le contenu du produit après son achat.
Obtenir les prix des produits Server-Delivered
Étant donné que les produits sont livrés à distance, il est également possible d’ajouter d’autres produits au fil du temps (sans mettre à jour le code de l’application), par exemple en ajoutant d’autres livres ou de nouveaux numéros d’un magazine. Pour que l’application puisse découvrir ces produits d’actualités et les afficher à l’utilisateur, le serveur supplémentaire doit stocker et fournir ces informations.
Les informations sur le produit doivent être stockées à plusieurs emplacements : sur votre serveur et dans iTunes Connect. En outre, des fichiers de contenu sont associés à chaque produit. Ces fichiers seront remis après un achat réussi.
Lorsque l’utilisateur souhaite acheter un produit, l’application doit déterminer les produits disponibles. Ces informations peuvent être mises en cache, mais doivent être remises à partir d’un serveur distant où est stockée la master liste des produits.
Le serveur retourne une liste d’ID de produit pour l’application à analyser.
L’application détermine ensuite lequel de ces ID de produit à envoyer à StoreKit pour récupérer les prix et les descriptions.
StoreKit envoie la liste des ID de produit aux serveurs d’Apple.
Les serveurs iTunes répondent avec des informations de produit valides (description et prix actuel).
L’application est
SKProductsRequestDelegate
transmise aux informations du produit pour l’affichage à l’utilisateur.
Achat de produits Server-Delivered
Étant donné que le serveur distant nécessite un moyen de valider la validité d’une demande de contenu (c’est-à-dire qu’il a été payé), les informations de reçu sont transmises pour l’authentification. Le serveur distant transfère ces données à iTunes pour vérification et, en cas de réussite, inclut le contenu du produit dans la réponse à l’application.
L’application ajoute un
SKPayment
à la file d’attente. Si nécessaire, l’utilisateur est invité à entrer son ID Apple et à confirmer le paiement.StoreKit envoie la demande au serveur pour traitement.
Une fois la transaction terminée, le serveur répond avec un reçu de transaction.
La
SKPaymentTransactionObserver
sous-classe reçoit le reçu et le traite. Étant donné que le produit doit être téléchargé à partir d’un serveur, l’application lance une demande réseau vers le serveur distant.La demande de téléchargement est accompagnée des données de reçu afin que le serveur distant puisse vérifier qu’il est autorisé à accéder au contenu. Le client réseau de l’application attend une réponse à cette demande.
Lorsque le serveur reçoit une demande de contenu, il analyse les données de reçu et envoie une requête directement aux serveurs iTunes pour vérifier que le reçu est pour une transaction valide. Le serveur doit utiliser une logique pour déterminer s’il faut envoyer la demande à l’URL de production ou de bac à sable. Apple vous suggère de toujours utiliser l’URL de production et de basculer vers le bac à sable si votre réception status 21007 (reçu de bac à sable envoyé au serveur de production). Pour plus d’informations, reportez-vous au Guide de programmation de validation des reçus d’Apple.
iTunes case activée le reçu et retourne un status de zéro s’il est valide.
Le serveur attend la réponse d’iTunes. S’il reçoit une réponse valide, le code doit localiser le fichier de contenu du produit associé à inclure dans la réponse à l’application.
L’application reçoit et analyse la réponse, en enregistrant le contenu du produit dans le système de fichiers de l’appareil.
L’application active le produit, puis appelle storeKit’s
FinishTransaction
. L’application peut ensuite éventuellement afficher le contenu acheté (par exemple, afficher la première page d’un livre ou d’un magazine acheté).
Une autre implémentation pour les fichiers de contenu de produit très volumineux peut consister simplement à stocker le reçu de transaction à l’étape 9 afin que la transaction puisse être effectuée rapidement et à fournir une interface utilisateur permettant à l’utilisateur de télécharger le contenu du produit réel ultérieurement. La demande de téléchargement suivante peut renvoyer le reçu stocké pour accéder au fichier de contenu du produit requis.
Écriture Server-Side code de vérification des reçus
La validation d’un reçu dans le code côté serveur peut être effectuée à l’aide d’une simple requête/réponse HTTP POST qui englobe les étapes 5 à 8 dans le diagramme de flux de travail.
Extrayez la SKPaymentTansaction.TransactionReceipt
propriété dans l’application. Il s’agit des données qui doivent être envoyées à iTunes pour vérification (étape 5).
Encodez en base64 les données de réception de transaction (à l’étape 5 ou 6).
Créez une charge utile JSON simple comme suit :
{
"receipt-data" : "(base-64 encoded receipt here)"
}
HTTP POST le JSON vers pour https://buy.itunes.apple.com/verifyReceipt la production ou https://sandbox.itunes.apple.com/verifyReceipt pour le test.
La réponse JSON contient les clés suivantes :
{
"status" : 0,
"receipt" : { (receipt repeated here) }
}
Une status de zéro indique un reçu valide. Votre serveur peut continuer à traiter le contenu du produit acheté. La clé de réception contient un dictionnaire JSON avec les mêmes propriétés que l’objet SKPaymentTransaction
reçu par l’application, de sorte que le code serveur peut interroger ce dictionnaire pour récupérer des informations telles que la product_id et la quantité de l’achat.
Pour plus d’informations, consultez la documentation du Guide de programmation de validation des reçus d’Apple.