記事

Appへのサブスクリプションオファーの実装

対象となるサブスクリプション登録者に、自動更新サブスクリプションプロダクトの割引価格を提供します。

概要

サブスクリプションオファーは、中断している登録者に再利用を促したり、現存の登録者を維持したりするのに効果的な場合があります。macOS、iOS、tvOSで、中断している登録者または現存の登録者に対し、自動更新サブスクリプションの期間限定割引や無料サービス期間を提供できます。オファーを実装するには、まずApp Store Connectで秘密鍵の生成などの設定を完了します。詳しくは、「サブスクリプションオファーの設定」を参照してください。

オファーを利用できる登録者について、基準を決めます。Appで、SKProduct(英語)内のdiscounts(英語)配列に、App Store Connectで設定したオファーの詳細が表示されます。ユーザーに提供するオファーを示すには、署名されたpaymentDiscount(英語)SKMutablePayment(英語)オブジェクトに含めます。

サブスクリプションオファーの使用に関するビジネスガイダンスは、「自動更新サブスクリプション」>「プロモーションオファー」を参照してください。

オファーを準備する

サブスクリプションオファーを提示するには、まず、登録者の利用資格を判断し、App Storeからプロダクトの詳細を取得し、サーバで署名を生成します。

図1

ユーザーの利用資格を判断し、オファーを準備する手順

ユーザーの利用資格を判断し、オファーを準備する手順。

利用資格を判断する

ユーザーがサブスクリプションオファーを利用できるかどうか判断するには、2つのポイントがあります。

  • App Storeは、サブスクリプションオファーの利用対象となるAppにおいて、既存のサブスクリプションまたは期限切れのサブスクリプションがあるすべてのカスタマーを見分けます。レシートに既存のサブスクリプションまたは期限切れのサブスクリプション購入が含まれているかどうか確認して、現在の登録者、または中断している登録者を特定できます。

  • 特定のサブスクリプションオファーでは、追加の利用条件を判断します。ビジネスニーズによって決定される幅広いビジネスロジックに基づいて、利用条件を決めることができます。

サーバ間通知DID_CHANGE_RENEWAL_STATUSを使用して利用資格を判断することを検討してください。この通知は、サブスクリプションの自動更新ステータス変更によってトリガされます。たとえば、登録者が「登録の管理」で自動更新を無効にしたり、AppleCareに問い合わせてサブスクリプションをキャンセルしたりすると、通知が届きます。サーバ通知の詳細については、「Enabling Server-to-Server Notifications」(サーバ間通知の有効化)を参照してください。ユーザーがオファーを利用できる場合、Appからカスタマーに提示できるように、サーバがAppに通知します。

また、DeviceCheck(英語)を実装して、以前にオファーを利用したことがあるデバイスを追跡することも検討してください。DeviceCheckを使うと、ユーザーのプライバシーを保護しながら、利用資格を判断するためのパラメータを定義できます。

プロダクトの詳細をリクエストする

サブスクリプション利用者にオファーの利用資格があると判断したら、次の手順として、オファーを含むプロダクトの詳細をApp Storeにリクエストします。詳細を取得するには、SKProductsRequest(英語)とサブスクリプションのプロダクトIDを使います。

これに対する応答として、App Storeから、SKProduct(英語)でローカライズされた情報が返されます。SKProductdiscounts(英語)配列に、App Store Connectでそのプロダクトについて設定したすべてのサブスクリプションオファーが含まれます。SKProductDiscount(英語)オブジェクトには、ローカライズされた価格を含め、オファーの詳細が含まれます。

discounts(英語)配列の中のどのオファーをユーザーに対して提示するのかは、開発者が決定します。

署名を作成する

署名は、指定されたパラメータと開発者の秘密鍵を使ってサーバで生成される、一意の文字列です。これをSKPaymentDiscount(英語)signature(英語)パラメータに含めると、App Storeはそれを使ってサブスクリプションオファーを検証します。署名には期限があり、オファーごとに一意で、一度しか使えません。

署名を生成するには、サーバに安全なリクエストを送信します。サーバは、applicationUsername(英語)productIdentifier(英語)、およびidentifier(英語)を認識している必要があります。サーバにまだこれらの情報がない場合は、リクエストの中で、Appからこれらのパラメータを提供する必要があります。詳しくは、「サブスクリプションオファー用の署名の生成」を参照してください。

サーバから、署名文字列、および署名の生成に使用した追加の値(noncetimestampkeyIdentifier)を返す必要があります。これらの値を使って、オファーを表現するSKMutablePayment(英語)オブジェクトにネストされたSKPaymentDiscount(英語)オブジェクトのパラメータを完成させます。App Storeでの署名の支払いパラメータが一致しないと判断されると、トランザクションは失敗します。

以下のサンプルコードは、サーバから署名をリクエストし、割引オファーを準備する方法を示しています。

// Fetch the signature from your server to be applied to the offer.
// At this point you know the user and the product the offer is for, and which offer you want to display.
public func prepareOffer(usernameHash: String, productIdentifier: String, offerIdentifier: String, completion: (SKPaymentDiscount) -> Void) {

    // Make a secure request to your server, providing the username, product, and discount data
    // Your server will use these values to generate the signature and return it, along with the nonce, timestamp, and key identifier that it uses to generate the signature.
    YourServer.fetchOfferDetails(username: usernameHash, productIdentifier: productIdentifier, offerIdentifier: offerIdentifier, completion: { (nonce: UUID, timestamp: NSNumber, keyIdentifier: String, signature: String) in 

        // Create an SKPaymentDiscount to be used later when the user initiates the purchase
        let discountOffer = SKPaymentDiscount(identifier: offerIdentifier, keyIdentifier: keyIdentifier, nonce: nonce, signature: discountsignature, timestamp: timestamp)

        completion(discountOffer)
    })
}

