iOS_Apple アプリ内購入の詳しい手順

iOS Apple アプリ内購入の詳細な手順

iOS 開発の 2 つの支払い方法

1 Apple Pay + は、Alipay、WeChat、UnionPay などの外部決済を呼び出します。

アップルペイとは?

簡単に言えば「決済ツール」です。海外で普及しているクレジットカードの場合、Apple Pay は米国の国情に非常に合致しています。しかし、中国にとっては、WeChat 決済と Alipay 決済がより便利であり、中国人の行動に沿っています。
そういえば、Apple Pay が Alipay に似たオンラインおよびオフラインの決済ツールであることはご存じかもしれません。
Alipay や WeChat と同様に、Apple Pay は主に実際の現金取引を対象としています。もちろん、仮想商品の支払いをサポートするプラットフォームもあります。たとえば、タオバオ プラットフォームでは、仮想アイテム、電話代、ゲーム カードなどを販売しています。ただし、これは Apple のアプリ内購入の範囲内ではありません。

もちろん、独自のアプリでは、さまざまな支払い方法にアクセスできます。

2 Apple アプリ内購入 IAP (アプリ内購入)

アプリ内購入とは?

購入した商品がこのアプリで使用および消費される場合は、アプリ内購入を使用する必要があります。そうしないと、ゲーム通貨、オンライン ブック、アプリで使用される小道具、およびその他の仮想製品など、オンラインで拒否されます。タオバオでのショッピングなど、通常の商品を購入する場合は、アプリ内購入を使用する必要はありません。アプリ内購入の場合、Apple は約 30% の手数料を取る必要があります。

Apple のアプリ内購入価格表の実際の収入は動的であり、税の変更に応じて変化します. 通常、Apple は金額の約 30% を請求します. ただし、表の価格とグレードは通常変更されていません。

もちろんリワード機能もアプリ内課金企画に含まれています。したがって、たとえば、WeChat の報酬機能とライブ プロジェクトの報酬アンカーでは、アプリ内購入を使用する必要があります。

  • アプリ内購入機能のあるプロジェクトの将来のコストは、 Android や PC よりも30%高くなることは簡単に理解できます。

  • アプリ内購入の使用シナリオ: iQiyi APP を使用してメンバーを購入し、QQ Doudizhu で QB を充電するなど。

  • 支払いポップアップ アイコン、価格、詳細などはhttps://developer.apple.comで設定する必要があります。詳細は後述する。

プロジェクトクレジットでコースを購入するにはアプリ内購入が必要なので、この記事ではIAPのポリシールール、コード統合+パケットロス処理、課税や銀行口座情報の入力などについて詳しく紹介します。

1 IAP ルールの詳細な説明

  • この記事で言及されている IAP (アプリ内購入) は、特に Apple App Store のアプリ内購入を指します。これは、アプリ内での仮想商品またはサービスの購入のために Apple が提供する一連のトランザクション システムです。
    まず、IAP の基本的なルールといくつかの重要なポイントについて説明します。

1.1 適用範囲

  • ゲーム小道具、電子書籍、音楽、ビデオ、サブスクリプションメンバー、アプリの高度な機能など、アプリでの支払いが必要な製品機能または仮想商品/サービス。
  • IAP は、アプリ内の物理的な商品の購入 (Taobao での衣服の購入など) には適用されません。IAP は、仮想商品 (リチャージなど) またはアプリで使用されないサービス (クレジットのチャージなど) には適用されません。またはサービス (車を呼び出す Didi など)。
    そこで質問なのですが、アプリで音楽アルバムを購入すると、アプリでデジタル アルバムを聴くだけでなく、物理的な製品 CD も入手できますが、これは IAP に適していますか?
    答えは当てはまります。アプリ内のデジタル アルバムと物理的な製品 CD を分離して使用できるため、デジタル アルバムは IAP の適用範囲に一致し、購入には IAP が必要です。そうでなければ、さまざまなゲームで 648 で販売されている小道具はすべて、商品にはゲームの小道具だけでなく、購入後の 50 セントの物理的な記念品 (たとえば) が含まれていると主張し、IAP を直接バイパスします. Apple は終了しませんか?
    Apple は、適用範囲内の仮想商品またはサービスについて、購入および支払いに IAP を使用する必要があると規定しており、Alipay、WeChat による支払い、およびその他の支払い方法 (Apple Pay を含む) を使用することはできません。アプリ、コピーライティングを促すなど)アプリ以外のチャネルを通じてユーザーを購入するように誘導します。
  • Apple も原則として、外部引き換えコードなどを介してアプリ内の仮想商品やサービスのロックを解除することを許可していませんが、実際には引き換えコードの制限はややあいまいです。クーポンまたはサインイン特典)、外部引き換えコードなのかコンテンツ引き換えコードなのかを厳密に定義することは困難です。したがって、IAP 購入にクーポンを使用することは一般的に許可されていますが、アプリ外で引き換えコードを購入し、アプリ内で仮想商品やサービスと引き換えることが明らかな場合は、Apple によって拒否されます。
  • さらに、App Store Review Guidelines 3.1.4 には次のような特別なルールがあります。

