开始做jsapi支付时看了好多的demo及好多的博客感觉有大坑,果不其然,一点一点从坑中爬出。
  1. 前期准备,首先微信公众号中的配置,现在微信支付中配置好支付授权目录,先解释一下支付授权目录时做什么的,在微信发起支付时要获取用户的openid,而获取openid之前要获取一个code,而这个code是获取openid的凭证,而在获取code时微信会有一个回调页面而这个页面就是你的授权支付目录,如果这个目录不正确则后续没有办法进行。例如:你要支付的页面为www.weixin.com/wxpay/JsApiPayPage.aspx时,你需要将目录配置为www.weixin.com/wxpay/以免出现问题。
  2. 其次要配置的就是网页授权获取用户基本信息接口 这个配置的作用使你能访问到支付的接口及回调页面能够返回,其中的域名必须是备案的。
  3. 正式开始从坑中爬,首先介绍微信调试工具微信web开发工具调微信页面神器,微信网站都可以用这个工具。首先拿到微信支付demo然后各种运行然后不行,首先在default页面中的<a href="http://paysdk.weixin.qq.com/example/ProductPage.aspx">JSAPI支付</a>全部都是微信的链接而不是你project的目录,这里在example目录中发现了所有的目录,你可以将default页面的中链接改为exampe目录中的页面,也可以不用改,直接运行example中你想要的接口的页面。下面看到jsapipage.aspx就是jsapi的demo了。
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="JsApiPayPage.aspx.cs" Inherits="WxPayAPI.JsApiPayPage" %><!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"/> <title>微信支付样例-JSAPI支付</title>
</head><script type="text/javascript">//调用微信JS api 支付function jsApiCall(){WeixinJSBridge.invoke('getBrandWCPayRequest',<%=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><body><form runat="server"><br/><div align="center"><br/><br/><br/><asp:Button ID="submit" runat="server" Text="立即支付" OnClientClick="callpay()" style="width:210px; height:50px; border-radius: 15px;background-color:#00CD00; border:0px #FE6714 solid; cursor: pointer;  color:white;  font-size:16px;" /></div></form>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Net;
using System.IO;
using System.Threading;
using LitJson;
using System.Web.Security;namespace WxPayAPI
{public partial class JsApiPayPage : System.Web.UI.Page{public static string wxJsApiParam {get;set;} //H5调起JS API参数protected void Page_Load(object sender, EventArgs e){Log.Info(this.GetType().ToString(), "page load");if (!IsPostBack){string openid = Request.QueryString["openid"];string total_fee = Request.QueryString["total_fee"];//检测是否给当前页面传递了相关参数if (string.IsNullOrEmpty(openid) || string.IsNullOrEmpty(total_fee)){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...");submit.Visible = false;return;}//若传递了相关参数,则调统一下单接口,获得后续相关接口的入口参数JsApiPay jsApiPay = new JsApiPay(this);jsApiPay.openid = openid;jsApiPay.total_fee = int.Parse(total_fee);//JSAPI支付预处理try{WxPayData unifiedOrderResult = jsApiPay.GetUnifiedOrderResult();wxJsApiParam = jsApiPay.GetJsApiParameters();//获取H5调起JS API参数                    Log.Debug(this.GetType().ToString(), "wxJsApiParam : " + wxJsApiParam);//在页面上显示订单信息Response.Write("<span style='color:#00CD00;font-size:20px'>订单详情:</span><br/>");Response.Write("<span style='color:#00CD00;font-size:20px'>" + unifiedOrderResult.ToPrintStr() + "</span>");}catch(Exception ex){Response.Write("<span style='color:#FF0000;font-size:20px'>" + "下单失败,请返回重试" + "</span>");submit.Visible = false;}}}}
}

在这第一个坑,可以看到首先是获取querystring中的openid和total_fee
这两个参数是一个是关注微信的唯一标识和订单的价格,然而首先在获取openid这就是个坑,要获取openid首先要获取到code,在获取到code之后才能获取到openid和access_token。我的做法是在pageLode中加这个。

try{//调用【网页授权获取用户信息】接口获取用户的openid和access_tokenjsApiPay.GetOpenidAndAccessToken();mOpenid = jsApiPay.openid;mAccess_token = jsApiPay.access_token;}
catch (Exception ex){Response.Write("<span style='color:#FF0000;font-size:20px'>" + ex.Message + "</span>");}

其中GetOpenidAndAccessToken方法就有将获取code带码

/*** * 网页授权获取用户基本信息的全部过程* 详情请参看网页授权获取用户基本信息:http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html* 第一步:利用url跳转获取code* 第二步:利用code去获取openid和access_token* */public void GetOpenidAndAccessToken(){if (!string.IsNullOrEmpty(page.Request.QueryString["code"])){//获取code码,以获取openid和access_tokenstring code = page.Request.QueryString["code"];Log.Debug(this.GetType().ToString(), "Get code : " + code);GetOpenidAndAccessTokenFromCode(code);}else{//构造网页授权获取code的URLstring host = page.Request.Url.Host;string path = page.Request.Path;string redirect_uri = HttpUtility.UrlEncode("http://www.weixin.com/wxpay.aspx");WxPayData data = new WxPayData();data.SetValue("appid", WxPayConfig.APPID);data.SetValue("redirect_uri", redirect_uri);data.SetValue("response_type", "code");data.SetValue("scope", "snsapi_base");data.SetValue("state", "STATE" + "#wechat_redirect");string url = "https://open.weixin.qq.com/connect/oauth2/authorize?" + data.ToUrl();Log.Debug(this.GetType().ToString(), "Will Redirect to URL : " + url);try{//触发微信返回code码         page.Response.Redirect(url);//Redirect函数会抛出ThreadAbortException异常,不用处理这个异常}catch (System.Threading.ThreadAbortException ex){}}}

其中首先会判断是否获取到了code,如果没有就会执行获取code操作,其中的redirect_uri就是回掉地址,会在这个页面返回code继续执行获取openid和access_token的操作。而在之前pageload中加的那段代码就是在同一个页面两次执行GetOpenidAndAccessToken方法。
4.下面是一个巨坑,当你获取到openid之后还有个非常重要的pay_sign要获取之后还有一个回调地址,这个地址是你在成功支付后微信返回的回调通知。每发起一次支付操作都要获取一次pay_sign操作,而这个参数是发起调用jsapi操作的必须的参数。

function jsApiCall(){WeixinJSBridge.invoke('getBrandWCPayRequest',<%=wxJsApiParam%>,//josn串function (res){WeixinJSBridge.log(res.err_msg);alert(res.err_code + res.err_desc + res.err_msg);});}

就是<%=wxJsApiParam%>,而<%=wxJsApiParam%>是由

名称 变量名 描述
公众号id appId 商户注册具有支付权限的公众号成功后即可获得
时间戳 timeStamp 当前的时间
随机字符串 nonceStr 随机字符串,不长于32位。推荐随机数生成算法
订单详情扩展字符串 package 统一下单接口返回的prepay_id参数值,提交格式如:prepay_id=*
签名方式 signType 签名算法,暂支持MD5
签名 paySign 签名,详见签名生成算法

在demo中lib文件夹中的WxpayApi.cs中的UnifiedOrder方法中获取这些参数,而其中的回调页面的地址是写在配置文件中的 public const string NOTIFY_URL = “http://paysdk.weixin.qq.com/example/ResultNotifyPage.aspx“;而这个配置文件并不是webcofig是在lib中的config.cs中商户号等一系列的配置也在其中。之后就可以发起支付了。
5.最后一坑,支付成功后的返回,在js中只有一个

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("支付取消");//location.href = "JsApiPayPage.aspx?tepid=1";break;default:alert("支付失败");//location.href = "JsApiPayPage.aspx?tepid=2";break;}}

真正的支付回调页面在ResultNotifyPage.aspx中,其中有回调支付的判断,更有返回的订单的信息,可以在这个页面对支付成功或失败的订单进行处理。

总结:微信jaspi的坑总算爬出来了,其中发起支付到最后的支付成功总共调用了4次接口。更深表demo很坑。

asp.net 微信jsapi支付相关推荐

  1. php微信jsapi支付小结,ThinkPHP接入微信支付 - JSAPI支付

    一.支付准备 二.获取用户openid 首先,到微信公众平台后台 - 设置 - 网页授权域名(别忘了添加开发者) // 在头部引入WechatPubService.php文件,见附录一 use app ...

  2. 微信JSAPI支付 跟 所遇到的那些坑

    首先介绍一下我在调用微信支付接口使用的是 weixin.senparc SDK,非常方便好用开源的一个微信开发SDK. weixin.senparc SDK 官网:http://weixin.senp ...

  3. 微信JSApi支付~订单号和微信交易号

    返回目录 谈谈transactionId和out_trade_no 前一篇微信JSApi支付~坑和如何填坑文章反映不错,所以又写了个后篇,呵呵. 每个第三方在线支付系统中都会有至少两类订单号,其一为支 ...

  4. 微信JSAPI支付对接流程及支付接口设计

    文章目录 前言 一.JSAPI支付场景及逻辑 二.开发步骤 1.设置支付目录 2.设置授权域名 3.业务流程 三.代码设计 1. 支付页面 2. Controller 3. JS调起支付 4. 工具类 ...

  5. 关于微信JSAPI支付成功后,点击完成后没有返回值并且页面被自动关闭问题

    微信JSAPI支付成功后,点击完成后没有返回值并且页面被自动关闭 简介 解决方式 错误的处理方式 总结 简介 最近很多人可能都遇到一个问题,在使用微信JSAPI支付成功后,不走成功的回调方法,只有支付 ...

  6. JAVA+微信JSAPI支付

    JAVA+微信JSAPI支付 引入依赖 获取请求ip 组装微信支付请求 回调处理 引入依赖 <dependency><groupId>com.github.binarywang ...

  7. php接入微信JSAPI支付,微信内拉起支付,基于thinkPHP框架 WeChatDeveloper支付类包

    文章:php接入微信支付,扫码支付和H5支付(非微信浏览器),基于thinkPHP框架 WeChatDeveloper支付类包 踩坑指南 文章:php快速接入支付宝即时支付,PC网站支付和手机网站支付 ...

  8. php 微信统一下单接口,微信JSAPI支付,统一下单接口

    微信JSAPI支付,统一下单接口 今天小编给大家分享一下微信支付的统一下单接口,其实微信官网上也有SDK和DEMO下载了,但是不太好理解,小编就自己整理一份容易理解的代码,看不懂官方的,就来看看小编这 ...

  9. C# .NETMVC 微信JSAPI支付

    C# .NET MVC微信JSAPI支付 经过本人不断翻找资料和百度终于结合一些大佬的经验和思路弄出来一个MVC的微信支付了. 再弄微信支付之前我们需要先有一个商户号,并且开通了微信支付的JSAPI支 ...

最新文章

  1. http、https比较
  2. 案例:图书管理——补充知识(数组相关API)||补充知识(数组响应式变化)
  3. Consul入门07 - Consul Web界面
  4. 计算机网络【三】物理层数据通信
  5. oracle gets/exec 单位,ORACLE AWR使用基础
  6. 机器学习速成课程 | 练习 | Google Development——编程练习:提高神经网络的性能
  7. git tag什么时候使用_git使用教程9pycharm 使用 tag 打标签
  8. RK3399Pro Android Rock-X 人工智能开发系列(2)
  9. Xcode误删Images.xcassets文件夹的恢复办法(Assets.xcassets)
  10. 每一句都值得品味的话
  11. 下docfetcher先下Java,docfetcher怎么用?docfetcher搜索文档内容的方法介绍
  12. C语言男性标准体重,男性的标准体重是多少又如何计算?
  13. 使用iTunes制作iPhone6s plus铃声
  14. centos 解压压缩包到指定目录
  15. Nagios和ndo2db系统脚本---for gentoo
  16. Rust: Descending Order
  17. Libra最后的命运
  18. android 使用ios字体大小,ios和android上的字体大小不同
  19. android p蓝色壁纸,iPhone和Android的最佳蓝色系壁纸分享
  20. python 排产计划_生产排程计划表

热门文章

  1. 项目经验教训总结(教育软件)
  2. 让32位Eclipse和64位Eclipse同时在64的Windows7上运行
  3. html图片左右转换,jquery实现图片左右切换的方法
  4. 人生忠告一共给所有女人和男人
  5. 认识USB-TYPEA/B/C/micro/mini
  6. I.MX6ULL之LCD显示
  7. php mysql字符串截取比较读取_MySQL字符串截取 和 截取字符进行查询
  8. 局域网下 mac和Windows 互相访问共享文件
  9. 华为p10自带计算机,华为p10如何连接电脑 华为p10连接电脑教程【图文】
  10. USACO-The Castle