必要参数: 

    1) AppID,AppSecret : 在微信公众号后台管理—>(菜单栏)开发 —> 基本设置

    2)商户号 :在微信公众号后台管理—>(菜单栏)微信支付—> 商户号管理

     

    3)商户秘钥 :在微信商户平台(可直接点击上图的“查看”)商户平台 —> 产品中心 —> 开发配置

 基本配置:

      1)IP白名单:a.测试电脑的ip地址,b.存放WebApi的服务器电脑ip地址

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

注:  a.前端页面的地址 b.后台支付方法的地址(都是域名而不是IP)

具体步骤:

    1)添加充值按钮

<div class="mui-content-padded" style="margin-top: 6%;">
<button id='login' class="mui-btn mui-btn-block mui-btn-primary">充值</button>
</div>

  2)引用js

       获取当前设备的IP地址: <script type="text/javascript" src="http://pv.sohu.com/cityjson?ie=utf-8"></script>         

3)获取code  ,openid     

注:redirect_uri:是返回当前页面的 url,code的值会追加在这个地址后面,所以可以根据url的地址截取到需要的code值(如果有需要加的参数,可以直接写在后面,如标记的一样)
(function($) {
$.init();
var url = location.search;
var str = url.substr(1);
code = str.split('code=')[1].split('&')[0];
//页面加载时,判断code有没有值,没有就访问 获取if (code == 'null') {
var numberurl = cardnumber + "=" + id;
window.location.href =
"https://open.weixin.qq.com/connect/oauth2/authorize?appid=(是你的AppID)&redirect_uri=http://llcz.jolinmind.com/taocan.html?number=" +
numberurl + "&id=" + id + "&response_type=code&scope=snsapi_base&state=STATE&connect_redirect=1#wechat_redirect"; } else {
var codeN = code;
mui.ajax({
url: '……/api/pay/get?jsoncallback=?',
data: {
code: codeN
},
async: true,
dataType: 'json',
crossDomain: true,
type: 'get',
timeout: 10000,
success: function(data) {
openid=data;
},
});
} })(mui);

   后台Webapi:

   _appid =AppID ,_secret =AppSecret 

  public object Get(string code)
{
string html = string.Empty;
string url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+ _appid + "&secret="+ _secret + "&code="+ code + "&grant_type=authorization_code";
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Method = "GET";
request.ContentType = "text/html;charset=UTF-8";
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
Stream ioStream = response.GetResponseStream();
StreamReader sr = new StreamReader(ioStream, Encoding.UTF8);
html = sr.ReadToEnd();
sr.Close();
ioStream.Close();
response.Close();
RepParamrepCode rep = JsonConvert.DeserializeObject<RepParamrepCode>(html);
return rep.openid; } public class RepParamrepCode
{
public string access_token { get; set; }
public string expires_in { get; set; }
public string refresh_token { get; set; }
public string openid { get; set; }
public string scope { get; set; }
}

     4)支付

    document.getElementById("login").addEventListener('tap', function() {
getCode();
});function getCode() {
mui.ajax({
url: '……/api/pay/get?jsoncallback=?',
data: {
openid: openid,
motto: returnCitySN.cip,(当前设备的IP地址)
xufei: (支付金额)
},
async: true,
dataType: 'json',
crossDomain: true,
type: 'get',
timeout: 10000,
success: function(res) {
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(res)
}
}
});
}
}
function onBridgeReady(data) {
var list = JSON.parse(data);
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId": (你的AppId),
"timeStamp": list['timeStamp'], //时间戳,自1970年以来的秒数
"nonceStr": list['nonceStr'], //随机串
"package": list['package1'],
"signType": list['signType'], //微信签名方式:
"paySign": list['paySign'] //微信签名
},
function(res) {
if (res.err_msg == "get_brand_wcpay_request:ok") {
操作成功后,你自己的方法。 } else if (res.err_msg == "get_brand_wcpay_request:cancel") {
mui.alert('取消支付!', '提示'); } else {
mui.alert('支付失败!', '提示');
}
});
}

  后台Webapi:

  public string Get(string openid, string motto, int xufei)
{
return Getprepay_id(_appid, _mch_id, GetRandomString(),"抬头", getRandomTime(), xufei, motto, "http://……/api/OM/get(支付成功后验证数据库是否有数据的地址)", openid); }
//微信统一下单获取prepay_id & 再次签名返回数据
private static string Getprepay_id(string appid, string mch_id, string nonce_str, string body,string out_trade_no,int total_fee, string spbill_create_ip ,string notify_url, string openid)
{
var url = "https://api.mch.weixin.qq.com/pay/unifiedorder";//微信统一下单请求地址 string strA = "appid=" + appid + "&body=" + body + "&mch_id=" + mch_id + "&nonce_str=" + nonce_str + "&notify_url=" + notify_url + "&openid=" + openid + "&out_trade_no=" + out_trade_no + "&spbill_create_ip=" + spbill_create_ip + "&total_fee=" + total_fee + "&trade_type=JSAPI"; string strk = strA + "&key=" + _key; //key为商户平台设置的密钥key(假)
string strMD5 = MD5(strk).ToUpper();//签名
var formData = "<xml>";
formData += "<appid>" + appid + "</appid>";//appid
formData += "<body>" + body + "</body>";
formData += "<mch_id>" + mch_id + "</mch_id>";//商户号
formData += "<nonce_str>" + nonce_str + "</nonce_str>";//随机字符串,不长于32位。
formData += "<notify_url>" + notify_url + "</notify_url>";
formData += "<openid>" + openid + "</openid>";
formData += "<out_trade_no>" + out_trade_no + "</out_trade_no>";
formData += "<spbill_create_ip>" + spbill_create_ip + "</spbill_create_ip>";//终端IP --用户ip
formData += "<total_fee>" + total_fee + "</total_fee>";
formData += "<trade_type>JSAPI</trade_type>";//交易类型(JSAPI--公众号支付)
formData += "<sign>" + strMD5 + "</sign>"; //签名
formData += "</xml>";
string v = sendPost(url, formData);
string prepay_id = v;
//时间戳
string _time = getTime().ToString(); string strB = "appId=" + appid + "&nonceStr=" + nonce_str + "&package=prepay_id=" + prepay_id + "&signType=MD5&timeStamp=" + _time + "&key=" + _key;
wx w = new wx();
w.timeStamp = _time;
w.nonceStr = nonce_str;
w.package1 = "prepay_id=" + prepay_id;
w.paySign = MD5(strB).ToUpper();
w.signType = "MD5";
return JsonConvert.SerializeObject(w);
} private static string sendPost(string postUrl, string menuInfo)
{
string returnValue = string.Empty;
byte[] byteData = Encoding.UTF8.GetBytes(menuInfo);
Uri uri = new Uri(postUrl);
HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(uri);
webReq.Method = "POST";
webReq.ContentType = "application/x-www-form-urlencoded";
webReq.ContentLength = byteData.Length;
//定义Stream信息
Stream stream = webReq.GetRequestStream();
stream.Write(byteData, , byteData.Length);
stream.Close();
//获取返回信息
HttpWebResponse response = (HttpWebResponse)webReq.GetResponse();
StreamReader streamReader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
returnValue = streamReader.ReadToEnd();
//关闭信息
streamReader.Close();
response.Close();
stream.Close(); XmlDocument doc = new XmlDocument();
doc.LoadXml(returnValue);
XmlNodeList list = doc.GetElementsByTagName("xml");
XmlNode xn = list[];
string prepay_ids = xn.SelectSingleNode("//prepay_id").InnerText;
return prepay_ids; }
         /// <summary>