「承認された物理的な製品 (おもちゃなど) とオプションで組み合わせて機能するアプリの機能は、IAP オプションも利用できる場合、IAP を使用せずに機能のロックを解除できます。」

  • つまり、ユーザーがアプリ内で機能を購入し、その機能を物理的な製品と組み合わせて使用​​する必要がある場合、IAP 以外の方法で機能のロックを解除することは許可されますが、前提はIAP 購入のオプションがまだ必要であること。
  • 例えば、ユーザーが健康管理アプリで高度な歩数計機能を購入するとしますが、この歩数計機能はブレスレットと組み合わせて使用​​する必要があり、ブレスレットと一緒にパッケージ化して購入する必要があります。この場合、アプリは IAP 購入オプションに基づいて他の購入方法を提供できます。
  • しかし、実際にはそのような事例は見られなかったようです。アプリは歩数計を完全に無料の機能に変えることができますが、ブレスレットなしでは機能せず、ブレスレットはアプリの外で使用される物理的な製品と見なされるため、IAP とは関係ありません。誰がトラブルを探して、これを IAP にして、Apple に分け前を与えるのですか?
  • さらに、クロスプラットフォーム同期の複雑なケースがいくつかあります。これについては、この記事の第 3 部で詳しく説明します。

1.2 IAP のタイプ

  • 前述のように、IAP は商品取引システムであり、単純な支払いシステムではありません。すべての購入アイテムは、アプリの itunes connect バックグラウンドで製品を作成し、レビューのために Apple に送信する必要があり、レビューが通過すると、購入アイテムが有効になります。
  • IAP アイテムを作成する場合、主に 4 つのタイプから選択できます。

1.2.1 消耗品(消耗品)

  • このタイプは、ゲームの小道具や仮想通貨など、複数回購入できる消耗品に適しています。

1.2.2 非消耗品(非消耗品)

  • このタイプは、電子書籍、ゲーム レベルなどの永久有効アイテムの 1 回限りの購入に適しています。
  • This type of project supports cross-device synchronization and local restore. たとえば、ユーザーがアプリで書籍を購入した場合、アプリのアカウントを使用せずに、同じ Apple ID デバイスを使用してすべてのアプリで書籍を無料で入手できます。アプリ内で本を削除しても、無料で再取得できます。

1.2.3 更新不可のサブスクリプション

  • クラウドミュージック会員や一部の動画アプリ会員など、有効期限のある非自動更新アイテムに適したタイプです。デバイス間の同期とローカル復元メカニズムはなく、ユーザーは複数の購入を行うことができます。

1.2.4 自動更新サブスクリプション

  • このタイプは、Apple Music の月額サブスクリプションなどの自動更新サブスクリプション アイテムに適しています. ユーザーが購入した後、サブスクリプションは、ユーザーが手動でキャンセルするか、開発者が IAP アイテムを削除するまで、毎月自動的に更新されます.
  • 非消耗品と同様に、このタイプはクロスデバイス同期とローカル復元メカニズムもサポートしています。
  • これまで、このタイプはニューススタンド カテゴリ (新聞と雑誌) のアプリのみをサポートしていました. 2016 年 6 月から、すべてのタイプのアプリがサポートされています. ただし、ニューススタンド カテゴリを除いて、国内のアプリではこのタイプのアプリ内購入はほとんど使用されていません.

1.2.4.1 無料購読

  • このタイプは、自動更新サブスクリプションの特殊なケースであり、無料のサブスクリプション アイテムに適用され、ニューススタンド カテゴリのアプリのみをサポートし、クロスデバイス同期とローカル復元メカニズムもサポートします。
    In-App Purchase Programming Guide には、各タイプの適用性と特徴が詳しく説明されています。

その中で、特に注意を払う必要があるのは次のとおりです。

  • 1 非消耗品の IAP プロジェクトの場合、Apple はアプリに「購入の復元」機能を提供して、デバイス間の同期とローカル復元をサポートすることを要求します。同時に、アプリ自体にユーザー アカウント システムがある場合、ユーザーは 1 回支払うだけで済み、IAP アイテムは復元メカニズムを通じて複数のユーザー アカウントに無限にコピーできます。
    したがって、一度購入すると永続的に有効な電子書籍などのアイテムについて、アプリ自体のユーザー アカウント システムを使用し、デバイス間の同期やローカル復元メカニズムを回避したい場合は、更新不可のサブスクリプション タイプを選択することを検討できます。 . 同時に、一般的に更新不可のサブスクリプションには有効期間が固定されていることを考慮して、Apple の審査に対処するために無期限の有効期間 (9999 日など) を追加できます。
  • 2 消耗品と更新不可のサブスクリプションは、どちらも繰り返し購入できる IAP アイテムで、前者は消耗性が高く、後者はサブスクリプション性が高いです。もう 1 つの違いは、非更新サブスクリプションの IAP プロジェクトの場合、ユーザーが以前に一度購入し、有効期限後またはアプリ アカウントの切り替え後に再度購入した場合、支払いプロセス中にシステム ポップアップ ウィンドウが表示され、購入が以前に行われたことをユーザーに思い出させます。アイテムを再度購入するかどうか、ユーザーが誤ってキャンセルをクリックした場合、支払いプロセスは終了します。
    Apple がこのポップアップ ウィンドウを設計した当初の意図は、ユーザーが同じアイテムを繰り返し購入するのを防ぐために、Apple ID に基づいてユーザーを識別することです。ただし、ユーザー アカウント システムを備えたアプリの場合、このプロンプトは少し冗長ですが、影響はほとんどありません。したがって、IAP プロジェクトが消耗品と更新不可のサブスクリプションの両方に適している場合は、消耗品を選択することをお勧めします。

