スタートガイド


dodaiiを始めましょう。
まずはアプリ内課金ついて説明します。

InAppPurchase(アプリ内課金)とは

InAppPurchase、日本語で言うとアプリ内課金とは何か簡単に説明します。アプリ内課金が導入されるまでは、開発者がユーザに課金する方法がアプリの本体代金または、自身が運営するウェブサイト上等で別途決済を通すことしか出来ませんでした。アプリ内課金の登場で開発者は必要な追加機能や月額利用料の課金等をアプリ内で自前の決済手段を用意せずに完結することが出来るようになりました。

では、具体的にどんな事がアプリ内課金で出来るか見てみます。

・ベーシックバージョンのアプリケーションに対して、追加の機能を提供する
・ブックリーダのアプリ内で、電子書籍をダウンロード販売する
・ゲーム上でバーチャルなアイテムを購入させる
・専門のニュース情報を月額課金で提供する

アプリ内課金のダイアログ(スポニチ プロ野球速報 2010)

これらはアプリ内課金の利用の一部であって、後述するAppleが禁止しているコンテンツ以外はすべて課金の対象とすることが出来ます。

■販売コンテンツの3つの形

-Non-Consumable(非消費型)プロダクト
 Non-Consumable(非消費型)とは、一度しか購入できないプロダクトのことで、たとえば以下のようなプロダクトを販売するときに利用します。

 ・無料版から有料版へのアップグレードやアドオン機能の追加。
 ・電子書籍などダウンロード販売

これらの商品は、一度購入した後は同じ商品をもう一度購入することはないため、StoreKitの挙動で一つのAppleIDにつき1回しか購入できないようになっています。もう一度購入しようとすると「このアイテムはすでに購入しています。無料でダウンロードしますか?」とダイアログがでる仕組みになっています。

また、Non-Consumableに限り、購入情報をアップル側で保管してくれるので、「リストア」という操作を行うことが可能で、かつ同じAppleIDで登録されているiPhone/iPod touchで共用することができます。つまり、iPhoneであるゲームの追加ステージを購入したあと、iPod touchでリストアを行うとiPod touchでも遊べるという仕様になっています。

-Consumable(消費型)プロダクト
 Consumable(消費型)とは、以下のように何度も購入可能なプロダクトのことです。
 ・バーチャルアイテム(ゲームにおける武器など)
 ・バーチャルコイン
 ・デジタルコンテンツのレンタル

 これらは、何度でも購入が可能ですが、アップルが購入情報を保存してくれない為、以下のようなことを気をつける必要があります。
 ・データが消えてしまった場合の対応
 →アプリケーション内に、購入したアイテムの情報を保存している場合、たとえばアプリケーションを削除したり、そもそも本体ごと修理交換してしまった場合など、ユーザーはもう一度プロダクトを購入しなければならず、トラブルに発展する可能性があります。
 ・別のiPhoneにうつせない
 →Non-Consumableと違い、購入したアイテムは別の端末にうつせない為、ユーザーが共有を期待している場合は問い合わせが来るかもしれません。事前に断りをどこかに入れておくとよいでしょう。

-Subscription(継続課金)
 Subscriptionとは、和訳すると購読という意味ですが、一定期間ごとに繰り返し課金するタイプのプロダクトです。プロダクトの例は、日本の開発者にはなじみ深いものとなっています。
 ・月額料金
 ・3ヶ月料金
 ・年額料金
 これら、繰り返しの単位は開発者が自由に決めることが出来ますが、逆に言うとアップルではいっさい管理を行ってくれません。つまり、たとえば「1ヶ月料金」を支払ったユーザに、次回いつ請求のダイアログを表示するかは各開発者のサーバで管理する必要があります。
 基本的な挙動はConsumableと同じで、リストアや共有は出来ません。Consumableとの違いは、再購入するときに課金ダイアログでの表示が「期間を延長しますか?」となるくらいです。

