微信支付经常用到,做个详细的demo!!!

为了配置好更换,我一般都是把配置放在数据库。

pom依赖

<!--微信支付--><dependency><groupId>com.github.binarywang</groupId><artifactId>weixin-java-pay</artifactId><version>4.0.0</version></dependency><dependency><groupId>jdom</groupId><artifactId>jdom</artifactId><version>1.0</version></dependency>

微信工具

public class PayUtil {/*** 签名字符串** @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 text          需要签名的字符串* @param sign          签名结果* @param key           密钥* @param input_charset 编码格式* @return 签名结果*/public static boolean verify(String text, String sign, String key, String input_charset) {text = text + key;String mySign = DigestUtils.md5Hex(getContentBytes(text, input_charset));if (mySign.equals(sign)) {return true;} else {return false;}}/*** @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);}}private static boolean isValidChar(char ch) {if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'))return true;if ((ch >= 0x4e00 && ch <= 0x7fff) || (ch >= 0x8000 && ch <= 0x952f))return true;// 简体中文汉字编码return false;}/*** 除去数组中的空值和签名参数** @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 requestUrl    请求地址* @param requestMethod 请求方法* @param outputStr     参数*/public static String httpRequest(String requestUrl, String requestMethod, String outputStr) {// 创建SSLContextStringBuffer 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 blocke.printStackTrace();}return result;}/*** 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。** @param strXml* @return* @throws JDOMException* @throws IOException*/public static Map doXMLParse(String strXml) throws Exception {if (null == strXml || "".equals(strXml)) {return null;}/*=============  !!!!注意,修复了微信官方反馈的漏洞,更新于2018-10-16  ===========*/try {Map<String, String> data = new HashMap<String, String>();// TODO 在这里更换DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();documentBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);documentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);documentBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);documentBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);documentBuilderFactory.setXIncludeAware(false);documentBuilderFactory.setExpandEntityReferences(false);InputStream stream = new ByteArrayInputStream(strXml.getBytes("UTF-8"));org.w3c.dom.Document doc = documentBuilderFactory.newDocumentBuilder().parse(stream);doc.getDocumentElement().normalize();NodeList nodeList = doc.getDocumentElement().getChildNodes();for (int idx = 0; idx < nodeList.getLength(); ++idx) {Node node = nodeList.item(idx);if (node.getNodeType() == Node.ELEMENT_NODE) {org.w3c.dom.Element element = (org.w3c.dom.Element) node;data.put(element.getNodeName(), element.getTextContent());}}try {stream.close();} catch (Exception ex) {// do nothing}return data;} catch (Exception ex) {throw ex;}}/*** 获取子结点的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();}/*** StringUtils工具类方法* 获取一定长度的随机字符串,范围0-9,a-z** @param length:指定字符串长度* @return 一定长度的随机字符串*/public static String getRandomStringByLength(int length) {String base = "abcdefghijklmnopqrstuvwxyz0123456789";Random random = new Random();StringBuffer sb = new StringBuffer();for (int i = 0; i < length; i++) {int number = random.nextInt(base.length());sb.append(base.charAt(number));}return sb.toString();}/*** IpUtils工具类方法* 获取真实的ip地址** @param request* @return*/public static String getIpAddr(HttpServletRequest request) {String ip = request.getHeader("X-Forwarded-For");if (StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {//多次反向代理后会有多个ip值,第一个ip才是真实ipint index = ip.indexOf(",");if (index != -1) {return ip.substring(0, index);} else {return ip;}}ip = request.getHeader("X-Real-IP");if (StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {return ip;}return request.getRemoteAddr();}public static InputStream String2InPutStream(String str) {return new ByteArrayInputStream(str.getBytes());}
}

订单小工具

public class OrderUtil {public static String getGeneralOrder() {Date date=new Date();String newString = String.format("%0"+4+"d", (int)((Math.random()*9+1)*1000));SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");String format = sdf.format(date);return format+newString;}
}

提交支付后返给前端的参数

@Data
@ApiModel("微信解码数据")
public class WxOrderResponse {/*** 时间戳*/@ApiModelProperty("时间戳")private String timeStamp;/*** 随机字符串*/@ApiModelProperty("随机字符串")private String nonceStr;/*** prepay_id*/@ApiModelProperty("prepay_id")private String prepayId;/*** 微信支付签名*/@ApiModelProperty("微信支付签名")private String paySign;public String toJson() {return WxGsonBuilder.create().toJson(this);}
}

支付业务Service

public interface WxPayService {//微信小程序支付Result wxPay(String orderId, String openId, String name, BigDecimal amount);//支付回调逻辑boolean orderUpdate(PayTransaction payTransaction, Integer type);//微信退款  支付方式(1app微信 2微信公众号 3微信小程序 9h5微信) 支付单号 退款金额  订单编号boolean wxRefund(Integer payWay, String payNum, String payMoney, String orderNum, Long ordersId, BigDecimal totalFee);//查询订单boolean getQueryOrder(String orderNum);
}

支付业务代码实现类

@Service
@Slf4j
public class WxPayServiceImpl implements WxPayService {@ResourceOrderJpaRepository orderJpaRepository;@ResourceCommonRepository commonRepository;@ResourcePayTransactionJpaRepository payTransactionJpaRepository;@ResourceConsumptionJpaRepository consumptionJpaRepository;//小程序appIdprivate String appId;//微信支付的商户idprivate String mchId;//微信支付的商户密钥private String key;//支付成功后的服务器回调urlprivate String notifyUrl;//签名方式,固定值private String singType = "MD5";//交易类型,小程序支付的固定值为JSAPIprivate String tradeType;//微信统一下单接口地址private String payUrl;//微信查询订单接口private String orderQuery;//微信退款查询接口private String refundQuery;@Overridepublic Result wxPay(String orderId, String openId, String name, BigDecimal amount) {log.info("=========================验证订单是否存在=========================");//通过订单号获取订单if (StrUtil.isEmpty(orderId)) {return ResultUtil.error(500, "订单不存在");}//根据订单号获取订单Order order = orderJpaRepository.findOrderById(orderId);if (order == null) {return ResultUtil.error(500, "订单不存在");}if (order.getStatus() != OrderEnums.StatusEnum.WAIT_PAY.getKey()) {return ResultUtil.error(500, "只有待支付的订单才可以支付");}if (order.getPayPrice().compareTo(amount) != 0) {return ResultUtil.error(500, "支付价格不一致");}//检查订单是否支付中或支付成功if (getQueryOrder(orderId)) {return ResultUtil.error(500, "订单支付中或已支付,请稍等");}log.info("进入订单支付");appId = commonRepository.findOne(6).getValue();mchId = commonRepository.findOne(27).getValue();key = commonRepository.findOne(28).getValue();notifyUrl = commonRepository.findOne(29).getValue();tradeType = commonRepository.findOne(30).getValue();payUrl = commonRepository.findOne(31).getValue();try {log.info("=========================准备支付参数=========================");//生成的随机字符串String nonceStr = PayUtil.getRandomStringByLength(32);//获取客户端的ip地址String ip = "127.0.0.1";//金额String total = amount.multiply(new BigDecimal("100")).setScale(0, BigDecimal.ROUND_DOWN) + "";//封装请求参数Map<String, String> packageParams = new HashMap<String, String>();packageParams.put("appid", appId);packageParams.put("mch_id", mchId);packageParams.put("nonce_str", nonceStr);packageParams.put("body", name);packageParams.put("out_trade_no", orderId);//商品订单号packageParams.put("spbill_create_ip", ip);packageParams.put("total_fee", total);//支付金额,这边需要转成字符串类型,否则后面的签名会失败packageParams.put("notify_url", notifyUrl);packageParams.put("trade_type", tradeType);packageParams.put("openid", openId);// 除去数组中的空值和签名参数packageParams = PayUtil.paraFilter(packageParams);String prestr = PayUtil.createLinkString(packageParams); // 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串log.info("=========================第一次签名=========================");//MD5运算生成签名,这里是第一次签名,用于调用统一下单接口String mySign = PayUtil.sign(prestr, key, "utf-8").toUpperCase();log.info("=========================" + mySign + "=========================");//拼接统一下单接口使用的xml数据,要将上一步生成的签名一起拼接进去String xml = "<xml>"+ "<appid>" + appId + "</appid>"+ "<body>" + name + "</body>"+ "<mch_id>" + mchId + "</mch_id>"+ "<nonce_str>" + nonceStr + "</nonce_str>"+ "<notify_url>" + notifyUrl + "</notify_url>"+ "<openid>" + openId + "</openid>"+ "<out_trade_no>" + orderId + "</out_trade_no>"+ "<spbill_create_ip>" + ip + "</spbill_create_ip>"+ "<total_fee>" + total + "</total_fee>"+ "<trade_type>" + tradeType + "</trade_type>"+ "<sign>" + mySign + "</sign>"+ "</xml>";log.info("=========================准备下单参数=========================");log.info("=========================" + xml + "=========================");log.info("=========================开始调起下单=========================");//调用统一下单接口,并接受返回的结果String result = PayUtil.httpRequest(payUrl, "POST", xml);log.info("=========================下单返回参数=========================");log.info("=========================" + result + "=========================");// 将解析结果存储在HashMap中Map map = PayUtil.doXMLParse(result);log.info("=========================解析返回参数=========================");String returnCode = (String) map.get("return_code");//返回状态码String resultCode = (String) map.get("result_code");//业务结果//封装返回参数WxOrderResponse response = new WxOrderResponse();if (returnCode.equals("SUCCESS")) {if (resultCode.equals("SUCCESS")) {log.info("=========================下单成功=========================");// 业务结果String prepayId = (String) map.get("prepay_id");//返回的预付单信息response.setNonceStr(nonceStr);response.setPrepayId(prepayId);Long timeStamp = System.currentTimeMillis() / 1000;response.setTimeStamp(timeStamp.toString());String stringSignTemp = "appId=" + appId + "&nonceStr=" + nonceStr + "&package=prepay_id=" + prepayId + "&signType=" + singType + "&timeStamp=" + timeStamp;//再次签名,这个签名用于小程序端调用wx.reQueSetPayment方法String paySign = PayUtil.sign(stringSignTemp, key, "utf-8").toUpperCase();log.info("=======================第二次签名:" + paySign + "=====================");response.setPaySign(paySign);//更新订单信息order.setPayType(OrderEnums.PayType.WX.getKey());orderJpaRepository.save(order);log.info("订单更新完成");return ResultUtil.success(response);} else {return ResultUtil.error(500, (String) map.get("err_code_des"));}} else {log.info("=======================解析错误=====================");return ResultUtil.error(500, "微信下单错误");}} catch (Exception e) {log.error("微信支付下单异常:", e);return ResultUtil.error(500, "微信支付错误");}}@Overridepublic boolean orderUpdate(PayTransaction payTransaction, Integer type) {//判断参数是否存在if (payTransaction == null) {return false;}if (StrUtil.isEmpty(payTransaction.getId())) {return false;}if (StrUtil.isEmpty(payTransaction.getPayFrom())) {return false;}if (payTransaction.getStatus() == null || payTransaction.getStatus() != OrderEnums.PayStatus.OK.getKey()) {return false;}log.info("订单回调进入订单更新-验证通过");//根据商品订单编号获取用户商品订单Order order = orderJpaRepository.findOrderById(payTransaction.getId());if (order.getStatus() == OrderEnums.StatusEnum.PAY_OK.getKey()) {return true;}if (order.getPayPrice().multiply(new BigDecimal("100")).compareTo(payTransaction.getRealTotalMoney()) != 0) {return false;}//数据都存在且没有问题,更新订单状态order.setPayTime(payTransaction.getPayTime());order.setStatus(OrderEnums.StatusEnum.PAY_OK.getKey());order.setIsPay(CommonEnums.YesOrNoEnum.YES.getKey());orderJpaRepository.save(order);log.info("订单支付成功结束");//增加消费记录Consumption consumption = new Consumption();consumption.setUserId(order.getUserId());consumption.setOrderId(order.getId());consumption.setType(ConsumptionEnums.PayType.XF.getKey());consumption.setAmount(order.getPayPrice());consumption.setRemake("酒店预定");consumption.setStatus(CommonEnums.StatusEnum.OPEN.getKey());consumption.setCreateTime(new Date());consumptionJpaRepository.save(consumption);//插入支付回调payTransactionJpaRepository.save(payTransaction);log.info("支付回调成功添加");return true;}@Overridepublic boolean wxRefund(Integer payWay, String payNum, String payMoney, String orderNum, Long ordersId, BigDecimal totalFee) {WXConfig config = null;try {config = new WXConfig();} catch (Exception e) {e.printStackTrace();}config.setAppId("");//微信分配的公众账号ID(企业号corpid即为此appid)config.setKey("");//商户秘钥config.setMchId("");//微信支付分配的商户号WXPay wxpay = new WXPay(config);Map<String, String> data = new HashMap<>();data.put("appid", config.getAppID());data.put("mch_id", config.getMchID());data.put("nonce_str", WXPayUtil.generateNonceStr());try {data.put("sign", WXPayUtil.generateSignature(data, config.getKey(), WXPayConstants.SignType.MD5));} catch (Exception e) {e.printStackTrace();return false;}String refundNum = OrderUtil.getGeneralOrder();data.put("out_trade_no", payNum); //订单号,支付单号一致data.put("out_refund_no", refundNum); //退款单号,同一笔用不同的退款单号double total_fee = Double.valueOf(totalFee.toString());data.put("total_fee", new Double(total_fee * 100).intValue() + ""); //1块等于微信支付传入100);data.put("refund_fee", new Double(Double.valueOf(payMoney).doubleValue() * 100).intValue() + ""); //1块等于微信支付传入100);//使用官方API退款try {Map<String, String> response = wxpay.refund(data);if ("SUCCESS".equals(response.get("return_code"))) {//主要返回以下5个参数//成功后更改订单逻辑return true;} else {return false;}} catch (Exception e) {log.info("返回");e.printStackTrace();return false;}}@Overridepublic boolean getQueryOrder(String orderId) {appId = commonRepository.findOne(6).getValue();mchId = commonRepository.findOne(27).getValue();key = commonRepository.findOne(28).getValue();orderQuery = commonRepository.findOne(33).getValue();try {log.info("=========================准备查询订单=========================");//生成的随机字符串String nonceStr = PayUtil.getRandomStringByLength(32);//封装请求参数Map<String, String> packageParams = new HashMap<String, String>();packageParams.put("appid", appId);packageParams.put("mch_id", mchId);packageParams.put("out_trade_no", orderId);//商品订单号packageParams.put("nonce_str", nonceStr);// 除去数组中的空值和签名参数packageParams = PayUtil.paraFilter(packageParams);String pest = PayUtil.createLinkString(packageParams); // 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串log.info("=========================第一次签名=========================");//MD5运算生成签名,这里是第一次签名,用于调用统一下单接口String mySign = PayUtil.sign(pest, key, "utf-8").toUpperCase();log.info("=========================" + mySign + "=========================");//拼接统一下单接口使用的xml数据,要将上一步生成的签名一起拼接进去String xml = "<xml>"+ "<appid>" + appId + "</appid>"+ "<mch_id>" + mchId + "</mch_id>"+ "<nonce_str>" + nonceStr + "</nonce_str>"+ "<out_trade_no>" + orderId + "</out_trade_no>"+ "<sign>" + mySign + "</sign>"+ "</xml>";log.info("=========================准备查询订单参数=========================");log.info("=========================" + xml + "=========================");log.info("=========================开始调起查询订单=========================");//调用统一下单接口,并接受返回的结果String result = PayUtil.httpRequest(orderQuery, "POST", xml);log.info("=========================查询订单返回参数=========================");log.info("=========================" + result + "=========================");// 将解析结果存储在HashMap中Map map = PayUtil.doXMLParse(result);log.info("=========================解析返回参数=========================");String returnCode = (String) map.get("return_code");//返回状态码String resultCode = (String) map.get("result_code");//业务结果String tradeState = (String) map.get("trade_state");//交易状态if (returnCode.equals("SUCCESS") && resultCode.equals("SUCCESS")) {if (tradeState.equals("SUCCESS") || tradeState.equals("USERPAYING")) {return true;} else {return false;}} else {log.info("=======================查询订单错误=====================");return false;}} catch (Exception e) {log.error("微信查询订单异常:", e);return false;}}//模拟 回调//@PostConstructpublic void get() {PayTransaction transaction = new PayTransaction();transaction.setId("c28c6b61a3cf4e279544863f27e1d5f0");transaction.setStatus(2);transaction.setRealTotalMoney(new BigDecimal("1"));transaction.setPayType(0);transaction.setPayFrom("4200001155202108160850926981");transaction.setPayTime(DateUtil.parseDateTime("2021-08-16 09:25:21"));transaction.setCreateBy("wx");transaction.setCreateBy("2021-02-02 12:12:12");orderUpdate(transaction, 4);}
}

支付回调

@RestController
@Api(value = "微信支付", tags = {"微信支付"})
@RequestMapping(value = "/wxPay")
@Slf4j
public class WxPayController {@ResourceCommonRepository commonRepository;@ResourceOrderJpaRepository orderJpaRepository;@ResourceWxPayService wxPayService;//微信支付的商户密钥private String key;@IgnoreSecurity@PostMapping("/wxNotify")@ApiOperation(value = "微信支付回调")@ResponseBodypublic void wxNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {key = commonRepository.findOne(28).getValue();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为微信返回的xmlString notifyXml = sb.toString();String resXml = "";log.info("微信返回xml:" + notifyXml);Map map = PayUtil.doXMLParse(notifyXml);String returnCode = (String) map.get("return_code");if ("SUCCESS".equals(returnCode)) {log.info("回调成功,开始验证签名");//验证签名是否正确Map<String, String> validParams = PayUtil.paraFilter(map);  //回调验签时需要去除sign和空值参数String validStr = PayUtil.createLinkString(validParams);//把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串String sign = PayUtil.sign(validStr, key, "utf-8").toUpperCase();//拼装生成服务器端验证的签名log.info("微信返回签名:" + map.get("sign"));log.info("服务器端签名:" + sign);//根据微信官网的介绍,此处不仅对回调的参数进行验签,还需要对返回的金额与系统订单的金额进行比对等if (sign.equals(map.get("sign"))) {/**此处添加自己的业务逻辑代码start**///获取订单String orderId = (String) map.get("out_trade_no");//支付金额(单位:分)BigDecimal totalFee = new BigDecimal((String) map.get("total_fee"));//支付时间 格式20141030133525String timeEnd = DateUtil.format(DateUtil.parse((String) map.get("time_end"), "yyyyMMddHHmmss"), "yyyy-MM-dd HH:mm:ss");//微信支付订单号(支付来源)String transactionId = (String) map.get("transaction_id");//构建支付回调实体PayTransaction payTransaction = new PayTransaction();payTransaction.setId(orderId);payTransaction.setStatus(OrderEnums.PayStatus.OK.getKey());payTransaction.setRealTotalMoney(totalFee);payTransaction.setPayType(OrderEnums.PayType.WX.getKey());payTransaction.setPayFrom(transactionId);payTransaction.setPayTime(DateUtil.parseDateTime(timeEnd));payTransaction.setCreateTime(new Date());payTransaction.setCreateBy("wx");log.info("回调成功:" + payTransaction.toString());boolean flag = false;Order order = orderJpaRepository.findOrderById(payTransaction.getId());if (order != null) {log.info("进入支付回调业务");flag = wxPayService.orderUpdate(payTransaction, 1);}/**此处添加自己的业务逻辑代码end**/if (flag) {log.info("回调逻辑成功,通知微信");//通知微信服务器已经支付成功resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"+ "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";} else {log.info("回调逻辑出错,等待回调");//支付成功,但是逻辑出错,请求再次回调resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"+ "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";}}} else {resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"+ "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";}log.info("回调支付结束======" + resXml);BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());out.write(resXml.getBytes());out.flush();out.close();}
}

微信小程序支付,查询和支付回调相关推荐