1.3 価格

  • IAP プロジェクトを作成するときは、価格を設定する必要があります.この価格は、Apple の事前設定された価格レベルからのみ選択できます.たとえば、レベル 1 は 1 ドルと 6 元に対応し、レベル 2 は 2 ドルと 12 元に対応します.最高レベルの 87 は 999.99 米ドルと 6498 元に相当します。また、特定の通貨領域の開発者とユーザーの世話をすることもあり、1ドルと1元に対応する準備レベルA、1ドルと3元に対応する準備レベルBなど、いくつかの特別なレベルがあります。さらに、IAPプロジェクトは、どのレベルにも満たない9.9元の価格を設定することはできません。詳細な価格表はApple の公式ドキュメントに記載されています

  • Apple の価格帯表は通常調整されませんが、一部の通貨の為替レートが大幅に変更された場合、その通貨の価格が調整されることを排除するものではありません.調整前に、Apple はにメールを送信します.開発者に通知します。

  • また、価格水準表の各通貨の為替レート関係と実際の為替レートには差異があり、タオバオの一部の低価格 iOS ゲーム内購入エージェントは、特定の通貨の為替レート差を利用して取引を行っています。

  • アプリが中国国外でリリースされる場合、開発者は為替レートの問題に注意を払う必要があるかもしれません。一部の地域では、人民元で決済されたアプリ内購入の収入は、対応する価格レベルの人民元収入よりも低くなるため、実際の収入を厳密に計算する必要がある場合 (金融統計収入、アプリ内課金など)購入収入はプラットフォームCP側とさらに議論する必要があります)共有)、実際の支払い通貨とアプリ内購入の金額とそれに対応する為替レートに基づいて収入を計算する必要があるか、いくつかの方法を使用して制限することができます特定の地域でのアプリ内購入 (この記事のセクション 2.2 で説明)。

  • なお、IAP プロジェクトの価格は、製品リリース後に itunes connect のバックグラウンドで変更でき、期間限定の割引価格も設定できます。ただ、インターネット接続アプリの多くはアプリ内課金アイテムの価格を独自のサーバーから取得しているため、価格を変更したり期間限定割引を設定したりするには、双方で対応する必要があり、かなり手間がかかります。面倒。

1.4 スプリット

  • 多くの人は、App Store での有料アプリとアプリ内購入について、Apple と開発者がデフォルトで 3/7 のシェアを共有していることを知っています。
  • しかし実際には、一部の地域では Apple は開発者と共有する前に取引税を差し引く必要があり、開発者の実際のシェアは必ずしも 70% ではありません。2015 年 10 月以降、Apple は中国での App Store での購入に対して 2% の取引税を差し引いています.中国のアカウントで購入された IAP については、開発者の実際のシェアは 68% から 69% の間です. また、中国以外の地域では取引税の基準が異なるため、1.3で述べたように、厳密に実所得を計算する必要がある場合は、この部分を考慮する必要があるかもしれません。
  • さまざまな地域でのアプリ内購入については、アプリ内購入の価格とそれに対応する開発者の実際の収入が、Apple の価格レベル表 (1.3 のリンク) に詳しく記載されています。
  • さらに、2016 年 6 月の Apple の新しい規則によると、Auto-Renewable Subscription IAP について、ユーザーが 1 年以上のサブスクリプションを購入した場合、開発者は 2 年目からシェアの 85% を取得できます。詳細については、https:
    //developer.apple.com/app-store/subscriptions/を確認してください。

1.5 決済

  • IAP トランザクションの収益について、Apple は通常、請求サイクルとして 5 週間 (毎年 1 月/4 月/7 月/10 月) または 4 週間 (残りの月) を取り、各請求サイクルの終了後 33 日目に開発者に支払います。 .

2 IAP設計・開発のポイント

2.1 IAP プロジェクトの作成と提出

  • IAP を開発する前に、iTunes Connect のバックグラウンドで IAP 製品を作成し、仕様に従って製品 ID、製品名、価格、スクリーンショットなどの情報を入力する必要があります。
  • アプリの現在のバージョンが新しく追加された IAP プロジェクトをサポートしている場合、バージョンを公開せずに IAP レビューのために直接送信できます。アプリの新機能に連携する必要がある場合は、アプリ版と合わせて提出する必要があります。
    「iTunes Connect のアプリ内購入設定ガイド」では、 IAP の作成と送信のプロセスを詳しく紹介しています。

その中で、特に注意を払う必要があるのは次のとおりです。

2.1.1 作成した IAP を削除しないようにする

  • 作成された IAP の製品 ID を除くすべての情報を変更できます. IAP を削除すると、同じ製品 ID で別の IAP を作成することはできなくなり、製品 ID は永久に無効になります. 通常、製品 ID には特定の命名規則があり、アプリ内の購入アイテムをマークするために使用されます.命名規則の下で特定の製品 ID が永久に無効になると、製品 ID の命名規則全体が変更され、ピット〜

