微信支付说明
1.统一下单接口
统一支付接口:
  url: https://api.mch.weixin.qq.com/pay/unifiedorder
  目的:通过此接口来创建预支付订单,获取订单支付需要的prepay_id
  过程:
    1.对所有的支付中使用到的参数以字典序排序,然后使用商户的key进行MD5加密,获得加密字符串sign,
    2.然后将sign加入以上信息中将其转化为xml,调用统一下单接口,获取prepay_id。
  代码说明:
    
   

1.构建支付参数
//写购买商品的详情
JSONObject object = new JSONObject();
JSONArray array = new JSONArray();
JSONObject object1 = new JSONObject();
object1.put("goods_id","购买商品id");
object1.put("goods_name","购买商品名称");
object1.put("quantity","购买商品数量");
object1.put("price","商品单价");
array.add(object1);
object.put("goods_detail",array);
//构建统一下单需要的参数
Map<String,String> map = new HashMap<>();
map.put('appid',"支付的微信公众号的appid");
map.put("mch_id","支付的商户号");
map.put("device_info","设备编号");
map.put("sign_type","加密类型,一般使用MD5");
map.put("body","商品描述");
map.put("out_trade_no","商户订单号");
map.put("total_url","购买总金额");
map.put("notify_url","支付成功后微信的回掉地址,地址不许带参数");
map.put("trade_type","交易类型");
map.put("nonce_str","随机字符串");
map.put("detail","商品详情");
map.put("openid","支付人的openid");
map.put("spbill_create_ip","支付人ip地址");
//将统一下单参数进行字典序排序,进行签名

/**
* 微信支付签名算法(详见:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3).
*
* @param params 参数信息
* @param signType 签名类型,如果为空,则默认为MD5
* @param signKey 签名Key
* @param ignoreSignType 签名时,是否忽略signType
* @return 签名字符串
*/
public static String createSign(Map<String, String> params, String signType, String signKey, boolean ignoreSignType) {
  SortedMap<String, String> sortedMap = new TreeMap<>(params);   StringBuilder toSign = new StringBuilder();
  for (String key : sortedMap.keySet()) {
    String value = params.get(key);
    boolean shouldSign = false;
    if (ignoreSignType && "sign_type".equals(key)) {
      shouldSign = false;
    } else if (StringUtils.isNotEmpty(value)
      && !Lists.newArrayList("sign", "key", "xmlString", "xmlDoc", "couponList").contains(key)) {
       shouldSign = true;
    }   if (shouldSign) {
    toSign.append(key).append("=").append(value).append("&");
  }
 }   toSign.append("key=").append(signKey);
  if ("HMAC_SHA256".equals(signType)) {
    return createHmacSha256Sign(toSign.toString(), signKey);
  } else {
    return DigestUtils.md5Hex(toSign.toString()).toUpperCase();
  }
} //将上一步得到的签名加入上一个支付参数中,转为xml请求统一支付下单接口,获取订单支付需要的prepay_id
map.put("sign","上一步得到的签名");
//将map转为xml
public static String map2XmlString(Map<String, String> map) {
  String xmlResult = "";   StringBuffer sb = new StringBuffer();
  sb.append("<xml>");
  for (String key : map.keySet()) {
    String value = "<![CDATA[" + map.get(key) + "]]>";
    sb.append("<" + key + ">" + value + "</" + key + ">");
  }
  sb.append("</xml>");
  xmlResult = sb.toString();
  return xmlResult;
}
//进行网络请求 public static String httpPostWithXml(String xml, String url){
  StringBuffer stringBuffer = new StringBuffer();
  HttpPost post = null;
  try {
    HttpClient httpClient = new DefaultHttpClient(); // 设置超时时间
//httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 2000);
//httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 2000);     post = new HttpPost(url);
// 构造消息头
    post.setHeader("Content-type", "application/json; charset=utf-8");
    post.setHeader("Connection", "Close"); // 构建消息实体
    StringEntity entity = new StringEntity(xml,"UTF-8");
    entity.setContentEncoding("UTF-8");
// 发送Json格式的数据请求
    entity.setContentType("application/json");
    post.setEntity(entity);     HttpResponse response = httpClient.execute(post);
// 检验返回码
    int statusCode = response.getStatusLine().getStatusCode();
    if(statusCode != HttpStatus.SC_OK){
      LogUtil.info("请求出错: "+statusCode);
    }else{
      InputStream inputStream = response.getEntity().getContent();
      BufferedReader br = new BufferedReader(new InputStreamReader(inputStream,"utf-8"));       String str= "";
      while((str = br.readLine()) != null){
        stringBuffer .append(str );
      }
    }
  } catch (Exception e) {
    e.printStackTrace();
  }
  return stringBuffer.toString();
}
//得到了prepay_id,获取支付的签名
Map<String,String> map = new HashMap<>();
map.put('appId',"支付的微信公众号的appid");
map.put("signType","加密类型");
map.put("nonceStr","随机字符串");
map.put("package","固定格式: prepay_id=上一步获得的prepay_id");
map.put("timeStamp","当前时间戳");
//将上面的参数使用商户key进行签名,得到paysign,将paySign加入上面的参数之中,发给h5页面调起支付。
map.put(paySign,"得到的签名"); //h5页面调起支付
WeixinJSBridge.invoke(
  'getBrandWCPayRequest', {
    "appId":rs.appId, //公众号名称,由商户传入
    "timeStamp":rs.timeStamp, //时间戳,自1970年以来的秒数
    "nonceStr":rs.nonceStr, //随机串
    "package":rs.package,
    "signType":"MD5", //微信签名方式:
    "paySign":rs.paySign //微信签名
  },
  function(res){
    if(res.err_msg == "get_brand_wcpay_request:ok" ) {
      //支付成功
    }else if(res.err_msg =="get_brand_wcpay_request:fail"){
      //支付失败
    }else if(res.err_msg == "get_brand_wcpay_request:cancel"){
      //取消支付
    }else {
      //其他情况
    }
  }
);