  1. 微信小程序中使用JSAPI支付

    微信小程序中使用JSAPI支付 在微信小程序中使用微信支付api[wx.requestPayment]需要传递以下字段 如何获取支付所需要的值 在微信小程序中使用微信支付api[wx.requestP ...

  2. 微信小程序服务商下子商户支付下单接口

    微信小程序服务商下子商户支付下单流程 调用方法 <?php namespace app\index\controller; class WeixinPay extends Base { prot ...

  3. 微信小程序--订单查询页面

    微信小程序–订单查询页面 包含功能点: 订单查询 结构:order.wxml <tabs tabList="{{tabList}}" binditemChange=" ...

  4. 基于微信小程序公交查询系统设计与实现

    [摘 要]随着互联网的技术的不断更新发展,人们生活节奏也在不断的加快,对于网络的依赖也越来越紧密,尤其是在等公交,经常会错过班次,但又不知道,下次班次几点发车,这样会导致乘客花掉大把时间在等待,如果可 ...

  5. 微信小程序 星座查询

    微信小程序 星座查询 1.界面布局 1. .xml代码 <image class="anime_bg" src="/images/cartoon_2.jpg&quo ...

  6. 微信小程序+java后台实现支付(java操作)

    支付,在微信小程序上面称为当一个用户使用该小程序,当进入到支付环节,我们需要调用微信支付接口过程,进行一系列的操作,并记录下来. 微信小程序与java接口实现支付操作,大致思路如下: 1.微信小程序调 ...

  7. 微信小程序实现押金管理(支付押金、申请退还押金、押金明细)

    前言 本教程是基于 "apifm-wxapi" 模块,教你快速实现小程序开发,所以你可能需要先了解以下知识点: <创建 HelloWorld 项目> <使用 &q ...

  8. 微信小程序走工行聚合支付

    首先感谢大佬"快乐树上快乐果",没有他的支持,不知道要多踩多少坑,先贴上大佬的原文链接 https://blog.csdn.net/qq_39404258/article/deta ...

  9. 仿抖音滑动小短剧影视微信小程序源码带支付收益等模式

    项目功能介绍:支持无限滑动 高性能滑动 预加载 视频预览 支持剧情介绍,集合壁纸另外仿抖音滑动效果 支持会员模式,支持用户单独购买等等多功能 丰富的后台设置,具体大家可以看小编的后台演示图 具体小编也 ...

  10. 微信小程序--火车票查询

    写在最前面 微信小程序自九月份推出内测资格以来,经历了舆论热潮到现在看似冷清,但并不意味着大家不那么关注或者不关注了.我想不管是否有内测资格,只要是感兴趣的开发者已经进入潜心耕耘产品的阶段了,至少是静 ...

最新文章

  1. 安卓创建快捷方式相关问题 Intent Intent-filter
  2. C语言 Condition variables
  3. matlab 柏林噪声,游戏AI怎么写(一)——高级随机技术
  4. python字符串注意点
  5. Java中的list---ArrayList与LinkedList
  6. TTF字体文件内容获取
  7. 测试电脑整机功耗软件,有什么好的测电脑整机功耗的软件吗?
  8. 怎么在国内创建谷歌账号_如何在Google表格中创建下拉列表
  9. PTA 数据结构与算法分析 7-38 寻找大富翁 (25 分)
  10. cpu超线程优缺点_CPU有无超线程重要吗?i7 10700K与9700K对比测试
  11. 电信套餐2020一览表_移动联通接连放大招,5G 套餐要降价?
  12. 题解 P1340 【兽径管理】
  13. rejected Updates were rejected because the remote contains work that you
  14. 【5】OpenCV2.4.9实现图像拼接与融合方法【SURF、SIFT、ORB、FAST、Harris角点 、stitch 】
  15. Redis Java客户端的选择
  16. C盘各个文件的简单介绍
  17. 怎么查看Python扩展库所有可用安装版本
  18. 面向对象程序设计C++学习之路2
  19. paddle百度飞浆入门使用教程
  20. 整合SEO和UEO也许才是SEOer的出路

热门文章

  1. Java中级开发工程师知识点归纳
  2. JavaScript知识结构图
  3. 2021年12月中国A股电力行业上市企业市值排行榜:华能国际增幅最大,12月新增2家上市企业(附月榜TOP93详单)
  4. 职业软件测试工程师的修炼之道!
  5. cnpm的安装与使用
  6. mysql复合主键优缺点_复合主键在MySQL中的性能缺点
  7. 【双目视觉】双目立体匹配
  8. phpcms v9 使用原生php,PHPCMS V9 正式版初使用心得
  9. 网页被重新刷新(网址后面自动添加了?)
  10. 约瑟夫环问题链表实现(Java)