コンテンツのタイプ一覧
タイプ概要購入履歴の管理
Non-consumable購入すると二度と購入できないアップルが管理
Consumableアイテムやコインのような消費されるもの開発者が管理
Subscription期間課金開発者が管理


アプリ内課金の特徴


具体的な解説の前にアプリ内課金の特徴についてもう少し説明します。

・アプリ本体は無料でも有料でも構わないが、有料販売契約(Paid Contract)が必要
 OS3.0の導入当時は本体が有料のアプリのみで利用可能でしたが、2009年10月の改正により、本体が無料のアプリでもアプリ内課金を利用することが可能になりました。しかしアプリ内課金を利用するには、iTunesConnectの画面でPaidContractが有効になっている必要が有り、この契約を結ぶにはアップルに銀行・税務情報などを登録する必要があります。

・課金プロダクトの価格帯はアプリ本体と同じだが、無料には出来ない
  課金を行うプロダクトの価格帯は、アプリ本体と同じになるため、開発者が自由に価格を変更することは出来ず、日本円の場合は115円、230円、350円・・・という段階制となります。また、価格を無料にすることは出来ず、アプリ本体のように「一定期間無料セール」ということを行いたい場合は iTunesConnectを通さず、アプリで独自に実装する必要があります。

・決済はAppStoreとおなじ、AppleIDを利用する
 アプリ内課金で利用する決済方法は、AppStoreを始めとするiTunesでの決済と同じ、Apple IDとパスワードを利用しています。これはクレジットカードなど他の決済方法に比べ非常にシンプルで、ユーザにとって心理的にも利用しやすいでしょう。

・決済にはトランザクションが利用される
  アプリ内課金で決済を利用する際には、トランザクションの仕組みが利用されています。アプリケーションはさまざまな環境、たとえば急にオフラインになったり、電話などでアプリケーションが終了したりといった状況でも、課金失敗や2重課金が行われないように、トランザクションで管理されています。開発者はまず 購入処理をStoreKitにリクエストし、その決済が承認されると、次に課金プロダクトをユーザに提供する為の処理を行います。処理が完了したら購入用のトランザクションを完了させることにより決済のトランザクションがコミットされます。

・アプリケーションを立上げない限りは課金できない
  ウェブサービスの課金と違い、アプリ内課金は文字通りアプリを起動しない限り決済を行うことが出来ません。また、アプリ内課金プロダクトの種類にあるSubscriptionも、一定の期間で繰り返し自動決済するような機能はついておらず、ただ単に複数回の課金がシステム上受け入れ可能になっているだけです。

・課金用のプロダクト単体でAppStoreに登録し審査を受ける
 課金用プロダクトはその種類によらず、iTunesConnectへの登録と審査が必要になっています。これは100種類販売するものがあれば100種類とも登録・審査を経る必要があります。ただし登録を行うのはプロダクトのIDを発行することが目的で、たとえば電子書籍のデータ自体をアップロードすることはありません。同じく審査も、プロダクトの説明文および、購入後のスクリーンショットにて判断されます。

■課金プロダクトの販売に関するアップルのガイドライン

アプリ内課金を利用するには以下のガイドラインに従う必要があります。※
・課金プロダクトはあくまでデジタルコンテンツやオンラインサービスに限られ、書籍など
 現実の物販やサービスの販売は出来ない。
・一部のユーザーだけが購入できるのではなく、全員が購入できるようにする必要がある。
・説明文などに特定の通貨で価格情報を入れてはいけない。
・ポルノや不快な文章、中傷、ギャンブルなど不適切なコンテンツを販売してはいけない。(ただしギャンブルはシミュレーションである限りは許可されている。)

※詳しくはアップルのドキュメント「Getting Started with In App Purchase on iPhone OS」をご参照ください。


アプリ内課金の開発をはじめる

・[事前準備]BundleIdを決める
・[Provisioning Portal]AppID
・[Provisioning Portal]Enable In App Purcase
・[Provisioning Portal]プロビジョニングを作成する
・[iTunesConnect]テストユーザの登録
・[iTunesConnect]課金用アプリの空登録
・[iTunesConnect]課金アイテムの登録

