Je cherche à mettre en œuvre les nouveaux abonnements automatiques renouvelables à l'aide de l'achat d'applications, mais je ne sais pas comment ou quand vérifier si l'utilisateur est actuellement souscrit. Ma compréhension est que lorsque l'utilisateur abonna initialement à l'application peut utiliser la date d'achat avec la date d'abonnement pour calculer la durée de la durée de leur abonnement. Que se passe-t-il après cette date? Comment vérifions-nous si l'utilisateur a automatiquement renouvelé ou annulé?
Si j'utilise restoreCompletedTransactions
pour obtenir une transaction et une réception pour chaque renouvellement, l'utilisateur sera invité à entrer son mot de passe iTunes. Cela signifie-t-il que s'ils ont acheté une abonnement de 7 jours, ils devront entrer leur mot de passe tous les 7 jours lorsque l'application vérifie si l'abonnement est toujours valide?
Si vous souhaitez le vérifier à partir d'un serveur Web, vous pingez leur API et il renvoie le statut de l'abonnement et des informations renouvelables automatiques sur le dernier paiement.
Si vous êtes sur l'appareil, vous devez probablement appeler des installations de restauration de restauration que je devine demander le mot de passe.
Je ne vois aucune autre méthode. Je suppose que de l'appareil que vous pouvez vérifier l'abonnement en contactant le même service Web utilisé sur le côté serveur? Je ne sais pas comment les avantages et les inconvénients de cela.
Aujourd'hui, j'ai des problèmes avec ce problème.
Suivre Apple doc ici, j'ai utilisé ce moyen de vérifier que l'abonnement est expiré ou non. Mon idée: utilisateur Apple REST Réponse de l'API: (Demande de requête + Temps expiré) pour vérifier expiré ou non
+ (BOOL)checkInAppPurchaseStatus
{
// Load the receipt from the app bundle.
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
NSData *receipt = [NSData dataWithContentsOfURL:receiptURL];
if (receipt) {
BOOL sandbox = [[receiptURL lastPathComponent] isEqualToString:@"sandboxReceipt"];
// Create the JSON object that describes the request
NSError *error;
NSDictionary *requestContents = @{
@"receipt-data": [receipt base64EncodedStringWithOptions:0],@"password":@"SHARE_SECRET_CODE"
};
NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents
options:0
error:&error];
if (requestData) {
// Create a POST request with the receipt data.
NSURL *storeURL = [NSURL URLWithString:@"https://buy.iTunes.Apple.com/verifyReceipt"];
if (sandbox) {
storeURL = [NSURL URLWithString:@"https://sandbox.iTunes.Apple.com/verifyReceipt"];
}
NSMutableURLRequest *storeRequest = [NSMutableURLRequest requestWithURL:storeURL];
[storeRequest setHTTPMethod:@"POST"];
[storeRequest setHTTPBody:requestData];
BOOL rs = NO;
//Can use sendAsynchronousRequest to request to Apple API, here I use sendSynchronousRequest
NSError *error;
NSURLResponse *response;
NSData *resData = [NSURLConnection sendSynchronousRequest:storeRequest returningResponse:&response error:&error];
if (error) {
rs = NO;
}
else
{
NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:resData options:0 error:&error];
if (!jsonResponse) {
rs = NO;
}
else
{
NSLog(@"jsonResponse:%@", jsonResponse);
NSDictionary *dictLatestReceiptsInfo = jsonResponse[@"latest_receipt_info"];
long long int expirationDateMs = [[dictLatestReceiptsInfo valueForKeyPath:@"@max.expires_date_ms"] longLongValue];
long long requestDateMs = [jsonResponse[@"receipt"][@"request_date_ms"] longLongValue];
NSLog(@"%lld--%lld", expirationDateMs, requestDateMs);
rs = [[jsonResponse objectForKey:@"status"] integerValue] == 0 && (expirationDateMs > requestDateMs);
}
}
return rs;
}
else
{
return NO;
}
}
else
{
return NO;
}
}
J'espère que cette aide.
Mieux vaut utiliser une solution locale avant de faire appel à l'API Apple. Chaque fois que l'application fonctionne, c'est une bonne pratique pour valider le reçu local et si vous devez vérifier si un utilisateur dispose de l'abonnement actif, vous pouvez d'abord récupérer les achats à partir du reçu local et savoir que l'achat est toujours actif pour aujourd'hui. .
J'ai mis en place une petite bibliothèque écrite dans Swift
pour simplifier de travailler avec la réception intégrée localement. Vous pouvez facilement extraire l'objet qui représente le reçu (InAppReceipt
) et récupérer un achat actif/tous les achats.
N'hésitez pas à utiliser. link github
Voici un exemple de résolution de votre problème:
import TPInAppReceipt
do {
let receipt = try InAppReceiptManager.shared.receipt()
//retrive active auto renewable subscription for a specific product and date
let purchase = receipt.activeAutoRenewableSubscriptionPurchases(ofProductIdentifier: "ProductName", forDate: Date())
//retrive all auto renewable subscription purchases for a specific product
let allAutoRenewableSubscriptionPurchases = receipt.purchases(ofProductIdentifier: "productName").filter({ return $0.isRenewableSubscription })
} catch {
print(error)
}
Je commence une campagne autour de cette question. Voici mon observation et ma campagne:
Lors du renouvellement automatique, l'App Store appelle le paymentQueue
et publie une transaction. La transaction est affichée avec transaction.transactionState==SKPaymentTransactionStateRestored
.
Le problème est que malheureusement cela ne fait pas affiché qu'à un seul appareil. Un deuxième appareil ne reçoit pas l'affichage. Par conséquent, pour détecter le renouvellement automatique, ou plutôt pour détecter le manque d'autoroutewal et refuser le périphérique un abonnement continu, vous devez faire un restoreCompletedTransaction
ou "http Publier un JSON codé 64 bits contenant le dernier transaction". Si le premier, l'utilisateur doit donner leur mot de passe; C'est intrusif - comme vous l'avez signalé ci-dessus. Si ces derniers, beaucoup de codage supplémentaire sont nécessaires. Donc, ma question est ... pourquoi ne fonctionne pas StoreKit
avoir une commande:
(n'existe pas) - [[SKPaymentQueue defaultQueue] restoreAttachedTransactions:(NSArray *)transactions];
Cette commande déboulerait comme un restoreCompletedTransactions
mais il ne restaurerait que les transactions ci-jointes et, surtout, cela ne nécessiterait pas la connexion de l'utilisateur. Il a la même protection de sécurité que "HTTP Publier un JSON codé 64 bits contenant la dernière transaction" et permet de faire l'ensemble du processus d'achat d'applications à effectuer dans StoreKit
plutôt que de nécessiter un code d'enregistrement Web.
Si cela est logique pour vous, veuillez suggérer comment obtenir ceci à Apple ... merci.