2.1.2 参照名と表示名の区別に注意する

  • 参照名は開発者が見るためのものであり、表示名は IAP 支払いプロセスの確認購入システムのポップアップ ウィンドウでユーザーに表示され、自由に変更することはできません (変更を再送信する必要があります)。レビューのために IAP に送信)、名前を付けるときは明確にする必要があります。

2.1.3 アプリの審査が却下された場合

  • IAP をアプリ バージョンと一緒に審査に提出した場合、問題があれば、新しく提出されたすべての IAP プロジェクトとアプリ バージョンが同時に拒否されます。 IAP プロジェクト (各 IAP を手動で編集する必要があります。再提出するのは本当に面倒です)、そうしないと、Apple はレビューを続行できなくなります。

2.2 IAP 支払いプロセス

  • コンテンツのこの部分は、機能実現のロジックに属し、「アプリ内購入プログラミング ガイド」でも詳しく説明されています。

  • 具体的には, IAP支払いモードは2つのモードに分かれています:クライアント側の検証サーバー側の検証.クライアント側の検証モードは、支払い資格情報を偽造するのが簡単で、セキュリティが比較的低いです. 一般に, 非常に単純なスタンドアロンアプリのみができますほとんどのアプリはサーバー側の検証モードを使用します。

さらに、さまざまなタイプの IAP 支払いプロセスにもいくつかの小さな違いがあります (主に復元メカニズム) 以下では、IAP 支払いプロセスを説明するための例として、最も一般的に使用されるタイプの消耗品と更新不可のサブスクリプションを使用しています。

写真の説明を追加してください

ステップの説明:

  1. プログラムは、製品のリストを要求する要求をサーバーに送信します。
  2. サーバーは、製品 ID を含むリストを返します。
  3. プログラムは、製品情報を取得するために App Store に要求を送信します。
  4. App Store は製品情報を返します。
  5. プログラムは、返された製品情報をユーザーに表示します (App Store インターフェイス)
  6. ユーザーが商品を選択
  7. プログラムは App Store に支払い要求を送信します
  8. App Store は支払い要求を処理し、トランザクション完了情報を返します。
  9. プログラムはメッセージからデータを取得し、サーバーに送信します。
  10. サーバーはデータを記録し、監査 (当社の) チェックを実施します。
  11. サーバーはデータを App Store に送信して、トランザクションの有効性を検証します。
  12. App Store は受信したデータを解析し、データとそれが有効かどうかを示す識別子を返します。
  13. サーバーは返されたデータを読み取り、ユーザーが購入したコンテンツを判断します。
  14. サーバーは、購入したコンテンツをプログラムに渡します。

上記の手順の要約:

  • ユーザーが仮想アイテムの購入ページに入ると、アプリはバックグラウンド サーバーから商品リストを取得し、ユーザーに表示します。
  • ユーザーが特定の仮想アイテムをクリックして購入すると、APP は仮想アイテムの productionIdentifier を Apple サーバーに送信します。
  • Apple サーバーは、APP から送信された productionIdentifier に従って、対応するアイテム情報 (説明、価格など) を返します。
  • ユーザーが確認ボタンをクリックしてアイテムを購入すると、購入リクエストがAppleサーバーに送信されます
  • Apple サーバーが購入を完了すると、購入完了の証明をユーザーに返します。
  • APP は、検証のためにこの証明書をバックグラウンド サーバーに送信します。
  • バックグラウンド サーバーは、検証のためにこの証明書を Apple に送信します。Apple は、フィールドをバックグラウンド サーバーに返し、証明書が有効かどうかを示します。
  • バックグラウンドサーバーは検証結果をAPPに送信し、APPは検証結果に従って対応する処理を実行します

2.3 無視できない落とし穴

2.3.1 決済結果の返信の遅れ

  • 上記のプロセスのステップ 6 で、ネットワークの問題などのさまざまな理由により、ユーザーが正常に支払いを行った場合でも、クライアントはしばらくの間 Apple API からの支払い成功通知を受信せず、積極的に Apple API に要求することができません。支払い状況を確認するための API 受動的に通知を待ちます。
  • そのため、場合によっては、クライアントが支払いの成功の通知を受け取るのが遅れる場合があります (数分後、または次にアプリを開いたとき) この場合、次の 2 つのことを行う必要があります。
  • 1. クライアントは、支払い結果が未確認のすべての取引情報をローカルに保存し、監視プロセスを設定します. 成功した支払い情報を受け取った後、この取引のフォローアッププロセスを処理し続けます. 極端な場合、ユーザーがトランザクション結果を確認せずにアプリを削除すると、アプリのローカル データベースに保存されているトランザクション情報も失われるため、iOS システムのキーチェーンにトランザクション情報を保存することをお勧めします
  • 2 ローカルで支払い結果が未確認の取引情報がある場合、ユーザーは支払い結果がインタラクティブに表示されるまで待つ必要がある場合があります。

2.3.2 サーバー検証の遅延