・[事前準備]BundleIdを決める
 現在すでにあるアプリにアプリ内課金機能を持たせる場合も、全く新しいアプリを作る場合も、Bundle Identifierを先に決める必要があります。今までアップルは、アプリケーションがどんなBundleIdentifierでも対応できるようにワイルドカード(*)でのAppIDを発行するよう推奨してきましたが、アプリ内課金及びPushNotification(APNS)を利用する場合は、AppIDを固定することが必要になります。

命名規則に関しては、ドメイン名を逆向きにしたものに、アプリケーションの名前を付けたものになります。たとえばfeynman.co.jpというドメイン名の組織でSomeAppsというアプリケーションを開発する場合、jp.co.feynman.someappsというIdentifierを用います。

・[Provisioning Portal]App IDの登録
 Identifierをきめたら実際に登録を行います。Provisioning Portal( http://developer.apple.com/iphone/manage/overview/index.action )にログインしApp IDsの欄を開きます。New App IDよりBundle Seed ID(既存のものでも新規作成でも構わない)および、先ほど決めたBundle Identifierを入力し登録を行います。

AppID生成画面

・[Provisioning Portal]App IDに対するIn App Purchase機能を有効にする
 AppIDを生成したら、そのApp IDでIn App Purchaseを利用できるように設定を行う必要があります。App ID一覧画面で、先ほど生成したIDの右側にConfigureというリンクがでているのでそこから登録を行います。「Enable In App Purchase」のチェックを選択し、Doneを押すだけで完了です。
In App Purchaseを有効にする

・[Provisioning Portal]プロビジョニングプロファイルの作成
 次にプロビジョニングプロファイルを作成すると、Provisioning Portalでの作業は終了となります。先ほど生成したApp IDおよびすでにある証明書・デバイスリストを選択し開発用のプロファイルを作成します。同様にDistribution用のプロファイルも作成します。作成したプロファイルは、ダウンロードして ~/Library/MobileDevice/Provisioning Profilesに配置してください。

・[iTunesConnect]テストユーザの登録
 Provisioning Portalの作業が完了したら、次は課金プロダクトの設定をおこないます。iTunes Connectにログインし、テスト用のユーザを先に作成します。販売する国ごとのユーザを作成できるので、最低限米国と日本は用意してください。

iTunesConnect ( https://itunesconnect.apple.com/ )のManage Usersから、「In App Purchase Test User」を選択しAdd NewUserから、実際のアプリ内課金を購入テストするユーザーを登録します。
iTunesConnectのテストユーザ一覧画面


・[iTunesConnect]課金用アプリの登録
テストユーザの登録が終わったら、アプリケーションを登録します。Appleに審査してもらう必要はないので、アプリケーション名やアイコンや画像だけを登録します。iTunesConnectのホーム画面より 「Manage Your Applications」を開き、これから開発するアプリのメタ情報を登録します。実際のアプリケーションのバイナリをアップロードする必要はありませんが、登録を完了させる為にはダミーの画像が必要になります。手持ちの画像処理ソフトなどで以下のサイズの白紙のjpeg画像を作り書き出してください。

・512x512pxの大きなアイコン画像(JPEGまたはTIFF)
・320x480pxのiPhone/iPod touch用スクリーンショット(JPEGまたはTIFF)
・1024x768pxのiPad用スクリーンショット(JPEGまたはTIFF)

Add Newから通常の登録と同様に進めます。アプリ名、キーワードは最初から正しいものを登録しておき、残りの項目は適当に入力して進めてください。アプリのアップロードは「Upload application binary later」を選択しておくことでアップロードせずに進めることが出来ます。

・[iTunesConnect]課金アイテムの登録
 課金用のアプリ情報を登録すると、そのアプリに課金プロダクトを紐付けできるようになります。アプリの情報欄から、あるいはホーム画面から「Manage Your In App Purchases」を開き、アプリが選ばれた状態でCreateNewを選択してください。登録画面の各入力内容は以下の通りとなっています。

 ・Reference Name : 参照用の名前(iTunesConnectでの管理用でAppStoreには表示されません)
 ・Product ID:一意の商品ID
  命名規則として、{BundleIdentifier}.category.productNameとしてください。たとえば、jp.co.feynman.someapp.tier1.photoPack001のように、カテゴリ部分に価格帯を入れておくとあとで整理するときに分かりやすくなります(商品価格を変更する時は少し面倒になるので事前に考慮が必要です。)
 ・Type :商品の種別。前述の通りの3つに分類されます。
  -Consumable(消費型)
  -Non-Consumable(非消費型)
  -Subscription(購読型)
 ・Cleared for Sale:販売可能かどうか。ここのチェックを外すと、StoreKitで問い合わせても商品情報が返却されなくなります。終了した商品を、ユーザーが購入しないようにする為に利用します。dodaiiで制御する場合はつねにチェックを入れたままにして下さい。
 ・Price Tier:価格帯、前述のようにアプリ本体の価格帯と同じ段階制となっており、無料にすることは出来ません。

以上で、Web管理画面で行う作業は終了です。



StoreKitを利用した開発
■サンプルコードを使った処理の流れ

 サンプルコードを使いながら、各StoreKitの役割について説明します。ここでは、日本ではよくある月額課金を実現する方法を紹介します。

 処理の流れを簡単に図にしました。おおまかには起動時と課金時の2つの処理となります。

起動時の処理の流れ

課金時の処理の流れ

■StoreKitの各役割
StoreKitの各クラスは、大きく2つに分けられます。商品情報を扱うSKProduct系と、購入処理を行うSKPayment系です。
SKProductにはその商品が現在販売中かどうか、ユーザーの言語に応じた商品名などが格納されており、SKProductsRequestを使ってAppleに問い合わせを行います。
SKPaymentでは、実際の購入処理を行いますが、単にリクエスト・レスポンスではなく、決済と課金対象のプロダクトの提供が行われる一連の流れをキューとトランザクションで管理しています。


  ・SKPayment系
   ・SKMutablePayment
   ・SKPayment
   ・SKPaymentQueue
   ・SKPaymentTransaction
  ・SKProduct系
   ・SKProduct
   ・SKProductsRequest
   ・SKProductsResponse


■購入状況の確認
 アプリケーションが起動すると、現在の利用状況の確認が始まります。これは基本的にはpreferenceなどローカルに保存しておいてよいが、厳密を期す場合は毎回サーバに時刻合せとともに確認しにいったほうがよいでしょう。

----------------------------------------
- (void) viewDidLoad {
    [super viewDidLoad];
    // 購入状況チェック
    if([self isExpired]){ ・・・・1 ローカルファイルに保存された期限が切れていないかを調べるメソッド
    /**
    * 購入案内画面をだす
    */
    UIAlertView *alert = [[UIAlertView alloc]
     initWithTitle:@"Monthly Payment"
     message:@"Renew Your contract"
     delegate:self
     cancelButtonTitle:@"Not now"
     otherButtonTitles:@"Renew", nil];
    [alert show];
    [alert release];
    }
    else{・・・・2 ローカルファイルに保存された日付をデバッグ用に出力
        NSDate *nextExpireDate = [self expireDateFromFile];
        NSLog(@"nextExpireDate :%@",[nextExpireDate description]);
    }
}
----------------------------------------

■アイテムの取得
  サンプルコードはアイテムが3種類しかないのでアプリケーション内に定義していますが、商品入れ換えや、価格の変更が予定されている場合、以下のメソッドを使って iTunesConnectに登録されている課金プロダクトがCleared for Saleになっているかどうか、または最新の価格や各言語別にiTunesConnectで登録した商品名を問い合わせることが出来ます。

----------------------------------------
// SKProductRequestを発行する
- (void)requestProductData:(NSString *)name
{
    SKProductsRequest* request;
    request          = [[SKProductsRequest alloc] initWithProductIdentifiers: name];
    request.delegate = self;
    [request start];
}

// SKProductRequestのDelegateメソッド
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
    NSArray *myProduct = response.products;
for (SKProduct *p in myProduct) {
    [self paymentWithProductIdentifier:p.productIdentifier]; // 商品情報を使用した何らかの処理
        }
}
----------------------------------------

■購入トランザクションの開始
 購入リクエストは、1つのSKPaymentをキューに追加することで開始されます。キューは順次処理され、状態が変わるごとにObserverに通知されます。

----------------------------------------
// SKPaymentに課金プロダクトのIdentifierをセットし、SKPaymentQueueに追加する
- (void)paymentWithProductIdentifier:(NSString*)productIdentifier
{
SKPayment *payment = [SKPayment paymentWithProductIdentifier:productIdentifier];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}

// 購入トランザクションアップデート通知(Observer)
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
    for (SKPaymentTransaction *transaction in transactions) {
        switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchasing:
NSLog(@"購入中(updatedTransactions)");
break;
            case SKPaymentTransactionStatePurchased:
NSLog(@"購入完了(updatedTransactions)");
                [self completeTransaction:transaction];
                break;
            case SKPaymentTransactionStateFailed:
NSLog(@"購入失敗(updatedTransactions)");
                [self failedTransaction:transaction];
                break;
            case SKPaymentTransactionStateRestored:
NSLog(@"リストア完了(updatedTransactions)");
                [self restoreTransaction:transaction];
            default:
//NSLog(@"unknown transactionState: %d", transaction.transactionState);
                break;
        }
    }
}
----------------------------------------
Observerは、それぞれのTransactionStateにより、処理を振り分けます。この段階ではまだ課金は完了していません。

