Java微信订单查询

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 版权声明:本文首发 http://asing1elife.com ,转载请注明出处。 https://blog.csdn.net/asing1elife/article/details/82620040 ...
版权声明:本文首发 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());
    }

}
目录
相关文章
|
20天前
|
小程序 前端开发 算法
|
26天前
|
SQL Java 关系型数据库
java连接mysql查询数据(基础版,无框架)
【10月更文挑战第12天】该示例展示了如何使用Java通过JDBC连接MySQL数据库并查询数据。首先在项目中引入`mysql-connector-java`依赖,然后通过`JdbcUtil`类中的`main`方法实现数据库连接、执行SQL查询及结果处理,最后关闭相关资源。
|
25天前
|
Java API 开发者
Java如何实现企业微信审批流程
大家好,我是V哥。本文分享如何在企业微信中实现审批流程,通过调用企业微信的开放API完成。主要内容包括获取Access Token、创建审批模板、发起审批流程和查询审批结果。提供了一个Java示例代码,帮助开发者快速上手。希望对你有帮助,关注V哥爱编程,编码路上同行。
|
4月前
|
小程序 API 数据库
【微信小程序-原生开发】实用教程09 - 可滚动选项,动态列表-步骤条(含事件传参),动态详情(含微信云查询单条数据 doc)
【微信小程序-原生开发】实用教程09 - 可滚动选项,动态列表-步骤条(含事件传参),动态详情(含微信云查询单条数据 doc)
85 0
|
1月前
|
缓存 Java 数据处理
java查询大量数据优化
通过结合的高性能云服务,如其提供的弹性计算资源与全球加速网络,可以进一步增强这些优化策略的效果,确保数据处理环节更加迅速、可靠。蓝易云不仅提供稳定的基础架构,还拥有强大的安全防护和灵活的服务选项,是优化大型数据处理项目不可或缺的合作伙伴。
27 0
|
2月前
|
SQL Java
使用java在未知表字段情况下通过sql查询信息
使用java在未知表字段情况下通过sql查询信息
34 1
|
1月前
|
算法 小程序 Java
java制作海报三:获取微信二维码详情,并改变大小,合成到海报(另一张图片)上
这篇文章介绍了如何使用Java获取微信小程序的二维码,并将其调整大小后合成到海报(另一张图片)上。
41 0
|
1月前
|
小程序
java--微信小程序发送模板消息
java--微信小程序发送模板消息
106 0
|
3月前
|
存储 Java API
【Azure Developer】通过Azure提供的Azue Java JDK 查询虚拟机的CPU使用率和内存使用率
【Azure Developer】通过Azure提供的Azue Java JDK 查询虚拟机的CPU使用率和内存使用率
下一篇
无影云桌面