一小时搞定c#微信支付

文章目录


2023年3月8日 修正

好了,正文开始,希望能给需要的人看到,我离秃瓢又近了一步。
本文主要阐述的是C#发起jsapi支付的爬坑经历。也可以是H5页面发起的支付。

一、下载demo

https://pay.weixin.qq.com/wiki/doc/api/download/WxPayAPI_CS.zip

PS:我下的是cs_sdk_v3.0.9:

.NET C# 【微信支付】API对应的SDK和调用示例 付款码支付、JSAPI支付、Native支付
二、搭建环境

1、复制demo的 bussiness和lib到自己项目,然后需要nuget一下Newtonsoft.Json
在这里插入图片描述

2、因为只用到了支付,所以只需要一个页面JsApiPayPage.aspx,复制到项目(我改名为ApiPay.aspx)
在这里插入图片描述

三、微信支付参数

1、参数主要在lib目录下的DemoConfig.cs里修改:

必须有的GetAppID()、GetMchID、GetKey、GetAppSecret、GetNotifyUrl、GetIp.类里都有参数说明我就不赘述了。

2、微信设置,主要有两个地方。

授权支付目录:商户平台-->产品中心-->开发配置

授权网页访问接口:开发者中心-->网页授权获取用户信息-->修改

这两个地方都只需要填写ApiPay.aspx的上级目录(外网可访问的),比如:https://host/api/ApiPay.aspx,填写https://host/api/就行 ,不同的是网页授权要拷贝一个TXT

四、主要业务流程(看看了解一下就行)

如果上面的参数设置正确,恭喜你成功了一半。先讲下实现流程,在贴主要业务代码

1、前端H5支付跳到后端(支付金额是必须的)

2、获取openid:jsApiPay.GetOpenidAndAccessToken();这里是有个回调,先发送请求取得code,再验证网页权限去解析code 取得openid.

3、统一下单:jsApiPay.GetUnifiedOrderResult(),可以理解为让微信创建订单。

4、H5发起jsapi:jsApiPay.GetJsApiParameters(); 这里的prepay_id订单号要跟上一步返回的对应。不然会出错。

五、代码

其实代码上的改动只有ApiPay.aspx(因为就是复制过来的JsApiPayPage.aspx)
1、ApiPay.aspx前端:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ApiPay.aspx.cs" Inherits="Web.api.ApiPay" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta http-equiv="content-type" content="text/html;charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <script src="../js/jquery-1.9.1.min.js"></script>
    <script src="../js/jweixin-1.0.0.js"></script>
    <title>微信支付</title>
</head>

<script type="text/javascript">
    //调用微信JS api 支付
    function jsApiCall()
    {
       WeixinJSBridge.invoke(
          'getBrandWCPayRequest',
              <%=wxJsApiParam%>//josn串
            function (res) {
                switch (res.err_msg) {
                    case "get_brand_wcpay_request:ok":
                        $('#btn').click();
                        //支付成功,写入数据库;
                        break;
                    case "get_brand_wcpay_request:cancel":
                        alert("支付取消");
                        break;
                    default:
                        alert("支付失败");
                        break;
                }
            }
        );
    }
    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>
<body>
    <form runat="server">
        <div align="center" style="display: none;">
            <asp:Button ID="submit" runat="server" Text="立即支付" OnClientClick="callpay();return false;" Style="width: 210px; height: 50px; border-radius: 15px; background-color: #00CD00; border: 0px #FE6714 solid; cursor: pointer; color: white; font-size: 16px;" />
            <asp:Button ID="btn" runat="server" Text="写入数据库" Style="width: 210px; height: 50px; border-radius: 15px; background-color: #00CD00; border: 0px #FE6714 solid; cursor: pointer; color: white; font-size: 16px;" OnClick="btn_Click" />
        </div>
    </form>
</body>
</html>

2、ApiPay.aspx.cs

using System;
using WxPayAPI;
using System.Text;
namespace Web.api
{
    public partial class ApiPay : System.Web.UI.Page
    {
        public static string wxJsApiParam { get; set; } //H5调起JS API参数
        public string uid { get; set; }//用户ID
        public string oid { get; set; }//订单ID
        public string amount { get; set; }//支付金额
        public string openid{ get; set; }//支付用户的openid