■購入完了通知
ステートが、SKPaymentTransactionStatePurchasedとなった場合、購入が完了しているので、該当の課金プロダクトを提供します。

----------------------------------------
// トランザクションを完了させる
- (void) completeTransaction: (SKPaymentTransaction *)transaction
{
   // たとえばデリゲートに通知し、日付の延長や購入ウィンドウを閉じるなどの処理を行う
    if(delegate) {
        [delegate didFinishSKPaymentQueue:transaction.payment.productIdentifier];
    }

    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];// 購入を完了する 
}
----------------------------------------

実際の運用時は、購入されたレシート情報をサーバに保存し、サーバに保存が完了した段階でfinishTransactionを呼ぶ方が安全です。前述のよう にNon-Consumable以外の課金プロダクトはAppleでその履歴を復元することが出来ないので、課金後の処理に失敗したりデータが消えてしまった場合にユーザが混乱しトラブルの元になります。

サーバに保存するには、NSDictionaryなどをシリアライズし、 丸ごと送る・受け取るのが一番手軽です。日付などの簡単なデータの場合はこれで十分です。他方複雑なデータ構造を扱ったり、サーバの機能と連携させる場合は、それぞれのプロパティに対応した連携APIを構築する必要が出てきます。

NSDictionaryのシリアライズ/アンシリアライズ

