D-3.Line_pay_api 串接(二) V3 Request API

单纯以node.jsRuby.rb档案测试。

V3订单内容。

参考官方文件,只列出必填。

{
  "amount" : "与V2同",
  "currency" : "与V2同",
  "orderId" : "必须 uniq 不一定要用UUID",
  "packages" : [ //与V2相比,明显较像完整购物车。
    {
      "id" : "uniq of this package 不一定要用UUID",
      "amount" : "Integer 需与外面的amount同值",
      "name" : "选填 但不能取代id",
      "products" : [
        {
          "id" : "选填 商家商品ID",
          "name" : "商品名",
          "quantity" : "Integer 数量",
          "price ": "Integer 单价"  //需注意自己程序码金额是否都对得上。
        }
      ]
    }
  ],
  "redirectUrls" : {
    "confirmUrl": "使用者授权付款後,跳转到该商家URL",
    "cancelUrl" : "使用者通过LINE付款页,取消付款後跳转到该URL"
  }
}

其它关於checkout选项如昨日所说,有兴趣可以去官方文件看。

V3'Headers'。

红色部份即为不同处。
https://ithelp.ithome.com.tw/upload/images/20210927/20135887esjIpHyjqt.png

X-LINE-Authorization-Nonce : UUID(1 or 4) or timestamp(时间戳)
UUID: Universally Unique Identifier,通用唯一辨识码。
对於不是本科生的我来说,就是很难重复的一组随机生成密码。

X-LINE-Authorization : HMAC Base64 签章,HMAC加密演算法一种,非可逆。

Base64
The Base64 Content-Transfer-Encoding is designed to represent arbitrary sequences of octets in a form that need not be humanly readable.

以下是所需内容。
Signature = Base64(HMAC-SHA256(Your ChannelSecret, (Your ChannelSecret + URI + RequestBody + nonce)))
v3最难的部分,解决後就简单了。

Your ChannelSecret : your Channel Secret Key。
URI : 我们要先测Request,所以是"/v3/payments/request"
RequestBody : 订单内容。
nonce : UUID

Your ChannelSecret:只要KEY就好。

node.js档案内容。

const axios = require('axios') //这边作为发送请求用,请记得安装套件。
const uuid = require('uuid4')  //生成uuid套件,请记得安装套件。
const crypto = require('crypto-js') //加密套件,请记得安装套件。


let key = 'your ChannelSecret'
let nonce = uuid()
let uri = '/v3/payments/request'
let body = {
  amount : 500,
  currency : 'TWD',
  orderId : 'order20210921003',
  packages : [
    {
      id : "20210921003",
      amount : 500,
      products : [
        {
          name : "买不起的iphone13pro",
          quantity : 1,
          price : 500
        }
      ]
    }
  ],
  redirectUrls : {
    confirmUrl: "http://127.0.0.1:3000/confitmUrl",
    cancelUrl : "http://127.0.0.1:3000/cancelUrl"
  }
}

let encrypt = crypto.HmacSHA256(key + uri + JSON.stringify(body) + nonce, key)
//这边蛮特别的,与官方文件相反,应该是此套件的原因。
let hmacBase64 = crypto.enc.Base64.stringify(encrypt)

let configs = {
  headers: {
    'Content-Type': 'application/json',
    'X-LINE-ChannelId': your ChannelId,
    'X-LINE-Authorization-Nonce': nonce,
    'X-LINE-Authorization': hmacBase64
  }
}

axios.post('https://sandbox-api-pay.line.me/v3/payments/request', body, configs).then(res => {
  console.log(res.data)
})
$ node test

正确就会得到如V2与在postman上一样的讯息,以web来完成一样动作,一样在後台就可以看到这笔资讯了喔。