上記6~8の決済認証情報の検証過程において、ネットワークの問題などの理由により、クライアントがサーバーからの検証成功通知を間に合わない場合があります。

  • 1. クライアントは支払い認証情報をローカルに保存し、検証の成功または無効な検証の明確な結果が返されるまで、検証結果についてサーバーを継続的にポーリングします。支払い認証情報をキーチェーンに保存することをお勧めます
  • 2 クライアントがサーバーに結果をポーリングするとき、ユーザーが支払い結果ページで長時間待たされるのを避けるために、支払いプロセスは最初にインタラクティブ レベルで (一定のタイムアウト後) 終了することができます。支払いの繰り返しを避けるために、支払い結果を待つようユーザーに促す時間

2.3.3 非公式チャネルパッケージの支払い失敗

  • 上記のプロセスのステップ 1 で、ユーザーがインストールしたアプリが App Store の公式チャネル パッケージ (PP Assistant や同期プッシュなどのサード パーティのアプリ ストアからダウンロードしたもの) でない場合、Apple API は、 product id does not exist and end the payment process. 対話レベルで 上記のパフォーマンスは、ユーザーがクリックして購入した後、支払いが失敗したことを直接促していることを示しています。

  • 同様に、ジェイルブレイクされたデバイスにいくつかのアプリ内購入クラッキング プラグインをインストールした後、アプリ内購入も失敗します (戻り製品 ID は存在しません)。ただし、iOS デバイスの脱獄率は現在非常に低く、基本的に無視できます。

  • したがって、この問題の解決策は、返された製品 ID が存在しない場合、ユーザーに非公式チャネル パッケージをインストールするように促し、ユーザーを App Store に誘導して公式チャネル パッケージをダウンロードすることです。

2.3.4 通貨の検証

  • この記事のセクション 1.3 で説明したように、アプリが中国国外でリリースされているが、何らかの理由で特定の地域のアカウントのアプリ内購入を制限したい場合は、手順 4 でユーザーが支払った通貨単位を確認できます。上記のプロセスを実行し、一部の通貨の購入を禁止します。同時に、特別な地域でのアカウント購入をサポートしていないポップアップの指示と同様に、対応するリマインダーをインタラクションの観点からユーザーに提供する必要があります。

2.3.5 App Store の支払い方法に縛られていないユーザーの支払いプロセス

これは巨大な穴です!

  • ユーザーがアプリ内購入の前に App Store の支払い方法をバインドしていない場合、上記のプロセスの手順 5 で、システム ポップアップ ウィンドウで購入の確認をクリックした後 (初めて)、自動的にApp Store の拘束力のある支払い方法のインターフェイスにジャンプします。次に、支払い方法のバインドが正常に完了すると、自動的にアプリに戻り、システム ポップアップ ウィンドウ (2 回目) が再び表示され、ユーザーは購入を確認できます。
  • ただし、ユーザーが購入を確認するためにシステム ポップアップ ウィンドウを (初めて) クリックすると、Apple API はすぐに支払いの失敗をクライアントに返します...支払いの失敗...失敗...一般に、クライアントは支払い失敗のリターンを受け取ります。支払いはキャンセルされたと見なされ、ローカルのトランザクション情報は破棄されます。しかし、支払い方法のバインドが完了した後も、ユーザーが購入を確認し続けるとは思っていませんでした.これは、Apple の IAP システムの設計上の大きなバグです!
  • この落とし穴を知っていれば、解決策も非常に簡単です。つまり、Apple API が支払いの失敗を返した場合、2.3.1 と同様の方法で処理し、トランザクション情報を確認したままにして、戻り値を監視し続けます。支払い結果。

3 より多くの IAP 実践経験のまとめ

3.1 匿名購入

  • 初めて IAP を送信するときに匿名購入をサポートしていないため、多くのアプリが拒否されます. その理由は、App Store Review Guidelines が、アプリがユーザーが特定の機能を使用するために登録/ログインすることを許可しないことを要求しているためです.必要。
  • 通常の状況では、IAP のないアプリの場合、ユーザーに登録/ログインを強制して使用することは拒否されません (非常に厳しいレビュー担当者に遭遇しない限り) が、IAP の場合、一般的に匿名購入をサポートする必要があります。もちろん、強制的なユーザー登録/ログインが必要な理由をたくさん考えてみることもできます (たとえば、提供される商品やサービスがユーザーの携帯電話番号やメール アドレスを取得する必要があるなど)。レビュアーを説得します。
  • 匿名購入をサポートするには、通常、ユーザーがアプリ アカウントにログインしていないときにユーザーの購入記録を一時的に保存し、ユーザーがログインした後にアプリ アカウント データにマージする必要があります。

3.2 クロスプラットフォーム同期

