[LINE bot 好好玩 30 天玩轉 LINE API] 第 24 天:LINE Pay 實作

2020 11th 鐵人賽 LINE

本文同步刊載於 iT 邦幫忙第11屆鐵人賽:[LINE bot 好好玩 30 天玩轉 LINE API] 第 24 天:LINE Pay 實作

前言

昨天講解了如何使用,依造慣例今天就把它實作成程式吧!

實作 LINE Pay

LINE Pay reserve API

https://ithelp.ithome.com.tw/upload/images/20191009/20117701Yyik87xXud.png
  1. LINE Pay 用戶從商家的訂購單中選擇一種付款方式。
  2. 商家呼叫 LINE Pay 的「付款 reserve API」來建立付款 reserve 資訊和取得交易編號及 “paymentUrl”,其中的交易編號為付款 confirm 時的必要資訊。
  3. 商家呼叫在步驟 b 中收到的 paymentUrl (由 LINE Pay 提供)。
  4. LINE Pay 用戶經由通路網頁登入1確認是否為 LINE 用戶。
  5. 當用戶成功登入 LINE 後,LINE Pay 伺服器推送付款請求到 LINE。
  6. LINE 用戶在 LINE 應用程式中收到付款請求後,會移動至付款畫面。

以上為官方文件的說明
文件說明的 1 代表著我們應該選擇一般付款或是自動付款,而 2 就是我們主要需要實作的 API,3 在我們的範例中是直接呼叫我們實作的 API 來達成這件事情,通常來說應該是一個付款的按鈕,4、5、6 是 LINE Pay 實作的流程

實作 LINE Pay reserve API

我們製作一支 API 他的 URL 是 http://localhost:3000/line/pay/payments/request,這邊有一個地方比較特別我們用了 uuid 的 package 來做一個亂數的 orderId,如果是真的串接部分通常會是訂單編號,不過這邊為了大家測試方便所以用了這個做法

const uuidv4 = require('uuid/v4');

router.get('/payments/request', async function (req, res, next) {
  const payments = await rp({
    method: 'POST',
    uri: `https://sandbox-api-pay.line.me/v2/payments/request`,
    json: true,
    headers: {
      'X-LINE-ChannelId': process.env['LINE_PAY_CLIENT_ID'],
      'X-LINE-ChannelSecret': process.env['LINE_PAY_CLIENT_SECRET']
    },
    body: {
      "amount": 100,
      "productName": "ithome",
      "productImageUrl": "https://ithelp.ithome.com.tw/images/ironman/11th/event/kv_event/bear-fly.svg",
      "confirmUrl": process.env['LINE_PAY_CONFIRM_URL'],
      "orderId": uuidv4(),
      "currency": "TWD"
    }
  });

  res.send(payments);
});

實作完之後我們就可以使用它了,使用後出現如下:

{
  "returnCode": "0000",
  "returnMessage": "Success.",
  "info": {
    "paymentUrl": {
      "web": "https://sandbox-web-pay.line.me/web/payment/wait?transactionReserveId=N1cwak5XaHZHNmtZaDV2b0VKeGQvWC9GRW91V0ViQ1FTcnc5RllldUZtOEdBaWROcEFzZ2JrN2J1d255MG8yRR",
      "app": "line://pay/payment/N1cwak5XaHZHNmtZaDV2b0VKeGQvWC9GRW91V0ViQ1FTcnc5RllldUZtOEdBaWROcEFzZ2JrN2J1d255MG8yRR"
    },
    "transactionId": 2019100800069395700,
    "paymentAccessToken": "630574543066"
  }
}

點下我們的付款網址

https://ithelp.ithome.com.tw/upload/images/20191009/20117701hfuj8BI28g.png

如下就是上面說的步驟 4

登入完後的付款頁面

https://ithelp.ithome.com.tw/upload/images/20191009/20117701lzxnF7jyeh.png

如下為步驟 6

付款畫面 – 付款完成

https://ithelp.ithome.com.tw/upload/images/20191009/20117701fi4HkbODzG.png
  1. LINE Pay 用戶在 LINE Pay 付款畫面上選擇付款方式並輸入密碼。
  2. LINE Pay 儲存付款方式資訊,並將付款狀態變更為已授權。
  3. LINE Pay 用戶檢查付款資訊畫面。
  4. 當等待付款畫面中的交易變成可付款時,用戶會在付款已預約時被重新導向到從商家處收到的”confirmUrl”。
  5. 商家呼叫付款 confirm API,完成付款。.

如上 1、2、3 都是使用者在 LINE 上面的行為,這邊就不多做說明,由 4 開始說明,當用戶點下 PAY NOW 我們會收到 confirmUrl 的 request,這邊就是我們要實作的地方,5 呼叫 confirm API 也是

實作付款畫面 – 付款完成

在這邊實作一隻 callback API 實質就是 confirmUrl 會呼叫的 API,如下可以看到我們的 req.query.transactionId 會收到 transactionId 我們用它去完成 confirm API

router.get('/callback', async function (req, res, next) {
  const payments = await rp({
    method: 'POST',
    uri: `https://sandbox-api-pay.line.me/v2/payments/${req.query.transactionId}/confirm`,
    json: true,
    headers: {
      'X-LINE-ChannelId': process.env['LINE_PAY_CLIENT_ID'],
      'X-LINE-ChannelSecret': process.env['LINE_PAY_CLIENT_SECRET']
    },
    body: {
      "amount": 100,
      "currency": "TWD"
    }
  });

  res.send(`LINE pay transactionId: ${req.query.transactionId}</br> Confirm: ${JSON.stringify(payments)}`);
});

所以我們就來按下 PAY NOW 吧!
這時候會看到我們的頁面回傳了資訊

LINE pay transactionId: 2019100800069395710
Confirm: {
  "returnCode": "0000",
  "returnMessage": "Success.",
  "info": {
    "transactionId": 2019100800069395700,
    "orderId": "cacaadf2-2e72-4c62-959b-ff911a8c8293",
    "payInfo": [
      {
        "method": "CREDIT_CARD",
        "amount": 100,
        "maskedCreditCardNumber": "************1111"
      }
    ]
  }
}

結語

以上就是一個簡單的 LINE Pay 付款流程與 API 開發,如果想要看更詳細的資料可以直接參考官方的 API 文件,裡面有更詳細的說明!