/// MD5签名方法
/// </summary>
/// <param name="inputText">加密参数</param>
/// <returns></returns>
private static string MD5(string inputText)
{
MD5 md5 = new MD5CryptoServiceProvider();
byte[] fromData = System.Text.Encoding.UTF8.GetBytes(inputText);
byte[] targetData = md5.ComputeHash(fromData);
string byte2String = null; for (int i = ; i < targetData.Length; i++)
{
byte2String += targetData[i].ToString("x2");
} return byte2String;
}
        /// <summary>
/// 生成订单号
/// </summary>
/// <returns></returns>
private static string getRandomTime()
{
Random rd = new Random();//用于生成随机数
string DateStr = DateTime.Now.ToString("yyyyMMddHHmmssMM");//日期
string str = DateStr + rd.Next().ToString().PadLeft(, '');//带日期的随机数
return str;
}
        /// <summary>
/// 生成随机串
/// </summary>
/// <param name="length">字符串长度</param>
/// <returns></returns>
private static string GetRandomString(int length)
{
const string key = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
if (length < )
return string.Empty; Random rnd = new Random();
byte[] buffer = new byte[]; ulong bit = ;
ulong result = ;
int index = ;
StringBuilder sb = new StringBuilder((length / + ) * ); while (sb.Length < length)
{
rnd.NextBytes(buffer); buffer[] = buffer[] = buffer[] = 0x00;
result = BitConverter.ToUInt64(buffer, ); while (result > && sb.Length < length)
{
index = (int)(bit & result);
sb.Append(key[index]);
result = result >> ;
}
}
return sb.ToString();
}
         /// <summary>
/// 获取时间戳
/// </summary>
/// <returns></returns>
///
private static long getTime()
{
TimeSpan cha = (DateTime.Now - TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(, , )));
long t = (long)cha.TotalSeconds;
return t;
}

微信支付接口签名验证工具:

  https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=20_1

     