----------------------------------------
NSDictionary *dict;
// データ追加処理
NSData *pData = [NSPropertyListSerialization dataFromPropertyList:dict format:NSPropertyListBinaryFormat_v1_0 errorDescription:&error];
// アンシリアライズ
id retPlist;
retPlist = [NSPropertyListSerialization propertyListFromData: pData  mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&error];
dict = (NSDictionary*) retPlist;
----------------------------------------

[TIPS]レシートの中身

  Appleから購入完了通知として返却されるレシート( SKPaymentTransaction.transactionReceipt )は、base64形式でエンコードされたplist形式となっています。そのなかでpurchase-infoには、購入した情報が下記のように格納されています(一部パラメータはマスク済)。

----------------------------------------
{
 "item-id" = "300999999";
 "original-transaction-id" = "1000000000099999";
 "purchase-date" = "2010-04-10 10:20:54 Etc/GMT"; 
 "product-id" = "jp.co.feynman.sampleapp.item"; 
 "transaction-id" = "1000000000099999"; 
 "quantity" = "1"; 
 "original-purchase-date" = "2010-04-10 10:20:54 Etc/GMT"; 
 "bid" = "jp.co.feynman.sampleapp"; 
 "bvrs" = "1.0";
}
----------------------------------------

ほとんどのパラメータは、変数名で理解できますが、省略されているものでは、bidがアプリ内課金を利用するアプリ自体のbundleID、bvrsがそのアプリのバージョンとなっています。また、original-が接頭詞につく項目は、課金プロダクトのリストア時に、以前の購入時の値が利用されます。

