小程序付款

js:
小程拉起付款api

const app = getApp()
Page({
  onLoad: function (option) {
  },
   //付款,创建订单获取页面拉起付款所需参数
  payment: function(){
    let _this = this;
    let url = '/wxPay';
    wx.request({
      url: url,
      data: {
        openId: openid,
        money: '100' //金额为分
      },
      header: {
        'content-type': 'application/json' // 默认值
      },
      success: function (res) {
        console.log('res', res);
        if (res.data.flag == 'Y') {
          doWxPay(res.data)
        }
      }
    })
  },
 
    doWxPay(param) {
    let that = this;
    //小程序发起微信支付
    wx.requestPayment({
      timeStamp: param.result.timeStamp,//记住,这边的timeStamp一定要是字符串类型的,不然会报错
      nonceStr: param.result.nonceStr,
      package: param.result.package,
      signType: 'MD5',
      paySign: param.result.paySign,
      success: function (event) {
        console.log("支付成功")
      },
      fail: function (error) {
        console.log("支付失败")
        console.log(error)
      },
      complete: function () {
      }
    });
  },
})

后台代码:
付款成功回调api

public class OrderController {
    @ResponseBody
    @RequestMapping("/wxPay")
    public JSONObject wxPay(String openId, String money, HttpServletRequest request){
        JSONObject json = new JSONObject();
        try {
            //生成的随机字符串
            String nonce_str = Sha1Util.getRandomStringByLength(32);
            //商品名称
            String body ="商品付款";
            //获取本机的IP地址
            String spbill_create_ip = IpUtils.getIpAddr(request);
            String timeStamp=Sha1Util.getTimeStamp();//时间戳
            int number = (int)((Math.random()*9+1)*10000);
            String orderNo = "ODER-" + Long.toString(System.currentTimeMillis() / 1000) + String.valueOf(number);
            Long amount = Long.valueOf(money);


            TreeMap<String,String> packageParams = new TreeMap<String,String>();
            packageParams.put("appid", "小程序appid");
            packageParams.put("mch_id","小程序商户id");
            packageParams.put("nonce_str",nonce_str);//随机字符串
            packageParams.put("body",body);//商品名称
            packageParams.put("out_trade_no",orderNo); //商户订单号
            packageParams.put("total_fee",String.valueOf(amount)); //支付金额,单位:分,,这边需要转成字符串类型,否则后面的签名会失败
            packageParams.put("spbill_create_ip",spbill_create_ip);//ip地址
            packageParams.put("notify_url","回调地址");
            packageParams.put("trade_type","JSAPI");//回调地址
            packageParams.put("openid",openId);
            String wxpackage = WeiXinSignAndPackage.createPackage(packageParams, "商户密钥");
            packageParams.put("sign", wxpackage);
            System.out.println("--------------------------------------------");
            System.out.println(wxpackage);
            String result=WeiXinSignAndPackage.getPrepayId(packageParams,"https://api.mch.weixin.qq.com/pay/unifiedorder");//调用统一接口返回的值
            System.out.println("--------------------------------------------");
            System.out.println(result);
            if(result.equals("")){
                json.put("flag","N");
                json.put("msg","失败!");
                return  json;
            }
            String requestStr = this.requstStr(packageParams);
            //生成订单,业务逻辑
           

            Map<String,String> map= XMLUtil.doXMLParse(result);//调用统一接口返回的值转换为XML格式
            System.out.println(map);
            String return_code = (String) map.get("return_code");//返回状态码
            String result_code =  map.containsKey("result_code") ? map.get("result_code").toString() : "";//返回状态码
            String return_msg = (String) map.get("return_msg");
            if(return_code.equals("SUCCESS") &&  result_code.equals("SUCCESS")){
                TreeMap<String, String> wxPayParamMap = new TreeMap<String, String>();
                wxPayParamMap.put("appId", "appid");
                wxPayParamMap.put("timeStamp",timeStamp );
                wxPayParamMap.put("nonceStr",nonce_str);
                wxPayParamMap.put("package", "prepay_id="+map.get("prepay_id"));
                wxPayParamMap.put("signType", "MD5");
                String paySign=WeiXinSignAndPackage.createPaySign(wxPayParamMap,"商户密钥");//支付得到的签名
               
                wxPayParamMap.put("paySign", paySign);
                wxPayParamMap.put("payMoney", money);//到前段显示使用,支付不需要此参数
                wxPayParamMap.put("orderNo", orderNo);
                json.put("flag","Y");
                json.put("msg","成功!");
                json.put("result",wxPayParamMap);
            }else {
                json.put("flag","N");
                json.put("msg","失败!");
            }
        }catch(CustomException e){
            log.error("失败{}"+e);
            json.put("flag","N");
            json.put("msg","失败!");
        } catch(Exception e2){
            log.error("失败{}"+e2);
            json.put("flag","N");
            json.put("msg","发失败!");
        }
        return  json;
    }
   