Appleは原則として、Webでコースを購入してアプリで視聴するなど、外部チャネルを通じて支払いを必要とするアプリ内の機能や仮想グッズのロック解除を許可していませんが、実際にはクロスプラットフォームを行うことができます特定の条件下での同期 ユーザーが購入したコンテンツ:

  • 1 対応する製品の IAP 購入が iOS アプリでも提供されることを前提として、ユーザーが異なるプラットフォームで購入したコンテンツは、アプリ アカウントを通じて同期されます。このルールは、ほとんどのゲームに適用すると厳しいかもしれませんが、一般的なコンテンツ アプリは許容されます。
  • 2 電子書籍、音楽、ビデオなどのアイテムについては、アプリは簡単なコンテンツの読み取り/視聴機能のみを提供し、ユーザーをサポートできるコンテンツ (Kindle iOS 版など) を発見して購読するための機能は提供しません。外部チャネルからコンテンツを購入した後、アプリ内のコンテンツを購入する (詳細については、App Store レビュー ガイドライン 3.1.3 を参照してください)。しかし、実際には許可するかどうかはレビュアーの判断にもよるかもしれません.例えば、Cloud Classroom はかつて有料コースを購入できないバージョンを提出しましたが、ユーザーは Web で有料コースを購入し、それをオンラインで視聴することができました. iOS側ですが却下されました 理由 上記条件の内容の範囲外の有料コースです。

3.3 仮想通貨

  • IAP の価格レベル メカニズムにより、柔軟な製品価格設定 (9.9 RMB など) とマーケティング機能 (クーポン控除など) をサポートできません。多くのアプリは仮想通貨を導入し、最初に特定の仮想通貨をリチャージします。 IAP アプリ内購入 (6、12、18、648 など) を通じて価格を設定し、仮想通貨を使用して特定の商品を購入します。
  • IAP クロスプラットフォーム同期問題と同様に、iOS プラットフォームでチャージされた仮想通貨は他のプラットフォーム (Android、Web) で流通できず、外部プラットフォームでチャージされた仮想通貨は iOS プラットフォームで使用できず、 iOSプラットフォームでチャージした仮想通貨は、外部プラットフォームでは使用できません。
  • しかし実際には、Himalaya や Get などの一部のアプリでは、ユーザーが WeChat 公式アカウントで仮想通貨をチャージし (ただし、WeChat のチャージも iOS プラットフォームと他のプラットフォームを区別します)、アプリで使用できるようになっています。 、およびアプリ内の再充電インターフェースは、再充電で問題が発生した場合、WeChat公式アカウントに従ってカスタマーサービスの支援を受けることができることを暗黙のうちにユーザーに思い出させます(実際には、WeChatを使用して再充電するようにユーザーを案内します). 厳密に言えば、このアプローチは準拠していませんが、Apple の審査が厳しくない場合でも、合格することができます. これはサイド ボールと見なされます. このトリックの効果は悪くないと思います~

3.4 払い戻しの問題

  • Apple のポリシーによると、ユーザーは IAP の購入後 90 日以内にさまざまな理由 (控除後の購入の失敗、間違った購入、嫌いなど) で払い戻しを申請できますが、払い戻しが成功するかどうかについての最終決定権は Apple にあります。いいえ。
  • ユーザーが払い戻しを申請した場合、Apple は開発者との和解時に払い戻し注文を記録し (もちろん、元の購入注文もそこにあります)、お金は支払われず、Apple はどのユーザーが払い戻しを行ったかを通知しません。 . お金も、ユーザーが買った物も残ってる、ただの魔王様状態ですよ~
  • 注文データは、iTunes Connect のバックグラウンドで「支払いと財務レポート」で表示できますが、詳細な時間情報とユーザー情報がないと、対応するプラットフォームの注文を見つけるのが困難です。
  • ゲームや一部の自営プラットフォームの場合、収入が少なくなる場合があります。プラットフォームのCPパーティーと1つずつ共有する必要がある製品の場合、お金を失う可能性があります。この問題を解決するために、一連の払い戻し注文の割り当てルールを設計することができます. IAP注文の期間と金額に応じて、プラットフォーム注文のいくつかの情報と組み合わせて、IAP払い戻し注文がプラットフォーム注文に割り当てられます. 、プラットフォームとCPが共同で払い戻しを行います。
  • 過去のデータから判断すると、通常、悪意のある払い戻しが多数ない場合、IAP の払い戻し率は 1 ~ 3% になる可能性があります (アプリ コンテンツの品質、ユーザーの気分、Apple の気分によって異なります)。 . IAP 収益が大きいアプリの場合、払い戻しの問題を考慮する必要がある場合があります。

3.5 決済成功率

  • Cloud Classroom はかつて、iPhone での Alipay/WeChat 決済の決済データを比較しました (注: IAP をバイパスしてサードパーティの決済を使用することは規制違反であり、アプリの削除や開発者のアカウントの禁止につながる可能性があります。真似しよう!)とIAP決済データを比較したところ、三者決済ユーザーの決済成功率はIAPの約2~3倍で、2倍以上の収益に反映されていることがわかりました。
    国内の App Store ユーザーの決済習慣がサードパーティの決済ほど成熟していないことは容易に理解できます。さらにユーザーアンケート調査を行った結果、IAP 支払いの成功率に影響を与える多くの要因があることがわかりました。
  • 1 ユーザーがインストールしたアプリは、サードパーティのアプリ ストアから入手したものであるか、ジェイルブレイクされたデバイスを使用しており、IAP 支払いを使用できません (ユーザーの約 5%)
  • 2 ユーザーは App Store の支払い方法をバインドしていません (ユーザーの約 75%、データは驚くべきものです)
  • 3 ユーザーは IAP 支払いプロセス中に支払い方法のバインドに問題が発生し、あきらめました (ユーザーの約 50%)
  • 上記のデータはiPhone側のクラウド教室のユーザー層のみを表したものであり、ある意味ではクラウド教室のユーザーは比較的初心者(製品自体のターゲットユーザーの大部分は初心者)であることも示していますが、また、IAP の支払い方法に連絡したことはありません。異なる製品のターゲット ユーザー グループの App Store アプリ内購入の使用習慣には違いがあるはずです。
  • ただし、App Store でのアプリ内購入の人気に伴い (一方ではゲーム内購入によるものであり、他方では頻繁な 1 ドル購入などの Apple のプロモーションの恩恵も受けています)。アプリの利用、Alipay のバインドのサポートなど)、ユーザーのアプリ内購入の習慣も発展し続けており、データからも、IAP 決済の成功率が上昇していることがわかります。 IAP。

