Upload
-
View
294
Download
1
Embed Size (px)
Citation preview
Amon2 でかかれたAPI サーバ開発を引継いだ
( 課金の実装 )
who am I• t.amano / @sheercat• 職業 :
Servent CTO
• 言語 : perl go C C++ java clojure
• 会社 : livedoor → LINE → Diverse inc. (mixi 子会社 )
Diverse は何をやってる会社か?
YYC
youbride
そして、みなさん Poiboy やってますか?
Poiboy の API サーバは Amon2 です。
Plack です
• Data::ObjectDriverXslateData::FormValidatorLog::Minimal
nginxnginx_smalllightmysqlmemcached
で、 Poiboy とは
Poiboy
ポイして恋するコミュニケーションアプリです。(!?)
このアプリ、男性は登録したら「ポイされるのを待つだけ」という、ストイックで諦観とも似た世界観のアプリです(女性はガンガン男性をさがせます)
ところが、次回アップデートで男性からも女性に対してアピール可能になります。(この LT は Poiboy の宣伝ではありません)
アピールするにはドピーが必要です
\ドピー/
ドピーとはなにか
ドピーとは Poiboy 内の仮想通貨です
1ドピーは 10JPY です
ということで、アプリ内課金を実装する際のサーバサイドの話をします
iOS (in app purchase)
API サーバ側で in app purchase のレシート validate 処理をします(クライアントサイドでもできますが、なんか面倒そう)
in app purchase レシートをサーバで validate する場合は buy.itunes.apple.com/verifyReceipt にレシート投げつけてレスポンスで正否を見ます
ただし、 valid なレシートであればなんでも正とするため、はたしてそのレシートは本当に自分のアプリのレシートなのか ? を見ないといけません
具体的には itune connect に登録した tier をサーバ側でももっておいて、レシート中にある product_id と比較して一致しないものはクラックであると判断します。(レシート偽装はクラックの常套手段です)
偽装レシートとは、例えばこんなレシートです。.."product-id" = “com.zeptolab.ctrbonus.superpower1","bid" = “com.zeptolab.ctrexperiments”,..
また、 original_transaction_id を uniq key とするテーブルにレコード insert するなどして、同じレシートがなんども処理されないようにする必要があります。
サーバが落ちてたなどの理由でレシートの validate ができなかった場合は、アプリでレシートを保持しておいてリトライできるようにしておく必要があります。
price( 価格 ) 情報が結構面倒で、サーバ側にもっておくか、アプリ側で取得してレシートといっしょに API にくれるか、どちらかなんですが
itune connect に登録されている priceは為替、税制変更などのタイミングでさらっと ( 数年に一回とかの頻度で ) 変わるためアプリ側で取得してレシートといっしょに API にくれるのが理想的です。
下手にサーバ側でもってる price と比較してチェックとかすると、なんかのタイミングで全部エラーになったりして危険です。
かといって、単純にリクエストでもらったものを信用するのも危険です
レシートに price 情報入れるか、サーバから API たたいたら教えてくれませんかね> apple 神
Android (google wallet v3)
Android でも同じアプリの課金が始まると、ひとりのユーザーが Android で買った仮想通貨と iOS で買った仮想通貨を両方持てるので、めんどうなことになります
( iOS で買った仮想通貨を Android で使うことは apple の規約上許されてないと記憶しています。その逆も許されてないと記憶しています。)
Android の場合も同じくレシートをアプリから送ってもらいますが、 iOS のように API を叩くのではなく、公開鍵と、シグネチャをつかって自力で validation します
my $rsa = Crypt::OpenSSL::RSA->new_public_key($pub);unless ( $rsa->verify( $receipt, $signature ) ) { die "rsa verify error";}
こんな感じで。
iOS と同じく product id チェック、 order id ユニーク化は必須です
課金の試験
iOS も Android もテスターユーザーを登録できるのでそのユーザーで課金すると、実際には支払うこと無く課金テストができます。
Android は tester で課金すると orderId がレシートに入らないようになってしまいましたので注意が必要です。(6/7 くらいから )
計上、レポート
さて、計上のためのレポートは各課金実装よりもだいたい面倒なことになります。
• 仮想通貨の場合は購入時に計上ではなく、消費時に計上するので面倒さが倍増しますずっと保持したままの人がでるので、自動的に expire するなどしないとずっと計上できないですただし、 iOS では購入した仮想通貨に期限つけてはいけないという規約があります。
もし無料で仮想通貨を配ったりするときは購入したポイントと絶対混ぜないようにします。
iOS と Android も混ぜないほうがいいでしょう
場合により一定期間(年単位)トランザクションを全保存しなくてはならないこともあります。その場合はパンクしない保存方法で(DB に 1件 1件いれてると詰む )
仮想通貨の場合は、資金決済法により、供託金、有料通貨と無料通貨の表記、など
くわしくは御社の経理、法務、監査法人へお問い合わせください
まとめ
• 課金系はクラック対策必須product id 確認 transition id ユニークキー化サーバ不具合に備え、アプリにレシート再送処理課金実装時には、別デバイスで課金される想定をtest 課金時のレシートは本番と違うことがある課金実装よりも計上レポート実装のほうが重い法 律 重 要※法律、計上は課金実装前に詰めとかないと詰む
Poiboy
以上、ご清聴ありがとうございました