kintoneと連携した LINE PAY API v3 のサンプルアプリを試してみる

@stachibana さんのこちらのアプリを試した際の備忘録
https://github.com/stachibana/line-pay-v3-python-sdk-sample
![スクリーンショット 2020-11-04 0.43.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242610/489f9416-7d58-6788-7c19-60ffe3569596.png)
![スクリーンショット 2020-11-04 0.44.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242610/86905e92-47cc-24ee-8528-0480b9768047.png)

紆余曲折ありましたが、これをForkしてLINE Pay の一般決済（単発決済）だけを実装するためのスターターアプリができました。
https://github.com/maztak/line-pay-v3-python-starter

## LINE Pay 概要

###オーソリってなに？
ユーザーが決済を承認した後の売上確定待ち状態。これをCaputureすることで売上確定となる。

###Captureとは何？
Captureとは売上確定のことらしい。RequestAPIの利用時の`request_options`の値の中でoptions.payment.captureをFalseにすると、オーソリ状態（売上確定待ち状態）で止めることができる。それがどんなときに嬉しいかは知らん。

売上確定するにはCaptureAPIを使うことになるのだが、加盟店MyPageの売上管理＞売上対象照会からも手動で売上確定することが可能（なお以下はテストアカウントで本番決済したときの画面。Sandbox環境で模擬決済した場合はナビメニューの「Sandbox」から模擬決済の管理画面に入れる）。
<img width="1401" alt="スクリーンショット 2020-07-05 20.02.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242610/d5751bf2-5444-0649-f9d1-ffdefad356f3.png">

###Checkoutとは何？
一般用語としてや他の決済サービス（StripeとかPayjpとか）では、決済することそのもの、もしくは決済を簡単に実装できるライブラリのことを言うらしい。しかし、LINE Pay における Checkout は、ユーザーの住所とか送料を含めた決済機能のことを指すらしい。つまりECで商品の送付先を入力する作業を Checkoutを使えば省けるっぽい。

### LINE Pay API v2 と v3 の違い
公式リファレンス Migration V3
https://pay.line.me/documents/online_v3_ja.html#migration-api-v3

Developers.I.O さんの記事
https://dev.classmethod.jp/articles/devio-cafe-line/

#LINE Pay 加盟店アカウントを取得
正式なアカウントは法人または個人事業主でしか取得できないので、以下からSandboxアカウントを取得します
https://pay.line.me/jp/developers/techsupport/sandbox/testflow?locale=ja_JP

取得後のログイン画面
https://pay.line.me/portal/jp/auth/login

##Sandboxについて
LINE Pay にはテストができるSandbox環境が用意されているが、用語がごちゃごちゃしていて混乱しやすいので注意。

###Sandbox環境とproduction環境
Sandboxアカウントのチャネル情報（Channel ID, Channel Secret Key）を使っている環境のこと。
Sandbox環境で使用できるチャネル情報をテストチャネル情報という。

###Sandobxシミュレーター
これは LIEN Pay の決済シミュレーターのことで、Sandbox環境が`True`の時に決済しようとするとこれが起動する。

###加盟店MyPageの取引内訳
SandboxアカウントでSandboxシミュレーターを使って模擬決済した場合、加盟店MyPageに入ってナビバーにある「Sandbox」をクリックしたページで取引内訳が確認できる。
![スクリーンショット 2020-11-02 19.15.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242610/94e2b699-72c2-3ac3-85dc-82f653110316.png)


しかしSandbox環境でも`LINE_PAY_IS_SANDBOX = False`にしていると実際のお金が決済できてしまう（本サンプルアプリ特有のものかもしれない）。この場合は加盟店MyPageの「Sandbox」ページではなく、加盟店MyPageのホーム画面に取引内訳が記録される。

```app.py
LINE_PAY_IS_SANDBOX = False
```

さらに、Sandboxアカウントと正式な加盟店アカウントでは加盟店MyPageの表示が違う。Sandboxアカウントでは取引の一覧が見れるだけだが、正式な加盟店アカウントのMyPageではグラフが見れる。


##Herokuにデプロイしてみる
Webサービスとして運用することを想定したとき、当然どこかのサーバーにデプロイする必要があるので、今回は定番のHerokuを使います（LINE PAY API v2では決済サーバIPのホワイトリスト登録が必要だったので、固定IPではないHerokuは不向きでしたが、v3からはホワイトリスト登録不要になった）。

###Herokuで動かすにはgunicornが必要
Herokuにデプロイして`app.py`をRunした状態にしておきたい。今回はFlaskを使っている関係で実行命令ファイルProcfileにgunicornというフレームワーク？ライブラリ？が起動するように記述する。

####Flaskってなに
Pythonのミニマムフレームワーク。Rubyでいう Ruby on Rails のちっさい版。

####Procfileってなに
HeorkuデプロイしたPythonアプリの実行命令を書くファイル。

####gunicornってなに
Flaskを始めとする多くのPythonフレームワークではWSGIサーバーというものでアプリを動かすらしい。このWSGIサーバーとのやり取りをいい感じにしてくれるライブラリがgunicornっぽい。普通にプロジェクトフォルダ直下にProcfileって名前のファイル作成すればよかったはず‥。
![スクリーンショット 2020-11-04 0.34.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242610/3f985236-ad32-62c8-33e8-7b6931140167.png)

```Procfile
web: gunicorn app:app
```