【微信支付】公众号 JSAPI支付 HTML5(使用MUI前端框架)+WebApi 实现流程的更多相关文章

  1. 微信公众号JSAPI支付

    微信公众号JSAPI支付 一:配置参数 申请成功后,获取接口文件, 将所有文件放入项目根目录weixin下,在WxPay.ub.config.php中填入配置账户信息; 二:设置授权 开发者中心-&g ...

  2. 【weixi】微信支付---微信公众号JSAPI支付

    一.JSAPI支付 JSAPI支付是用户在微信中打开商户的H5页面,商户在H5页面通过调用微信支付提供的JSAPI接口调起微信支付模块完成支付.应用场景有: ◆ 用户在微信公众账号内进入商家公众号,打 ...

  3. 微信公众号JSAPI支付-多公众号向同一商户号支付的问题解决

    一.背景 项目提供公众号商城集成,在公众号里进行商品的购买,并与多家公众号合作增加渠道流量. . 二.实现 有关微信公众号.商户号的开通与支付绑定不细说 从背景里可知,我们需要实现多个公众号购买向同一 ...

  4. java微信公众号JSAPI支付以及所遇到的坑

    上周做了个支付宝微信扫码支付,今天总结一下.微信相比支付宝要麻烦许多 由于涉及到代理商,没办法,让我写个详细的申请流程,懵逼啊. 笔记地址 http://note.youdao.com/notesha ...

  5. PHP应用如何对接微信公众号JSAPI支付

    微信支付的产品有很多,1. JSAPI支付  2. APP支付  3. Native支付  4.付款码支付  5. H5支付. 其中基于微信公众号开发的应用选择“JSAPI支付“产品,其他APP支付需 ...

  6. 网站如何接入微信公众号JSAPI支付PHP版

    1.首先,我们要有一个微信公众号(分类类型有订阅号,服务号,企业号)我们的微信公众号一定是个服务号只有它才有微信支付接口.. 并且这个微信公众号一定要进行微信认证才能申请微信支付接口. 2.申请JSA ...

  7. 在Thinkphp中微信公众号JsApi支付

    由于网站使用的微信Native扫码支付,现在公众号需要接入功能,怎么办呢,看这官方文档,参考着demo进行写吧.直接进入正题 进入公众号(服务号)设置--->功能设置--->网页授权域名配 ...

  8. Vue3+Typescript+Node.js实现微信端公众号H5支付(JSAPI v3)教程--各种填坑

    ----微信支付文档,不得不说,挺乱!(吐槽截止) 功能背景 微信公众号中,点击菜单或者扫码,打开公众号中的H5页面,进行支付. 一.技术栈 前端:Vue:3.0.0,typescript:3.9.3 ...

  9. PHP微信公众号JSAPI网页支付(下)

    上一篇PHP微信公众号JSAPI网页支付(上)中讲到了公众号平台的相关设置以及支付的大致流程. 这一篇重点讲支付后,异步接受回调通知,以及处理后同步通知微信服务器. 首先梳理下整个jsapi支付的流程 ...

随机推荐

  1. 设计自用的golang日志模块

    设计自用的golang日志模块 golang的原生日志模块不能满足需求,而开源的第三方包,也不完全够用.用户较多的logrus,却没有rotate功能,这已经是众所周知的.对于运维来说,当然是希望日志 ...

  2. 扯扯python的多线程的同步锁 Lock RLock Semaphore Event Condition

    我想大家都知道python的gil限制,记得刚玩python那会,知道了有pypy和Cpython这样的解释器,当时听说是很猛,也就意味肯定是突破了gil的限制,最后经过多方面测试才知道,还是那德行… ...

  3. Qt编写自定义控件43-自绘电池

    一.前言 到了9102年了,现在智能手机不要太流行,满大街都是,甚至连爷爷奶奶级别的人都会用智能手机,本次要写的控件就是智能手机中的电池电量表示控件,采用纯painter绘制,其实也可以采用贴图,我估 ...

  4. 处理线上CPU负载过高的故障现象

    如何处理线上CPU100%的故障现象 处理流程: 1.登陆线上机器top命令,查看耗费cpu的进程号,举例来说发现进程24008持续耗费资源 2.top -Hp 24008去查看持续耗费cpu的线程号 ...

  5. 使用Tomcat搭建基于域名的虚拟机

    Tomcat搭建基于域名的虚拟主机,实际就是实现了同一个Tomcat部署多个项目(网站/应用程序).端口可以使用同一个,也可以不同. (1).在tomcat的conf文件夹下存在Tomcat的配置文件 ...

  6. Kafka Connect Architecture

    Kafka Connect's goal of copying data between systems has been tackled by a variety of frameworks, ma ...

  7. 基于Visual Studio Code搭建Vue开发环境

    安装node.js最新版 这里安装的是8.11.4版   image.png 更新npm至最新版 安装node.js后, npm默认版本为: 6.1.0   image.png 使用npm insta ...

  8. Vidual Studio vs2013彻底卸载

    我的win10 1803 2019年年中升级的,非常后悔,持续不间断的假死状态让人很无奈.又不舍得回退,因为很多保存的隐藏数据. 开始清理系统吧,东西越少性能越好,于是电脑就成了纯净版,甚至连 看到了 ...

  9. 【leetcode算法-中等】2. 两数相加

    [题目描述] 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表 ...

  10. SSH简介及两种远程登录的方法

    出处 https://blog.csdn.net/li528405176/article/details/82810342 目录 SSH的安全机制 SSH的安装 启动服务器的SSH服务 SSH两种级别 ...