微信公众号H5支付的更多相关文章

  1. 微信公众号H5支付遇到的那些坑

    简史 官方文档说的很清楚,商户已有H5商城网站,用户通过消息或扫描二维码在微信内打开网页时,可以调用微信支付完成下单购买的流程. 当然,最近微信支付平台也加入了纯H5支付,也就是说用户可以在微信以外的 ...

  2. 微信公众号H5支付步骤

    微信公众平台:https://mp.weixin.qq.com/ 进入 微信支付 管理>开通支付功能. 微信支付|商户平台: 设置安全目录:https://pay.weixin.qq.com/i ...

  3. 微信公众号JSAPI支付

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

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

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

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

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

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

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

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

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

  8. appium操作微信公众号H5 web页面

    安卓微信公众号的H5页面是webview,一般操作需要切换context. 在执行如下步骤,就能直接像识别native样识别webview 1.代码追加: ChromeOptions options ...

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

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

随机推荐

  1. pl/sql 语言设置

    1.select * from v$nls_parameters 查询nls的参数,获得数据库服务器端的字符编码 NLS_LANGUAGE NLS_CHARACTERSET 2.修改本地环境变量 NL ...

  2. Java泛型与Restlet客户端

    写一个与restlet服务器通信的客户端类,用于测试通信是否成功,并且进行交互.为了方便其他人使用,于是,写一个通用的方法封装起来,可是中途却放生了一些问题. 按照正常写法,顺序走下来是这样的: pu ...

  3. INDEX--创建索引和删除索引时的SCH_M锁

    最近有一个困惑,生产服务器上有一表索引建得乱七八糟,经过整理后需要新建几个索引,再删除几个索引,建立索引时使用联机(ONLINE=ON)创建,查看下服务器负载(磁盘和CPU压力均比较低的情况)后就选择 ...

  4. TSQL--删除登陆相关的用户

    无二话,上代码 --删除登陆相关的用户 --遍历所有数据库,查找到与登录名相关联的的用户,生成删除脚本 ) SET @loginName='DBA'; DECLARE @comm NVARCHAR(M ...

  5. [ASP.NET]Net Framework环境问题的一种修复方案

    一.情况介绍 造价软件基于.net framework 4.0开发,要成功运行需要在目标电脑上安装4.0版本以上的framework.一般情况下xp是没有的,win7系列自带3.5,都需要手动安装4. ...

  6. .Net Core2.0中使用ADO.NET

    学习了解.NET CORE有段时间,没有用其做项目的主要原因就是这么多年积累的类库兼容问题.今天就先解决SqlHelper的兼容性: 建立类库,目标框架选择.NET Core2.0,复制粘贴代码. 问 ...

  7. 枚举类型内部函数 enumerate

    enumerate()说明enumerate()是python的内置函数enumerate在字典上是枚举.列举的意思对于一个可迭代的(iterable)/可遍历的对象(如列表.字符串),enumera ...

  8. Mysql分析-profile详解

    一.前言当我们要对某一条sql的性能进行分析时,可以使用它. Profiling是从 mysql5.0.3版本以后才开放的.启动profile之后,所有查询包括错误的语句都会记录在内.关闭会话或者se ...

  9. Django(app的概念、ORM介绍及编码错误问题)

    day61 Django中的APP:         什么是APP?以及为什么要用APP?                  project  --> 项目  (老男孩教育大学校)        ...

  10. Swift 中@available 和 #available

    Swift 2.0 中,引入了可用性的概念.对于函数,类,协议等,可以使用@available声明这些类型的生命周期依赖于特定的平台和操作系统版本.而#available用在判断语句中(if, gua ...