前言

今天來聊聊「金流」,現今網路購物盛行,線上付款已經是常態,那麼要如何串接在自己的網站呢?下面我們來快速介紹一下。

金流服務提供商

所謂的金流服務商是指介於消費者和商家之間,處理線上金流交易的第三方機構,主要可分為「銀行」以及「第三方金流公司」,第三方金流公司中有「第三方支付」、「電子支付」和「行動支付」。

  • 銀行:各大銀行的線上收單服務。
  • 行動支付:簡單說就是透過行動裝置來進行付款的服務,像是:「Apple Pay」、「Google Pay」和「Samsung Pay」。
  • 第三方支付:僅提供代收付功能的就是第三方支付,在台灣較常見的是「藍新科技」、「綠界科技」、「紅陽科技」和「PayPal」。
  • 電子支付:電子支付除了能提供第三方支付代收付功能,還可以提供轉帳儲值的功能,例如:「橘子支付 GAMA PAY」、「街口支付」。

在串接的時候我們可以選擇第三方支付或是銀行,通常我們會以第三方支付為首選,一來相較於銀行整合的功能較多並且有一些額外的加值型服務,例如:物流服務、電子發票,串接第三方之支付以及實體刷卡等,另外就是申請的速度較快,銀行會因為需要串接多項功能需要進行跨部門申請,流程上會相當耗時,並且針對商家會有一些條件限制才能申請,對於中小店家來說第三方支付的優勢還是比較得出來的。

串接

雖然在 WP 中有提供一些外掛來串接金流,像是綠界和藍新也有提供 SDK 給 WooCommerce 購物車模組使用,但並不是所有的金流服務都有像這樣提供外掛套件來串接,所以在這邊分享一個簡單的方式來實作。

  1. 準備 helper.php,這邊是一些輔助串接金流商提供的文件,所需要的一些加解密方法。

    // HashKey AES 加解密方法
    function create_mpg_aes_encrypt ($parameter = "" , $key = "", $iv = "") {
        $return_str = '';
        if (!empty($parameter)) {
            $return_str = http_build_query($parameter);
        }
        return trim(bin2hex(openssl_encrypt(addpadding($return_str), 'aes-256-cbc', $key, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv)));
    }
    function addpadding($string, $blocksize = 32) {
        $len = strlen($string);
        $pad = $blocksize - ($len % $blocksize);
        $string .= str_repeat(chr($pad), $pad);
    
        return $string;
    }
    
    // HashKey AES 解密方法
    function create_aes_decrypt($parameter = "", $key = "", $iv = "") {
        return strippadding(openssl_decrypt(hex2bin($parameter),'AES-256-CBC', $key, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv));
    }
    
    function strippadding($string) {
        $slast = ord(substr($string, -1));
        $slastc = chr($slast);
        $pcheck = substr($string, -$slast);
        if (preg_match("/$slastc{" . $slast . "}/", $string)) {
            $string = substr($string, 0, strlen($string) - $slast);
            return $string;
        } else {
            return false;
        }
    }
    
    // HashIV SHA256 加密方法
    function SHA256($key="", $tradeinfo="", $iv=""){
        $HashIV_Key = "HashKey=".$key."&".$tradeinfo."&HashIV=".$iv;
        return $HashIV_Key;
    }
  2. 首先準備商品頁面 product.html,使用連結的方式導轉到付款中繼頁面。

    <!DOCTYPE html>
    <html>
        <head>
        <meta charset="UTF-8">
        <title>產品</title>
    </head>
    <body>
        <div>
            <h2>產品名稱</h2>
            <button type="button" onclick="location.href='pay.php?type=newebpay'">送出</button>
        </div>
    </body>
    </html>
  3. 準備付款中繼頁 pay.php,這邊可以針對一些金流的服務設定參數,以下是參考藍新的文件所使用的參數,這裡為了方便就直接 hard code。

    <?php
    require_once('helper.php');
    // 藍新測試 API url
    $URL = "https://ccore.newebpay.com/MPG/mpg_gateway";
    $VER = '1.5';
    $MerchantID = "商家代號"; // 請修改
    $HashKey = "API HashKey"; // 請修改
    $HashIV = "API HashIV"; // 請修改
    
    $trade_info_arr = array(
        'MerchantID' => $MerchantID,
        'RespondType' => 'JSON',
        'TimeStamp' => 1485232229,
        'Version' => $VER,
        'MerchantOrderNo' => 'A0001', // 訂單編號
        'Amt' => "100", // 產品價格
        'ItemDesc' => "產品名稱", //
    
        // 請修改 {your-domain}
        'ReturnURL' => "http://{your-domain}/thanks.html", // 付款完成後,要返回商店頁面
        'NotifyURL' => "http://{your-domain}/atm_notify.php", //付款通知的頁面
        'CustomerURL' =>"http://{your-domain}/ccard_notify.php", //商店取號的頁面
        'ClientBackURL' => "http://{your-domain}" , // 若取消付款,要返回商店頁面
        'ExpireDate' => date("Y-m-d" , mktime(0, 0, 0, date("m"),date("d")+3 ,date("Y")))
    );
    
    if (isset($_GET['type']) == 1 && $_GET['type'] == "newebpay") {
        $TradeInfo = create_mpg_aes_encrypt($trade_info_arr, $HashKey, $HashIV);
        $SHA256 = strtoupper(hash("sha256", SHA256($HashKey, $TradeInfo, $HashIV)));
        $html = '<!DOCTYPE html>';
        $html .='<html><head><meta charset="utf-8"></head><body>';
        $html .='<form name="newebpay" id="newebpay" method="post" action="'.$URL.'" style="display:none;">';
        $html .='<input type="text" name="MerchantID" value="'.$MerchantID.'" type="hidden">';
        $html .='<input type="text" name="TradeInfo" value="'.$TradeInfo.'"   type="hidden">';
        $html .='<input type="text" name="TradeSha" value="'.$SHA256.'" type="hidden">';
        $html .='<input type="text" name="Version"  value="'.$VER.'" type="hidden">';
        $html .='</form>';
        $html .='<script type="text/javascript">document.getElementById("newebpay").submit();</script>';
        $html .='</body></html>';
        echo $html;
    }
    ?>

    在串接 API 的時候,通常自己站台的 domain 是不允許 localhost 和 ip 的方式,可以使用 no-ip 或 ngrok 這類的服務來建立一個測試的 domain。

結語

以上的重點就在於進入中繼頁面網址的連結參數,並透過 javascript submit 來進行 API 的串接,利用這樣的方式就可以透過參數來管理多個金流的串接了。