D-2.Line_pay_api 串接(三) Rails 串接

文章目的只有练习串接requset部分,不是实作。
实作这样搞,一定会出事。

1.建立专案及productsorder

建议安装gem "figaro"

$ rails new project_name
$ rails g scaffold product name price:integer
$ rails g model order
$ rails g controller orders
#seed
Product.create(
  name: "测试商品",
  price: 500
)

$ rails db:create db:migrate db:seed

简易设定路径。

  root "products#index"
  resources :products
  resources :orders

2.建立订单。

这边直接在product#index选数量送出

  <%= form_tag orders_path, method: :post do %>
    <%= hidden_field_tag(:name, @product.name) %>
    <%= hidden_field_tag(:price, @product.price) %>
    <%= select_tag(:quantity, options_for_select([*1..4])) %>
    <%= submit_tag "送出", name: nil, class: "btn btn-primary" %>
  <% end %>

将昨天的Ruby测试文件直接功能化。

订单body部分。

def order_id
  "order#{SecureRandom.uuid}" #建议自制能不重复且独立的编号就好。
end

def packages_id
  "package#{SecureRandom.uuid}" #建议自制能不重复且独立的编号就好。
end

def amount
  params[:quantity].to_i * params[:price].to_i
  #因为订单简单化,所以body的两个amount共用。
end

def body
  @body = { amount: amount,
           currency: "TWD",
           orderId: order_id,
           packages: [ { id: packages_id,
                         amount: amount,
                         products: [ {
                         name: params[:name],
                         quantity: params[:quantity].to_i,
                         price: params[:price].to_i } ] } ],
           redirectUrls: { confirmUrl: "http://127.0.0.1:3000/confitmUrl",
                           cancelUrl: "http://127.0.0.1:3000/cancelUrl" } }
end

当然如果order有开较多栏位,也可订单建立後save,也可以重复使用资料,才是较好作法。


订单header部分。

private
def header_nonce
  @nonce = SecureRandom.uuid
end

def header
    get_signature()
    @header = {"Content-Type": "application/json",
          "X-LINE-ChannelId": ENV["line_pay_ChannelID"],
          "X-LINE-Authorization-Nonce": @nonce,
          "X-LINE-Authorization": @signature }
end

def get_signature
  secrect = ENV["lines_pay_ChannelSecret"]
  signature_uri = "/v3/payments/request"
  message = "#{secrect}#{signature_uri}#{@body.to_json}#{@nonce}"
  hash = OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), secrect, message)
  @signature = Base64.strict_encode64(hash)
end

header_noncebodyheader因为要确保加密资料都正确,所以这三项都是before_action用实体变数固定。

  before_action :header_nonce, only:[:create]
  before_action :body, only:[:create]
  before_action :header, only:[:create]

最後post部分,其实跟昨天长的的几乎一样。

def create
  response = JSON.parse(get_response.body)
  if response["returnMessage"] == "Success."
    redirect_to response["info"]["paymentUrl"]["web"]
    #这边做直接转址。
  else
    puts response
    #这个没意义,应该要做怎麽处理错误,这边只做印出观察错误资讯。
  end
end

private
def get_response
  uri = URI.parse("https://sandbox-api-pay.line.me/v3/payments/request")
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true
  request = Net::HTTP::Post.new(uri.request_uri, @header)
  request.body = @body.to_json
  response = http.request(request)
end

基本上这样就可以发出正确请求,取得如昨天的回传讯息,自动转址到付款画面。
当然正确文件撰写不会这样操作,order是重要文件,不会什麽栏位都没开,还有直接把逻辑都写在controller应该会被宰掉,但只要开头会了,一切就都好说。建立request一开始有功能细分好,後面的confirm与其他都几乎是照抄,注意body的不同及回传的重要讯息就好。

Line_pay_api简单练习就到这边啦!

  • 回传资料中transactionIdregKey等是一定要纪录的,未来串接其他部分都会用到,另外sandbox没有regKey回传值。

  • request apibody有一个选填选项options.payment.capture是让你选择confirm时自动确认或要卖家手动确认,但确认完後流程一样,但实作上就会是分歧点。
    我是卖家我当然设定自动确认啦!要退款等之後再说 XD!!!


<<:  Day28 - 铁人付外挂部署与发行(一)- 建立测试机

>>:  【Day28】React Query 简易说明及使用 (´∀`)

[Day 22] Leetcode 437. Path Sum III (C++)

前言 今天这题也是TOP 100 Liked中的题目─437. Path Sum III,是昨天最後...

day4 : k8s建置(下)

昨天成功的用terraform创建gcp的instance出来,也透过terraform自动的把in...

Day 13-制作购物车系统之安装及资料夹结构(二)

先来説说当在专题开启终端机後,如何在终端机自由切换专题前、後端资料夹。 -$cd frontend:...

停下来,回头望,比较快

由於近期的事项开始变多,自己也开始变得比较焦虑,像是需要进行海外业务的开发、社群活动的经营、程序码架...

[Day4]专案始动-续(前端篇)

今天我们继续来设定我们的架构,首先先把index.js的预设内容给删除掉。 透过检视原始码,可以取得...