| @@ -121,7 +121,9 @@ public interface WxMpPayService { | |||
| * <pre> | |||
| * 文档详见: | |||
| * 发送普通红包 https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_4&index=3 | |||
| * 接口地址:https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack | |||
| * 发送裂变红包 https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_5&index=4 | |||
| * 接口地址:https://api.mch.weixin.qq.com/mmpaymkttransfers/sendgroupredpack | |||
| * </pre> | |||
| * | |||
| * @param request 请求对象 | |||
| @@ -129,6 +131,19 @@ public interface WxMpPayService { | |||
| */ | |||
| WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request, File keyFile) throws WxErrorException; | |||
| /** | |||
| * <pre> | |||
| * 查询红包记录 | |||
| * 用于商户对已发放的红包进行查询红包的具体信息,可支持普通红包和裂变包。 | |||
| * 请求Url https://api.mch.weixin.qq.com/mmpaymkttransfers/gethbinfo | |||
| * 是否需要证书 是(证书及使用说明详见商户证书) | |||
| * 请求方式 POST | |||
| * </pre> | |||
| * @param mchBillNo 商户发放红包的商户订单号,比如10000098201411111234567890 | |||
| * @param keyFile 证书文件对象 | |||
| */ | |||
| WxPayRedpackQueryResult queryRedpack(String mchBillNo, File keyFile) throws WxErrorException; | |||
| /** | |||
| * <pre> | |||
| * 企业付款业务是基于微信支付商户平台的资金管理能力,为了协助商户方便地实现企业向个人付款,针对部分有开发能力的商户,提供通过API完成企业付款的功能。 | |||
| @@ -183,6 +183,32 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||
| return result; | |||
| } | |||
| @Override | |||
| public WxPayRedpackQueryResult queryRedpack(String mchBillNo, File keyFile) throws WxErrorException { | |||
| XStream xstream = XStreamInitializer.getInstance(); | |||
| xstream.processAnnotations(WxPayRedpackQueryRequest.class); | |||
| xstream.processAnnotations(WxPayRedpackQueryResult.class); | |||
| WxPayRedpackQueryRequest request = new WxPayRedpackQueryRequest(); | |||
| request.setMchBillNo(mchBillNo); | |||
| request.setBillType("MCHT"); | |||
| request.setAppid(this.wxMpService.getWxMpConfigStorage().getAppId()); | |||
| String mchId = this.wxMpService.getWxMpConfigStorage().getPartnerId(); | |||
| request.setMchId(mchId); | |||
| request.setNonceStr(System.currentTimeMillis() + ""); | |||
| String sign = this.createSign(BeanUtils.xmlBean2Map(request), | |||
| this.wxMpService.getWxMpConfigStorage().getPartnerKey()); | |||
| request.setSign(sign); | |||
| String url = PAY_BASE_URL + "/mmpaymkttransfers/gethbinfo"; | |||
| String responseContent = this.executeRequestWithKeyFile(url, keyFile, xstream.toXML(request), mchId); | |||
| WxPayRedpackQueryResult result = (WxPayRedpackQueryResult) xstream.fromXML(responseContent); | |||
| this.checkResult(result); | |||
| return result; | |||
| } | |||
| /** | |||
| * 微信公众号支付签名算法(详见:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3) | |||
| * | |||
| @@ -0,0 +1,57 @@ | |||
| package me.chanjar.weixin.mp.bean.pay.request; | |||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | |||
| /** | |||
| * <pre> | |||
| * 注释中各行对应含义: | |||
| * 字段名 | |||
| * 字段 | |||
| * 必填 | |||
| * 示例值 | |||
| * 类型 | |||
| * 说明 | |||
| * Created by Binary Wang on 2016-11-28. | |||
| * @author <a href="https://github.com/binarywang">binarywang(Binary Wang)</a> | |||
| * </pre> | |||
| */ | |||
| @XStreamAlias("xml") | |||
| public class WxPayRedpackQueryRequest extends WxPayBaseRequest { | |||
| /** | |||
| * 商户订单号 | |||
| * mch_billno | |||
| * 是 | |||
| * 10000098201411111234567890 | |||
| * String(28) | |||
| * 商户发放红包的商户订单号 | |||
| */ | |||
| @XStreamAlias("mch_billno") | |||
| private String mchBillNo; | |||
| /** | |||
| * 订单类型 | |||
| * bill_type | |||
| * 是 | |||
| * MCHT | |||
| * String(32) | |||
| * MCHT:通过商户订单号获取红包信息。 | |||
| */ | |||
| @XStreamAlias("bill_type") | |||
| private String billType; | |||
| public String getBillType() { | |||
| return billType; | |||
| } | |||
| public void setBillType(String billType) { | |||
| this.billType = billType; | |||
| } | |||
| public String getMchBillNo() { | |||
| return mchBillNo; | |||
| } | |||
| public void setMchBillNo(String mchBillNo) { | |||
| this.mchBillNo = mchBillNo; | |||
| } | |||
| } | |||
| @@ -14,7 +14,7 @@ public class WxPaySendRedpackRequest { | |||
| * 商户订单号(每个订单号必须唯一) 组成:mch_id+yyyymmdd+10位一天内不能重复的数字。 接口根据商户订单号支持重入,如出现超时可再调用。 | |||
| */ | |||
| @XStreamAlias("mch_billno") | |||
| private String mchBillno; | |||
| private String mchBillNo; | |||
| /** | |||
| * send_name | |||
| @@ -157,12 +157,12 @@ public class WxPaySendRedpackRequest { | |||
| @XStreamAlias("consume_mch_id") | |||
| private String consumeMchId; | |||
| public String getMchBillno() { | |||
| return this.mchBillno; | |||
| public String getMchBillNo() { | |||
| return mchBillNo; | |||
| } | |||
| public void setMchBillno(String mchBillno) { | |||
| this.mchBillno = mchBillno; | |||
| public void setMchBillNo(String mchBillNo) { | |||
| this.mchBillNo = mchBillNo; | |||
| } | |||
| public String getSendName() { | |||
| @@ -1,10 +1,10 @@ | |||
| package me.chanjar.weixin.mp.bean.pay.result; | |||
| import java.util.List; | |||
| import com.google.common.collect.Lists; | |||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | |||
| import java.util.List; | |||
| /** | |||
| * <pre> | |||
| * 查询订单 返回结果对象 | |||
| @@ -0,0 +1,405 @@ | |||
| package me.chanjar.weixin.mp.bean.pay.result; | |||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | |||
| /** | |||
| * <pre> | |||
| * 注释中各行对应含义: | |||
| * 字段名 | |||
| * 字段 | |||
| * 必填 | |||
| * 示例值 | |||
| * 类型 | |||
| * 说明 | |||
| * Created by Binary Wang on 2016-11-28. | |||
| * @author <a href="https://github.com/binarywang">binarywang(Binary Wang)</a> | |||
| * </pre> | |||
| */ | |||
| public class WxPayRedpackQueryResult extends WxPayBaseResult { | |||
| /** | |||
| * <pre> | |||
| * 商户订单号 | |||
| * mch_billno | |||
| * 是 | |||
| * 10000098201411111234567890 | |||
| * String(28) | |||
| * 商户使用查询API填写的商户单号的原路返回 | |||
| * </pre> | |||
| */ | |||
| @XStreamAlias("mch_billno") | |||
| private String mchBillNo; | |||
| /** | |||
| * <pre> | |||
| * 红包单号 | |||
| * detail_id | |||
| * 是 | |||
| * 1000000000201503283103439304 | |||
| * String(32) | |||
| * 使用API发放现金红包时返回的红包单号 | |||
| * </pre> | |||
| */ | |||
| @XStreamAlias("detail_id") | |||
| private String detailId; | |||
| /** | |||
| * <pre> | |||
| * 红包状态 | |||
| * status | |||
| * 是 | |||
| * RECEIVED | |||
| * string(16) | |||
| * SENDING:发放中, | |||
| * SENT:已发放待领取, | |||
| * FAILED:发放失败, | |||
| * RECEIVED:已领取, | |||
| * RFUND_ING:退款中, | |||
| * REFUND:已退款 | |||
| * </pre> | |||
| */ | |||
| @XStreamAlias("status") | |||
| private String status; | |||
| /** | |||
| * <pre> | |||
| * 发放类型 | |||
| * send_type | |||
| * 是 | |||
| * API | |||
| * String(32) | |||
| * API:通过API接口发放, | |||
| * UPLOAD:通过上传文件方式发放, | |||
| * ACTIVITY:通过活动方式发放 | |||
| * </pre> | |||
| */ | |||
| @XStreamAlias("send_type") | |||
| private String sendType; | |||
| /** | |||
| * <pre> | |||
| * 红包类型 | |||
| * hb_type | |||
| * 是 | |||
| * GROUP | |||
| * String(32) | |||
| * GROUP:裂变红包, | |||
| * NORMAL:普通红包 | |||
| * </pre> | |||
| */ | |||
| @XStreamAlias("hb_type") | |||
| private String hbType; | |||
| /** | |||
| * <pre> | |||
| * 红包个数 | |||
| * total_num | |||
| * 是 | |||
| * 1 | |||
| * int | |||
| * 红包个数 | |||
| * </pre> | |||
| */ | |||
| @XStreamAlias("total_num") | |||
| private Integer totalNum; | |||
| /** | |||
| * <pre> | |||
| * 红包金额 | |||
| * total_amount | |||
| * 是 | |||
| * 5000 | |||
| * int | |||
| * 红包总金额(单位分) | |||
| * </pre> | |||
| */ | |||
| @XStreamAlias("total_amount") | |||
| private Integer totalAmount; | |||
| /** | |||
| * <pre> | |||
| * 失败原因 | |||
| * reason | |||
| * 否 | |||
| * 余额不足 | |||
| * String(32) | |||
| * 发送失败原因 | |||
| * </pre> | |||
| */ | |||
| @XStreamAlias("reason") | |||
| private String reason; | |||
| /** | |||
| * <pre> | |||
| * 红包发送时间 | |||
| * send_time | |||
| * 是 | |||
| * 2015-04-21 20:00:00 | |||
| * String(32) | |||
| * 红包的发送时间 | |||
| * </pre> | |||
| */ | |||
| @XStreamAlias("send_time") | |||
| private String sendTime; | |||
| /** | |||
| * <pre> | |||
| * 红包退款时间 | |||
| * refund_time | |||
| * 否 | |||
| * 2015-04-21 23:03:00 | |||
| * String(32) | |||
| * 红包的退款时间(如果其未领取的退款) | |||
| * </pre> | |||
| */ | |||
| @XStreamAlias("refund_time") | |||
| private String refundTime; | |||
| /** | |||
| * <pre> | |||
| * 红包退款金额 | |||
| * refund_amount | |||
| * 否 | |||
| * 8000 | |||
| * Int | |||
| * 红包退款金额 | |||
| * </pre> | |||
| */ | |||
| @XStreamAlias("refund_amount") | |||
| private Integer refundAmount; | |||
| /** | |||
| * <pre> | |||
| * 祝福语 | |||
| * wishing | |||
| * 否 | |||
| * 新年快乐 | |||
| * String(128) | |||
| * 祝福语 | |||
| * </pre> | |||
| */ | |||
| @XStreamAlias("wishing") | |||
| private String wishing; | |||
| /** | |||
| * <pre> | |||
| * 活动描述 | |||
| * remark | |||
| * 否 | |||
| * 新年红包 | |||
| * String(256) | |||
| * 活动描述,低版本微信可见 | |||
| * </pre> | |||
| */ | |||
| @XStreamAlias("remark") | |||
| private String remark; | |||
| /** | |||
| * <pre> | |||
| * 活动名称 | |||
| * act_name | |||
| * 否 | |||
| * 新年红包 | |||
| * String(32) | |||
| * 发红包的活动名称 | |||
| * </pre> | |||
| */ | |||
| @XStreamAlias("act_name") | |||
| private String actName; | |||
| /** | |||
| * <pre> | |||
| * 裂变红包领取列表 | |||
| * hblist | |||
| * 否 | |||
| * | |||
| * | |||
| * 裂变红包的领取列表 | |||
| * </pre> | |||
| */ | |||
| @XStreamAlias("hblist") | |||
| private String hblist; | |||
| /** | |||
| * <pre> | |||
| * 领取红包的Openid | |||
| * openid | |||
| * 是 | |||
| * ohO4GtzOAAYMp2yapORH3dQB3W18 | |||
| * String(32) | |||
| * 领取红包的openid | |||
| * </pre> | |||
| */ | |||
| @XStreamAlias("openid") | |||
| private String openid; | |||
| /** | |||
| * <pre> | |||
| * 金额 | |||
| * amount | |||
| * 是 | |||
| * 100 | |||
| * int | |||
| * 领取金额 | |||
| * </pre> | |||
| */ | |||
| @XStreamAlias("amount") | |||
| private Integer amount; | |||
| /** | |||
| * <pre> | |||
| * 接收时间 | |||
| * rcv_time | |||
| * 是 | |||
| * 2015-04-21 20:00:00 | |||
| * String(32) | |||
| * 领取红包的时间 | |||
| * </pre> | |||
| */ | |||
| @XStreamAlias("rcv_time") | |||
| private String receiveTime; | |||
| public String getMchBillNo() { | |||
| return mchBillNo; | |||
| } | |||
| public void setMchBillNo(String mchBillNo) { | |||
| this.mchBillNo = mchBillNo; | |||
| } | |||
| public String getDetailId() { | |||
| return detailId; | |||
| } | |||
| public void setDetailId(String detailId) { | |||
| this.detailId = detailId; | |||
| } | |||
| public String getStatus() { | |||
| return status; | |||
| } | |||
| public void setStatus(String status) { | |||
| this.status = status; | |||
| } | |||
| public String getSendType() { | |||
| return sendType; | |||
| } | |||
| public void setSendType(String sendType) { | |||
| this.sendType = sendType; | |||
| } | |||
| public String getHbType() { | |||
| return hbType; | |||
| } | |||
| public void setHbType(String hbType) { | |||
| this.hbType = hbType; | |||
| } | |||
| public Integer getTotalNum() { | |||
| return totalNum; | |||
| } | |||
| public void setTotalNum(Integer totalNum) { | |||
| this.totalNum = totalNum; | |||
| } | |||
| public Integer getTotalAmount() { | |||
| return totalAmount; | |||
| } | |||
| public void setTotalAmount(Integer totalAmount) { | |||
| this.totalAmount = totalAmount; | |||
| } | |||
| public String getReason() { | |||
| return reason; | |||
| } | |||
| public void setReason(String reason) { | |||
| this.reason = reason; | |||
| } | |||
| public String getSendTime() { | |||
| return sendTime; | |||
| } | |||
| public void setSendTime(String sendTime) { | |||
| this.sendTime = sendTime; | |||
| } | |||
| public String getRefundTime() { | |||
| return refundTime; | |||
| } | |||
| public void setRefundTime(String refundTime) { | |||
| this.refundTime = refundTime; | |||
| } | |||
| public Integer getRefundAmount() { | |||
| return refundAmount; | |||
| } | |||
| public void setRefundAmount(Integer refundAmount) { | |||
| this.refundAmount = refundAmount; | |||
| } | |||
| public String getWishing() { | |||
| return wishing; | |||
| } | |||
| public void setWishing(String wishing) { | |||
| this.wishing = wishing; | |||
| } | |||
| public String getRemark() { | |||
| return remark; | |||
| } | |||
| public void setRemark(String remark) { | |||
| this.remark = remark; | |||
| } | |||
| public String getActName() { | |||
| return actName; | |||
| } | |||
| public void setActName(String actName) { | |||
| this.actName = actName; | |||
| } | |||
| public String getHblist() { | |||
| return hblist; | |||
| } | |||
| public void setHblist(String hblist) { | |||
| this.hblist = hblist; | |||
| } | |||
| public String getOpenid() { | |||
| return openid; | |||
| } | |||
| public void setOpenid(String openid) { | |||
| this.openid = openid; | |||
| } | |||
| public Integer getAmount() { | |||
| return amount; | |||
| } | |||
| public void setAmount(Integer amount) { | |||
| this.amount = amount; | |||
| } | |||
| public String getReceiveTime() { | |||
| return receiveTime; | |||
| } | |||
| public void setReceiveTime(String receiveTime) { | |||
| this.receiveTime = receiveTime; | |||
| } | |||
| } | |||
| @@ -183,6 +183,13 @@ public class WxPayRefundQueryResult extends WxPayBaseResult { | |||
| this.refundRecords = refundRecords; | |||
| } | |||
| public void composeRefundRecords(String xmlString) { | |||
| if (this.refundCount != null && this.refundCount > 0) { | |||
| this.refundRecords = Lists.newArrayList(); | |||
| //TODO 暂时待实现 | |||
| } | |||
| } | |||
| public static class RefundRecord { | |||
| /** | |||
| * <pre> | |||
| @@ -477,12 +484,5 @@ public class WxPayRefundQueryResult extends WxPayBaseResult { | |||
| } | |||
| } | |||
| public void composeRefundRecords(String xmlString){ | |||
| if(this.refundCount != null && this.refundCount > 0 ){ | |||
| this.refundRecords = Lists.newArrayList(); | |||
| //TODO 暂时待实现 | |||
| } | |||
| } | |||
| } | |||
| @@ -9,10 +9,7 @@ import me.chanjar.weixin.mp.bean.pay.request.WxEntPayRequest; | |||
| import me.chanjar.weixin.mp.bean.pay.request.WxPayRefundRequest; | |||
| import me.chanjar.weixin.mp.bean.pay.request.WxPaySendRedpackRequest; | |||
| import me.chanjar.weixin.mp.bean.pay.request.WxPayUnifiedOrderRequest; | |||
| import me.chanjar.weixin.mp.bean.pay.result.WxPayRefundQueryResult; | |||
| import me.chanjar.weixin.mp.bean.pay.result.WxPayRefundResult; | |||
| import me.chanjar.weixin.mp.bean.pay.result.WxPaySendRedpackResult; | |||
| import me.chanjar.weixin.mp.bean.pay.result.WxPayUnifiedOrderResult; | |||
| import me.chanjar.weixin.mp.bean.pay.result.*; | |||
| import org.testng.annotations.Guice; | |||
| import org.testng.annotations.Test; | |||
| @@ -36,6 +33,9 @@ public class WxMpPayServiceImplTest { | |||
| } | |||
| /** | |||
| * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#refund(WxPayRefundRequest, File)} . | |||
| */ | |||
| @Test | |||
| public void testRefund() throws Exception { | |||
| WxPayRefundRequest request = new WxPayRefundRequest(); | |||
| @@ -48,6 +48,10 @@ public class WxMpPayServiceImplTest { | |||
| System.err.println(result); | |||
| } | |||
| /** | |||
| * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#refundQuery(String, String, String, String)} . | |||
| */ | |||
| @Test | |||
| public void testRefundQuery() throws Exception { | |||
| WxPayRefundQueryResult result = this.wxService.getPayService().refundQuery("1", "", "", ""); | |||
| @@ -67,12 +71,15 @@ public class WxMpPayServiceImplTest { | |||
| } | |||
| /** | |||
| * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#sendRedpack(WxPaySendRedpackRequest, File)} . | |||
| */ | |||
| @Test | |||
| public void testSendRedpack() throws Exception { | |||
| WxPaySendRedpackRequest request = new WxPaySendRedpackRequest(); | |||
| request.setActName("abc"); | |||
| request.setClientIp("aaa"); | |||
| request.setMchBillno("aaaa"); | |||
| request.setMchBillNo("aaaa"); | |||
| request | |||
| .setReOpenid(((WxXmlMpInMemoryConfigStorage) this.wxService.getWxMpConfigStorage()).getOpenid()); | |||
| File keyFile = new File("E:\\dlt.p12"); | |||
| @@ -80,6 +87,16 @@ public class WxMpPayServiceImplTest { | |||
| System.err.println(redpackResult); | |||
| } | |||
| /** | |||
| * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#queryRedpack(String, File)}. | |||
| */ | |||
| @Test | |||
| public void testQueryRedpack() throws Exception { | |||
| File keyFile = new File("E:\\dlt.p12"); | |||
| WxPayRedpackQueryResult redpackResult = this.wxService.getPayService().queryRedpack("aaaa", keyFile); | |||
| System.err.println(redpackResult); | |||
| } | |||
| /** | |||
| * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#unifiedOrder(WxPayUnifiedOrderRequest)}. | |||
| */ | |||