|
@@ -17,6 +17,7 @@
|
|
#import "NSNULL+Filtration.h"
|
|
#import "NSNULL+Filtration.h"
|
|
#import "ASIFormDataRequest.h"
|
|
#import "ASIFormDataRequest.h"
|
|
#import "JSONKit.h"
|
|
#import "JSONKit.h"
|
|
|
|
+#import "NSObject+DeviceInfo.h"
|
|
|
|
|
|
NSString *const KMStoreLiteKitSecret = @"d8286a8909884e64b84d522305f07463";
|
|
NSString *const KMStoreLiteKitSecret = @"d8286a8909884e64b84d522305f07463";
|
|
NSString *const KMStoreKitSecret = @"b88b5d687d1547c2ad3c4dd882dec9db";
|
|
NSString *const KMStoreKitSecret = @"b88b5d687d1547c2ad3c4dd882dec9db";
|
|
@@ -28,6 +29,7 @@ NSString *const KMItunesServer = @"https://store.filmagepro.com:3018/api/subscri
|
|
NSString *const KMStoreReceipt = @"KMStoreReceiptKey";
|
|
NSString *const KMStoreReceipt = @"KMStoreReceiptKey";
|
|
|
|
|
|
NSString * const KMMonthLicenseProductIdentifier = @"com.pdfreaderpro.mac_free.member.all_access_pack_6months.001";
|
|
NSString * const KMMonthLicenseProductIdentifier = @"com.pdfreaderpro.mac_free.member.all_access_pack_6months.001";
|
|
|
|
+NSString * const KMYearLicenseProductIdentifier = @"com.pdfreaderpro.mac_free.member.all_access_pack_12months.001";
|
|
NSString * const KMNewMonthLicenseProductIdentifier = @"com.pdfreaderpro.mac_free.member.all_access_pack_new_6months.001";
|
|
NSString * const KMNewMonthLicenseProductIdentifier = @"com.pdfreaderpro.mac_free.member.all_access_pack_new_6months.001";
|
|
//NSString * const KMNewMonthLicenseProductIdentifier = @"com.pdftechnologies.pdfreader.mac.yearly.002.Test";
|
|
//NSString * const KMNewMonthLicenseProductIdentifier = @"com.pdftechnologies.pdfreader.mac.yearly.002.Test";
|
|
NSString * const KMAllLicenseProductIdentifier = @"com.pdfreaderpro.mac_free.member.all_access_pack_permanent_license.001";
|
|
NSString * const KMAllLicenseProductIdentifier = @"com.pdfreaderpro.mac_free.member.all_access_pack_permanent_license.001";
|
|
@@ -58,6 +60,8 @@ NSString * const KMIAPSubscriptionLoadedNotification = @"KMIAPSubscriptionLoaded
|
|
|
|
|
|
@property (nonatomic, assign) BOOL isTrialPeriod;//判断当前套餐是否试用过
|
|
@property (nonatomic, assign) BOOL isTrialPeriod;//判断当前套餐是否试用过
|
|
|
|
|
|
|
|
+@property (nonatomic, copy) NSString *autoRenewStatus;
|
|
|
|
+
|
|
@end
|
|
@end
|
|
|
|
|
|
@implementation IAPProduct
|
|
@implementation IAPProduct
|
|
@@ -94,6 +98,28 @@ NSString * const KMIAPSubscriptionLoadedNotification = @"KMIAPSubscriptionLoaded
|
|
return price;
|
|
return price;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+- (NSString *)discountPrice {
|
|
|
|
+ NSString *price = nil;
|
|
|
|
+ if (@available(macOS 10.14.4, *)) {
|
|
|
|
+ SKProductDiscount *flagDis = self.product.discounts.firstObject;
|
|
|
|
+#if !VERSION_DMG
|
|
|
|
+ if (flagDis.price) {
|
|
|
|
+ price = [self discountFormattedPrice:false price:flagDis.price];
|
|
|
|
+ } else {
|
|
|
|
+ price = [NSString stringWithFormat:@"USD $%0.2f", [self.offersPrice doubleValue]];
|
|
|
|
+#ifndef VERSION_DMG
|
|
|
|
+ // 获取产品价格信息
|
|
|
|
+ [[IAPProductsManager defaultManager] loadAllProducts];
|
|
|
|
+#endif
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
+ price = price ? : @"";
|
|
|
|
+ return price;
|
|
|
|
+}
|
|
|
|
+
|
|
- (NSString *)averagePrice {
|
|
- (NSString *)averagePrice {
|
|
NSString *price = nil;
|
|
NSString *price = nil;
|
|
#if !VERSION_DMG
|
|
#if !VERSION_DMG
|
|
@@ -101,7 +127,11 @@ NSString * const KMIAPSubscriptionLoadedNotification = @"KMIAPSubscriptionLoaded
|
|
price = [self formattedPrice:YES];
|
|
price = [self formattedPrice:YES];
|
|
} else {
|
|
} else {
|
|
if (self.priceNumber) {
|
|
if (self.priceNumber) {
|
|
- price = [NSString stringWithFormat:@"USD $%0.2f", [self.priceNumber doubleValue]/6.0];
|
|
|
|
|
|
+ CGFloat mouths = self.mouthNumber;
|
|
|
|
+ if (mouths <= 0) {
|
|
|
|
+ mouths = 1.0;
|
|
|
|
+ }
|
|
|
|
+ price = [NSString stringWithFormat:@"USD $%0.2f", [self.priceNumber doubleValue]/mouths];
|
|
}
|
|
}
|
|
#ifndef VERSION_DMG
|
|
#ifndef VERSION_DMG
|
|
// 获取产品价格信息
|
|
// 获取产品价格信息
|
|
@@ -113,6 +143,35 @@ NSString * const KMIAPSubscriptionLoadedNotification = @"KMIAPSubscriptionLoaded
|
|
return price;
|
|
return price;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+- (NSString *)discountAveragePrice {
|
|
|
|
+ NSString *price = nil;
|
|
|
|
+ if (@available(macOS 10.14.4, *)) {
|
|
|
|
+ SKProductDiscount *flagDis = self.product.discounts.firstObject;
|
|
|
|
+#if !VERSION_DMG
|
|
|
|
+ if (flagDis.price) {
|
|
|
|
+ price = [self discountFormattedPrice:true price:flagDis.price];
|
|
|
|
+ } else {
|
|
|
|
+ if (self.offersAveragePrice) {
|
|
|
|
+ CGFloat mouths = self.mouthNumber;
|
|
|
|
+ if (mouths <= 0) {
|
|
|
|
+ mouths = 1.0;
|
|
|
|
+ }
|
|
|
|
+ price = [NSString stringWithFormat:@"USD $%0.2f", [self.offersAveragePrice doubleValue]/mouths];
|
|
|
|
+ }
|
|
|
|
+#ifndef VERSION_DMG
|
|
|
|
+ // 获取产品价格信息
|
|
|
|
+ [[IAPProductsManager defaultManager] loadAllProducts];
|
|
|
|
+#endif
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
+ } else {
|
|
|
|
+ // Fallback on earlier versions
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ price = price ? : @"";
|
|
|
|
+ return price;
|
|
|
|
+}
|
|
|
|
+
|
|
- (NSString *)offersPrice {
|
|
- (NSString *)offersPrice {
|
|
NSString *price = nil;
|
|
NSString *price = nil;
|
|
if (self.offersPriceNumber) {
|
|
if (self.offersPriceNumber) {
|
|
@@ -125,7 +184,11 @@ NSString * const KMIAPSubscriptionLoadedNotification = @"KMIAPSubscriptionLoaded
|
|
- (NSString *)offersAveragePrice {
|
|
- (NSString *)offersAveragePrice {
|
|
NSString *price = nil;
|
|
NSString *price = nil;
|
|
if (self.offersPriceNumber) {
|
|
if (self.offersPriceNumber) {
|
|
- price = [NSString stringWithFormat:@"USD $%0.2f", [self.offersPriceNumber doubleValue]/6.0];
|
|
|
|
|
|
+ CGFloat mouths = self.mouthNumber;
|
|
|
|
+ if (mouths <= 0) {
|
|
|
|
+ mouths = 1.0;
|
|
|
|
+ }
|
|
|
|
+ price = [NSString stringWithFormat:@"USD $%0.2f", [self.offersPriceNumber doubleValue]/mouths];
|
|
}
|
|
}
|
|
price = price ? : @"";
|
|
price = price ? : @"";
|
|
return price;
|
|
return price;
|
|
@@ -135,6 +198,14 @@ NSString * const KMIAPSubscriptionLoadedNotification = @"KMIAPSubscriptionLoaded
|
|
return [self.offersPriceNumber doubleValue]/[self.priceNumber doubleValue];
|
|
return [self.offersPriceNumber doubleValue]/[self.priceNumber doubleValue];
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+- (BOOL)isCancelAutoRenew {
|
|
|
|
+ if (self.autoRenewStatus == nil) {
|
|
|
|
+ // 没有订阅
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ return [self.autoRenewStatus boolValue] == false;
|
|
|
|
+}
|
|
|
|
+
|
|
#pragma mark - Private Methods
|
|
#pragma mark - Private Methods
|
|
|
|
|
|
- (NSString *)formattedPrice:(BOOL)isAverage {
|
|
- (NSString *)formattedPrice:(BOOL)isAverage {
|
|
@@ -147,7 +218,11 @@ NSString * const KMIAPSubscriptionLoadedNotification = @"KMIAPSubscriptionLoaded
|
|
[numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
|
|
[numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
|
|
[numberFormatter setLocale:product.priceLocale];
|
|
[numberFormatter setLocale:product.priceLocale];
|
|
if (isAverage) {
|
|
if (isAverage) {
|
|
- NSNumber *number = [NSNumber numberWithDouble:[product.price doubleValue]/6.0];
|
|
|
|
|
|
+ CGFloat mouths = self.mouthNumber;
|
|
|
|
+ if (mouths <= 0) {
|
|
|
|
+ mouths = 1.0;
|
|
|
|
+ }
|
|
|
|
+ NSNumber *number = [NSNumber numberWithDouble:[product.price doubleValue]/mouths];
|
|
formattedString = [numberFormatter stringFromNumber:number];
|
|
formattedString = [numberFormatter stringFromNumber:number];
|
|
} else {
|
|
} else {
|
|
formattedString = [numberFormatter stringFromNumber:product.price];
|
|
formattedString = [numberFormatter stringFromNumber:product.price];
|
|
@@ -157,6 +232,30 @@ NSString * const KMIAPSubscriptionLoadedNotification = @"KMIAPSubscriptionLoaded
|
|
return formattedString;
|
|
return formattedString;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+- (NSString *)discountFormattedPrice:(BOOL)isAverage price:(NSDecimalNumber *)priceNum {
|
|
|
|
+ NSString *formattedString = nil;
|
|
|
|
+#if !VERSION_DMG
|
|
|
|
+ SKProduct *product = self.product;
|
|
|
|
+ if (product && [product.productIdentifier isEqualToString:self.productIdentifier]) {
|
|
|
|
+ NSNumberFormatter *numberFormatter = [[[NSNumberFormatter alloc] init] autorelease];
|
|
|
|
+ [numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
|
|
|
|
+ [numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
|
|
|
|
+ [numberFormatter setLocale:product.priceLocale];
|
|
|
|
+ if (isAverage) {
|
|
|
|
+ CGFloat mouths = self.mouthNumber;
|
|
|
|
+ if (mouths <= 0) {
|
|
|
|
+ mouths = 1.0;
|
|
|
|
+ }
|
|
|
|
+ NSNumber *number = [NSNumber numberWithDouble:[priceNum doubleValue]/mouths];
|
|
|
|
+ formattedString = [numberFormatter stringFromNumber:number];
|
|
|
|
+ } else {
|
|
|
|
+ formattedString = [numberFormatter stringFromNumber:priceNum];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
+ return formattedString;
|
|
|
|
+}
|
|
|
|
+
|
|
@end
|
|
@end
|
|
|
|
|
|
@interface IAPProductsManager ()
|
|
@interface IAPProductsManager ()
|
|
@@ -166,6 +265,7 @@ NSString * const KMIAPSubscriptionLoadedNotification = @"KMIAPSubscriptionLoaded
|
|
|
|
|
|
@property (nonatomic,retain) IAPProduct *monthProduct;
|
|
@property (nonatomic,retain) IAPProduct *monthProduct;
|
|
@property (nonatomic,retain) IAPProduct *newlyMonthProduct;
|
|
@property (nonatomic,retain) IAPProduct *newlyMonthProduct;
|
|
|
|
+@property (nonatomic,retain) IAPProduct *yearProduct;
|
|
@property (nonatomic,retain) IAPProduct *allAccessProduct;
|
|
@property (nonatomic,retain) IAPProduct *allAccessProduct;
|
|
@property (nonatomic,retain) IAPProduct *PDFToOfficeProduct;
|
|
@property (nonatomic,retain) IAPProduct *PDFToOfficeProduct;
|
|
|
|
|
|
@@ -215,12 +315,21 @@ NSString * const KMIAPSubscriptionLoadedNotification = @"KMIAPSubscriptionLoaded
|
|
self.monthProduct = [[[IAPProduct alloc] init] autorelease];
|
|
self.monthProduct = [[[IAPProduct alloc] init] autorelease];
|
|
self.monthProduct.productIdentifier = KMMonthLicenseProductIdentifier;
|
|
self.monthProduct.productIdentifier = KMMonthLicenseProductIdentifier;
|
|
self.monthProduct.priceNumber = @(29.99);
|
|
self.monthProduct.priceNumber = @(29.99);
|
|
|
|
+ self.monthProduct.mouthNumber = 1;
|
|
|
|
|
|
self.newlyMonthProduct = [[[IAPProduct alloc] init] autorelease];
|
|
self.newlyMonthProduct = [[[IAPProduct alloc] init] autorelease];
|
|
self.newlyMonthProduct.productIdentifier = KMNewMonthLicenseProductIdentifier;
|
|
self.newlyMonthProduct.productIdentifier = KMNewMonthLicenseProductIdentifier;
|
|
self.newlyMonthProduct.priceNumber = @(39.99);
|
|
self.newlyMonthProduct.priceNumber = @(39.99);
|
|
self.newlyMonthProduct.offersPriceNumber = @(29.99);
|
|
self.newlyMonthProduct.offersPriceNumber = @(29.99);
|
|
self.newlyMonthProduct.isOffers = isOffers;
|
|
self.newlyMonthProduct.isOffers = isOffers;
|
|
|
|
+ self.newlyMonthProduct.mouthNumber = 6;
|
|
|
|
+
|
|
|
|
+ self.yearProduct = [[[IAPProduct alloc] init] autorelease];
|
|
|
|
+ self.yearProduct.productIdentifier = KMYearLicenseProductIdentifier;
|
|
|
|
+ self.yearProduct.priceNumber = @(59.99);
|
|
|
|
+ self.yearProduct.offersPriceNumber = @(29.99);
|
|
|
|
+ self.yearProduct.isOffers = isOffers;
|
|
|
|
+ self.yearProduct.mouthNumber = 12;
|
|
|
|
|
|
self.allAccessProduct = [[[IAPProduct alloc] init] autorelease];
|
|
self.allAccessProduct = [[[IAPProduct alloc] init] autorelease];
|
|
self.allAccessProduct.productIdentifier = KMAllLicenseProductIdentifier;
|
|
self.allAccessProduct.productIdentifier = KMAllLicenseProductIdentifier;
|
|
@@ -240,6 +349,7 @@ NSString * const KMIAPSubscriptionLoadedNotification = @"KMIAPSubscriptionLoaded
|
|
|
|
|
|
self.productIdentifiers = @[KMMonthLicenseProductIdentifier,
|
|
self.productIdentifiers = @[KMMonthLicenseProductIdentifier,
|
|
KMNewMonthLicenseProductIdentifier,
|
|
KMNewMonthLicenseProductIdentifier,
|
|
|
|
+ KMYearLicenseProductIdentifier,
|
|
KMAllLicenseProductIdentifier,
|
|
KMAllLicenseProductIdentifier,
|
|
KMAILicenseProductIdentifier];
|
|
KMAILicenseProductIdentifier];
|
|
#else
|
|
#else
|
|
@@ -276,6 +386,7 @@ NSString * const KMIAPSubscriptionLoadedNotification = @"KMIAPSubscriptionLoaded
|
|
#endif
|
|
#endif
|
|
[_monthProduct release];
|
|
[_monthProduct release];
|
|
[_newlyMonthProduct release];
|
|
[_newlyMonthProduct release];
|
|
|
|
+ [_yearProduct release];
|
|
[_allAccessProduct release];
|
|
[_allAccessProduct release];
|
|
[_PDFToOfficeProduct release];
|
|
[_PDFToOfficeProduct release];
|
|
[_liteAIProduct release];
|
|
[_liteAIProduct release];
|
|
@@ -332,11 +443,84 @@ NSString * const KMIAPSubscriptionLoadedNotification = @"KMIAPSubscriptionLoaded
|
|
object:iapProduct.productIdentifier];
|
|
object:iapProduct.productIdentifier];
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
+
|
|
SKPayment *payment = [SKPayment paymentWithProduct:iapProduct.product];
|
|
SKPayment *payment = [SKPayment paymentWithProduct:iapProduct.product];
|
|
[[SKPaymentQueue defaultQueue] addPayment:payment];
|
|
[[SKPaymentQueue defaultQueue] addPayment:payment];
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+- (void)makeSubProduct:(IAPProduct *)iapProduct discount:(BOOL)discount {
|
|
|
|
+#if !VERSION_DMG
|
|
|
|
+ if (![SKPaymentQueue canMakePayments]) {
|
|
|
|
+ [[NSNotificationCenter defaultCenter] postNotificationName:KMIAPProductFailedNotification
|
|
|
|
+ object:iapProduct.productIdentifier];
|
|
|
|
+ return;
|
|
|
|
+ } else if (!iapProduct.product) {
|
|
|
|
+ [self loadAllProducts];
|
|
|
|
+ [[NSNotificationCenter defaultCenter] postNotificationName:KMIAPProductFailedNotification
|
|
|
|
+ object:iapProduct.productIdentifier];
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (@available(macOS 10.14.4, *)) {
|
|
|
|
+ if (discount == false) {
|
|
|
|
+ SKPayment *payment = [SKPayment paymentWithProduct:iapProduct.product];
|
|
|
|
+ [[SKPaymentQueue defaultQueue] addPayment:payment];
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ NSString *discountId = @"all_access_pack_12months_202407260";
|
|
|
|
+ NSString *sixDiscountId = @"all_access_pack_new_6months_202407260";
|
|
|
|
+// SKProductDiscount *discount = iapProduct.product.discounts.firstObject;
|
|
|
|
+ SKProductDiscount *flagDiscount = nil;
|
|
|
|
+ for (SKProductDiscount *dis in iapProduct.product.discounts) {
|
|
|
|
+ if ([dis.identifier isEqualToString:discountId]) {
|
|
|
|
+ flagDiscount = dis;
|
|
|
|
+ break;
|
|
|
|
+ } else if ([dis.identifier isEqualToString:sixDiscountId]) {
|
|
|
|
+ flagDiscount = dis;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (flagDiscount == nil) {
|
|
|
|
+ SKPayment *payment = [SKPayment paymentWithProduct:iapProduct.product];
|
|
|
|
+ [[SKPaymentQueue defaultQueue] addPayment:payment];
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // python3 -m pip install ecdsa
|
|
|
|
+ NSString *uuid = GetHardwareUUID().lowercaseString;
|
|
|
|
+ [self fetchOfferDetails:uuid productIdentifier:iapProduct.productIdentifier offerIdentifier:flagDiscount.identifier handler:^(NSString *nonce, CGFloat timestamp, NSString *sign, NSString *keyId, NSError *error) {
|
|
|
|
+ if (error == nil && sign != nil) {
|
|
|
|
+ SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:iapProduct.product];
|
|
|
|
+ NSUUID *uid = [[NSUUID alloc] initWithUUIDString:nonce];
|
|
|
|
+ NSNumber *time = [NSNumber numberWithDouble:timestamp];
|
|
|
|
+ SKPaymentDiscount *paymentDiscount = [[SKPaymentDiscount alloc] initWithIdentifier:flagDiscount.identifier keyIdentifier:keyId nonce:uid signature:sign timestamp:time];
|
|
|
|
+ payment.applicationUsername = @"user_name";
|
|
|
|
+ payment.paymentDiscount = paymentDiscount;
|
|
|
|
+
|
|
|
|
+ [[SKPaymentQueue defaultQueue] addPayment:payment];
|
|
|
|
+
|
|
|
|
+// SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:iapProduct.product];
|
|
|
|
+// NSUUID *uid = [[NSUUID alloc] initWithUUIDString:@"198b80fe-181f-53f4-9c4e-5d6e73f290eb"];
|
|
|
|
+// NSNumber *time = [NSNumber numberWithDouble:1721983323123];
|
|
|
|
+// SKPaymentDiscount *paymentDiscount = [[SKPaymentDiscount alloc] initWithIdentifier:flagDiscount.identifier keyIdentifier:@"7ZM85LHZYB" nonce:uid signature:@"MEUCIQCa3ZbKANYgJFsr71tCfPQeUyMXXMHKRFhzIDzxaJX8TAIgTN29r1bYCxwResW7gfos1DuWE9ni2MpcacOla+aUCTQ=" timestamp:time];
|
|
|
|
+// payment.applicationUsername = @"user_name";
|
|
|
|
+// payment.paymentDiscount = paymentDiscount;
|
|
|
|
+//
|
|
|
|
+// [[SKPaymentQueue defaultQueue] addPayment:payment];
|
|
|
|
+ } else {
|
|
|
|
+ [[NSNotificationCenter defaultCenter] postNotificationName:KMIAPProductFailedNotification
|
|
|
|
+ object:iapProduct.productIdentifier];
|
|
|
|
+ }
|
|
|
|
+ }];
|
|
|
|
+ } else {
|
|
|
|
+ SKPayment *payment = [SKPayment paymentWithProduct:iapProduct.product];
|
|
|
|
+ [[SKPaymentQueue defaultQueue] addPayment:payment];
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
+}
|
|
|
|
+
|
|
- (void)restoreSubscriptions {
|
|
- (void)restoreSubscriptions {
|
|
#if !VERSION_DMG
|
|
#if !VERSION_DMG
|
|
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
|
|
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
|
|
@@ -365,7 +549,8 @@ NSString * const KMIAPSubscriptionLoadedNotification = @"KMIAPSubscriptionLoaded
|
|
// 免费版
|
|
// 免费版
|
|
if (self.monthProduct.isSubscribed ||
|
|
if (self.monthProduct.isSubscribed ||
|
|
self.newlyMonthProduct.isSubscribed ||
|
|
self.newlyMonthProduct.isSubscribed ||
|
|
- self.allAccessProduct.isSubscribed) {
|
|
|
|
|
|
+ self.allAccessProduct.isSubscribed ||
|
|
|
|
+ self.yearProduct.isSubscribed) {
|
|
return YES;
|
|
return YES;
|
|
}
|
|
}
|
|
return NO;
|
|
return NO;
|
|
@@ -406,7 +591,8 @@ NSString * const KMIAPSubscriptionLoadedNotification = @"KMIAPSubscriptionLoaded
|
|
// 免费版
|
|
// 免费版
|
|
if (self.monthProduct.isSubscribed ||
|
|
if (self.monthProduct.isSubscribed ||
|
|
self.newlyMonthProduct.isSubscribed ||
|
|
self.newlyMonthProduct.isSubscribed ||
|
|
- self.allAccessProduct.isSubscribed) {
|
|
|
|
|
|
+ self.allAccessProduct.isSubscribed ||
|
|
|
|
+ self.yearProduct.isSubscribed) {
|
|
return YES;
|
|
return YES;
|
|
}
|
|
}
|
|
return NO;
|
|
return NO;
|
|
@@ -421,6 +607,21 @@ NSString * const KMIAPSubscriptionLoadedNotification = @"KMIAPSubscriptionLoaded
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+- (BOOL)isCancelAutoRenew {
|
|
|
|
+ // 是否取消订阅
|
|
|
|
+ BOOL result = IAPProductsManager.defaultManager.monthProduct.isCancelAutoRenew;
|
|
|
|
+ if (result == false) {
|
|
|
|
+ result = IAPProductsManager.defaultManager.newlyMonthProduct.isCancelAutoRenew;
|
|
|
|
+ }
|
|
|
|
+ if (result == false) {
|
|
|
|
+ result = IAPProductsManager.defaultManager.allAccessProduct.isCancelAutoRenew;
|
|
|
|
+ }
|
|
|
|
+ if (result == false) {
|
|
|
|
+ result = IAPProductsManager.defaultManager.yearProduct.isCancelAutoRenew;
|
|
|
|
+ }
|
|
|
|
+ return result;
|
|
|
|
+}
|
|
|
|
+
|
|
#if !VERSION_DMG
|
|
#if !VERSION_DMG
|
|
#pragma mark - Private Methods
|
|
#pragma mark - Private Methods
|
|
|
|
|
|
@@ -546,7 +747,14 @@ NSString * const KMIAPSubscriptionLoadedNotification = @"KMIAPSubscriptionLoaded
|
|
self.newlyMonthProduct.isTrialPeriod = YES;
|
|
self.newlyMonthProduct.isTrialPeriod = YES;
|
|
}
|
|
}
|
|
self.newlyMonthProduct.originalPurchased = YES;
|
|
self.newlyMonthProduct.originalPurchased = YES;
|
|
-
|
|
|
|
|
|
+ } else if ([product_id isEqualToString:self.yearProduct.productIdentifier]) {
|
|
|
|
+ if (!self.yearProduct.isSubscribed) {
|
|
|
|
+ self.yearProduct.isSubscribed = isActive;
|
|
|
|
+ }
|
|
|
|
+ if ([receipt[@"is_trial_period"] boolValue]) {
|
|
|
|
+ self.yearProduct.isTrialPeriod = YES;
|
|
|
|
+ }
|
|
|
|
+ self.yearProduct.originalPurchased = YES;
|
|
} else if ([product_id isEqualToString:self.allAccessProduct.productIdentifier]) {
|
|
} else if ([product_id isEqualToString:self.allAccessProduct.productIdentifier]) {
|
|
if (!self.allAccessProduct.isSubscribed) {
|
|
if (!self.allAccessProduct.isSubscribed) {
|
|
self.allAccessProduct.isSubscribed = quantity > 0 ? YES : NO;
|
|
self.allAccessProduct.isSubscribed = quantity > 0 ? YES : NO;
|
|
@@ -594,6 +802,14 @@ NSString * const KMIAPSubscriptionLoadedNotification = @"KMIAPSubscriptionLoaded
|
|
self.newlyMonthProduct.isTrialPeriod = YES;
|
|
self.newlyMonthProduct.isTrialPeriod = YES;
|
|
}
|
|
}
|
|
self.newlyMonthProduct.originalPurchased = YES;
|
|
self.newlyMonthProduct.originalPurchased = YES;
|
|
|
|
+ } else if ([product_id isEqualToString:self.yearProduct.productIdentifier]) {
|
|
|
|
+ if (!self.yearProduct.isSubscribed) {
|
|
|
|
+ self.yearProduct.isSubscribed = isActive;
|
|
|
|
+ }
|
|
|
|
+ if ([receipt[@"is_trial_period"] boolValue]) {
|
|
|
|
+ self.yearProduct.isTrialPeriod = YES;
|
|
|
|
+ }
|
|
|
|
+ self.yearProduct.originalPurchased = YES;
|
|
} else if ([product_id isEqualToString:self.allAccessProduct.productIdentifier]) {
|
|
} else if ([product_id isEqualToString:self.allAccessProduct.productIdentifier]) {
|
|
if (!self.allAccessProduct.isSubscribed) {
|
|
if (!self.allAccessProduct.isSubscribed) {
|
|
self.allAccessProduct.isSubscribed = quantity > 0 ? YES : NO;
|
|
self.allAccessProduct.isSubscribed = quantity > 0 ? YES : NO;
|
|
@@ -618,6 +834,23 @@ NSString * const KMIAPSubscriptionLoadedNotification = @"KMIAPSubscriptionLoaded
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if ([jsonResponse objectForKey:@"pending_renewal_info"]) {
|
|
|
|
+ NSArray *receipts =[jsonResponse objectForKey:@"pending_renewal_info"];
|
|
|
|
+ for (NSDictionary *receipt in receipts) {
|
|
|
|
+ NSString *product_id = receipt[@"product_id"];
|
|
|
|
+ NSString *status = receipt[@"auto_renew_status"];
|
|
|
|
+ if ([product_id isEqualToString:self.monthProduct.productIdentifier]) {
|
|
|
|
+ self.monthProduct.autoRenewStatus = status;
|
|
|
|
+ } else if([product_id isEqualToString:self.newlyMonthProduct.productIdentifier]) {
|
|
|
|
+ self.newlyMonthProduct.autoRenewStatus = status;
|
|
|
|
+ } else if([product_id isEqualToString:self.yearProduct.productIdentifier]) {
|
|
|
|
+ self.yearProduct.autoRenewStatus = status;
|
|
|
|
+ } else if ([product_id isEqualToString:self.allAccessProduct.productIdentifier]) {
|
|
|
|
+ self.allAccessProduct.autoRenewStatus = status;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
[[NSUserDefaults standardUserDefaults] setObject:self.allAccessProduct.isSubscribed ? @"YES":@"NO" forKey:@"allAccessProduct.isSubscribed"];
|
|
[[NSUserDefaults standardUserDefaults] setObject:self.allAccessProduct.isSubscribed ? @"YES":@"NO" forKey:@"allAccessProduct.isSubscribed"];
|
|
[[NSUserDefaults standardUserDefaults] setObject:self.PDFToOfficeProduct.isSubscribed ? @"YES":@"NO" forKey:@"PDFToOfficeProduct.isSubscribed"];
|
|
[[NSUserDefaults standardUserDefaults] setObject:self.PDFToOfficeProduct.isSubscribed ? @"YES":@"NO" forKey:@"PDFToOfficeProduct.isSubscribed"];
|
|
[[NSUserDefaults standardUserDefaults] synchronize];
|
|
[[NSUserDefaults standardUserDefaults] synchronize];
|
|
@@ -625,6 +858,80 @@ NSString * const KMIAPSubscriptionLoadedNotification = @"KMIAPSubscriptionLoaded
|
|
return YES;
|
|
return YES;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+- (void)prepareOffer:(NSString *)usernameHash productIdentifier:(NSString *)productIdentifier offerIdentifier:(NSString *)offerIdentifier handler:(void (^)(NSString *nonce, CGFloat timestamp, NSString *sign, NSString *keyId, NSError *error))handler {
|
|
|
|
+ [self fetchOfferDetails:usernameHash productIdentifier:productIdentifier offerIdentifier:offerIdentifier handler:^(NSString *nonce, CGFloat timestamp, NSString *sign, NSString *keyId, NSError *error) {
|
|
|
|
+ if (handler != nil) {
|
|
|
|
+ handler(nonce, timestamp, sign, keyId, error);
|
|
|
|
+ }
|
|
|
|
+ }];
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+- (void)fetchOfferDetails:(NSString *)usernameHash productIdentifier:(NSString *)productIdentifier offerIdentifier:(NSString *)offerIdentifier handler:(void (^)(NSString *nonce, CGFloat timestamp, NSString *sign, NSString *keyId, NSError *error))handler {
|
|
|
|
+ NSString *bundleID = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleIdentifier"]?:@"";
|
|
|
|
+
|
|
|
|
+ NSMutableDictionary *params = [NSMutableDictionary dictionary];
|
|
|
|
+ [params setObject:bundleID forKey:@"appBundleID"];
|
|
|
|
+ [params setObject:productIdentifier forKey:@"productIdentifier"];
|
|
|
|
+ [params setObject:offerIdentifier forKey:@"offerIdentifier"];
|
|
|
|
+ [params setObject:@"user_name" forKey:@"applicationUsername"];
|
|
|
|
+ [params setObject:usernameHash forKey:@"nonce"];
|
|
|
|
+
|
|
|
|
+ NSString *urlString = [NSString stringWithFormat:@"%@/api/orders/getDiscountSign", kVerificationServer];
|
|
|
|
+ NSString *linkString = urlString;
|
|
|
|
+ if(params.allKeys.count) {
|
|
|
|
+ if ([urlString rangeOfString:@"?"].location != NSNotFound) {
|
|
|
|
+ linkString = [urlString stringByAppendingFormat:@"&%@", [IAPProductsManager linkStringWithParams:params]];
|
|
|
|
+ } else {
|
|
|
|
+ linkString = [urlString stringByAppendingFormat:@"?%@", [IAPProductsManager linkStringWithParams:params]];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ NSURL *url = [NSURL URLWithString:linkString];
|
|
|
|
+
|
|
|
|
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
|
|
+ ASIFormDataRequest *request = [[[ASIFormDataRequest alloc] initWithURL:url] autorelease];
|
|
|
|
+ request.defaultResponseEncoding = NSUTF8StringEncoding;
|
|
|
|
+ request.timeOutSeconds = 20;
|
|
|
|
+ request.numberOfTimesToRetryOnTimeout = 3;
|
|
|
|
+ [request setRequestMethod:@"GET"];
|
|
|
|
+ [request setRequestHeaders:[NSMutableDictionary dictionaryWithObject:@"application/json" forKey:@"Content-Type"]];
|
|
|
|
+ [request startSynchronous];
|
|
|
|
+ NSError *error = request.error;
|
|
|
|
+ BOOL isSuccessful = NO;
|
|
|
|
+ NSString *nonce = nil;
|
|
|
|
+ CGFloat timestamp = 0;
|
|
|
|
+ NSString *sign = nil;
|
|
|
|
+ NSString *keyId = nil;
|
|
|
|
+ if (!error) {
|
|
|
|
+ NSDictionary *jsonResponse = [[request.responseString objectFromJSONString] filterNullObject];
|
|
|
|
+ NSDictionary *dict = jsonResponse[@"data"];
|
|
|
|
+ if ([dict isKindOfClass:[NSDictionary class]] && dict.count > 0) {
|
|
|
|
+ nonce = dict[@"nonce"];
|
|
|
|
+ timestamp = [dict[@"timestamp"] doubleValue];
|
|
|
|
+ sign = dict[@"sign"];
|
|
|
|
+ keyId = dict[@"keyIdentifier"];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
|
+ if (handler) {
|
|
|
|
+ handler(nonce, timestamp, sign, keyId, error);
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ });
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
++ (NSString*)linkStringWithParams:(NSDictionary*)params {
|
|
|
|
+ NSString *link = @"";
|
|
|
|
+
|
|
|
|
+ for (NSString *key in params.allKeys) {
|
|
|
|
+ if ([link rangeOfString:@"="].location != NSNotFound)
|
|
|
|
+ link = [link stringByAppendingString:@"&"];
|
|
|
|
+
|
|
|
|
+ link = [link stringByAppendingFormat:@"%@=%@", key, params[key]];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return link;
|
|
|
|
+}
|
|
|
|
+
|
|
- (void)loadAllProducts {
|
|
- (void)loadAllProducts {
|
|
NSSet *identifiers = [NSSet setWithArray:self.productIdentifiers];
|
|
NSSet *identifiers = [NSSet setWithArray:self.productIdentifiers];
|
|
SKProductsRequest *productRequest = [[[SKProductsRequest alloc] initWithProductIdentifiers:identifiers] autorelease];
|
|
SKProductsRequest *productRequest = [[[SKProductsRequest alloc] initWithProductIdentifiers:identifiers] autorelease];
|
|
@@ -660,6 +967,16 @@ NSString * const KMIAPSubscriptionLoadedNotification = @"KMIAPSubscriptionLoaded
|
|
self.monthProduct.isSubscribed = YES;
|
|
self.monthProduct.isSubscribed = YES;
|
|
} else if ([productIdentifier isEqualToString:self.newlyMonthProduct.productIdentifier]) {
|
|
} else if ([productIdentifier isEqualToString:self.newlyMonthProduct.productIdentifier]) {
|
|
self.newlyMonthProduct.isSubscribed = YES;
|
|
self.newlyMonthProduct.isSubscribed = YES;
|
|
|
|
+ [self loadReceipt:^(NSError *error) {
|
|
|
|
+ [[NSNotificationCenter defaultCenter] postNotificationName:KMIAPSubscriptionLoadedNotification
|
|
|
|
+ object:nil];
|
|
|
|
+ }];
|
|
|
|
+ } else if ([productIdentifier isEqualToString:self.yearProduct.productIdentifier]) {
|
|
|
|
+ [self loadReceipt:^(NSError *error) {
|
|
|
|
+ [[NSNotificationCenter defaultCenter] postNotificationName:KMIAPSubscriptionLoadedNotification
|
|
|
|
+ object:nil];
|
|
|
|
+ }];
|
|
|
|
+ self.yearProduct.isSubscribed = YES;
|
|
} else if ([productIdentifier isEqualToString:self.allAccessProduct.productIdentifier]) {
|
|
} else if ([productIdentifier isEqualToString:self.allAccessProduct.productIdentifier]) {
|
|
self.allAccessProduct.isSubscribed = YES;
|
|
self.allAccessProduct.isSubscribed = YES;
|
|
[[NSUserDefaults standardUserDefaults] setObject:self.allAccessProduct.isSubscribed ? @"YES":@"NO" forKey:@"allAccessProduct.isSubscribed"];
|
|
[[NSUserDefaults standardUserDefaults] setObject:self.allAccessProduct.isSubscribed ? @"YES":@"NO" forKey:@"allAccessProduct.isSubscribed"];
|
|
@@ -759,12 +1076,12 @@ NSString * const KMIAPSubscriptionLoadedNotification = @"KMIAPSubscriptionLoaded
|
|
[alert setMessageText:@""];
|
|
[alert setMessageText:@""];
|
|
#if VERSION_FREE
|
|
#if VERSION_FREE
|
|
if (self.monthProduct.isSubscribed ||
|
|
if (self.monthProduct.isSubscribed ||
|
|
- self.newlyMonthProduct.isSubscribed) {
|
|
|
|
|
|
+ self.newlyMonthProduct.isSubscribed || self.yearProduct.isSubscribed) {
|
|
informative = NSLocalizedString(@"Restore successfully", nil);
|
|
informative = NSLocalizedString(@"Restore successfully", nil);
|
|
} else if (self.allAccessProduct.isSubscribed) {
|
|
} else if (self.allAccessProduct.isSubscribed) {
|
|
informative = NSLocalizedString(@"Restore successfully. You can start using the advanced tools, including PDF to Office, PDF Watermark, Page Editor, and more.", nil);
|
|
informative = NSLocalizedString(@"Restore successfully. You can start using the advanced tools, including PDF to Office, PDF Watermark, Page Editor, and more.", nil);
|
|
} else if (self.monthProduct.originalPurchased ||
|
|
} else if (self.monthProduct.originalPurchased ||
|
|
- self.newlyMonthProduct.originalPurchased) {
|
|
|
|
|
|
+ self.newlyMonthProduct.originalPurchased || self.yearProduct.originalPurchased) {
|
|
informative = [NSString stringWithFormat:@"\n%@\n\n%@\n\n%@\n\n",
|
|
informative = [NSString stringWithFormat:@"\n%@\n\n%@\n\n%@\n\n",
|
|
NSLocalizedString(@"Your subscription has expired, please repurchase", nil),
|
|
NSLocalizedString(@"Your subscription has expired, please repurchase", nil),
|
|
NSLocalizedString(@"—》If you already completed the payment, simply click the \"Restore Previous Purchase\" button directly from the upgrade page to enable all the advanced features at no cost to you.", nil),
|
|
NSLocalizedString(@"—》If you already completed the payment, simply click the \"Restore Previous Purchase\" button directly from the upgrade page to enable all the advanced features at no cost to you.", nil),
|
|
@@ -885,6 +1202,8 @@ NSString * const KMIAPSubscriptionLoadedNotification = @"KMIAPSubscriptionLoaded
|
|
self.monthProduct.product = product;
|
|
self.monthProduct.product = product;
|
|
} else if ([product.productIdentifier isEqualToString:self.newlyMonthProduct.productIdentifier]) {
|
|
} else if ([product.productIdentifier isEqualToString:self.newlyMonthProduct.productIdentifier]) {
|
|
self.newlyMonthProduct.product = product;
|
|
self.newlyMonthProduct.product = product;
|
|
|
|
+ } else if ([product.productIdentifier isEqualToString:self.yearProduct.productIdentifier]) {
|
|
|
|
+ self.yearProduct.product = product;
|
|
} else if ([product.productIdentifier isEqualToString:self.allAccessProduct.productIdentifier]) {
|
|
} else if ([product.productIdentifier isEqualToString:self.allAccessProduct.productIdentifier]) {
|
|
self.allAccessProduct.product = product;
|
|
self.allAccessProduct.product = product;
|
|
} else if ([product.productIdentifier isEqualToString:self.PDFToOfficeProduct.productIdentifier]) {
|
|
} else if ([product.productIdentifier isEqualToString:self.PDFToOfficeProduct.productIdentifier]) {
|