Java微信订单查询
Java微信订单查询
Java 通过统一下单 API 进行订单支付后,除等待微信通过 notify_url 进行回调通知外,还可以主动查询订单状态
更多精彩
- 更多技术博客,请移步 asing1elife’s blog
前置条件
可参考 Java 微信扫码支付 如果实现微信支付
官网
定义请求参数对象
- 订单查询请求参数(必填)
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;
}
- 查询订单请求参数(非必填)
public class QueryOrderRequestExt extends QueryOrderRequest {
// 签名类型,默认MD5
private String sign_type;
}
定义接收参数对象
- 查询订单接收参数(必填)
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;
}
- 查询订单接收参数(非必填)
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;
}
生成订单信息
-
SOPConstants.WECHAT_PAY_APP_ID
是公众账号 id -
SOPConstants.WECHAT_PAY_MCH_ID
是商户id -
WechatUtil.makeNonceStr()
是生成的随机字符串 -
WechatUtil.makeSign(BeanMap.create(ext))
是根据请求参数制作签名 -
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);
}
向微信发起订单查询请求
-
SOPConstants.WECHAT_PAY_QUERY_URL
是微信订单查询的请求 URL -
WechatConnection.connect()
是向微信发起请求的通用方法 - 只有
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;
}
}
微信支付相关操作工具类
- 该工具类目前提供了数据转换、签名生成、随机数生成的通用方法
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());
}
}

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
Java微信扫码支付
版权声明:本文首发 http://asing1elife.com ,转载请注明出处。 https://blog.csdn.net/asing1elife/article/details/82620021 Java微信扫码支付 以下内容是基于模式二开发 在开发之前需要先到微信支付官网注册账号,并获取到以下信息 appid:wx1137939101111111公众账号id mch_id:1438111111 商户号 key:4Inn0va1eSxOnl1neqsxwuhan1111111密钥 send_url:https://api.mch.weixin.qq.com/pay/unifiedorder统一下单API notify_url:http://127.0.0.1:8080/sop/order/notify/wechat支付成功回调地址 更多精彩 更多技术博客,请移步 asing1elife’s blog 官网 微信支付官网 扫码支付开发者文档 模式 需要在公众平台后台设置支付回调URL ,用于接收用户扫码后微信支付系统回调的productid和openid 直接调用统一下单API ...
-
下一篇
详解JVM内存管理与垃圾回收机制3 - JVM中对象的内存布局
在Java语言层面,可以通过Class类来描述普通的Java类,当JVM创建对象的同时,会生成对应的Class对象,用来描述此对象的大致模型,这也是反射的基础。那么在JVM的内部是如何描述一个普通的对象?我们先从一个简单的示例着手,这有一个Child类: public class Child extends Person implements Action { // 小孩上几年级 public int grade; // Action接口就一个动作:walk @Override public void walk() { } } 通过Child child = new Child()来创建对象时,JVM在堆中开辟空间存放对象实例数据的同时,会在栈中创建该对象的引用,用于存放child对象在堆内存中的首地址,大致的示意图如下所示。 新创建对象内存占用示意图 现在请大家思考:站在JVM的角度,要完整地描述运行时的child对象,需要记录哪些信息? 脑袋里可能马上就会跳出来这些信息: 对象所属类的相关信息: 类(包含父类)的名称、实现了哪些接口、是否有注解、方法列表、属性列表、常量等 实例数据...
相关文章
文章评论
共有0条评论来说两句吧...