詳しい解説は、日本語のStoreKitプログラミングガイドに記載がございます。
http://developer.apple.com/jp/iphone/library/documentation/NetworkingInternet/Conceptual/StoreKitGuide/StoreKitGuide.pdf

■レシートの正当性の確認
 サーバを利用している場合は、レシートの正当性を確認する必要があります。レシートの構造は簡単に偽装可能であるため、その情報が正しいかをアップルに問い合わせます。サンプルコードは単体動作を前提としているので必要ありませんが、たとえば以下のようなコードになります。

----------------------------------------
PHP 5.3の例
 $receipt = json_encode(array("receipt-data" => $_GET["receipt"]));//レシートをエンコード
 $url = "https://sandbox.itunes.apple.com/verifyReceipt";// 開発用URL
 $ch = curl_init();// 接続にcURLを利用
 curl_setopt($ch, CURLOPT_URL, $url);
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 curl_setopt($ch, CURLOPT_POST, true);
 curl_setopt($ch, CURLOPT_POSTFIELDS, $receipt );
 $encodedResponse = curl_exec($ch);
 curl_close($ch);
 $response = json_decode($encodedResponse);//レスポンスをデコード
 if ($response->{'status'} != 0){
     // 認証失敗処理
 }
----------------------------------------


■課金コンテンツの提供
 決済が正しく行えたら、必要なプロダクトの提供を行います。サンプルコードではNSUserDefaultsを利用しますが、セキュリティ的に重要であればKeychainなど必要なデータソースに保存を行います。

----------------------------------------

- (void)didFinishSKPaymentQueue:(NSString*)productIdentifier {
    NSLog(@"Product purchase success! :%@",productIdentifier);
    int addMonth = 0;
    if([productIdentifier isEqualToString:kProductIdentifierOneMonth]){
        addMonth = 1;
    }else if([productIdentifier isEqualToString:kProductIdentifierThreeMonth]){
        addMonth = 3;
    }else if([productIdentifier isEqualToString:kProductIdentifierSixMonth]){
        addMonth = 6;
    }
    NSLog(@"addMonth:%d",addMonth);
    //現在日時を取得し、購入月数の分だけ足してplistに書き込む
    NSDateComponents *month = [[NSDateComponents alloc] init];
    [month setMonth:addMonth];
    NSDate *expireDate = [[NSCalendar currentCalendar] dateByAddingComponents:month toDate:fromDate options:0];
    [month release];
    NSLog(@"Next Date:%@",[expireDate description]);
    // 書込み先
    NSArray *dirpaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString* path = [NSString stringWithFormat:@"%@/%@",[dirpaths objectAtIndex:0],kFileNameForSaveData];
    //kNextExpireDateをキーにして書き込む
    NSMutableDictionary* dict;
    dict = [NSMutableDictionary dictionary];
    [dict setObject:expireDate forKey:kNextExpireDate];
    [dict writeToFile:path atomically:YES];
}
----------------------------------------


■決済完了通知
 全ての処理が完了したら、SKPaymentQueueに対し、現在のトランザクションを完了させます。これでユーザーに課金が発生します。

