Jex’s Note

金流串接

(最後更新 : 2016-04-28)

智付寶

介紹

智付寶有個很大的好處是提供測試環境,你可以直接去註冊,不用事先到主站註冊

這是它的測試環境註冊完後直接去開立商店,但期限只有 30 天(如果需要延長,直接寫信告知客服 cs@pay2go.com 就可以了)

接著到商店後台就會看到 API 串接金鑰了,到這裡先停,我們先做程式的部份,本篇以 Rails 實作,如果使用其他語言的朋友也沒關係,理解概念才是重點

實作導到智付寶的付款頁面

智付寶文件專區選擇 MPG API 文件,裡面串接方法寫的很清楚,我們直接看 Code :

Controller :

# 智付寶文件規定的5個欄位必須按照字母順序
chain = "Amt=#{@order.total}&MerchantID=#{智付寶MerchantID}&MerchantOrderNo=#{@order.id}&TimeStamp=#{@order.created_at.to_i}&Version=#{智付寶Version}"

# 頭先加上 HashKey,尾再加上 HashIV ,最後以 SHA-256 加密後再轉大寫
@check_value = Digest::SHA256.hexdigest("HashKey=#{智付寶HashKey}&#{chain}&HashIV=#{智付寶HashIV}").upcase
  • 智付寶Merchant ID : 在支付寶後台的商店清單會顯示商店代號,不要點到你的商店裡,裡面沒有顯示
  • 智付寶Version : 要看 API 文件的那個欄位,它會跟你說。i.e. 請帶 1.2。
  • 智付寶HashKey : 後台的商店基本資料的API串接金鑰
  • 智付寶HashIV : 後台的商店基本資料的API串接金鑰

HTML :

<form method="post" action="https://capi.pay2go.com/MPG/mpg_gateway">               <!-- 此為測試的 url, 正式為 : https://api.pay2go.com/MPG/mpg_gateway -->
  <input type="hidden" name="MerchantID" value="<%= 智付寶MerchantID %>"/>
  <input type="hidden" name="RespondType" value="JSON"/>
  <input type="hidden" name="CheckValue" value="<%= @check_value %>"/>
  <input type="hidden" name="TimeStamp" value="<%= @order.created_at.to_i %>"/>
  <input type="hidden" name="Version" value="<%= 智付寶Version %>"/>
  <input type="hidden" name="MerchantOrderNo" value="<%= @order.id %>"/>
  <input type="hidden" name="Amt" value="<%= @order.total %>"/>
  <input type="hidden" name="ItemDesc" value="TESTTESTTEST"/>                       <!-- 商品資訊,先隨便帶 -->
  <input type="text" name="CustomerURL" value="<%= customer_payments_url %>"/>
  <input type="hidden" name="Email" value="your_email@gmail.com"/>                  <!-- 付款成功時會依照 Email 欄位填的 Email 寄送付款成功信件 -->
  <input type="hidden" name="LoginType" value="0"/>                                 <!-- 0 = 不須登入智付寶會員 -->
  <button type="submit">付款</button>
</form>

送出後就會接到智付寶的付款頁面,在裡面預設有四種付款方式供選擇 Web ATM / ATM轉帳 / 超商代碼繳費 / 條碼繳費;信用卡付款(VISA金融卡)一次付清/分期付款則需要另外在後台申請開通

除了信用卡付款需要打測試用的卡號(4000-2222-2222-2222),其他都是點一點就能模擬付款成功,相當方便

只有當客戶使用非即時交易支付方式 : ATM 轉帳(VACC)、超商代碼繳費(CVS) 、條碼繳費(BARCODE)時,需要額外儲存繳費代碼;使用 WebATM 或信用卡則不需要

接收取號完成參數 - 儲存繳費代碼

前言

當客戶使用非即時交易支付方式時,雖然說繳費代碼會顯示在智付寶的頁面上,但如果使用者忘記儲存就離開,那麼它就沒辦法再得知繳費代碼了, 所以我們要有個 API 接收智付寶傳回來的繳費代碼,以便使用者在我們的網站上也可以查詢

這個 API 的 URL 需定義在傳送給智付寶表單的 CustomerURL 欄位

<input type="text" name="CustomerURL" value="<%= customer_payments_url %>"/>
實作 API

用它回傳的 CheckCode 來驗證資料是否有無被竄改,再判斷取號是否成功

resp = JSON.parse(params[:JSONData])
result = JSON.parse(resp['Result'])

