【问题标题】:How to test app store purchase receipt to obtain original application version如何测试应用商店购买收据以获得原始应用程序版本
【发布时间】:2014-12-20 00:11:21
【问题描述】:

我想在应用启动时加载应用购买收据。如何模拟应用购买(不是应用内购买,而是实际应用购买)以便我有收据? (我正在尝试从付费转为免费增值)。

我正在使用此代码加载收据

(BOOL)isAppPreviouslyPurchased {
    BOOL wasPreviouslyPurchased = false;

    // Load the receipt from the app bundle.
    NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
    NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];
    if (receiptData) {

        //read purchase version from receipt
        NSDictionary *receipt = [NSJSONSerialization JSONObjectWithData:receiptData options:0 error:nil];
        NSString *oldVersion = receipt[@"original_application_version"];
        float vFloat = [oldVersion floatValue];

        if (vFloat < 1.6) {
            wasPreviouslyPurchased = true;
        }
    }

    return wasPreviouslyPurchased;
}

【问题讨论】:

  • 有人想知道这是否就是为什么这么多应用程序有“恢复购买”的原因?
  • 有人想知道为什么这只适用于应用内购买......而不是实际的应用购买......也许在愤世嫉俗之前先阅读问题。
  • 对不起,我不是愤世嫉俗,我只是想知道恢复应用内购买是否存在类似问题。对于应用内购买,您需要手动触发器 AFAIK。

标签: ios


【解决方案1】:

首先:刷新收据

SKReceiptRefreshRequest *request = [[SKReceiptRefreshRequest alloc] init];
request.delegate = self;
[request start];

添加SKPaymentTransactionObserver协议和这个方法

- (void)paymentQueue:(SKPaymentQueue *)queue
 updatedTransactions:(NSArray *)transactions
{
    for (SKPaymentTransaction *transaction in transactions) {
        switch (transaction.transactionState) {
            // Call the appropriate custom method for the transaction state.
            case SKPaymentTransactionStatePurchasing:
                [self showTransactionAsInProgress:transaction deferred:NO];
                break;
            case SKPaymentTransactionStateDeferred:
                [self showTransactionAsInProgress:transaction deferred:YES];
                break;
            case SKPaymentTransactionStateFailed:
                [self failedTransaction:transaction];
                break;
            case SKPaymentTransactionStatePurchased:
                [self completeTransaction:transaction];
                break;
            case SKPaymentTransactionStateRestored:
                [self restoreTransaction:transaction];
                break;
            default:
                // For debugging
                NSLog(@"Unexpected transaction state %@", @(transaction.transactionState));
                break;
        }
    }
}

然后,当调用此方法时,您的收据将被刷新;)

其次:您必须解密收据

NSData *receipt; // Sent to the server by the device

// Create the JSON object that describes the request
NSError *error;
NSDictionary *requestContents = @{
    @"receipt-data": [receipt base64EncodedStringWithOptions:0]
};
NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents
                                                      options:0
                                                        error:&error];

if (!requestData) { /* ... Handle error ... */ }

// Create a POST request with the receipt data.
NSURL *storeURL = [NSURL URLWithString:@"https://buy.itunes.apple.com/verifyReceipt"];
NSMutableURLRequest *storeRequest = [NSMutableURLRequest requestWithURL:storeURL];
[storeRequest setHTTPMethod:@"POST"];
[storeRequest setHTTPBody:requestData];

// Make a connection to the iTunes Store on a background queue.
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:storeRequest queue:queue
        completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
    if (connectionError) {
        /* ... Handle error ... */
    } else {
        NSError *error;
        NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
        if (!jsonResponse) { /* ... Handle error ...*/ }
        /* ... Send a response back to the device ... */
    }
}];

您可以使用此代码对其进行解密,但 Apple 并不真正推荐它。您应该从您的服务器调用 iTunes。

然后,您可以使用 Apple 服务器返回的响应调用您的方法。

像这样(通过本地验证,Apple 说的不好)

NSData *receipt; // Sent to the server by the device

// Create the JSON object that describes the request
NSError *error;
NSDictionary *requestContents = @{
    @"receipt-data": [receipt base64EncodedStringWithOptions:0]
};
NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents
                                                      options:0
                                                        error:&error];

if (!requestData) { /* ... Handle error ... */ }

// Create a POST request with the receipt data.
NSURL *storeURL = [NSURL URLWithString:@"https://buy.itunes.apple.com/verifyReceipt"];
NSMutableURLRequest *storeRequest = [NSMutableURLRequest requestWithURL:storeURL];
[storeRequest setHTTPMethod:@"POST"];
[storeRequest setHTTPBody:requestData];

// Make a connection to the iTunes Store on a background queue.
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:storeRequest queue:queue
        completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
    if (connectionError) {
        /* ... Handle error ... */
    } else {
        NSError *error;
        NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
        if (!jsonResponse) { /* ... Handle error ...*/ }
          [self isAppPreviouslyPurchased:jsonResponse];
    }
}];

-(BOOL)isAppPreviouslyPurchased:(NSDictionary *)receipt {
    BOOL wasPreviouslyPurchased = false;

        NSString *oldVersion = receipt[@"original_application_version"];
        float vFloat = [oldVersion floatValue];

        if (vFloat < 1.6) {
            wasPreviouslyPurchased = true;
        }

    return wasPreviouslyPurchased;
}

【讨论】:

  • 谢谢。但是我如何首先获得收据?我需要它来购买实际的应用程序。从 xcode 构建不会给我。
  • 好的,我编辑我的帖子。您必须刷新收据。
  • 刷新收据试试
  • 你能告诉我这将如何快速进行吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多