#import
<StoreKit/StoreKit.h>
#import
"Subscription.h"
#import
"Base64EncDec.h"
#import
"JSON.h"
@implementation
Subscription
//
レシートの復元処理
- (NSDictionary *)verifyReceipt:(NSString *)base64Receipt {
NSURL *url = [NSURL URLWithString:SUBSCRIPTION_URL];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSString *json = [NSString stringWithFormat:
@"{\"receipt-data\":\"%@\", \"password\":\"%@\"}"
, base64Receipt, SHARED_SECRET];
[request setHTTPBody:[json dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPMethod:
@"POST"
];
NSError *error;
NSURLResponse *response;
NSData *decodeData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *receipt = [[NSString alloc] initWithData:decodeData encoding:NSUTF8StringEncoding];
NSDictionary *dict = [receipt JSONValue];
[receipt release];
return
dict;
}
//
レシートデータの必要な項目をアプリ内に保存
- (NSInteger)savePurchaseInfo:(NSDictionary *)dict {
NSNumber *status = [dict objectForKey:
@"status"
];
if
([status isEqual:[NSNumber numberWithInt:
0
]] ==
NO
) {
return
[status integerValue];
}
//
レシートデータをアプリ内に保存
NSDictionary *receiptDict = [dict objectForKey:
@"latest_receipt_info"
];
NSNumber *expired = [receiptDict objectForKey:
@"expires_date"
];
NSString *latestReceipt = [dict objectForKey:
@"latest_receipt"
];
//
:
completed =
YES
;
return
0
;
}
//
レシートのデコードと保存
- (
BOOL
)decodeReceiptWithTransaction:(NSString *)_receipt isRestore:(
BOOL
)_isRestore {
NSDictionary *dict = [
self
verifyReceipt:_receipt];
NSInteger code = [
self
savePurchaseInfo:dict];
if
(code !=
0
) {
return
NO
;
}
else
{
if
(_isRestore) {
restored =
YES
;
}
return
YES
;
}
}
//
プロダクトの取得で呼び出されるデリゲート
- (
void
)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
if
(response ==
nil
) {
return
;
}
for
(SKProduct *product
in
response.products ) {
SKPayment *payment = [SKPayment paymentWithProduct:product];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
}
- (
void
)failedTransaction:(SKPaymentTransaction *)transaction {
if
(!showedAlert) {
showedAlert =
YES
;
switch
([transaction.error code]) {
case
SKErrorUnknown:
//
購入処理を中止
break
;
case
SKErrorClientInvalid:
//
不正なクライアント
break
;
case
SKErrorPaymentCancelled:
//
購入処理をキャンセル
break
;
case
SKErrorPaymentInvalid:
//
不正な購入
break
;
case
SKErrorPaymentNotAllowed:
//
購入が許可されていない
break
;
default
:
break
;
}
}
}
//
購入(リストア)トランザクション
- (
void
)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
for
(SKPaymentTransaction *transaction
in
transactions) {
switch
(transaction.transactionState) {
case
SKPaymentTransactionStatePurchasing: {
//
購入中の処理
break
;
}
case
SKPaymentTransactionStatePurchased: {
//
購入成功時の処理
[
self
decodeReceiptWithTransaction:[transaction.transactionReceipt stringEncodedWithBase64] isRestore:
NO
];
[queue finishTransaction:transaction];
break
;
}
case
SKPaymentTransactionStateFailed: {
//
購入失敗時の処理
[
self
failedTransaction:transaction];
[queue finishTransaction:transaction];
break
;
}
case
SKPaymentTransactionStateRestored: {
//
購入履歴復元時の処理
[
self
decodeReceiptWithTransaction:[transaction.transactionReceipt stringEncodedWithBase64] isRestore:
YES
];
[queue finishTransaction:transaction];
break
;
}
}
}
//
購入(リストア)成功時の終了処理
if
(restored || completed) {
//
:
}
}
//
リストア成功時の処理
- (
void
)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue {
restored =
YES
;
//
:
}
//
リストア失敗時の処理
- (
void
)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error {
//
:
}
//
課金処理(クライアントから呼び出されるメソッド)
- (
void
) subscribe {
completed =
NO
;
[[SKPaymentQueue defaultQueue] addTransactionObserver:
self
];
productIds = [NSSet setWithObject:
"
プロダクト
ID"
];
skRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIds];
skRequest.delegate =
self
;
[skRequest start];
}
//
リストア処理(クライアントから呼び出されるメソッド)
- (
void
)restore {
restored =
NO
;
[[SKPaymentQueue defaultQueue] addTransactionObserver:
self
];
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
- (
void
) dealloc {
[[SKPaymentQueue defaultQueue] removeTransactionObserver:
self
];
[
super
dealloc];
}
@end