支払いの要求

購入プロセスの第2段階では、図 3-1に示すように、ユーザーが特定のプロダクトを購入することを選択した後、AppがApp Storeに支払い要求を送信します。

図 3-1 購入プロセスの各段階—支払いの要求

支払い要求の作成

ユーザーがプロダクトを購入することを選択した場合は、リスト 3-1に示すように、プロダクトオブジェクトを使用して支払い要求を作成し、必要に応じて数量を設定します。プロダクトオブジェクトは、「プロダクト情報の取得」に示すように、Appのプロダクト要求によって返されるプロダクトの配列に由来します。

リスト 3-1 支払い要求の作成

SKProduct *product = <# Product returned by a products request #>;
SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:product];
payment.quantity = 2;

異常アクティビティの検知

App Storeは異常アクティビティ検知エンジンを使用して不正に対応します。追加情報を提供することで、エンジンの異常トランザクション検知能力を向上するAppもあります。ユーザーがApp Storeアカウントに加えてAppのアカウントを持っている場合、支払い要求の際にこの追加情報を提供してください。

たとえば、次の2つの例を考えてみましょう。通常、サーバ上の多くのユーザーがそれぞれゲームを使用するためにコインを購入し、各ユーザーが別のApp Storeアカウントから購入のため支払いを行います。対照的に、サーバ上の1人のユーザーがコインが何回も購入し、別のApp Storeアカウントから購入のための支払いを行うことは異常なことです。App Storeがこの種の異常アクティビティを単独で検知することはできません。サーバ上のどのアカウントがトランザクションと関連付けられているかについて、Appからの情報が必要です。

この情報を提供するためには、支払いオブジェクトのapplicationUsernameプロパティにサーバ上のユーザーアカウント名の一方向ハッシュを入力します。リスト 3-2に例を示します。

リスト 3-2 Appのユーザー名の提供

#import <CommonCrypto/CommonCrypto.h>
 
// Common Cryptoを使用してSHA-256ハッシュを計算するカスタムメソッド
- (NSString *)hashedValueForAccountName:(NSString*)userAccountName
{
    const int HASH_SIZE = 32;
    unsigned char hashedChars[HASH_SIZE];
    const char *accountName = [userAccountName UTF8String];
    size_t accountNameLen = strlen(accountName);
 
    // ユーザー名の長さがハッシュ関数の呼び出し時に
    // 書き直されるために十分短いことを確認
    if (accountNameLen > UINT32_MAX) {
        NSLog(@"Account name too long to hash: %@", userAccountName);
        return nil;
    }
    CC_SHA256(accountName, (CC_LONG)accountNameLen, hashedChars);
 
    // バイト配列を16進法の文字列に変換。
    NSMutableString *userAccountHash = [[NSMutableString alloc] init];
    for (int i = 0; i < HASH_SIZE; i++) {
        // 読みやすくするため、4バイトごとにダッシュを追加。
        if (i != 0 && i%4 == 0) {
            [userAccountHash appendString:@"-"];
        }
        [userAccountHash appendFormat:@"%02x", hashedChars[i]];
    }
 
    return userAccountHash;
}

このプロパティの入力に別の方法を使用する場合、入力する値がサーバ上のユーザーアカウントに一意に関連付けられた不透明な識別子であるようにします。デベロッパアカウントのApple ID、ユーザーのApple ID、サーバ上のユーザーのハッシュなしのアカウント名は使用しないでください。

支払い要求の送信

トランザクションキューに支払い要求を追加すると、App Storeに送信されます。キューに支払いオブジェクトを複数回追加すると、オブジェクトは複数回送信されます。そのためユーザーは複数回課金され、Appはプロダクトを複数回配信されます。

[[SKPaymentQueue defaultQueue] addPayment:payment];

Appが支払い要求を送信するたびに、対応するトランザクションが発生し、処理が必要になります。トランザクションとトランザクションキューについては、「App Storeがトランザクションを処理するまでの待機」で説明します。