微信公众平台开发 - 微信支付(公众号支付)

Posted 竹殇

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微信公众平台开发 - 微信支付(公众号支付)相关的知识,希望对你有一定的参考价值。

即 微信内H5调起支付 ,使用的是微信的内置浏览器的API,也是JSSDK,但和微信网页开发的 JS-SDK是不一样的。

微信网页开发需要引入 http://res.wx.qq.com/open/js/jweixin-1.2.0.js 文件,然后使用配置的方式来进行相关接口的调用;

而H5调起支付不需要引入文件,调用方式也不同,且 注入权限验证配置的参数也多一些。

SDK与DEMO下载:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1

WeixinJSBridge API (微信内置浏览器私有接口)

1.首先开通微信支付功能,通过之后可以拿到商户号和商户账号及密码,去登录商户平台做开发配置

2.登录商户平台配置支付授权目录

添加之前需要生成本机的数据证书,否则无权限操作

支付授权目录应该为当前页面链接的上一级目录.

接着设置密钥

 

后面调用需要用到这些信息

调用的话官方的demo例子还是很全的:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1

public class JsApiPay
    {

        /// <summary>
        /// openid用于调用统一下单接口
        /// </summary>
        public string openid { get; set; }

        /// <summary>
        /// access_token用于获取收货地址js函数入口参数
        /// </summary>
        public string access_token { get; set; }

        /// <summary>
        /// 商品金额,用于统一下单
        /// </summary>
        public int total_fee { get; set; }

        /// <summary>
        /// 统一下单接口返回结果
        /// </summary>
        public WxPayData unifiedOrderResult { get; set; }

        public JsApiPay()
        {

        }


        /**
        * 
        * 通过code换取网页授权access_token和openid的返回数据,正确时返回的JSON数据包如下:
        * {
        *  "access_token":"ACCESS_TOKEN",
        *  "expires_in":7200,
        *  "refresh_token":"REFRESH_TOKEN",
        *  "openid":"OPENID",
        *  "scope":"SCOPE",
        *  "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
        * }
        * 其中access_token可用于获取共享收货地址
        * openid是微信支付jsapi支付接口统一下单时必须的参数
        * 更详细的说明请参考网页授权获取用户基本信息:http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html
        * @失败时抛异常WxPayException
        */
        public void GetOpenidAndAccessTokenFromCode(string code)
        {
            try
            {
                //构造获取openid及access_token的url
                WxPayData data = new WxPayData();
                data.SetValue("appid", WxPayConfig.APPID);
                data.SetValue("secret", WxPayConfig.APPSECRET);
                data.SetValue("code", code);
                data.SetValue("grant_type", "authorization_code");
                string url = "https://api.weixin.qq.com/sns/oauth2/access_token?" + data.ToUrl();

                //请求url以获取数据
                string result = HttpService.Get(url);

                Log.Debug(this.GetType().ToString(), "GetOpenidAndAccessTokenFromCode response : " + result);

                //保存access_token,用于收货地址获取
                JsonData jd = JsonMapper.ToObject(result);
                access_token = (string)jd["access_token"];

                //获取用户openid
                openid = (string)jd["openid"];

                Log.Debug(this.GetType().ToString(), "Get openid : " + openid);
                Log.Debug(this.GetType().ToString(), "Get access_token : " + access_token);
            }
            catch (Exception ex)
            {
                Log.Error(this.GetType().ToString(), ex.ToString());
                throw new WxPayException(ex.ToString());
            }
        }

        /**
         * 调用统一下单,获得下单结果
         * @return 统一下单结果
         * @失败时抛异常WxPayException
         */
        public WxPayData GetUnifiedOrderResult()
        {
            //统一下单
            WxPayData data = new WxPayData();
            data.SetValue("body", "test");
            data.SetValue("attach", "test");
            data.SetValue("out_trade_no", WxPayApi.GenerateOutTradeNo());
            data.SetValue("total_fee", total_fee);
            data.SetValue("time_start", DateTime.Now.ToString("yyyyMMddHHmmss"));
            data.SetValue("time_expire", DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss"));
            data.SetValue("goods_tag", "test");
            data.SetValue("trade_type", "JSAPI");
            data.SetValue("openid", openid);

            WxPayData result = WxPayApi.UnifiedOrder(data);
            if (!result.IsSet("appid") || !result.IsSet("prepay_id") || result.GetValue("prepay_id").ToString() == "")
            {
                Log.Error(this.GetType().ToString(), "UnifiedOrder response error!");
                throw new WxPayException("UnifiedOrder response error!");
            }

            unifiedOrderResult = result;
            return result;
        }

        /**
        *  
        * 从统一下单成功返回的数据中获取微信浏览器调起jsapi支付所需的参数,
        * 微信浏览器调起JSAPI时的输入参数格式如下:
        * {
        *   "appId" : "wx2421b1c4370ec43b",     //公众号名称,由商户传入     
        *   "timeStamp":" 1395712654",         //时间戳,自1970年以来的秒数     
        *   "nonceStr" : "e61463f8efa94090b1f366cccfbbb444", //随机串     
        *   "package" : "prepay_id=u802345jgfjsdfgsdg888",     
        *   "signType" : "MD5",         //微信签名方式:    
        *   "paySign" : "70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信签名 
        * }
        * @return string 微信浏览器调起JSAPI时的输入参数,json格式可以直接做参数用
        * 更详细的说明请参考网页端调起支付API:http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7
        * 
        */
        public string GetJsApiParameters()
        {
            Log.Debug(this.GetType().ToString(), "JsApiPay::GetJsApiParam is processing...");

            WxPayData jsApiParam = new WxPayData();
            jsApiParam.SetValue("appId", unifiedOrderResult.GetValue("appid"));
            jsApiParam.SetValue("timeStamp", WxPayApi.GenerateTimeStamp());
            jsApiParam.SetValue("nonceStr", WxPayApi.GenerateNonceStr());
            jsApiParam.SetValue("package", "prepay_id=" + unifiedOrderResult.GetValue("prepay_id"));
            jsApiParam.SetValue("signType", "MD5");
            jsApiParam.SetValue("paySign", jsApiParam.MakeSign());

            string parameters = jsApiParam.ToJson();

            Log.Debug(this.GetType().ToString(), "Get jsApiParam : " + parameters);
            return parameters;
        }


        /**
        * 
        * 获取收货地址js函数入口参数,详情请参考收货地址共享接口:http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_9
        * @return string 共享收货地址js函数需要的参数,json格式可以直接做参数使用
        */
        public string GetEditAddressParameters()
        {
            string parameter = "";
            try
            {
                //这个地方要注意,参与签名的是网页授权获取用户信息时微信后台回传的完整url
                string url = string.Format("http://{0}/Business/TongMall/TongPay/Index/?moduleId=5000", ConfigurationManager.AppSettings["DoMain"]);

                //构造需要用SHA1算法加密的数据
                WxPayData signData = new WxPayData();
                signData.SetValue("appid", WxPayConfig.APPID);
                signData.SetValue("url", url);
                signData.SetValue("timestamp", WxPayApi.GenerateTimeStamp());
                signData.SetValue("noncestr", WxPayApi.GenerateNonceStr());
                signData.SetValue("accesstoken", access_token);
                string param = signData.ToUrl();

                Log.Debug(this.GetType().ToString(), "SHA1 encrypt param : " + param);
                //SHA1加密
                string addrSign = GetSwcSH1(param);
                Log.Debug(this.GetType().ToString(), "SHA1 encrypt result : " + addrSign);

                //获取收货地址js函数入口参数
                WxPayData afterData = new WxPayData();
                afterData.SetValue("appId", WxPayConfig.APPID);
                afterData.SetValue("scope", "jsapi_address");
                afterData.SetValue("signType", "sha1");
                afterData.SetValue("addrSign", addrSign);
                afterData.SetValue("timeStamp", signData.GetValue("timestamp"));
                afterData.SetValue("nonceStr", signData.GetValue("noncestr"));

                //转为json格式
                parameter = afterData.ToJson();
                Log.Debug(this.GetType().ToString(), "Get EditAddressParam : " + parameter);
            }
            catch (Exception ex)
            {
                Log.Error(this.GetType().ToString(), ex.ToString());
                throw new WxPayException(ex.ToString());
            }

            return parameter;
        }

        public static string GetSwcSH1(string value)
        {
            SHA1 algorithm = SHA1.Create();
            byte[] data = algorithm.ComputeHash(Encoding.UTF8.GetBytes(value));
            string sh1 = "";
            for (int i = 0; i < data.Length; i++)
            {
                sh1 += data[i].ToString("x2").ToUpperInvariant();
            }
            return sh1;
        }
    }
    public class TongPay_Mod
    {
        private decimal price;
        public decimal Price
        {
            get { return price; }
            set { price = value; }
        }

        public string wxEditAddrParam { get; set; }

        public string openid { get; set; }
    }

    public class TongJsApiPay_Mod
    {
        public string wxJsApiParam { get; set; }

        public string Info { get; set; }
    }


        public ViewResult TongJsApiPay(TongPay_Mod model)
        {
            TongJsApiPay_Mod model1 = new TongJsApiPay_Mod();
            //检测是否给当前页面传递了相关参数
            if (string.IsNullOrEmpty(model.openid) || string.IsNullOrEmpty(model.Price.ToString()))
            {
                Response.Write("<span style=\'color:#FF0000;font-size:20px\'>" + "页面传参出错,请返回重试" + "</span>");
                Log.Error(this.GetType().ToString(), "This page have not get params, cannot be inited, exit...");
            }

            //若传递了相关参数,则调统一下单接口,获得后续相关接口的入口参数
            JsApiPay jsApiPay = new JsApiPay();
            jsApiPay.openid = model.openid;
            jsApiPay.total_fee = Convert.ToInt32((Convert.ToDecimal(model.Price) * 100));

            //JSAPI支付预处理
            try
            {
                WxPayData unifiedOrderResult = jsApiPay.GetUnifiedOrderResult();
                model1.wxJsApiParam = jsApiPay.GetJsApiParameters();//获取H5调起JS API参数                    
                Log.Debug(this.GetType().ToString(), "wxJsApiParam : " + model1.wxJsApiParam);
                //在页面上显示订单信息
                model1.Info = unifiedOrderResult.ToPrintStr();
            }
            catch (Exception ex)
            {
                model1.Info = ex.Message;
                //model1.Info= "下单失败,请返回重试";
            }
            return View(model1);
        }

页面显示获取的参数

@{
    Layout = "~/Views/Shared/_Layout_WeUI.cshtml";
}

@model WY.WxcModel.TongJsApiPay_Mod

<script type="text/javascript">

    //调用微信JS api 支付
    function jsApiCall() {
        WeixinJSBridge.invoke(
        \'getBrandWCPayRequest\',
        @Html.Raw(Model.wxJsApiParam),//josn串
         function (res) {
             WeixinJSBridge.log(res.err_msg);
             alert(res.err_code + res.err_desc + res.err_msg);
         }
         );
    }

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

</script>

<table class="my_header">
    <tr>
        <td>
            <button class="headerBtn aHeaderLeft">&nbsp;</button>
        </td>
        <td style="text-align: center">订单确认及支付</td>
        <td>&nbsp;
        </td>
    </tr>
</table>
<div style="width: 100%; height: 300px; padding-left: 8px;">
    这里显示一些确认信息,优惠信息之类的
    <br />
    <span style=\'color: #00CD00; font-size: 16px;\'>
        @(new MvcHtmlString(Model.Info))
    </span>
</div>
<a id="btnSave" class="weui-btn weui-btn_primary" data-ajax="false" style="color: #fff; text-shadow: none; margin: 10px" onclick="callpay()">立即支付</a>

支付

 

以上是关于微信公众平台开发 - 微信支付(公众号支付)的主要内容,如果未能解决你的问题,请参考以下文章

微信支付

java开发微信扫码支付,怎么做测试,公众账号ID,商户号这些怎么来?

微信公众号基本信息配置

微信公众号支付出现:“当前页面的URL未注册”

微信支付之公众号支付

这个公众号支付接入微信支付时,是否必须是服务号?