6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

iOS2Advent Calendar 2017

Day 11

iOSアプリ内課金でのレシート検証をサーバサイド対応させる

Last updated at Posted at 2017-12-11

こちらの記事は iOS2 Advent Calendar 2017 11日の記事です。

はじめに

アプリ内課金(以下、IAP)を実装することがあるかと思います。
その中で、レシートの検証をすることも少なくはないかと思います。
しかし、非サーバサイド経験だとサーバサイドの実装を待たないと検証できないから作業が止まったとかある中でサンプルを紹介できればと思います。(URLRequestでローカル検証したらええやんっていうのはナシで)

環境

  • Xcode8.3.3
  • iOS10.2 Later
  • Python3.6.2

サーバサイド部分開発

サーバサイドのフレームワークは軽い実装なので bottle を使用しました。
pyinapp というライブラリがあったのですが、定期購読型の対応がされていなかったのでForkして修正したものを今回を取り入れます。(PR出しているのですがマージされる見込みがないので指定でインストールできるようにします。)

$ pip install bottle
$ pip install git+https://github.com/nnsnodnb/pyinapp
app.py
from bottle import default_app, run, route, request, response
from pyinapp import AppStoreValidator, InAppValidationError


# iOSアプリ側からPOSTリクエストを送信する
@route('/receipt', method='POST')
def receipt_validation():
    if 'receipt-data' not in request.json:
        return response(body='Bad Request"', status=400)
    
    bundle_id = 'アプリのBundle ID'
    validator = AppStoreValidator(bundle_id) # bundleはnonnull
    # validator = AppStoreValidator(bundle_id, sandbox=True) # sandboxはdefaultがFalse
    # validator = AppStoreValidator(bundle_id, password='hogehogehgoe') # passwordは定期購読型等で取得するパスワードになります
    
    try:
        purchases = validator.validate(request.json['receipt-data'])
        _process(purchases)
        
        return 'Success'
    except InAppValidationError as e:
        print(e)


def _process(purchases):
    for p in purchases:
        print(p)


app = default_app()


if __name__ == '__main__':
    run(host='0.0.0.0', port=8080, debug=True, reloader=True)
def _process(purchases):
    for p in purchases:
        print(p)

アクセスURLは上記の場合は http://<IP_ADRESS>:8080/receipt となりPOST以外は受け付けません

ここで print するときにプロパティは以下がアクセスできます。

  • p.transaction_id
  • p.product_id
  • p.quantity
  • p.purchased_at
  • p.response

ただし、 p.response 以下に関しては辞書型なので適宜対応が必要です。
p/response/status を確認したい場合は p.reponse['status'] でアクセスします。

レシートの検証が完了したら、とりあえずなんですが、サーバ側から Success と返ってきて StatusCode: 200 とか成功のレスポンスがあるはずなのでそれで以降のiOS側の対応はいけるかと思います。

最後に

宣言になってしまうのですが、 DjangoというPythonのフレームワークで使用できる p.response.status のように簡単にアクセスできるようになるライブラリプラグインを作成中です。

投稿遅くなってすみません:bow:

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?