     /**
     * 微信小程序支付成功回调函数
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping(value = "/callback")
    public void wxNotify(HttpServletRequest request,HttpServletResponse response) throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream)request.getInputStream()));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while((line = br.readLine()) != null){
            sb.append(line);
        }
        br.close();
        //sb为微信返回的xml
        String notityXml = sb.toString();
        String resXml = "";
        System.out.println("接收到的报文:" + notityXml);

        Map map = PayUtil.doXMLParse(notityXml);

        String returnCode = (String) map.get("return_code");
        if("SUCCESS".equals(returnCode)){
            String result_code = (String) map.get("result_code");
            String transaction_id = (String) map.get("transaction_id");
                //验证签名是否正确
                Map<String, String> validParams = PayUtil.paraFilter(map);  //回调验签时需要去除sign和空值参数
                String validStr = PayUtil.createLinkString(validParams);//把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
                String sign = PayUtil.sign(validStr, "商户密钥", "utf-8").toUpperCase();//拼装生成服务器端验证的签名

                //根据微信官网的介绍,此处不仅对回调的参数进行验签,还需要对返回的金额与系统订单的金额进行比对等
                if(sign.equals(map.get("sign"))){
                    System.out.println("验签成功,微信支付订单号:"+transaction_id);
                    String out_trade_no =  map.containsKey("out_trade_no") ? map.get("out_trade_no").toString() : "";
                    if(StringUtils.isNotEmpty(out_trade_no)){
                        try {
                           //业务逻辑

                            
                        }catch (Exception e){
                            e.printStackTrace();
                        }

                    }

                    //通知微信服务器已经支付成功
                    resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
                } else {
                    System.out.println("微信支付回调失败!签名不一致");
                }


        }else{
            resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
        }
        System.out.println(resXml);
        System.out.println("微信支付回调数据结束");

        BufferedOutputStream out = new BufferedOutputStream(
            response.getOutputStream());
        out.write(resXml.getBytes());
        out.flush();
        out.close();
    }
    
	 private String requstStr(TreeMap<String, String> payParamMap) {
        StringBuffer buffer = new StringBuffer();
        buffer.append("<xml>");
        if (payParamMap != null && !payParamMap.isEmpty()) {
            for (Map.Entry<String, String> entry : payParamMap.entrySet()) {
                if (entry.getKey().equals("attach") || entry.getKey().equals("body") || entry
                    .getKey().equals("sign")) {
                    buffer.append("<" + entry.getKey() + ">");
                    buffer.append("<![CDATA[" + entry.getValue() + "]]>");
                    buffer.append("</" + entry.getKey() + ">");
                } else {
                    buffer.append("<" + entry.getKey() + ">");
                    buffer.append(entry.getValue());
                    buffer.append("</" + entry.getKey() + ">");
                }
            }
        }
        buffer.append("</xml>");
        System.out.println(buffer.toString());
        return buffer.toString();
    }
}




public class WeiXinSignAndPackage {

    //编码
    private static String inputCharset="UTF-8";

    /**
     * 创建支付包Package
     * @param treeMap
     * @return
     */
    public static String createPackage(TreeMap<String,String> treeMap,String paternerKey){
        String string1=originalString(treeMap);
        String stringSignTemp = string1 + "key="+paternerKey;
        String sign= MD5Util.MD5Encode(stringSignTemp, inputCharset).toUpperCase();
 	}
 	
 	/**
     * 创建支付签名paysign
     * @param
     * @return
     */
    public static String createPaySign(TreeMap<String,String> param,String paternerKey){
        String string1=originalString(param);
        String stringSignTemp = string1 + "key="+paternerKey;
        System.out.println("签名调试输出:"+stringSignTemp);
        String paysign=MD5Util.MD5Encode(stringSignTemp, inputCharset).toUpperCase();
        return paysign;
    }
    
	 public static String getPrepayId(TreeMap<String, String> payParamMap,String prepayIdUrl){
        StringBuffer buffer = new StringBuffer();
        buffer.append("<xml>");
        if (payParamMap != null && !payParamMap.isEmpty()) {
            for (Entry<String, String> entry : payParamMap.entrySet()) {
                if(entry.getKey().equals("attach") || entry.getKey().equals("body") || entry.getKey().equals("sign")){
                    buffer.append("<"+entry.getKey()+">");
                    buffer.append("<![CDATA["+entry.getValue()+"]]>");
                    buffer.append("</"+entry.getKey()+">");
                }else{
                    buffer.append("<"+entry.getKey()+">");
                    buffer.append(entry.getValue());
                    buffer.append("</"+entry.getKey()+">");
                }
            }
        }
        buffer.append("</xml>");
        System.out.println(buffer.toString());
        String result= HttpClient.sendPost(prepayIdUrl, buffer.toString());
        return result;
    }
 }      