# 這裡的 MerchantID 不使用 POST 過來的,使用我們自已的會更安全
chain = "Amt=#{result['Amt']}&MerchantID=#{智付寶MerchantID}&MerchantOrderNo=#{result['MerchantOrderNo']}&TradeNo=#{result['TradeNo']}"

# 頭先加上 **HashIV** 尾再加上 **HashKey** (這邊的順序與 check_value 那邊不同),以 SHA-256 加密後再轉大寫
@check_code = Digest::SHA256.hexdigest("HashIV=#{智付寶HashIV}&#{chain}&HashKey=#{智付寶HashKey}").upcase

# 檢查 CheckCode
if @check_code == result['CheckCode']
  if resp['Status'] == 'SUCCESS'          # 若取號成功,則回傳 SUCCESS。

    # Extra info
    extra_info = {
      bank_code: result['BankCode'],        # ATM 轉帳
      code_no: result['CodeNo'],            # ATM 轉帳 / 超商代碼繳費
      barcode_1: result['Barcode_1'],       # 條碼繳費
      barcode_2: result['Barcode_2'],       # 條碼繳費
      barcode_3: result['Barcode_3'],       # 條碼繳費
    }

    # 儲存以下重要資料 :
    # result['TradeNo'],
    # result['PaymentType'],
    # "#{result['ExpireDate']} #{result['ExpireTime']}",
    # resp['Result']                        # 將 ATM 轉帳/超商代碼繳費/條碼繳費 及相關訊息存起來

  end
end

接收付款成功參數 - 將訂單改為已付款

前言

智付寶提供兩種方式接收參數,你需要去設定前景(Return URL)背景(Notify URL), 但我不知道如果超商付款的話是不是也會戳 Return URL? 因為超商付款就沒有在網站上了, 所以我把 Return URL 只做為線上付款成功後導向自已網站成功訊息的頁面,換句話說 Return URL 可有可無沒關係, 而 Notify URL 當作主要確認客戶是否成功付款的 API, 當智付寶收到款項後會戳這個 API,所以一定要設定它

  • 先在智付寶後台設定好這兩個 URL, 注意!! 這兩個 Route 的 method 都要用 POST
  • Rails 需要在接口的 controller 加上 : skip_before_action :verify_authenticity_token (以便通過防 CSRF Token 驗證)
實作 API

用它回傳的 CheckCode 來驗證資料是否有無被竄改,再判斷付款是否成功

resp = JSON.parse(params[:JSONData])
result = JSON.parse(resp['Result'])

# 這裡的 MerchantID 不使用 POST 過來的,使用我們自已的會更安全
chain = "Amt=#{result['Amt']}&MerchantID=#{智付寶MerchantID}&MerchantOrderNo=#{result['MerchantOrderNo']}&TradeNo=#{result['TradeNo']}"

# 頭先加上 HashIV,尾再加上 HashKey (這邊的順序與 check_value 那邊不同,要注意),以 SHA-256 加密後再轉大寫
@check_code = Digest::SHA256.hexdigest("HashIV=#{智付寶HashIV}&#{chain}&HashKey=#{智付寶HashKey}").upcase

# 檢查 CheckCode
if @check_code == result['CheckCode']
  if resp['Status'] == 'SUCCESS'            # 若交易付款成功,則回傳 SUCCESS

    if 此訂單未付款成功
      # 將訂單改成付款成功,並且把一些重要的回傳資料存起來 :
      # result['PayTime']
      # result['TradeNo']
      # result['PaymentType']
      # result['EscrowBank']
      # resp['Result']                      # 將其他參數存下來
    end

  else
    # 若交易付款失敗,則回傳錯誤代碼。  代碼對應請參考文件
  end
end

要注意如果這個 API 被重覆 POST 也不能影響你的資料

補充

測試環境

在智付寶的測試環境下,當使用非即時性支付(e.g. 超商代碼繳費),是有可能會先收到 Notify URL(付款成功通知),再收到 Customer URL(取號成功通知),這並不符合常理 (我自已測都是先收到 Notify URL 才收到 Customer URL), 所以我有特別去跟技術部的客服確認一下,確實是會這樣,但在 Production 環境就會是正常了 (會先收到 Customer URL 才收到 Notify URL)。

產生 Barcode 條碼

顯示非即時性交易傳回來的 barcode,可以使用智付寶的資源,改最後面的 barcode_text 值即可:

https://api.pay2go.com/API/barcode_display/get_barcode_img?barcode_text=test1

顯示如下 :

barcode.JPG

Comments