您现在的位置是:首页 > 文章详情

Java微信订单查询

日期:2018-09-10点击:364
版权声明:本文首发 http://asing1elife.com ,转载请注明出处。 https://blog.csdn.net/asing1elife/article/details/82620040

Java微信订单查询

Java 通过统一下单 API 进行订单支付后,除等待微信通过 notify_url 进行回调通知外,还可以主动查询订单状态

更多精彩

前置条件

可参考 Java 微信扫码支付 如果实现微信支付

官网

【微信支付】扫码支付开发者文档

定义请求参数对象

  1. 订单查询请求参数(必填)
public class QueryOrderRequest { // 公众账号id private String appid; // 商户号 private String mch_id; // 商户订单号,32位以内,不重复 private String out_trade_no; // 随机字符串,32位以内 private String nonce_str; // 签名,遵循签名算法 private String sign; }
  1. 查询订单请求参数(非必填)
public class QueryOrderRequestExt extends QueryOrderRequest { // 签名类型,默认MD5 private String sign_type; } 

定义接收参数对象

  1. 查询订单接收参数(必填)
public class QueryOrderResponse { // 返回状态码,通信标识,SUCCESS/FAIL private String return_code; // 公众账号id private String appid; // 商户号 private String mch_id; // 随机字符串 private String nonce_str; // 签名 private String sign; // 业务结果,交易标识,SUCCESS/FAIL private String result_code; // 用户标识 private String openid; // 交易类型,JSAPI,NATIVE,APP private String trade_type; // 交易状态,SUCCESS-成功 USERPAYING-支付中 private String trade_state; // 付款银行 private String bank_type; // 标价金额,单位分 private int total_fee; // 现金支付金额 private int cash_fee; // 微信支付订单号 private String transaction_id; // 商户订单号 private String out_trade_no; // 支付完成时间 private String time_end; // 交易状态描述 private String trade_state_desc; }
  1. 查询订单接收参数(非必填)
public class QueryOrderResponseExt extends QueryOrderResponse { // 返回信息,非空则表示返回了错误信息 private String return_msg; // 错误代码 private String err_code; // 错误代码描述 private String err_code_des; // 设备号 private String device_info; // 是否关注公众号 private String is_subscribe; // 应结订单金额 private String settlement_total_fee; // 标价币种 private String fee_type; // 现金支付币种 private String cash_fee_type; // 附加数据 private String attach; } 

生成订单信息

  1. SOPConstants.WECHAT_PAY_APP_ID 是公众账号 id
  2. SOPConstants.WECHAT_PAY_MCH_ID 是商户id
  3. WechatUtil.makeNonceStr() 是生成的随机字符串
  4. WechatUtil.makeSign(BeanMap.create(ext)) 是根据请求参数制作签名
  5. WechatUtil.truncateDataToXML(QueryOrderRequestExt.class, ext) 是将数据转换为 XML 形式
private String generateOrderInfo(Long orderId) { OrderDTO order = orderManageService.getOrder(orderId); QueryOrderRequestExt ext = new QueryOrderRequestExt(); ext.setAppid(SOPConstants.WECHAT_PAY_APP_ID); ext.setMch_id(SOPConstants.WECHAT_PAY_MCH_ID); ext.setOut_trade_no(order.getCode()); ext.setNonce_str(WechatUtil.makeNonceStr()); ext.setSign(WechatUtil.makeSign(BeanMap.create(ext))); return WechatUtil.truncateDataToXML(QueryOrderRequestExt.class, ext); }

向微信发起订单查询请求