----------------------------------------
// トランザクションを完了させる
- (void) completeTransaction: (SKPaymentTransaction *)transaction
{
   // たとえばデリゲートに通知し、日付の延長や購入ウィンドウを閉じるなどの処理を行う
    if(delegate) {
        [delegate didFinishSKPaymentQueue:transaction.payment.productIdentifier];
    }

    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];// 購入を完了する 
}
----------------------------------------

■トランザクションのレストア
 今回の購読では利用できませんが、Non-Consumable(非消費型)プロダクトでは、以前の購入情報を再読み込みすることが可能です。

----------------------------------------
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
----------------------------------------

を呼び出すとリストア用のキューが開始し、
 paymentQueue:queue updatedTransactions:transactions
のデリゲートメソッドに対して、transactionStateがSKPaymentTransactionStateRestoredという状態で通知される為、通常の購入と同じように処理を行えば良いでしょう。


dodaii利用前に準備するもの、やっておくこと


 dodaiiを利用して、InAppPurchase対応のアプリケーションを作成するためには、dodaii以外のApple社側のシステムでもいくつかの設定が必要です。アップルの「iTunesConnect開発ガイド[PDF]」もご参照ください。

  • 有料アプリケーションのContactがIn Effectであること
  • 有料アプリケーションの登録が終了していること。登録を行うために、仮のアイコンやスクリーンショットを登録することになります。バイナリは未アップの状態で構いません。
  • Program Portalで、InAppPurchase用のApp IDが作成されていること。次のInAppPurchase用のプロダクトを作成するために、Program Portalで設定したBundle IDを選択する必要があります。
  • 登録したアプリに対して「Manage Your In App Purchases 」で、プロダクトを関連付けしていること。
  •  「 Manage Users  」で、InAppPurchaseテスト用のユーザが作成されていること。

iTunesConnectへの課金プロダクト登録

iTunesConnect(https://itunesconnect.apple.com /WebObjects/iTunesConnect.woa)へアクセスし「Manage Your In App Purchases 」のリンクから、プロダクトを登録したいアプリケーションを選択します。入力画面では以下の情報を入力します。

    * Reference Name : 管理用のプロダクト名(非公開)
    * Product ID : プロダクトの識別子。一般的に<<アプリケーションのbundleIdentifier>>.一意のID とします。
          o 例)com.apple.myapp.product1023 (com.apple.myappがアプリのBundle Identifierの場合)
    * Type : 複数回の購入が可能かどうかを設定します。
    * 一度しか購入できない場合はNon-consumable、複数回購入可能な場合はconsumableかSubscriptionを選択します
    * Price Tier : 価格帯を選択します。設定できる価格はアプリ本体と同じ115円〜となっています。
    * Cleared for Sale : 販売可能かどうかを設定します。dodaiiで制御する場合はつねにチェックを入れたままにして下さい。


dodaiiへのアプリケーション登録


dodaiiへ有料販売プロダクトを登録する前に、まずは大本となるアプリケーションを登録します。上のメニューのApplicationを開きRegisterから登録を行います。

アプリ名と説明文を入力し、登録を行うと一覧画面に現れます。同時に、iPhoneからdodaiiを利用するためのtokenが発行されますので、このトークンを使ってapiとの通信を行います。

<登録方法>ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
dodaiiの無料アカウントの登録後、dodaii Panel へログインして下さい。

 ※dodaiiの無料アカウントの登録・ログインはこちらから
https://dodaii.com/panel/

画面上部の「アプリケーション」からアプリケーション一覧画面を開きます。
「新規登録」より、開発するアプリを登録します。



アプリを登録されますと、登録されたアプリに対しトークンが発行されます。



ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー


dodaiiへのプロダクト登録


次に、有料課金プロダクトをdodaiiに登録しましょう。dodaiiにはプロダクトグループという機能があります、これは例えば販売したい商品を期間で区切りたい場合などに「200910」と登録し、そこにプロダクトを登録することにより、アプリケーションの販売時に使い分けることが可能です。グループを使用しない(=グループと紐付けない)ことも可能ですが、サンプルコードはグループを使用しますので今回は登録を行います。