{
  returnCode: '0000',
  returnMessage: 'Success.',
  info: {
    paymentUrl: {
      web: 'https://sandbox-web-pay.line.me/web/payment/wait?transactionReserveId=UldUZmpTZ2krMjVZQUxlQWtBZTZEemVGeXh2ZXNvWlM1SUVHMklsRWt5NURnU2xXTUU5VHNJNDA4SzVIL29uTQ',
      app: 'line://pay/payment/UldUZmpTZ2krMjVZQUxlQWtBZTZEemVGeXh2ZXNvWlM1SUVHMklsRWt5NURnU2xXTUU5VHNJNDA4SzVIL29uTQ'
    },
    transactionId: 2021092100690434300,
    paymentAccessToken: '995830200615'
  }
}

Ruby部分。

require 'securerandom'
require 'base64'
require 'OpenSSL'
require 'net/http'
require 'uri' #在irb不用引入。
require 'json'
#上面都为内建,Rails内都不用引入。

secrect = "请换成你的key"
nonce = SecureRandom.uuid
signature_uri = "/v3/payments/request"
body = {
  amount: 500,
  currency: "TWD",
  orderId: "order20210921005",
  packages: [
    {
      id: "nauosika0105",
      amount: 500,
      products: [
        {
          name: "买不起的iphone13pro",
          quantity: 1,
          price: 500
        }
      ]
    }
  ],
  redirectUrls: {
    confirmUrl: "http://127.0.0.1:3000/confitmUrl",
    cancelUrl: "http://127.0.0.1:3000/cancelUrl"
  }
}

#由於之後会重复利用,乾脆建立方法了。
def get_signature(secrect, signature_uri, body, nonce)
  message = "#{secrect}#{signature_uri}#{body.to_json}#{nonce}"
  hash = OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), secrect, message)
  Base64.strict_encode64(hash)
end

signature = get_signature(secrect, signature_uri, body, nonce)

header = {"Content-Type": "application/json",
          "X-LINE-ChannelId": "请换成你的测试ID", #node是数字,Ruby用字串。
          "X-LINE-Authorization-Nonce": nonce,
          "X-LINE-Authorization": signature
}

uri = URI.parse("https://sandbox-api-pay.line.me/v3/payments/request")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true #一定要开喔,使用https传输。

request = Net::HTTP::Post.new(uri.request_uri, header)
request.body = body.to_json
#这两行是带资料进去,可以发现跟js很不同。

response = http.request(request)
puts response.body
#发送请求及印出。
$ ruby filename.rb

ok!,但如回传是1106或其他就看一下是哪边没填写正确吧。

串API有一件事很单纯,就是它要什麽,我们给什麽,还有我们要把它回传的抓出来。
单纯以Ruby档练习後,明天就用Rails串接看看request部分。


补充:
*觉得用net/http与Ruby本身的加密程序较罗唆,也是有httparty与其他加密gem可以使用。

*nonce改用时间戳较适当,最好是uuid+时间戳。时间戳与uuid产生所花时间,时间戳较快一点点点。

*Net::HTTPRuby的函式库之一,主要在建构HTTP使用者代理,若只是单纯只需要GET其实用不到这一个函示库。
更多用途请看文件: https://ruby-doc.org/stdlib-3.0.2/libdoc/net/http/rdoc/Net/HTTP.html


<<:  大数据平台:分散式计算

>>:  Day-13 ConstraintLayout

爬虫怎麽爬 从零开始的爬虫自学 DAY22 python网路爬虫开爬-4翻页继续爬

前言 各位早安,书接上回我们学会透过发送 cookie 来绕过18岁守门员,今天我们要学习如何翻页继...

菜鸟新人第七十五天

当小菜渣也好一阵子了, 来记录一下 铁人赛结束後,也顺利的录取心目中满意的公司 十一月报到後就开始当...

[Day 16 - 小试身手] 用HTML、CSS、JS打造个人网站 (3)

在上一篇:用HTML、CSS、JS打造个人网站 (2),完成了网页的所有内容,接下来的工作就是让网...

[DAY1]什麽是聊天机器人?

聊天机器人主要分为两种类型: 以工作为导向 (宣告式) 的聊天机器是专注於执行一项功能的单一用途程序...

DAY13 - [JS] 重新改写ToDoList

今日文章目录 需求说明 事前准备 重点说明 参考资料 DAY12练习ToDoList分类项目,遇到...