1. 程式人生 > >一文秒懂如何搭建一個最簡單的充值系統

一文秒懂如何搭建一個最簡單的充值系統

數據 一起 表示 存在 除了 社會 index 原因 必須

? ???閱讀完本文大概需要5分鐘。

目錄

  • 移動支付
    • 微信支付
    • 支付寶支付
  • 充值體系
    • 最基礎的架構
    • 生產環境應用
  • 總結
  • 參考

? ???一切都是生意。“天下熙熙皆為利來,天下攘攘皆為利往”。不知從什麽時候起,人類社會誕生了公司這樣的組織,而這個組織把人們結合在一起,產生了各種行業和商業形態,最後,公司的一切活動都變成了生意。當然,大公司有大公司的生意,小公司有小公司的買賣。

? ???過去幾年saas服務軟件大行其道,這其中就有大家熟悉的阿裏雲服務,客戶註冊賬戶+線上支付就能使用軟件。

? ???線上支付,相信大家都不陌生。支付寶,微信,雲閃付,蘋果支付等,人人都離不開支付通道。我們看到很多大公司都有自己的支付體系和金融體系。大廠,財大氣粗,有足夠的投入可以自建高可用的支付體系。那麽,如何中小微企業想在做點小生意,沒有足夠的資源自建支付體系,怎麽玩?

? ???借力。這就好比大廠花了大價錢,找到水源,然後挖了一口井,小店也得活不是,給點傭金,分一股“清泉”吧。

一、移動支付
 

