必要参数: 

    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. Redis 单线程却能支撑高并发 - 简书 https://www.jianshu.com/p/2d293482f272

    小结: 1.在 I/O 多路复用模型中,最重要的函数调用就是 select,该方法的能够同时监控多个文件描述符的可读可写情况:2.Redis 服务采用 Reactor 的方式来实现文件事件处理器(每一 ...

  2. 8个华丽而实用的Java图表类库

    8个华丽而实用的Java图表类库 转 https://www.300168.com/yidong/show-2744.html   核心提示:学习Java的同学注意了!!! 学习过程中遇到什么问题或者 ...

  3. osg 三维模型加载与解析(fbx、3ds、ive、obj、osg)

    void TeslaManage::OnlineTreeViewDoubleClick(const QModelIndex & index) { int row = index.row(); ...

  4. ubuntu server 18.04 有线网卡默认关闭,需要手工配置才能使用的方法

    1.安装完ubuntu server 18.04 后,笔记本电脑的有线网卡已经识别了,但是没有ip, 并且插上网线后端口灯不亮. 解决方法: 第一步.配置端口链路状态为 up # ip link se ...

  5. 阶段5 3.微服务项目【学成在线】_day17 用户认证 Zuul_06-用户认证-认证服务查询数据库-Bcrypt介绍

    演示MD5加密的方式 数据库内的数据密码虽然都是6个1但是 每次加密出来的字符串是不一样的 加盐 测试BCrpty 循环10次加密 密码的校验 比人工的加盐要方便的多 这是创建的一个Spring的Be ...

  6. PAT 甲级 1044 Shopping in Mars (25 分)(滑动窗口,尺取法,也可二分)

    1044 Shopping in Mars (25 分)   Shopping in Mars is quite a different experience. The Mars people pay ...

  7. thymeleaf自定义属性

    例如我想给添加一个属性data-page,可以根据(SpringEL/Ognl)表达式计算获得. 需求: 期望效果 app个数大于0,有数据时链接 <xxx data-page="/a ...

  8. PostgreSQL学习笔记——内置函数

    算术函数(数值计算) +(加).-(减).*(乘)./(除) ABS函数--绝对值: ABS(数值) MOD--求余: MOD(被除数,除数) ROUND--四舍五入: ROUND(对象数值,保留小数 ...

  9. Vue 中 css scoped 样式穿透 ( stylus[>>>] / sass / less[/deep/] )

    scoped看起来很好用,当时在Vue项目中,当我们引入第三方组件库时(如使用element-ui),需要在局部组件中修改第三方组件库样式,而又不想去除scoped属性造成组件之间的样式覆盖.这时我们 ...

  10. python全栈索引

    书签 python基础 太白金星 TigerLee python基础一 pytcharm安装详细教程 python基础二 python基础数据类型 Python最详细,最深入的代码块小数据池剖析 深浅 ...