「綠界(Ecpay)」金流介接教學

一、介紹

綠界科技Ecpay是第三方支付,提供金流、信用卡代收代付的服務。

二、開發工具

  • 整合開發環境:Visual Studio 2019
  • 語言:C#
  • .net framework:4.6.2

三、綠界測試資訊

此教學只提供綠界測試環境,正式環境請參考完整版-全方位金流API技術文件

1. 測試後台

  • 網址:https://vendor-stage.ecpay.com.tw
  • 特店編號:2000132
  • 廠商管理後台登入帳號:stagetest1234
  • 廠商管理後台登入密碼:test1234
  • 身分證件末四碼/統一編號:53538851
  • HashKey:5294y06JbISpM5x9
  • HashIV:v77hoKGq4kWxNNIS

2. 測試信用卡

  • 卡號:4311-9522-2222-2222
  • 安全碼:222
  • 信用卡測試有效月/年:MM/YYYY 值請大於現在當下時間的月/年

四、登入綠界測試後台

圖、開啟 https://vendor-stage.ecpay.com.tw,輸入測試帳號 stagetest1234,按下繼續

圖、輸入測試帳號、密碼後,在按登入

圖、按一般訂單查詢,按全方位金流訂單,即可查詢訂單資訊

五、範例程式碼

  1. C# MVC的範例,有 產生訂單、取得訂單資訊、取得虛擬帳號 …等功能。
/// <summary>
/// MVC Controller
/// </summary>
public class EcpayController : Controller
{
    /// <summary>
    /// 取得付款資訊
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public ActionResult PayInfo(string id)
    {
        var cache = MemoryCache.Default;
        var cacheData = cache.Get(id);
        var dataStr = JsonConvert.SerializeObject(cacheData);
        var data = JsonConvert.DeserializeObject<Dictionary<string, string>>(dataStr);
        return View("EcpayView", data);
    }

    /// <summary>
    /// 取得虛擬帳號 資訊
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public ActionResult AccountInfo(string id)
    {
        var cache = MemoryCache.Default;
        var cacheData = cache.Get(id);
        var dataStr = JsonConvert.SerializeObject(cacheData);
        var data = JsonConvert.DeserializeObject<Dictionary<string, string>>(dataStr);
        return View("EcpayView", data);
    }

    /// <summary>
    /// 產生訂單
    /// </summary>
    /// <returns></returns>
    public ActionResult Index()
    {
        var orderId = Guid.NewGuid().ToString().Replace("-", "").Substring(0, 20);

        //需填入 你的網址
        var website = $"XXXX";

        var order = new Dictionary<string, string>
        {
            //特店交易編號
            { "MerchantTradeNo",  orderId},

            //特店交易時間 yyyy/MM/dd HH:mm:ss
            { "MerchantTradeDate",  DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")},

            //交易金額
            { "TotalAmount",  "100"},

            //交易描述
            { "TradeDesc",  "無"},

            //商品名稱
            { "ItemName",  "測試商品"},

            //允許繳費有效天數(付款方式為 ATM 時,需設定此值)
            { "ExpireDate",  "3"},

            //自訂名稱欄位1
            { "CustomField1",  ""},

            //自訂名稱欄位2
            { "CustomField2",  ""},

            //自訂名稱欄位3
            { "CustomField3",  ""},

            //自訂名稱欄位4
            { "CustomField4",  ""},

            //綠界回傳付款資訊的至 此URL
            { "ReturnURL",  $"{website}/api/Ecpay/AddPayInfo"},

            //使用者於綠界 付款完成後,綠界將會轉址至 此URL
            { "OrderResultURL", $"{website}/Ecpay/PayInfo/{orderId}"},

            //付款方式為 ATM 時,當使用者於綠界操作結束時,綠界回傳 虛擬帳號資訊至 此URL
            { "PaymentInfoURL",  $"{website}/api/Ecpay/AddAccountInfo"},

            //付款方式為 ATM 時,當使用者於綠界操作結束時,綠界會轉址至 此URL。
            { "ClientRedirectURL",  $"{website}/Ecpay/AccountInfo/{orderId}"},

            //特店編號, 2000132 測試綠界編號
            { "MerchantID",  "2000132"},

            //忽略付款方式
            { "IgnorePayment",  "GooglePay#WebATM#CVS#BARCODE"},

            //交易類型 固定填入 aio
            { "PaymentType",  "aio"},

            //選擇預設付款方式 固定填入 ALL
            { "ChoosePayment",  "ALL"},

            //CheckMacValue 加密類型 固定填入 1 (SHA256)
            { "EncryptType",  "1"},
        };

        //檢查碼
        order["CheckMacValue"] = GetCheckMacValue(order);

        return View(order);
    }

    /// <summary>
    /// 取得 檢查碼
    /// </summary>
    /// <param name="order"></param>
    /// <returns></returns>
    private string GetCheckMacValue(Dictionary<string, string> order)
    {
        var param = order.Keys.OrderBy(x => x).Select(key => key + "=" + order[key]).ToList();

        var checkValue = string.Join("&", param);

        //測試用的 HashKey
        var hashKey = "5294y06JbISpM5x9";

        //測試用的 HashIV
        var HashIV = "v77hoKGq4kWxNNIS";

        checkValue = $"HashKey={hashKey}" + "&" + checkValue + $"&HashIV={HashIV}";

        checkValue = HttpUtility.UrlEncode(checkValue).ToLower();

        checkValue = GetSHA256(checkValue);

        return checkValue.ToUpper();
    }

    /// <summary>
    /// SHA256 編碼
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    private string GetSHA256(string value)
    {
        var result = new StringBuilder();
        var sha256 = SHA256Managed.Create();
        var bts = Encoding.UTF8.GetBytes(value);
        var hash = sha256.ComputeHash(bts);

        for (int i = 0; i < hash.Length; i++)
        {
            result.Append(hash[i].ToString("X2"));
        }

        return result.ToString();
    }
}
  1. 產生、送出訂單資訊的 View
@model System.Collections.Generic.Dictionary<string, string>
@{ Layout = null; }
<!DOCTYPE html>
<html>
<body>
    <form id="form" name="form" action="https://payment-stage.ecpay.com.tw/Cashier/AioCheckOut/V5" method="POST">
        @foreach (var key in @Model.Keys.ToList())
        {
            @(key) <input type="text" name="@key" value="@Model[key]" /><br />
        }
    </form>
    <script type="text/javascript">
        window.onload = function () {
            document.getElementById("form").submit();
        }
    </script>
</body>
</html>
  1. 取得訂單資訊、虛擬帳號的 View
@model System.Collections.Generic.Dictionary<string, string>
@{ Layout = null; }
<!DOCTYPE html>
<html>
<body>
    @foreach (var key in @Model.Keys.ToList())
    {
        @(key) <input type="text" name="@key" value="@Model[key]" disabled /><br />
    }
</body>
</html>
  1. Api 用來接收 綠界的訂單資訊、虛擬帳號資訊
/// <summary>
/// API Controller
/// </summary>
public class EcpayController : ApiController
{
    /// <summary>
    /// 綠界回傳 付款資訊
    /// </summary>
    /// <param name="info"></param>
    /// <returns></returns>
    [HttpPost]
    public HttpResponseMessage AddPayInfo(JObject info)
    {
        try
        {
            var cache = MemoryCache.Default;
            cache.Set(info.Value<string>("MerchantTradeNo"), info, DateTime.Now.AddMinutes(60));
            return ResponseOK();
        }
        catch (Exception e)
        {
            return ResponseError();
        }
    }