###Gitコミットして Heroku に push

```terminal
$git init
$git add .
$git commit -m "initial commit"

$ heroku login --interactive
$ heroku create my-app-name #任意のアプリ名を付けてください
$ git push heroku master
```

###環境変数の設定
`.gitignore`で`.env`ファイルをgit管理から無視するようにしているため当然Herokuにpushされません（僕は知らなかった）。そのためHeroku側で`heroku config:set`で環境編集をセットしてやる必要があります。

```terminal
$heroku config:set LINE_PAY_CHANNEL_ID="xxx"
$heroku config:set LINE_PAY_CHANNEL_SECRET="xxx"

$heroku config #一応、環境変数が間違いなくセットされてるか確認しよう
```

トップページがエラーになるときは、この環境変数のセットし忘れであることが多い。

##つまづきポイント

###line-payがアップデート 
LINE Pay のライブラリである line-pay が 0.0.1 -> 0.1.0 にアップデートしていた。requirements.txtでline-payライブラリのバージョンをあげましょう。

```requirements.txt
line-pay==0.1.0
```

ちなみに僕のrequirements.txtは、なんかの理由で`pip freeze`というコマンドを使ったらしく以下のようになってました。これをHerokuにデプロイして動いているので、何か必要なことがあったのかも‥。

```requirements.txt
certifi==2020.4.5.1
chardet==3.0.4
click==7.1.2
dominate==2.5.1
Flask==1.1.2
Flask-Bootstrap==3.3.7.1
gunicorn==20.0.4
idna==2.8
itsdangerous==1.1.0
Jinja2==2.11.2
line-pay==0.1.0
MarkupSafe==1.1.1
pykintone==0.3.10
python-dotenv==0.10.3
pytz==2020.1
PyYAML==5.3.1
requests==2.22.0
tzlocal==2.1
urllib3==1.25.9
visitor==0.1.3
Werkzeug==1.0.1
```

###Request後のリダイレクトエラー
リダイレクト先がhttpssになるエラーが起きた。以下はGitコミットの差分ですが、`replace()`でhttpsに統一しようとしている部分を消したらちゃんと動きました。ただ決済時にhttp通信をすること自体がやばいので、あくまで応急処置です。

```app.py
         "redirectUrls": {
-            "confirmUrl": request.host_url.replace('http', 'https') + "confirm",
-            "cancelUrl": request.host_url.replace('http', 'https') + "cancel"
+            "confirmUrl": request.host_url + "confirm",
+            "cancelUrl": request.host_url + "cancel"
         }
```

###kintoneのアプリ名は一意に

kintoneアプリは過去に一度でも使ったことがあるアプリ名を使用すると動かない。今回kintoneアプリ名には「linepay」が設定されています。例えばこのアプリを一度削除し、もう一度テンプレートからアプリ作成したとしても本サンプルアプリは動いてくれません（トップページの表示や決済はできる）。そのためkintoneアプリの設定画面からアプリ名を過去に使用していないものに変更してやる必要があります。
![スクリーンショット 2020-11-03 23.27.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242610/15acd2e6-d52b-ce65-0815-59289a75c454.png)
![スクリーンショット 2020-11-03 23.28.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242610/9ad233f2-14d3-8bf5-0e34-6b51d0aa3ae8.png)


###その他のつまづきポイント
- account.ymlのドメイン名はサブドメインだけでよかった
- Herokuデプロイ前に一度ローカルで試す場合はPythonのバージョンが3.6以下だと動かない
- デプロイ直後（もしくは初回）に決済しようとすると Internal Server Error となる。原因不明。
- line pay sandbox 申請が最初数回エラーになった。何回かやってれば直った。


##役立ちそうなコマンド

###Herokuとのgit紐付け

```
# herokuからのクローン
heroku git:clone APPNAME

# herokuとローカルの紐付け
heroku git:remote --app APPNAME
# こっちでもOK
git remote add heroku https://git.heroku.com/AppName.git
```


###Herokuの再起動方法

```
$ heroku ps:scale web=0
# 再びスタートするときは↓
$ heroku ps:scale web=1
```

###Herokuのキャッシュ削除方法

間違ってるかも。

```terminal

$ heroku plugins:install heroku-repo
$ heroku repo:purge_cache -a appname

$ git commit --allow-empty -m "Purge cache"
$ git push heroku master
```
https://help.heroku.com/18PI5RSY/how-do-i-clear-the-build-cache

##LINE Pay v2 の実装サンプル
- Pythonによるv2の実装（Python+Heroku+Docker）
https://qiita.com/sumihiro3/items/7a8f3a59e79e8d9b7a9c

- Node.jsによるv2の実装（Node.js+Heroku）
https://qiita.com/nkjm/items/b4f70b4daaf343a2bedc
 - リッチメニューのLIFFから決済させる
https://qiita.com/ufoo68/items/a6d036d143fe4950aea3
 - Python版
https://qiita.com/keigohtr/items/161c9fb1584758ae3e35

##参考

- [ngrokが便利すぎる](https://qiita.com/mininobu/items/b45dbc70faedf30f484e)
- [pythonでローカルwebサーバを立ち上げる](https://qiita.com/okhrn/items/4d3c74563154f191ba16)
- [https://qiita.com/suzu_D/items/aaa568933e89ee029e00](https://qiita.com/suzu_D/items/aaa568933e89ee029e00)