アプリケーション一覧から、対象アプリケーションの「プロダクト詳細」を選択すると、プロダクトグループとプロダクトの一覧が表示されますが、初期段階ではグループは存在しません。
プロダクトグループ一覧の下にある「登録」から新たにグループを作成することが可能です。

また、プロダクト一覧の下にある「登録」からプロダクトの登録を行うことが可能です。
付属ファイルにサムネイル用の画像2点をアップロード頂きご確認ください。







dodaii web panel で登録された情報はAPIによりjson形式で値を返します。
APIの詳細に関しましては、APIリファレンスをご覧下さい。

http://support.dodaii.com/inapp_purchase/api_reference_v2

レスポンスのイメージは以下のようになります。

https://dodaii.com/api/v2/product/decdc5444c24142895238ec9a0ce3778

なお、プロダクト情報入力画面の項目に対する説明と、返されるAPIの例は以下のようになります。

1.基本情報

・アプリケーション名 

・プロダクトグループ名 ( Optional )
    例) "name":"プロダクトグループ名"

・プロダクト名
    例) "name":"プロダクト名"

・状態
    販売中/不使用
        不使用にセットすると、APIでの取得対象から外れます。
        一時的に販売しない場合にご利用ください。

・識別子(identifier)
    例) "identifier":"dodaii_ITEM_1 "

・無料アイテム
    有効にすることでdodaiiサーバ側では無料アイテムとして認識されます。 
    例) "freeItemFlag":false


2.課金コンテンツ (Optional)
    「課金コンテンツ (Optional)」では各言語ごとの設定が可能となっております、
    販売を対象とする言語の項目を設定していきます。

・表示名
    コンテンツの表示名 例)  "displayedName":"ドダイサンプル"

・ダウンロードファイル 1 〜5
    ダウンロードコンテンツをアップロードできます。容量が5MB以内のファイルを
    5つまで、もしくは、300MB以内のファイルを1つ登録可能です。
    例) "fileName":"test.zip"
    ※5MB以上のファイル登録はプロダクト一覧画面の「巨大ファイルアップロード」からアップロードを行います。
    

2-2.APIで利用可能な追加情報の登録 (Optional)
    ・Free Column 1〜5
        コンテンツ情報のテキストを設定することができます。
        例) "freeColumn1":"サンプル画像全030枚"

    ・付属情報 1 〜5
        購入処理以前に取得できる画像などのファイルを設定することができます。
        例) "fileName":"dodaii_sample.PNG"
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

以上でサーバー側の準備は整いました。

サンプルコードについて

コードの組み込み

まず基本となるApplicationBundleIdentifierを書き換えます。Info.plistを開き、ご自身のプロダクトを登録したアプリのidentifierに書き換えます。

その後、GravureViewer.hの以下の部分に、
アプリ登録後に発行されるトークンをセットしてご使用ください。
  #define APPLICATION_ID @"YOUR_DIDAII_APPLICATION_TOKEN_HERE"


また、開発でご使用頂く際はTAStoreManagerの
NSURL *apiUrl = [[NSURL alloc] initWithString:[NSString stringWithFormat:@"%@/transaction/",DODAII_URL] ];
という行を
NSURL *apiUrl = [[NSURL alloc] initWithString:[NSString stringWithFormat:@"%@/transaction/sandbox/",DODAII_URL] ];
という風に開発用の購入確認通知APIに変更頂く必要がございます。


ご利用の際はNSLogなどを入れていただいて動作の流れを確認いただければと思います。

提出ガイドへ
ą
101.png
(20k)
admin dodaii,
2011/04/26 2:32
ą
102.png
(7k)
admin dodaii,
2011/04/26 2:32
ċ
test.zip
(15478k)
admin dodaii,
2011/04/26 2:32
Comments