@@ -121,7 +121,9 @@ public interface WxMpPayService { | |||||
* <pre> | * <pre> | ||||
* 文档详见: | * 文档详见: | ||||
* 发送普通红包 https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_4&index=3 | * 发送普通红包 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://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> | * </pre> | ||||
* | * | ||||
* @param request 请求对象 | * @param request 请求对象 | ||||
@@ -129,6 +131,19 @@ public interface WxMpPayService { | |||||
*/ | */ | ||||
WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request, File keyFile) throws WxErrorException; | 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> | * <pre> | ||||
* 企业付款业务是基于微信支付商户平台的资金管理能力,为了协助商户方便地实现企业向个人付款,针对部分有开发能力的商户,提供通过API完成企业付款的功能。 | * 企业付款业务是基于微信支付商户平台的资金管理能力,为了协助商户方便地实现企业向个人付款,针对部分有开发能力的商户,提供通过API完成企业付款的功能。 | ||||
@@ -183,6 +183,32 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
return result; | 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) | * 微信公众号支付签名算法(详见: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位一天内不能重复的数字。 接口根据商户订单号支持重入,如出现超时可再调用。 | * 商户订单号(每个订单号必须唯一) 组成:mch_id+yyyymmdd+10位一天内不能重复的数字。 接口根据商户订单号支持重入,如出现超时可再调用。 | ||||
*/ | */ | ||||
@XStreamAlias("mch_billno") | @XStreamAlias("mch_billno") | ||||
private String mchBillno; | |||||
private String mchBillNo; | |||||
/** | /** | ||||
* send_name | * send_name | ||||
@@ -157,12 +157,12 @@ public class WxPaySendRedpackRequest { | |||||
@XStreamAlias("consume_mch_id") | @XStreamAlias("consume_mch_id") | ||||
private String consumeMchId; | 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() { | public String getSendName() { | ||||
@@ -1,10 +1,10 @@ | |||||
package me.chanjar.weixin.mp.bean.pay.result; | package me.chanjar.weixin.mp.bean.pay.result; | ||||
import java.util.List; | |||||
import com.google.common.collect.Lists; | import com.google.common.collect.Lists; | ||||
import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
import java.util.List; | |||||
/** | /** | ||||
* <pre> | * <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; | this.refundRecords = refundRecords; | ||||
} | } | ||||
public void composeRefundRecords(String xmlString) { | |||||
if (this.refundCount != null && this.refundCount > 0) { | |||||
this.refundRecords = Lists.newArrayList(); | |||||
//TODO 暂时待实现 | |||||
} | |||||
} | |||||
public static class RefundRecord { | public static class RefundRecord { | ||||
/** | /** | ||||
* <pre> | * <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.WxPayRefundRequest; | ||||
import me.chanjar.weixin.mp.bean.pay.request.WxPaySendRedpackRequest; | 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.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.Guice; | ||||
import org.testng.annotations.Test; | 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 | @Test | ||||
public void testRefund() throws Exception { | public void testRefund() throws Exception { | ||||
WxPayRefundRequest request = new WxPayRefundRequest(); | WxPayRefundRequest request = new WxPayRefundRequest(); | ||||
@@ -48,6 +48,10 @@ public class WxMpPayServiceImplTest { | |||||
System.err.println(result); | System.err.println(result); | ||||
} | } | ||||
/** | |||||
* Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#refundQuery(String, String, String, String)} . | |||||
*/ | |||||
@Test | @Test | ||||
public void testRefundQuery() throws Exception { | public void testRefundQuery() throws Exception { | ||||
WxPayRefundQueryResult result = this.wxService.getPayService().refundQuery("1", "", "", ""); | 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 | @Test | ||||
public void testSendRedpack() throws Exception { | public void testSendRedpack() throws Exception { | ||||
WxPaySendRedpackRequest request = new WxPaySendRedpackRequest(); | WxPaySendRedpackRequest request = new WxPaySendRedpackRequest(); | ||||
request.setActName("abc"); | request.setActName("abc"); | ||||
request.setClientIp("aaa"); | request.setClientIp("aaa"); | ||||
request.setMchBillno("aaaa"); | |||||
request.setMchBillNo("aaaa"); | |||||
request | request | ||||
.setReOpenid(((WxXmlMpInMemoryConfigStorage) this.wxService.getWxMpConfigStorage()).getOpenid()); | .setReOpenid(((WxXmlMpInMemoryConfigStorage) this.wxService.getWxMpConfigStorage()).getOpenid()); | ||||
File keyFile = new File("E:\\dlt.p12"); | File keyFile = new File("E:\\dlt.p12"); | ||||
@@ -80,6 +87,16 @@ public class WxMpPayServiceImplTest { | |||||
System.err.println(redpackResult); | 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)}. | * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#unifiedOrder(WxPayUnifiedOrderRequest)}. | ||||
*/ | */ | ||||