こちらの記事は 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
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
のように簡単にアクセスできるようになるライブラリプラグインを作成中です。
投稿遅くなってすみません