        protected void Page_Load(object sender, EventArgs e)
        {
            if (Request.QueryString["fee"] != null)
            {
                amount = Request.QueryString["fee"];
            }
            if (Request.QueryString["uid"] != null)
            {
                uid = Request.QueryString["uid"];
            }
            if (Request.QueryString["oid"] != null)
            {
                oid = Request.QueryString["oid"];
            }
            //-----------------因为多次回调,必须写!IsPostBack外才能获取-----------------------------
            if (!IsPostBack)
            {
                JsApiPay jsApiPay = new JsApiPay(this);
                if (Request.QueryString["fee"] != null)
                {
                    double amt = double.Parse(Request.QueryString["fee"])*100;
                    jsApiPay.total_fee = int.Parse(amt.ToString());
                    amount = Request.QueryString["fee"];
                }
               if (string.IsNullOrEmpty(openid))//1、微信登录验证
                {
                    //获取openid
                    jsApiPay.GetOpenidAndAccessToken();
                    openid = jsApiPay.openid;
                }
                //检测是否给当前页面传递了相关参数
                if (string.IsNullOrEmpty(openid))
                {
                    return;
                }
                else
                {
                    jsApiPay.openid= openid;
                }
                //JSAPI支付预处理
                try
                {
                    WxPayData unifiedOrderResult = jsApiPay.GetUnifiedOrderResult();//2、发起统一支付
                    wxJsApiParam = jsApiPay.GetJsApiParameters();//3、获取H5调起JS API参数 
                }
                catch (Exception ex)
                {
                    Response.Write("<span style='color:#FF0000;font-size:20px'>" + "下单失败,请返回重试</span>");
                    return;
                }
                doPay();//4、发起支付
            }
        }
        //H5请求支付  之前2统一下单创建的订单
        public void doPay()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<script language='javascript'>");
            sb.Append("$('#submit').click();");
            sb.Append("</script>");
            ClientScript.RegisterStartupScript(this.GetType(), "LoadPicScript", sb.ToString());
        }
        //5、支付成功后的业务逻辑(按自己的程序修改就行)
        protected void btn_Click(object sender, EventArgs e)
        {
            string str = string.Format("{0},{1},{2}", oid, uid, amount);
            if (saveinmysql(str)) {//支付成功状态写入数据库saveinmysql是唯一属于我的函数了
                yesPay();
            }
        }
        //6、支付成功,业务流程全部完事,可以跑路了
        public void yesPay()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<script language='javascript'>");
            sb.Append("alert('支付成功');window.location.href ='支付成功跳出支付.html");
            sb.Append("</script>");
            ClientScript.RegisterStartupScript(this.GetType(), "LoadPicScript", sb.ToString());
        }
    }
}

3、因为我前端传了fee(total_fee)、uid(我的)、oid(我的)三个参数,所以微信登录回调会弄掉,需要修改(注意修改 host ):
\business\JsApiPay.cs的GetOpenidAndAccessToken()

                string host = page.Request.Url.Host;//这里改成域名如 www.xxx.com
                string path = page.Request.Path;
                string requt = page.Request.Url.Query;//主要是这里和下一句,把?后的也加入回调地址
               string redirect_uri = HttpUtility.UrlEncode("http://" + host + path+ requt);

六、大坑插眼:

认真执行一、二、三、五,基本支付就成功了。这里对大坑进行插眼,秃瓢警告,嘤嘤嘤

1、前端一定要传 total_fee(本文的fee),且记得100倍

2、三、2的两个授权页面一定要到位,不然坑死

3、微信开发者工具,需要公众号设置开发者权限,虽然支付后面的无法调试,还是能看到JS错误

4、用手机微信测试的话,一定要在手机、设置、应用、微信,里清一下缓存,不然你会发现太他瞄的坑了

5、GetNotifyUrl这个一定要填,公网能访问就行,虽然也没啥用(非扫码支付不跳那的)。

6、这个最坑,demo自带的bug:在五、1里(代码)有个jweixin-1.0.0.js,我是下载到本地的,实际路径为:``http://res.wx.qq.com/open/js/jweixin-1.0.0.js
(<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>)
这个不调用,你会发现,支付成功,回调没卵用(这蛋疼的问题卡我一晚上,离秃瓢又近了一步)

7、附上签名测试工具,感觉没啥用,唯一有用的是测试你的key和appid是否匹配。毕竟签名封装都是写好的,不用改

8、统一下单发起支付签名加密方式要一致,我都用的SIGN_TYPE_HMAC_SHA256(HMAC-SHA256),一个MD5.一个HMAC-SHA256肯定报错的

 WxPayData unifiedOrderResult = jsApiPay.GetUnifiedOrderResult();//2、发起统一支付
 wxJsApiParam = jsApiPay.GetJsApiParameters();//3、获取H5调起JS API参数

--------------end-----------------

再次吐槽,微信的工作人员太偷工减料了,只看API文档会被坑死,码农何必为难码农,诶。

已经尽量写得很详细了,第一次发帖,如果有帮到你,记得给个赞

  • 41
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值