3.6 不正行為

IAP のシェア、払い戻し、支払いの成功率などの一連の問題を考慮すると、次のような IAP を密かにバイパスしてサードパーティの支払いを使用する多くの方法があります。

  • 1.バックグラウンドスイッチコントロールを使用して、特定の時間にサードパーティの支払いを開始します
  • 2 ユーザーの情報と行動に基づいて明らかに Apple のレビュアーではないユーザー (特に一部の高額ユーザー) を特定し、サードパーティの支払いを開始するなど... しかし、会社の企業開発部門の要件に従って

    マーケティング部門、および法務部門は、IAPの問題を台無しにしないでください! Apple のルールに従い、良い製品を作り、App Store のレコメンデーションに努めます。

4 コード統合

アプリ内購入に必要なコードは非常に小さく、わずか数百行です。

4.1 ヘッダーファイルのインポート

import StoreKit

4.2 次の 2 つのプロキシ

SKProductsRequestDelegate, SKPaymentTransactionObserver

4.3 アプリ内購入の検出を有効にする

func add(_ observer: SKPaymentTransactionObserver)

let paymentQueue: PaymentQueue = SKPaymentQueue.default()
paymentQueue.add(self)

4.4 アプリ内購入のクリックイベントを設定する

private func purchase(
    product: SKProduct, 
    quantity: Int,
    atomically: Bool,      
    applicationUsername: String = "", 
    completion: @escaping (PurchaseResult) -> Void
) {
    
    
    guard SwiftyStoreKit.canMakePayments else {
    
    
        let error = NSError(
          domain: SKErrorDomain, 
          code: SKError.paymentNotAllowed.rawValue,
          userInfo: nil
        )
        completion(.error(error: SKError(_nsError: error)))
        return
    }

    paymentQueueController.startPayment(
      Payment(
        product: product, 
        quantity: quantity, 
        atomically: atomically, 
        applicationUsername: applicationUsername
      ) {
    
     result in
        completion(self.processPurchaseResult(result))
    })
}

4.5 商品のリクエスト、商品情報の取得、エージェント

private let request: SKProductsRequest
deinit {
    
    
    request.delegate = nil
}
private init(
  productIds: Set<String>,
  callback: @escaping RequestCallback
) {
    
    
    self.callback = callback
    request = SKProductsRequest(productIdentifiers: productIds)
    super.init()
    request.delegate = self
}

class func startQuery(
  _ productIds: Set<String>, 
  callback: @escaping RequestCallback
) -> InAppProductQueryRequest {
    
    
    let request = InAppProductQueryRequest(productIds: productIds, callback: callback)
    request.start()
    return request
}

func start() {
    
    
    request.start()
}
func cancel() {
    
    
    request.cancel()
}

// MARK: SKProductsRequestDelegate
func productsRequest(
  _ request: SKProductsRequest,
  didReceive response: SKProductsResponse
) {
    
    
    let retrievedProducts = Set<SKProduct>(response.products)
    let invalidProductIDs = Set<String>(response.invalidProductIdentifiers)
    performCallback(RetrieveResults(retrievedProducts: retrievedProducts,
        invalidProductIDs: invalidProductIDs, error: nil))
}

func requestDidFinish(_ request: SKRequest) {
    
    

}

func request(
  _ request: SKRequest, 
  didFailWithError error: Error
) {
    
    
    performCallback(
      RetrieveResults(
        retrievedProducts: Set<SKProduct>(), 
        invalidProductIDs: Set<String>(), 
        error: error
      )
    )
}

private func performCallback(_ results: RetrieveResults) {
    
    
    DispatchQueue.main.async {
    
    
        self.callback(results)
    }
}

4.6 サンドボックス テスト環境の検証と正式な環境

public enum VerifyReceiptURLType: String {
    
    
    // 正式环境验证
		case production = "https://buy.itunes.apple.com/verifyReceipt"
    // 沙盒测试环境验证
		case sandbox = "https://sandbox.itunes.apple.com/verifyReceipt"
}

public init(service: VerifyReceiptURLType = .production) {
    
    
    self.service = service
}

private let service: VerifyReceiptURLType

