zoukankan      html  css  js  c++  java
  • JAVA 微信支付 native方式

         最近做了一个微信native方式支付的demo,整理一下。

        首先到微信公众号官网阅读开发文档,虽然文档对于java没有例子,但是也可以作参考。https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1

        我的demo是用户在商家系统H5页面发起付款申请,商家系统通过H5页面收集相关参数,调用java方法生成支付字符串返回给H5页面,H5页面将支付字符串生成二维码,用户扫描即可支付。我这是最简单的例子。先看页面吧,JSP页面中javascript脚本如下:

    <script src="qrcode.js"></script>   

    <script>
    //这个地址是Demo.java生成的code_url,这个就是java生成的支付字符串,javascript把这个字符串变成二维码显示在页面上,用户即可扫码支付
    var url="weixin://wxpay/bizpayurl?pr=30XrslD";
    //参数1表示图像大小,取值范围1-10;参数2表示质量,取值范围'L','M','Q','H'
    var qr = qrcode(10, 'M');
    qr.addData(url);
    qr.make();
    var dom=document.createElement('DIV');
    dom.innerHTML = qr.createImgTag();
    var element=document.getElementById("qrcode");
    element.appendChild(dom);
    </script>

        看过了jsp页面如何使用支付字符串,那么就来看看最关键的如何用java生成这个支付二维码链接字符串。

        1、 首先看java类中需要的变量有哪些

      //微信支付商户开通后 微信会提供appid和appsecret和商户号partner
      private static String appid = ".......";
      private static String appsecret = ".........";
      //商户号,公众号支付申请通过后发给申请人的邮件中有该信息,需要用商户号登录商户平台查看用户已付款订单等等支付信息
      private static String partner = ".......";
      //这个参数partnerkey是在商户后台配置的一个32位的key,微信商户平台-账户设置-安全设置-api安全。是自己设置的,设置后自己记住。我在商户平台没有发现能查看的地方
      private static String partnerkey = "........";
      //微信支付成功后通知地址 必须要求80端口并且地址不能带参数
      private static String notifyurl = "http://localhost:8080/weChatpay/page/back.jsp";

      2、定义一个支付pojo

          

    public class WxPayDto {

    private String orderId;//订单号
    private String totalFee;//金额
    private String spbillCreateIp;//订单生成的机器 IP
    private String notifyUrl;//这里notify_url是 支付完成后微信发给该链接信息,可以判断会员是否支付成功,改变订单状态等
    private String body;// 商品描述根据情况修改
    private String openId;//微信用户对一个公众号唯一

    //getter、setter等方法

    }

      3、设置支付所需参数

    WxPayDto tpWxPay1 = new WxPayDto();
    tpWxPay1.setBody("商品信息");
    tpWxPay1.setOrderId(getNonceStr());//这个是订单号,可以根据自己系统实际需要设置,我这里其实设置的是时间戳字符串
    tpWxPay1.setSpbillCreateIp("127.0.0.1");
    tpWxPay1.setTotalFee("0.01");//用户需要支付的金额,单位是元
    String codeurl= getCodeurl(tpWxPay1);//这个codeurl就是需要传给H5页面的支付参数了,大概是这样滴:weixin://wxpay/bizpayurl?pr=30XrslD

     4、生成支付二维码链接字符串方法

        

    /**
    * 获取微信扫码支付二维码连接
    */
    public static String getCodeurl(WxPayDto tpWxPayDto){

    // 1 参数
    // 订单号
    String orderId = tpWxPayDto.getOrderId();
    // 附加数据 原样返回
    String attach = "";
    // 总金额以分为单位,不带小数点
    String totalFee =tpWxPayDto.getTotalFee()*100;

    // 订单生成的机器 IP
    String spbill_create_ip = tpWxPayDto.getSpbillCreateIp();
    // 这里notify_url是 支付完成后微信发给该链接信息,可以判断会员是否支付成功,改变订单状态等。
    String notify_url = notifyurl;
    String trade_type = "NATIVE";

    // 商户号
    String mch_id = partner;
    // 随机字符串
    String nonce_str = getNonceStr();//我设置的是时间戳字符串

    // 商品描述根据自己系统情况修改
    String body = tpWxPayDto.getBody();

    // 商户订单号
    String out_trade_no = orderId;

    SortedMap<String, String> packageParams = new TreeMap<String, String>();
    packageParams.put("appid", appid);
    packageParams.put("mch_id", mch_id);
    packageParams.put("nonce_str", nonce_str);
    packageParams.put("body", body);
    packageParams.put("attach", attach);
    packageParams.put("out_trade_no", out_trade_no);

    // 这里写的金额为1 分,根据自己系统实际需要到时修改
    packageParams.put("total_fee", totalFee);
    packageParams.put("spbill_create_ip", spbill_create_ip);
    packageParams.put("notify_url", notify_url);

    packageParams.put("trade_type", trade_type);

    RequestHandler reqHandler = new RequestHandler(null, null);
    reqHandler.init(appid, appsecret, partnerkey);

    String sign = reqHandler.createSign(packageParams);
    String xml = "<xml>" + "<appid>" + appid + "</appid>" + "<mch_id>"
    + mch_id + "</mch_id>" + "<nonce_str>" + nonce_str
    + "</nonce_str>" + "<sign>" + sign + "</sign>"
    + "<body><![CDATA[" + body + "]]></body>"
    + "<out_trade_no>" + out_trade_no
    + "</out_trade_no>" + "<attach>" + attach + "</attach>"
    + "<total_fee>" + totalFee + "</total_fee>"
    + "<spbill_create_ip>" + spbill_create_ip
    + "</spbill_create_ip>" + "<notify_url>" + notify_url
    + "</notify_url>" + "<trade_type>" + trade_type
    + "</trade_type>" + "</xml>";
    String code_url = "";
    //统一支付接口
    String createOrderURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    code_url = new GetWxOrderno().getCodeUrl(createOrderURL, xml);
    return code_url;//支付二维码链接字符串
    }

       这就是最简单的java版本微信公众号扫码native支付方式demo,欢迎你交流经验问题。

      ps:这是GetWxOrderno类的全部代码

    package com.utils;


    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;

    import org.apache.http.HttpResponse;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.client.params.ClientPNames;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.util.EntityUtils;
    import org.jdom.Document;
    import org.jdom.Element;
    import org.jdom.JDOMException;
    import org.jdom.input.SAXBuilder;

    import com.utils.http.HttpClientConnectionManager;

    public class GetWxOrderno
    {
    public static DefaultHttpClient httpclient;

    static
    {
    httpclient = new DefaultHttpClient();
    httpclient = (DefaultHttpClient)HttpClientConnectionManager.getSSLInstance(httpclient);
    }


    /**
    *description:获取预支付id
    *@param url
    *@param xmlParam
    *@return
    * @author ex_yangxiaoyi
    * @see
    */
    public static String getPayNo(String url,String xmlParam){
    DefaultHttpClient client = new DefaultHttpClient();
    client.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true);
    HttpPost httpost= HttpClientConnectionManager.getPostMethod(url);
    String prepay_id = "";
    try {
    httpost.setEntity(new StringEntity(xmlParam, "UTF-8"));
    HttpResponse response = httpclient.execute(httpost);
    String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
    if(jsonStr.indexOf("FAIL")!=-1){
    return prepay_id;
    }
    Map map = doXMLParse(jsonStr);
    prepay_id = (String) map.get("prepay_id");
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    return prepay_id;
    }

    /**
    *description:获取扫码支付连接
    *@param url
    *@param xmlParam
    *@return
    * @author ex_yangxiaoyi
    * @see
    */
    public static String getCodeUrl(String url,String xmlParam){
    DefaultHttpClient client = new DefaultHttpClient();
    client.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true);
    HttpPost httpost= HttpClientConnectionManager.getPostMethod(url);
    String code_url = "";
    try {
    httpost.setEntity(new StringEntity(xmlParam, "UTF-8"));
    HttpResponse response = httpclient.execute(httpost);
    String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
    if(jsonStr.indexOf("FAIL")!=-1){
    return code_url;
    }
    Map map = doXMLParse(jsonStr);
    code_url = (String) map.get("code_url");
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    return code_url;
    }


    /**
    * 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
    * @param strxml
    * @return
    * @throws JDOMException
    * @throws IOException
    */
    public static Map doXMLParse(String strxml) throws Exception {
    if(null == strxml || "".equals(strxml)) {
    return null;
    }

    Map m = new HashMap();
    InputStream in = String2Inputstream(strxml);
    SAXBuilder builder = new SAXBuilder();
    Document doc = builder.build(in);
    Element root = doc.getRootElement();
    List list = root.getChildren();
    Iterator it = list.iterator();
    while(it.hasNext()) {
    Element e = (Element) it.next();
    String k = e.getName();
    String v = "";
    List children = e.getChildren();
    if(children.isEmpty()) {
    v = e.getTextNormalize();
    } else {
    v = getChildrenText(children);
    }

    m.put(k, v);
    }

    //关闭流
    in.close();

    return m;
    }
    /**
    * 获取子结点的xml
    * @param children
    * @return String
    */
    public static String getChildrenText(List children) {
    StringBuffer sb = new StringBuffer();
    if(!children.isEmpty()) {
    Iterator it = children.iterator();
    while(it.hasNext()) {
    Element e = (Element) it.next();
    String name = e.getName();
    String value = e.getTextNormalize();
    List list = e.getChildren();
    sb.append("<" + name + ">");
    if(!list.isEmpty()) {
    sb.append(getChildrenText(list));
    }
    sb.append(value);
    sb.append("</" + name + ">");
    }
    }

    return sb.toString();
    }
    public static InputStream String2Inputstream(String str) {
    return new ByteArrayInputStream(str.getBytes());
    }

    }

  • 相关阅读:
    Flask-wtforms 组件
    flask-session
    [架构漫谈]软件架构师如何工作
    [Python]爬取新型冠状病毒2.2至今的所有数据 python 2020.2.13
    [Python]爬取首都之窗百姓信件网址id python 2020.2.13
    假期学习【十三】信息领域热词分析系统--整体完成
    假期学习【十二】热词分析系统--初步展示
    [Python]python对csv去除重复行 python 2020.2.11
    pip工具下载速度慢的问题
    [Python]pyhon去除txt文件重复行 python 2020.2.10
  • 原文地址:https://www.cnblogs.com/DylanZ/p/5867287.html
Copyright © 2011-2022 走看看