LINEPayのAPI、決済予約実行時のDB接続に関しての試行錯誤をして、なんとか決済ができるようになりました。

【LINEPayビギナー】APIコールの後のDB接続と例外時の表示に悩む

しかし、正常系ルートばかりに気を取らていると、一歩前の落とし穴に気がつかないものですね。

LINEPayでの処理順をもう一度おさらいすると、

  1. 自サーバーから決済予約APIをコールし、決済URLを取得
  2. ユーザーが決済URLへ進むと、LINEPayが起動、ユーザーが決済承認
  3. 決済承認された後、自サーバーの任意のURLへ移動、そこで決済実行のAPI(Confirm API)にアクセスして決済完了

です。

この処理順、”決済に必要な情報を確保して、かつ売上情報に必要な情報を確保しておく”という視点で整理すると、1.の段階でのみ、それが可能なことが分かります。
2.以降は外部サービス側へ主導権が移り、戻ってきた時も決済の取引番号というような、外部サービスと自サーバー内のデータをつなげるデータキー的なものしか取得はできません。
1.の段階で、「とにかく必要なものはとっとけ!」なのです。

1.の段階での情報確保し、3.の決済完了まで正常に完了、DBを覗くと、設計通りにシステム上で”有効”となっている売上情報も予定通りに入っていて、一安心。
なんて思っていた時間もありました!

2.の段階で発生しうるユーザーによる”決済承認前のキャンセル”行動を、すっぱり、忘れていたんですなー。

2.で「LINEPayが起動」しますので、起動したアプリ上にてユーザーが「やっぱりやーめた!」とキャンセルできるタイミングがあります。(2回ほど。)
1.はあくまでも決済予約。いかにデータが取れるとは言え、ここで取ったデータは”仮”状態。ここで”有効”してはアカンのです。
私、うっかり1.の段階で”有効”にしちゃっていたので、テストしている時にLINEPay側の決済状況とシステム上の有効な売上情報の件数がマッチせず、「あれ?」となりました。
1.の段階では仮扱い、3.で有効にする処理を追加して無事実装完了でございます。

なお、2.のキャンセル発生もイベントとして捕捉は可能です。
決済予約のParameterには”cancelUrl”を設定することをお勧めします。
例えば、こんな感じです。

	      // オプション作成
	      const options = {
	        productName: data.name, // 商品名
	        amount: data.total, // 決済額
	        currency: "JPY", // 通貨
	        orderId: uuid, // 注文番号
	        // LINEPayから追加Parameterはないので、
                //キャンセル処理で必要なデータは先にクエリパラメータでつけておくこと
                cancelUrl: '/pay/cancel' + '?orderId='+ uuid ,
               /* 後は各システムに合わせて設定するParameter */
	     }

今回の場合は、注文番号からキャンセル発生した売上情報をDBから再検索して、”仮でキャンセル発生”状態にしました。
仮扱いのままでいいではないか?という指摘もありそうですが、これには理由があります。
マーケティング向けのデータ作りとか。
キャンセル以外で途中処理が落ちた?的な調査が発生した場合の追跡データ作りとか。
いわゆるデータのステータスのコントロールを細かくしておくだけで、後からできることが増えるからです。