本文代碼示例是基於威富通移動支付(https://www.swiftpass.cn/products/epay/page.html)

  1. 微信支付

? ???場景介紹

用戶掃描商戶展示在各種場景的二維碼進行支付。:

? ???步驟1:商戶根據微信支付的規則,為不同商品生成不同的二維碼(如圖6.1),展示在各種場景,用於用戶掃描購買。

? ???步驟2:用戶使用微信“掃一掃”(如圖6.2)掃描二維碼後,獲取商品支付信息,引導用戶完成支付(如圖6.3)。

技術分享圖片

? ???步驟3:用戶確認支付,輸入支付密碼(如圖6.4)。

? ???步驟4:支付完成後會提示用戶支付成功(如圖6.5),商戶後臺得到支付成功的通知,然後進行發貨處理。


技術分享圖片

? ???查看是否安裝成功:


技術分享圖片

? ???筆者在實際項目中要使用微信掃碼付款功能,開發的時候選擇的是微信掃碼支付的模式一(https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_4)

技術分享圖片

? ???代碼片段

/// <summary>
        /// 威富通-微信支付
        /// </summary>
        /// <param name="total_fee">訂單金額</param>
        /// <param name="orderno">訂單號</param>
        /// <param name="productName">產品名稱</param>
        private void WebChat(decimal total_fee, string orderno, string productName)
        {
            try
            {
                total_fee = total_fee * 100;//單位:分
                PayReqEntity entity = new PayReqEntity();
                entity.mch_id =“商戶ID”
                string key =“KEY";//您申請的
                entity.key = key;
                entity.req_url = "https://pay.swiftpass.cn/pay/gateway";
                entity.service = "pay.weixin.native";
                entity.version = "2.0";
                entity.out_trade_no = orderno;
                entity.body = productName;
                entity.attach = "";
                entity.total_fee = Math.Round(total_fee).ToString();
                entity.time_start = "";
                entity.time_expire = "";
                entity.mch_create_ip = AppUtils.GetIp();
                entity.notify_url = ChargeHelper.BuildUrl() + "WebChat/Notify.aspx";
                WeChatPayInterface service = new WeChatPayInterface();
                PayResEntity result = service.SubmitPay(entity);
                if (!result.IsSuccess)
                {
                    string msg = result.Message;
                    if (msg.Contains("訂單已存在"))
                    {
                        msg = msg + ",請重新下單!";
                    }
                    Response.Write("<script>alert('" + msg + "')</script>");
                    return;
                }
                Session["pavlue"] = result.arr;
                Response.Redirect("WebChat/Pay.aspx");
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

? ???付款完成之後,會回調WebChat/Pay.aspx頁面,執行訂單業務功能。

public void callback()
        {
            try
            {
                WeChatPayInterface service = new WeChatPayInterface();
                Stream stream = Request.InputStream;
                string key = "KEY";//你申請的
                NotifyResEntity result = service.PayResult(key, stream);
                if (!result.IsSuccess)
                {
                    Log.Info("[威富通-微信支付回調]:" + result.Message);
                    Response.Write("failure");
                    return;
                }
                Hashtable data = result.data;
                /*-----------交易狀態------------
                 SUCCESS—支付成功
                 REFUND—轉入退款
                 NOTPAY—未支付
                 CLOSED—已關閉
                 PAYERROR—支付失敗(其他原因,如銀行返回失敗)
                 ------------------------------------ */
                string out_trade_no = data["out_trade_no"].ToString();//商戶訂單號
                int status = Convert.ToInt32(data["status"]);//返回狀態碼(0表示成功,非0表示失敗此字段是通信標識,非交易標識,交易是否成功需要查看 result_code 來判斷)
                int result_code = Convert.ToInt32(data["result_code"]);//業務結果(0表示成功,非0表示失敗)
                if (status == 0 && result_code == 0)
                {
                    string total_fee = data["total_fee"].ToString();//總金額,以分為單位,不允許包含任何字、符號
                    string transaction_id = data["transaction_id"].ToString();//平臺交易單號
                    //此處可以在添加相關處理業務 ,更新數據庫表中的記錄。
                    int proxyid = 0;
                    string bankbill = "";
                    ulong employeeid = 1;
                    string comment = "微信支付";
                    string billtype = "正常訂單";
                    int payment = 24;//微信支付
                    string bankname = "";
                    string payer = "";
                    string orderno = out_trade_no;
                    string taobaopayno = transaction_id;
                    decimal amountpaid = 0;
                    if (!string.IsNullOrEmpty(total_fee))
                    {
                        amountpaid = Convert.ToDecimal(total_fee) / 100;
                    }
         
                    //TODO:業務處理部分
                    Response.Write("success");
                    return;
                    
                }
                else
                {
                    Log.Info("[威富通-微信支付回調]:商戶訂單號out_trade_no=" + out_trade_no + "狀態碼status=" + status + ",業務結果result_code=" + result_code);
                }
            }
            catch (Exception ex)
            {
                Log.Info("[威富通-微信支付回調]異常:" + ex);
            }
            Response.Write("failure");
        }

2.支付寶支付

? ???場景介紹

????掃碼支付,指用戶打開支付寶錢包中的“掃一掃”功能,掃描商戶針對每個訂單實時生成的訂單二維碼,並在手機端確認支付。

? ???調用流程

https://docs.open.alipay.com/194/105170/

技術分享圖片

????商戶系統調用支付寶預下單接口alipay.trade.precreate,獲得該訂單二維碼圖片地址。
????發起輪詢獲得支付結果:等待5秒後調用交易查詢接口alipay.trade.query通過支付時傳入的商戶訂單號(out_trade_no)查詢支付結果(返回參數TRADE_STATUS),如果仍然返回等待用戶付款(WAIT_BUYER_PAY),則再次等待5秒後繼續查詢,直到返回確切的支付結果(成功TRADE_SUCCESS 或 已撤銷關閉TRADE_CLOSED),或是超出輪詢時間。在最後一次查詢仍然返回等待用戶付款的情況下,必須立即調用交易撤銷接口alipay.trade.cancel將這筆交易撤銷,避免用戶繼續支付。
????除了主動輪詢,也可以通過接受異步通知獲得支付結果,詳見掃碼異步通知,註意一定要對異步通知做驗簽,確保通知是支付寶發出的。

代碼片段:

 private void Alipay(decimal total_fee, string orderno, string productName)
        {
            total_fee = total_fee * 100;//單位:分
            PayReqEntity entity = new PayReqEntity();
            entity.mch_id = "商戶ID";
            string key = 商戶Key"";
            entity.key = key;
            entity.req_url = "https://pay.swiftpass.cn/pay/gateway";
            entity.service = "pay.alipay.native";
            entity.version = "2.0";
            entity.out_trade_no = orderno;
            entity.body = productName;
            entity.attach = "";
            entity.total_fee = Math.Round(total_fee).ToString();
            entity.time_start = "";
            entity.time_expire = "";
            entity.mch_create_ip = AppUtils.GetIp();
            entity.notify_url = ChargeHelper.BuildUrl() + "Alipay/Notify.aspx";
            WeChatPayInterface service = new WeChatPayInterface();
            PayResEntity result = service.SubmitPay(entity);
            if (!result.IsSuccess)
            {
                string msg = result.Message;
                if (msg.Contains("訂單已存在"))
                {
                    msg = msg + ",請重新下單!";
                }
                Response.Write("<script>alert('" + msg + "')</script>");
                return;
            }
            Session["alipay_pavlue"] = result.arr;
            Response.Redirect("Alipay/Pay.aspx");
        }

????支付完成,同樣回調Alipay/Pay.aspx

public void callback()
        {
            try
            {
                WeChatPayInterface service = new WeChatPayInterface();
                Stream stream = Request.InputStream;
                string key = "KEY";//填寫自己的
                NotifyResEntity result = service.PayResult(key, stream);
                if (!result.IsSuccess)
                {
                    Log.Info("[威富通-支付寶支付回調]:" + result.Message);
                    Response.Write("failure");
                    return;
                }
                Hashtable data = result.data;
                /*-----------交易狀態------------
                 SUCCESS—支付成功
                 REFUND—轉入退款
                 NOTPAY—未支付
                 CLOSED—已關閉
                 PAYERROR—支付失敗(其他原因,如銀行返回失敗)
                 ------------------------------------ */
                //string trade_state = data["trade_state"].ToString();
                string out_trade_no = data["out_trade_no"].ToString();//商戶訂單號
                int status = Convert.ToInt32(data["status"]);//返回狀態碼(0表示成功,非0表示失敗此字段是通信標識,非交易標識,交易是否成功需要查看 result_code 來判斷)
                int result_code = Convert.ToInt32(data["result_code"]);//業務結果(0表示成功,非0表示失敗)
                if (status == 0 && result_code == 0)
                {
                    string total_fee = data["total_fee"].ToString();//總金額,以分為單位,不允許包含任何字、符號
                    string transaction_id = data["transaction_id"].ToString();//平臺交易單號
                    //此處可以在添加相關處理業務 ,更新數據庫表中的記錄。
                    int proxyid = 0;
                    string bankbill = "";
                    ulong employeeid = 1;
                    string comment = "支付寶支付";
                    string billtype = "正常訂單";
                    int payment = 23;//威富通-支付寶支付
                    string bankname = "";
                    string payer = "";
                    string orderno = out_trade_no;
                    string taobaopayno = transaction_id;
                    decimal amountpaid = 0;
                    if (!string.IsNullOrEmpty(total_fee))
                    {
                        amountpaid = Convert.ToDecimal(total_fee) / 100;
                    }
                    //TODO:業務處理部分
                    Response.Write("success");
                    return;
                }
                else
                {
                    Log.Info("[威富通-支付寶支付回調]:商戶訂單號out_trade_no=" + out_trade_no + "狀態碼status=" + status + ",業務結果result_code=" + result_code);
                }
            }
            catch (Exception ex)
            {
                Log.Info("[威富通-支付寶支付回調]異常:" + ex);
            }
            Response.Write("failure");
        }

二、充值體系

任何一家公司做生意的都會使用支付業務,這裏以SAAS行業支付為例。

  • 最基本的充值業務架構

    滿足一下基本需求

    • 用戶賬戶中心
    • 用戶可充值,可查看訂單和購買商品
    • 代理商、銷售等營銷部門可以查看業績報表
技術分享圖片
  • 訂單生成流程

? ???在實際生產環境中中,訂單的流程也是較為重要的一環。


技術分享圖片

  • 防止重復支付

? ???支付完成,回調的時候檢測訂單狀態。已支付的就不再執行。

  • 如何保證支付一致性

? ???在實際生產環境中中,總會發生支付接口支付成功,回調執行訂單業務失敗的情況,簡單的辦法是可以增加一個單獨檢查業務,定時對不一致的訂單進行二次執行。

三、總結

? ???基本的充值體系是通用的。訂單業務量大的可以增加消息隊列處理。在保證一致性方面,我們在該架構上還有很多細節可以完善。

四、參考

  • ??https://pay.weixin.qq.com/wiki/doc/api/index.html
  • ??https://docs.open.alipay.com/194/106078/

? ???個人微信公眾號:


技術分享圖片

一文秒懂如何搭建一個最簡單的充值系統