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

     閱讀完本文大概須要5分鐘。php

目錄

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

     一切都是生意。「天下熙熙皆爲利來,天下攘攘皆爲利往」。不知從何時起,人類社會誕生了公司這樣的組織,而這個組織把人們結合在一塊兒,產生了各類行業和商業形態,最後,公司的一切活動都變成了生意。固然,大公司有大公司的生意,小公司有小公司的買賣。html

     過去幾年saas服務軟件大行其道,這其中就有你們熟悉的阿里雲服務,客戶註冊帳戶+線上支付就能使用軟件。數據庫

     線上支付,相信你們都不陌生。支付寶,微信,雲閃付,蘋果支付等,人人都離不開支付通道。咱們看到不少大公司都有本身的支付體系和金融體系。大廠,財大氣粗,有足夠的投入能夠自建高可用的支付體系。那麼,如何中小微企業想在作點小生意,沒有足夠的資源自建支付體系,怎麼玩?swift

     借力。這就比如大廠花了大價錢,找到水源,而後挖了一口井,小店也得活不是,給點佣金,分一股「清泉」吧。api

1、移動支付
 微信

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

  1. 微信支付

     場景介紹異步

用戶掃描商戶展現在各類場景的二維碼進行支付。:微信支付

     步驟1:商戶根據微信支付的規則,爲不一樣商品生成不一樣的二維碼(如圖6.1),展現在各類場景,用於用戶掃描購買。ui

     步驟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");
        }

2、充值體系

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

  • 最基本的充值業務架構

    知足一下基本需求

    • 用戶帳戶中心
    • 用戶可充值,可查看訂單和購買商品
    • 代理商、銷售等營銷部門能夠查看業績報表
  • 訂單生成流程

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



  • 防止重複支付

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

  • 如何保證支付一致性

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

3、總結

     基本的充值體系是通用的。訂單業務量大的能夠增長消息隊列處理。在保證一致性方面,咱們在該架構上還有不少細節能夠完善。

4、參考

     我的微信公衆號:


相關文章
相關標籤/搜索