Zeals TECH BLOG

チャットボットでネットにおもてなし革命を起こす、チャットコマース『Zeals』を開発する株式会社Zealsの技術やエンジニア文化について発信します。

LINEトーク上でのLINE Pay決済を史上初のサービス化まで持っていった話

f:id:dainiizawa:20200221191121j:plain

はじめに

こんにちは! ZEALSで主にRailsReactを書いている中村です!

今回は昨年3月にLINE Payによるチャット内決済を導入したのでその時のお話をしていこうと思います!

リリース当初は結構バズったので当時の記事を貼っておきます!

prtimes.jp

LINE Payの機能

弊社で導入したLINE PayはV2です(現在はV3が最新)。

V2では以下のような決済機能があります。

一般決済機能

決済をリクエストする度にLINE Pay会員がLINE Payにアクセスし、支払い手段を選択し決済パスワード を確認して取引を行う機能

継続決済機能

加盟店で決済が必要なタイミングにLINE Pay会員の操作なく加盟店サーバーとLINE Payサーバー間で決 済を行う機能
 

ZEALSでは今回一般決済を使用したので、一般決済についてご紹介しつつZEALSではどのように実装したかご紹介します。

LINE Pay API V2の公式リファレンス

https://pay.line.me/jp/developers/apis/onlineApis?locale=ja_JP

LINE Payを試して見たい方はsandbox用意されているのでぜひ使用してみてください! pay.line.me

DB

決済に関する情報を保存するためのテーブルを作成しました。
(全てのカラムを書くことは割愛させて頂きます。)

カラム 制約 コメント
user_id references null:false, foreign_key: true userのidを保存する
transaction_id string null: false 決済予約時に発行された取引番号(19桁)


transaction_idは最初bigint型にしていたのですが、
mysqlで対応できる最大値が9223372036854775807までで、対応仕切れなかったため
string型に変更しました。
開発途中で気づくことができて本当に良かったです。。。笑

またreturn_code・return_messageはLINE Pay APIで用意されているものを
そのまま保存します。
 

決済までの流れ

決済までの流れは下記のようになります。

f:id:nakayuu07:20200219222423p:plain 写真引用: https://qiita.com/nkjm/items/b4f70b4daaf343a2bedc

ここでいうSPがZEALSになります。

写真にも書いてるように、一般決済を行う際には下記の2種類のAPIを叩きます
- RESERVE_API(決済予約)
- CONFIRM_API(決済確定)

まずは、Bot内の会話で商品の紹介をします。

f:id:nakayuu07:20200220203057p:plain

『ご購入はこちらから』をタップした際に、弊社のAPIにリクエストを飛ばすように設定しています。

このアクションでRESERVE_API(決済予約)を叩くために必要なヘッダー情報パラメータを準備し、
実際にRESERVE_APIを叩きます。

  • RESERVE_APIのURL
Sandbox: 'https://sandbox-api-pay.line.me/v2/payments/request'
Real: 'https://api-pay.line.me/v2/payments/request'
  • 必要なヘッダー情報
['Content-Type']:  application/json
['X-LINE-ChannelId']: 各店舗のchannelID
['X-LINE-ChannelSecret']: 各店舗のChannelSecret
  • 必要なパラメータ
'productName': 商品名, 
'amount': 決済金額, 
'currency': 通貨('JPY', 'USD'), 
'orderId': 加盟店で管理するユニークなID,
'confirmUrl': LINE Pay で決済承認(決済方法選択、パスワード認証)後に遷移するURL
  • 今回の決済で利用しているその他のパラメーター
'productImageUrl': 商品の画像

商品名・決済金額・商品の画像はyamlファイルで管理しており、そこから取得しています。

  • 実際にRESERVE_APIを叩いた後のレスポンス
{
  "returnCode" :"0000",
  "returnMessage" : "OK",
  "info" : {
    "transactionId" : 123123123123,
    "paymentUrl" : {
      "web" : "http://web-pay.line.me/web/wait?transactionReserveId=blahblah",
      "app" : "line://pay/payment/blahblah"
    }
  }
}

レスポンスで返ってきたpaymentUrlをユーザーに送ります。

ユーザーがリンクをタップすると下記の画面に飛びます。

f:id:nakayuu07:20200220203059p:plain

この画面の『支払う』ボタンを押すと、RESERVE_APIを叩く際にパラメータに含めたconfirmUrlに遷移します。

このconfirmUrlに弊社のAPIのリンクを仕込んでおり、ここのアクションでLINE PayのCONFIRM_APIを叩きます。

  • CONFIRM_APIのURL
Sandbox: "https://sandbox-api-pay.line.me/v2/payments/{ transactionId }/confirm"
Real: "https://api-pay.line.me/v2/payments/{ transactionId }/confirm"

//transactionIdはRESERVE_APIを叩いた時のレスポンスに含まれる
  • 必要なヘッダー情報
['Content-Type']:  "application/json"
['X-LINE-ChannelId']: "各店舗のchannelID"
['X-LINE-ChannelSecret']: "各店舗のChannelSecret"
  • 必要なパラメーター
'amount': 決済金額, 
'currency': 通貨('JPY', 'USD')
  • レスポンスの例
{
  "returnCode" : "0000",
  "returnMessage" : "OK",
  "info" : {
    "orderId" : "order_210124213"
    "transactionId" :20140101123123123,
    "payInfo" : [
       {"method" : "BALANCE", "amount" : 10},
       {"method" : "DISCOUNT", "amount" : 10}
     ]
  }
}

ここまで来ると決済は完了です。

決済終了後にLINE上からサンクスメッセージを送って終了となります。

f:id:nakayuu07:20200220182308p:plain

大変だった点

チャット内決済の実例が少なく、APIの仕様書を読みながら探り探り実装しました。
そのため、APIの仕様書を見てどの決済システムを使って
どのようにプロダクトに落とし込むのかを考えるのがすごく大変でした
APIの設計書がスラスラ読めるようになりたいです。。。

終わりに

最後まで見ていただきありがとうございます!

最新のV3のAPIを試してみたいと思います!

よければ皆さんも是非LINE Pay APIを試してみてください!

Zealsでは、発見した課題をワクワクしながら技術で解決するエンジニアを求めています!ご興味がある方は、ぜひ下記募集からご応募ください!

hrmos.co