public class XMLUtil {
    /**
     * 解析String类型的xml流对象InputStream
     * 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
     * @param strxml
     * @return
     * @throws JDOMException
     * @throws java.io.IOException
     */
    public static Map<String,String> doXMLParse(String strxml) throws JDOMException, IOException {
        if(null == strxml || "".equals(strxml)) {
            return null;
        }

        Map<String,String> m = new HashMap<String,String>();
        InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));
        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 = XMLUtil.getChildrenText(children);
            }
            m.put(k, v);
        }
        //关闭流
        in.close();
        return m;
    }
}
public class PayUtil {

  /**
   * 除去数组中的空值和签名参数
   * @param sArray 签名参数组
   * @return 去掉空值与签名参数后的新签名参数组
   */
  public static Map<String, String> paraFilter(Map<String, String> sArray) {
    Map<String, String> result = new HashMap<String, String>();
    if (sArray == null || sArray.size() <= 0) {
      return result;
    }
    for (String key : sArray.keySet()) {
      String value = sArray.get(key);
      if (value == null || value.equals("") || key.equalsIgnoreCase("sign")
          || key.equalsIgnoreCase("sign_type")) {
        continue;
      }
      result.put(key, value);
    }
    return result;
  }
  /**
   * 把数组所有元素排序,并按照“参数=参数值”的模式用“&”字符拼接成字符串
   * @param params 需要排序并参与字符拼接的参数组
   * @return 拼接后字符串
   */
  public static String createLinkString(Map<String, String> params) {
    List<String> keys = new ArrayList<String>(params.keySet());
    Collections.sort(keys);
    String prestr = "";
    for (int i = 0; i < keys.size(); i++) {
      String key = keys.get(i);
      String value = params.get(key);
      if (i == keys.size() - 1) {// 拼接时,不包括最后一个&字符
        prestr = prestr + key + "=" + value;
      } else {
        prestr = prestr + key + "=" + value + "&";
      }
    }
    return prestr;
  }


  /**
   * 签名字符串
   * @param text需要签名的字符串
   * @param key 密钥
   * @param input_charset编码格式
   * @return 签名结果
   */
  public static String sign(String text, String key, String input_charset) {
    text = text + "&key=" + key;
    return DigestUtils.md5Hex(getContentBytes(text, input_charset));
  }


  /**
   * @param content
   * @param charset
   * @return
   * @throws SignatureException
   * @throws UnsupportedEncodingException
   */
  public static byte[] getContentBytes(String content, String charset) {
    if (charset == null || "".equals(charset)) {
      return content.getBytes();
    }
    try {
      return content.getBytes(charset);
    } catch (UnsupportedEncodingException e) {
      throw new RuntimeException("MD5签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset);
    }
  }



  /**
   *
   * @param requestUrl请求地址
   * @param requestMethod请求方法
   * @param outputStr参数
   */
  public static String httpRequest(String requestUrl,String requestMethod,String outputStr){
    // 创建SSLContext
    StringBuffer buffer = null;
    try{
      URL url = new URL(requestUrl);
      HttpURLConnection conn = (HttpURLConnection) url.openConnection();
      conn.setRequestMethod(requestMethod);
      conn.setDoOutput(true);
      conn.setDoInput(true);
      conn.connect();
      //往服务器端写内容
      if(null !=outputStr){
        OutputStream os=conn.getOutputStream();
        os.write(outputStr.getBytes("utf-8"));
        os.close();
      }
      // 读取服务器端返回的内容
      InputStream is = conn.getInputStream();
      InputStreamReader isr = new InputStreamReader(is, "utf-8");
      BufferedReader br = new BufferedReader(isr);
      buffer = new StringBuffer();
      String line = null;
      while ((line = br.readLine()) != null) {
        buffer.append(line);
      }
      br.close();
    }catch(Exception e){
      e.printStackTrace();
    }
    return buffer.toString();
  }
  public static String urlEncodeUTF8(String source){
    String result=source;
    try {
      result=java.net.URLEncoder.encode(source, "UTF-8");
    } catch (UnsupportedEncodingException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    return result;
  }


  /**
   * 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
     * @param strxml
     * @return
     */
  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());
  }


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值