  1. SOPConstants.WECHAT_PAY_QUERY_URL 是微信订单查询的请求 URL
  2. WechatConnection.connect() 是向微信发起请求的通用方法
  3. 只有 ext.getResult_code() ext.getResult_code() ext.getTrade_state() 的值都是 SUCCESS 才能确定订单支付成功
public Boolean getPayResult(Long orderId) { String orderInfo = generateOrderInfo(orderId); QueryOrderResponseExt ext = null; try { ext = (QueryOrderResponseExt) WechatConnection.connect(SOPConstants.WECHAT_PAY_QUERY_URL, orderInfo, QueryOrderResponseExt.class); } catch (IOException e) { logger.error("微信查询订单" + orderId + "失败!", e); } if (ext == null) { return false; } if (WechatConnection.SUCCESS_CODE.equals(ext.getResult_code())) { if (WechatConnection.SUCCESS_CODE.equals(ext.getResult_code()) && WechatConnection.SUCCESS_CODE.equals(ext.getTrade_state())) { // 更新订单状态 orderPayService.updateOrderInfo(ext.getOut_trade_no(), OrderPay.wchatPay.getCode()); return true; } else { logger.error("订单" + orderId + "交易失败,交易状态:" + ext.getTrade_state()); return false; } } else { logger.error("订单" + orderId + "查询失败!"); return false; } }

微信支付相关操作工具类

  1. 该工具类目前提供了数据转换、签名生成、随机数生成的通用方法
public class WechatUtil { private static Logger logger = LoggerFactory.getLogger(WechatUtil.class); /** * 数据转换为xml格式 * * @param object * @param obj * @return */ public static String truncateDataToXML(Class<?> object, Object obj) { XStream xStream = new XStream(new XppDriver(new XmlFriendlyReplacer("_-", "_"))); xStream.alias("xml", object); return xStream.toXML(obj); } /** * 数据转换为对象 * * @param object * @param str * @return */ public static Object truncateDataFromXML(Class<?> object, String str) { XStream xStream = new XStream(new XppDriver(new XmlFriendlyReplacer("_-", "_"))); xStream.alias("xml", object); return xStream.fromXML(str); } /** * 生成随机字符串 * * @return */ public static String makeNonceStr() { StringBuffer str = new StringBuffer(DateUtil.getSysDateString("yyyyMMddHHmmssS")); str.append((new Random().nextInt(900) + 100)); return str.toString(); } /** * 拼接签名数据 * * @return */ public static String makeSign(BeanMap beanMap) { SortedMap<String, String> signMaps = Maps.newTreeMap(); for (Object key : beanMap.keySet()) { Object value = beanMap.get(key); // 排除空数据 if (value == null) { continue; } signMaps.put(key + "", String.valueOf(value)); } // 生成签名 return generateSign(signMaps); } /** * 生成签名 * * @param signMaps * @return * @throws Exception */ public static String generateSign(SortedMap<String, String> signMaps) { StringBuffer sb = new StringBuffer(); // 字典序 for (Map.Entry signMap : signMaps.entrySet()) { String key = (String) signMap.getKey(); String value = (String) signMap.getValue(); // 为空不参与签名、参数名区分大小写 if (null != value && !"".equals(value) && !"sign".equals(key) && !"key".equals(key)) { sb.append(key).append("=").append(value).append("&"); } } // 拼接key sb.append("key=").append(SOPConstants.WECHAT_PAY_KEY); // MD5加密 return Objects.requireNonNull(encoderByMd5(sb.toString())).toUpperCase(); } /** * 利用MD5进行加密 * * @param str 待加密的字符串 * @return 加密后的字符串 */ private static String encoderByMd5(String str) { // 生成一个MD5加密计算摘要 MessageDigest md = null; try { md = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { logger.error("MD5加密失败!", e); } if (md == null) { return null; } // 计算md5函数 md.update(str.getBytes()); // digest()最后确定返回md5 hash值,返回值为8为字符串。因为md5 hash值是16位的hex值,实际上就是8位的字符 // BigInteger函数则将8位的字符串转换成16位hex值,用字符串来表示;得到字符串形式的hash值 return new BigInteger(1, md.digest()).toString(16); } }

微信支付请求建立类

public class WechatConnection { // 成功标志 public static final String SUCCESS_CODE = "SUCCESS"; /** * 建立微信连接,并返回结果 * * @param url * @param info * @param object * @return * @throws IOException */ public static Object connect(String url, String info, Class<?> object) throws IOException { // 建立连接 HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); conn.setConnectTimeout(8000); conn.setRequestMethod("POST"); conn.setDoOutput(true); // 发送数据 BufferedOutputStream bos = new BufferedOutputStream(conn.getOutputStream()); bos.write(info.getBytes()); bos.flush(); bos.close(); // 获取数据 BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); // 接收数据 String line; StringBuffer str = new StringBuffer(); while ((line = reader.readLine()) != null) { str.append(line); } return WechatUtil.truncateDataFromXML(object, str.toString()); } }
原文链接:https://yq.aliyun.com/articles/646437
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章