1. 程式人生 > >C# 微信支付之JSAPI支付

C# 微信支付之JSAPI支付

前面說過微信支付的APP支付,這篇說說JSAPI的支付。

JSAPI支付只能在微信瀏覽器裡面使用,主要用於公眾號裡面的H5應用的支付。

開發前的準備

公眾號支付開發步驟

1、設定測試目錄

在微信公眾平臺設定,欄目見圖7.7。支付測試狀態下,設定測試目錄,測試人的微訊號新增到白名單,發起支付的頁面目錄必須與設定的精確匹配。並將支付連結發到對應的公眾號會話視窗中才能正常發起支付測試。注意正式目錄一定不能與測試目錄設定成一樣,否則支付會出錯。

微信內網頁支付設定欄目入口

圖7.7 微信內網頁支付設定欄目入口

2、設定正式支付目錄

根據圖中欄目順序進入修改欄目,勾選JSAPI網頁支付開通該許可權,並配置好支付授權目錄,該目錄必須是發起支付的頁面的精確目錄,子目錄下無法正常呼叫支付。具體介面如圖7.8所示:

微信網頁內支付介面授權目錄設定

圖7.8 微信網頁內支付介面授權目錄設定

再到開發》介面許可權》網頁服務》網頁賬號,填上你的網址。如下圖:

商戶平臺有兩個賬號,一個是用於APP支付的,一個是用於公眾號支付的,這裡我們需要用公眾號的那個。

商戶平臺有兩個東西會用到,一個是Partner ID,就是微信支付商戶號;一個是Key,就是對商戶平臺的登入密碼進行MD5加密後得到的字串,到API安全>>API金鑰>>設定金鑰,把這個MD5字串填進去儲存就行了,如下圖:

1.生成openid
            JsApiPay jsApiPay = new JsApiPay(this);
            //呼叫【網頁授權獲取使用者資訊】介面獲取使用者的openid和access_token
            jsApiPay.GetOpenidAndAccessToken();

            ViewState["OpenID"] = jsApiPay.openid;


2.發起支付
前臺JS程式碼:
               
    <script type="text/javascript">

        var appId = '<%=appId%>';
        var prepayId = '<%=prepayId%>';
        var nonceStr = '<%=nonceStr%>';
        var timeStamp = '<%=timeStamp%>';
        var sign = '<%=sign%>';

        function onBridgeReady() {
            WeixinJSBridge.invoke(
                'getBrandWCPayRequest', {
                    "appId": appId,     //公眾號名稱,由商戶傳入     
                    "timeStamp": timeStamp,         //時間戳,自1970年以來的秒數     
                    "nonceStr": nonceStr, //隨機串     
                    "package": "prepay_id=" + prepayId,
                    "signType" : "MD5",         //微信簽名方式:     
                    "paySign": sign //微信簽名 
                },
                function (res) {
                    // 使用以上方式判斷前端返回,微信團隊鄭重提示:res.err_msg將在使用者支付成功後返回    ok,但並不保證它絕對可靠。
                    switch (res.err_msg)
                    {
                        case "get_brand_wcpay_request:ok":
                            alert("支付成功");
                            break;
                        case "get_brand_wcpay_request:cancel":
                            alert("支付取消");
                            break;
                        default:
                            alert("支付失敗");
                            break;
                    }
                }
            ); 
        }

        if (typeof WeixinJSBridge == "undefined"){
            if( document.addEventListener ){
                document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
            }else if (document.attachEvent){
                document.attachEvent('WeixinJSBridgeReady', onBridgeReady); 
                document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
            }
        }else{
            onBridgeReady();
        }

    </script>


後臺CS程式碼:
 protected void Page_Load(object sender, EventArgs e)
    {
        if (Request.QueryString["openid"] != null)
        {
            ViewState["OpenID"] = Request.QueryString["openid"];
            WxPay();
        }
        else
        {
            Response.Redirect("WxPay.aspx");
        }
    }

    protected void btnPay_Click(object sender, EventArgs e)
    {
        WxPay();
    }

    public string appId;
    public string prepayId;
    public string nonceStr;
    public string timeStamp;
    public string sign;

    /// <summary>
    /// 支付方法
    /// </summary>
    private void WxPay()
    {
        appId = WxPayConfig.APPID;
        string partnerId = WxPayConfig.MCHID;
        string key = WxPayConfig.KEY;
        string body = txtProductName.Text.Trim();
        string orderNumber = DateTime.Now.ToString("yyyyMMddHHmmss");
        int price = int.Parse(txtPrict.Text.Trim());

        UnifiedOrder order = new UnifiedOrder();
        order.appid = appId;
        order.mch_id = partnerId;
        order.nonce_str = TenpayUtil.getNoncestr();
        order.body = body;
        order.out_trade_no = orderNumber;
        order.total_fee = price;    //單位是分
        order.spbill_create_ip = Page.Request.UserHostAddress;
        order.notify_url = "http://www.yourdomain.com/notify.aspx";
        order.trade_type = "JSAPI";
        if (ViewState["OpenID"] != null)
        {
            order.openid = ViewState["OpenID"].ToString();  //JSAPI必須傳入openid
        }

        TenpayUtil tu = new TenpayUtil();

        prepayId = tu.getPrepay_id(order, key);
        nonceStr = order.nonce_str;
        timeStamp = TenpayUtil.getTimestamp();

        SortedDictionary<string, string> sParams = new SortedDictionary<string, string>();
        sParams.Add("appId", appId);
        sParams.Add("nonceStr", nonceStr);
        sParams.Add("package", "prepay_id=" + prepayId);
        sParams.Add("signType", "MD5");
        sParams.Add("timeStamp", timeStamp);
        sign = tu.getsign(sParams, key);
    }

這裡要注意的是appId、nonceStr這些欄位要大小寫正確,否則加密會出錯導致支付失敗。 3.查詢訂單狀態 這個可以參考前面APP支付