public func validate(
  receipt: String,
  password autoRenewPassword: String? = nil,
  completion: @escaping (VerifyReceiptResult) -> Void) {
    
    

  let storeURL = URL(string: service.rawValue)! // safe (until no more)
  let storeRequest = NSMutableURLRequest(url: storeURL)
  storeRequest.httpMethod = "POST"

  let requestContents: NSMutableDictionary = [ "receipt-data": receipt ]
  // password if defined
      if let password = autoRenewPassword, !password.isEmpty {
    
    
    requestContents.setValue(password, forKey: "password")
  }

  // Encore request body
  do {
    
    
    storeRequest.httpBody = try JSONSerialization.data(withJSONObject: requestContents, options: JSONSerialization.WritingOptions.prettyPrinted)
  } catch let e {
    
    
    completion(.error(error: .requestBodyEncodeError(error: e)))
    return
  }

  // Remote task
  let task = URLSession.shared.dataTask(with: storeRequest as URLRequest) {
    
     data, _, error -> Void in

    // there is an error
    if let networkError = error {
    
    
      completion(.error(error: .networkError(error: networkError)))
      return
    }

    // there is no data
    guard let safeData = data else {
    
    
      completion(.error(error: .noRemoteData))
      return
    }

    // cannot decode data
    guard let receiptInfo = try? JSONSerialization.jsonObject(with: data!, options: .mutableLeaves) as? ReceiptInfo ?? [:] else {
    
    
      let jsonStr = String(data: safeData, encoding: String.Encoding.utf8)
      completion(.error(error: .jsonDecodeError(string: jsonStr)))
      return
    }

    // get status from info
    if let status = receiptInfo["status"] as? Int {
    
    
      let receiptStatus = ReceiptStatus(rawValue: status) ?? ReceiptStatus.unknown
      if case .testReceipt = receiptStatus {
    
    
        let sandboxValidator = AppleReceiptValidator(service: .sandbox)
        sandboxValidator.validate(receipt: receipt, password: autoRenewPassword, completion: completion)
      } else {
    
    
        if receiptStatus.isValid {
    
    
          completion(.success(receipt: receiptInfo))
        } else {
    
    
          completion(.error(error: .receiptInvalid(receipt: receiptInfo, status: receiptStatus)))
        }
      }
    } else {
    
    
      completion(.error(error: .receiptInvalid(receipt: receiptInfo, status: ReceiptStatus.none)))
    }
  }
  task.resume()
}

5 IAP QA テストのヘルプ

IAP サンドボックス テスト アカウントの使用

6 App Store の契約、税金、銀行取引

6.1 iTunes Connect へのログイン

  1. iTunes Connectにサインインする

  2. 契約、税金、銀行のページに移動

    写真の説明を追加してください

6.2 アプリケーションの契約タイプを選択する

契約、課税、銀行のページに入ると、3 種類の契約が表示されます.以前に積極的に契約を申請したことがない場合、通常、現在有効にしている契約は iOS 無料アプリケーションのみです.

このページの内容は、次の 2 つの部分に分かれています。

  • 依頼契約
  • Contracts In Effect (発効した契約)。

契約には次の 3 種類があります。

  • iOS無料アプリ(無料アプリ契約)
  • iOS有料アプリ(有料アプリ契約)
  • iAd App NetNetwork(広告契約)

6.3 iOS有料アプリ契約の申し込み

  • クリックして iOS 有料アプリケーションの契約を申し込むと、契約のステータスが次のようになり、ステータスが Pending Tax、Bank、Contact であることがわかります。これは、連絡先、銀行、税務情報が入力されていないことを意味します。
    写真の説明を追加してください

6.4 銀行口座を追加する

ここに画像の説明を挿入
ここに画像の説明を挿入

  • 銀行のCNAPSコード(ABA送金ルート番号)を入力

ここに画像の説明を挿入

6.5 納税申告書(弊社とは関係ありませんが、記入が必要です)

ここに画像の説明を挿入

デフォルトでは、米国がチェックされ、その他の単語がチェックされ、通常は何もチェックされていません

ここに画像の説明を挿入

米国納税フォームを選択すると、選択後に 2 つの質問が表示されます

  • 最初の質問は次のとおりです。米国居住者かどうか、米国のパートナーシップまたは米国の会社を持っているかどうかを尋ねます。そうでない場合は、直接 [いいえ] を選択してください。

ここに画像の説明を挿入

  • 2 番目の質問は次のとおりです。米国で商業活動を行っているかどうかを尋ねます。ない場合は、いいえを選択してください。

ここに画像の説明を挿入

6.5.1 税金情報の入力

以下の点を含みます。

  • 個人または団体名:個人または団体名
  • 設立国:あなたが所在する国
  • 受益者のタイプ: 受益方式、独立した開発者が個人を選択
  • 永住権:住所
  • 郵送先住所:郵送先住所
  • Name of Person Making this Declaration:声明人
  • タイトル: タイトル

これらの情報を入力した後、送信できます
写真の説明を追加してください

6.5.2 連絡先情報を入力します。個人の開発者の場合は、すべて自分で書きます

写真の説明を追加してください

6.6 審査待ち

すべての情報を入力すると、契約ステータスが処理中になり、約半日で完了します。

写真の説明を追加してください

おすすめ

転載: blog.csdn.net/FlyingKuiKui/article/details/129182829