オファーを提示する

オファーは、メールなどさまざまなチャンネルでユーザーに提示できますが、ユーザーはAppのUI内でオファーを利用する必要があります。SKProductDiscount(英語)オブジェクトの価格と期間を使用して、適切なタイミングで、Appにオファーを表示します。このオブジェクトの詳細情報を使うことによって、確実に、開発者が提供しようとするオファーをユーザーに対して表示できます。デザインに関するガイダンスは、「Auto-Renewable Subscriptions」>「Clearly Describing Subscriptions」(英語)を参照してください。

誤解を招いたり、ユーザーを混乱させたりするのを避けるため、オファーは利用資格のある登録者にのみ提示します。

トランザクションを完了する

ユーザーがサブスクリプションオファーの購入を選択した後、支払い要求を送信し、レシートを検証して、オファーをロック解除します。

図2

署名済みのオファーで支払い要求を作成し、レシートを検証し、サービスをロック解除する手順

支払い要求の作成からサービスのロック解除までの手順。

支払い要求を作成する

ユーザーがApp内でオファーの購入を開始したら、SKMutablePayment(英語)を署名済みのオファーとともにApp Storeに送信します。生成した署名とそのパラメータ(identifierkeyIdentifiernonce(1回限り使用)、およびtimestamp)を含むSKPaymentDiscount(英語)オブジェクトを作成します。このオブジェクトを、SKPaymentDiscountオブジェクトとしてSKMutablePayment(英語)オブジェクトに追加します。

SKMutablePayment(英語)オブジェクトには、署名に含まれるものと同じapplicationUsername(英語)(多くの場合、ユーザー名の一意のハッシュ)を含めてください。SKMutablePaymentオブジェクトをキューに追加します。

// An example function that makes a buy request with a subscription offer attached.
public func buyProduct(productIdentifier: SKProduct, forUser usernameHash: String, withOffer discountOffer: SKPaymentDiscount) {

    // The original product being purchased.
    let payment = SKMutablePayment(product: product)

    // You must set applicationUsername to be the same as the one used to generate the signature.
    payment.applicationUsername = usernameHash

    // Add the offer to the payment.
    payment.paymentDiscount = discountOffer

    // Add the payment to the queue for purchase.
    SKPaymentQueue.default().add(payment)
}

ユーザーにトランザクションの状態を通知する

App Storeは、オファーを検証すると、支払い要求を処理してSKPaymentTransaction(英語)を生成します。Appはそれを使ってトランザクションを検証し、検証結果に基づいてコンテンツをロック解除します。

支払い要求のトランザクションの状態を処理し、必要に応じてカスタマーに通知します。トランザクションが成功すると、App StoreによってAppのレシートがそのトランザクションで自動的にアップデートされ、SKPaymentTransactionState.purchased(英語)の状態になります。オンデバイスでレシートをbase64エンコードし、レシートのデータをサーバに安全に送信します。

レシートを検証する

すべての購入で行うのと同じように、App Storeでレシートを検証します。これは、サーバからverifyReceiptエンドポイントを呼び出すことによって行います。App Storeは、ユーザーの購入に関する情報を含むJSON応答を送信します。詳しくは、「App Storeでレシートを検証する」を参照してください。

登録者がオファーを利用すると、レシートの購入トランザクションにpromotional_offer_idが含まれます。このレシートフィールドは、App Store Connectで設定したオファーIDを含む文字列です。レシートで過去のトランザクションを調べ、カスタマーが利用したオファーを特定できます。

サービスをロック解除する

ユーザーがサブスクリプションプロダクトを購入したことを検証した後、Appでユーザー向けにサブスクリプションサービスをロック解除します。必要に応じて、オファーに関するカスタマーの利用基準をアップデートします。

カスタマーがサブスクリプションオファーを利用すると、次の請求イベント時にオファー期間が開始します。

  • 同じ期間の別のサブスクリプションへのアップグレードまたは登録切り替えの場合、サブスクリプションオファーによって請求イベントがトリガされ、ただちに有効になります。

  • 期間が異なる別のサブスクリプションへのダウングレードまたは登録切り替えの場合、次の更新日にサブスクリプションオファーの期間が有効になります。

  • お試しオファー中の同じサブスクリプションの場合、このサブスクリプションオファー期間は、次に予定されている請求イベント時に有効になります。

オファー期間が終了すると、サブスクリプションオファーは標準の価格で自動更新されます。

ユーザーが利用して有効にできるサブスクリプションオファーは、一度に1つだけです。現在のオファーが終了する前にユーザーが別のオファーを受け取ると、現在のオファーは次の請求イベントでキャンセルされ、新しいオファーが有効になります。

関連項目

サブスクリプションオファーの提供

サブスクリプションオファーの設定

App Store Connectでキーを生成し、自動更新サブスクリプションのオファーを設定します。

サブスクリプションオファー用の署名の生成

秘密鍵を使用して、サブスクリプションオファーを検証するための署名を作成します。

Node.jsを使用したサブスクリプションオファー用の署名の生成

秘密鍵と軽量の暗号ライブラリを使用して、署名を生成します。

class SKPaymentDiscount(英語)

支払いに適用される署名済みの割引。