    /// <summary>
    /// 綠界回傳 虛擬帳號資訊
    /// </summary>
    /// <param name="info"></param>
    /// <returns></returns>
    [HttpPost]
    public HttpResponseMessage AddAccountInfo(JObject info)
    {
        try
        {
            var cache = MemoryCache.Default;
            cache.Set(info.Value<string>("MerchantTradeNo"), info, DateTime.Now.AddMinutes(60));
            return ResponseOK();
        }
        catch (Exception e)
        {
            return ResponseError();
        }
    }

    /// <summary>
    /// 回傳給 綠界 失敗
    /// </summary>
    /// <returns></returns>
    private HttpResponseMessage ResponseError()
    {
        var response = new HttpResponseMessage();
        response.Content = new StringContent("0|Error");
        response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html");
        return response;
    }

    /// <summary>
    /// 回傳給 綠界 成功
    /// </summary>
    /// <returns></returns>
    private HttpResponseMessage ResponseOK()
    {
        var response = new HttpResponseMessage();
        response.Content = new StringContent("1|OK");
        response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html");
        return response;
    }

}

六、範例的信用卡付款操作步驟

圖、進入http://你的網址/Ecpay/index 產生測試訂單

圖、輸入 測試信用卡 相關資訊後,按下立即付款 Pay now

圖、輸入驗證碼

圖、回到http://你的網址/Ecapy/PayInfo/訂單編號 取得訂單編號

七、範例的ATM付款操作步驟

圖、進入http://你的網址/Ecpay/index 產生測試訂單


圖、選擇ATM櫃台再按下取得繳費帳號

圖、回到http://你的網址/Ecapy/AccountInfo/訂單編號 取得ATM繳費資訊

圖、登入綠界測試後台,查詢訂單編號,按下模擬付款來進行ATM的付款

圖、模擬付款成功

參考

  1. 綠界金流
  2. 串接規格下載
  3. 完整版-全方位金流API技術文件
  4. 綠界測試後台
  5. 使用「Visual Studio 2019」建置一個有 Mvc 和 Web Api 架構的網站

留言

這個網誌中的熱門文章

使用「NLog」來記錄應用程式的大小事吧

使用「LINE Messaging API」發送 line 訊息

使用「Line-Notify」發送 line 訊息

「Katalon Recorder」簡化測試腳本撰寫的工具

「Chrome Headless」隱藏瀏覽器的介面,讓爬蟲程式偷偷的執行

「Selenium」前端 UI 自動化測試、爬蟲程式 最佳利器

使用 Visual Studio 2019 實作「RESTful API」

如何傳送訊息至「Teams」的 Channel