Skip to content

Commit

Permalink
#53 实现微信支付查询订单的接口,并重构规范化微信支付相关接口类的命名
Browse files Browse the repository at this point in the history
  • Loading branch information
binarywang committed Oct 25, 2016
1 parent dff627b commit e30138f
Show file tree
Hide file tree
Showing 20 changed files with 964 additions and 955 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,23 @@
*/
public interface WxMpPayService {

/**
* <pre>
* 查询订单(详见https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2)
* 该接口提供所有微信支付订单的查询,商户可以通过查询订单接口主动查询订单状态,完成下一步的业务逻辑。
* 需要调用查询接口的情况:
◆ 当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知;
◆ 调用支付接口后,返回系统错误或未知交易状态情况;
◆ 调用被扫支付API,返回USERPAYING的状态;
◆ 调用关单或撤销接口API之前,需确认支付状态;
* 接口地址:https://api.mch.weixin.qq.com/pay/orderquery
* </pre>
* @param transactionId 微信支付分配的商户号
* @param outTradeNo 商户系统内部的订单号,当没提供transaction_id时需要传这个。
* @throws WxErrorException
*/
WxPayOrderQueryResult queryOrder(String transactionId, String outTradeNo) throws WxErrorException;

/**
* 统一下单(详见http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1)
* 在发起微信支付前,需要调用统一下单接口,获取"预支付交易会话标识"
Expand All @@ -21,31 +38,21 @@ public interface WxMpPayService {
* @param request 请求对象
*
*/
WxUnifiedOrderResult unifiedOrder(WxUnifiedOrderRequest request)
throws WxErrorException;
WxPayUnifiedOrderResult unifiedOrder(WxPayUnifiedOrderRequest request) throws WxErrorException;

/**
* 该接口调用“统一下单”接口,并拼装发起支付请求需要的参数
* 详见http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&lang=zh_CN
* @param request 请求对象
*/
Map<String, String> getPayInfo(WxUnifiedOrderRequest request) throws WxErrorException;

/**
* 该接口提供所有微信支付订单的查询,当支付通知处理异常戒丢失的情冴,商户可以通过该接口查询订单支付状态。
* 详见http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2
* @throws WxErrorException
*
*/
WxMpPayResult getJSSDKPayResult(String transactionId, String outTradeNo)
throws WxErrorException;
Map<String, String> getPayInfo(WxPayUnifiedOrderRequest request) throws WxErrorException;

/**
* 读取支付结果通知
* 详见http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7
*
*/
WxMpPayCallback getJSSDKCallbackData(String xmlData);
WxPayJsSDKCallback getJSSDKCallbackData(String xmlData);

/**
* <pre>
Expand All @@ -57,7 +64,7 @@ WxMpPayResult getJSSDKPayResult(String transactionId, String outTradeNo)
* @param keyFile 证书文件对象
* @return 退款操作结果
*/
WxMpPayRefundResult refund(WxMpPayRefundRequest request, File keyFile) throws WxErrorException;
WxPayRefundResult refund(WxPayRefundRequest request, File keyFile) throws WxErrorException;

/**
* <pre>
Expand All @@ -78,7 +85,7 @@ WxMpPayResult getJSSDKPayResult(String transactionId, String outTradeNo)
* @param request 请求对象
* @param keyFile 证书文件对象
*/
WxRedpackResult sendRedpack(WxSendRedpackRequest request, File keyFile) throws WxErrorException;
WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request, File keyFile) throws WxErrorException;

/**
* <pre>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,64 +46,26 @@ public WxMpPayServiceImpl(WxMpService wxMpService) {
}

@Override
public WxMpPayResult getJSSDKPayResult(String transactionId,
String outTradeNo) throws WxErrorException {
String nonce_str = System.currentTimeMillis() + "";

SortedMap<String, String> packageParams = new TreeMap<>();
packageParams.put("appid",
this.wxMpService.getWxMpConfigStorage().getAppId());
packageParams.put("mch_id",
this.wxMpService.getWxMpConfigStorage().getPartnerId());

if (transactionId != null && !"".equals(transactionId.trim())) {
packageParams.put("transaction_id", transactionId);
} else if (outTradeNo != null && !"".equals(outTradeNo.trim())) {
packageParams.put("out_trade_no", outTradeNo);
} else {
throw new IllegalArgumentException(
"Either 'transactionId' or 'outTradeNo' must be given.");
}

packageParams.put("nonce_str", nonce_str);
packageParams.put("sign", this.createSign(packageParams,
this.wxMpService.getWxMpConfigStorage().getPartnerKey()));

StringBuilder request = new StringBuilder("<xml>");
for (Map.Entry<String, String> para : packageParams.entrySet()) {
request.append(String.format("<%s>%s</%s>", para.getKey(),
para.getValue(), para.getKey()));
}
request.append("</xml>");

String url = PAY_BASE_URL + "/pay/orderquery";
String responseContent = this.wxMpService.post(url, request.toString());
XStream xstream = XStreamInitializer.getInstance();
xstream.alias("xml", WxMpPayResult.class);
return (WxMpPayResult) xstream.fromXML(responseContent);
}

@Override
public WxMpPayCallback getJSSDKCallbackData(String xmlData) {
public WxPayJsSDKCallback getJSSDKCallbackData(String xmlData) {
try {
XStream xstream = XStreamInitializer.getInstance();
xstream.alias("xml", WxMpPayCallback.class);
return (WxMpPayCallback) xstream.fromXML(xmlData);
xstream.alias("xml", WxPayJsSDKCallback.class);
return (WxPayJsSDKCallback) xstream.fromXML(xmlData);
} catch (Exception e) {
e.printStackTrace();
}

return new WxMpPayCallback();
return new WxPayJsSDKCallback();
}

@Override
public WxMpPayRefundResult refund(WxMpPayRefundRequest request, File keyFile)
public WxPayRefundResult refund(WxPayRefundRequest request, File keyFile)
throws WxErrorException {
checkParameters(request);

XStream xstream = XStreamInitializer.getInstance();
xstream.processAnnotations(WxMpPayRefundResult.class);
xstream.processAnnotations(WxMpPayRefundRequest.class);
xstream.processAnnotations(WxPayRefundResult.class);
xstream.processAnnotations(WxPayRefundRequest.class);

request.setAppid(this.wxMpService.getWxMpConfigStorage().getAppId());
String partnerId = this.wxMpService.getWxMpConfigStorage().getPartnerId();
Expand All @@ -115,7 +77,7 @@ public WxMpPayRefundResult refund(WxMpPayRefundRequest request, File keyFile)

String url = PAY_BASE_URL + "/secapi/pay/refund";
String responseContent = this.executeRequestWithKeyFile(url, keyFile, xstream.toXML(request), partnerId);
WxMpPayRefundResult wxMpPayRefundResult = (WxMpPayRefundResult) xstream.fromXML(responseContent);
WxPayRefundResult wxMpPayRefundResult = (WxPayRefundResult) xstream.fromXML(responseContent);

if (!"SUCCESS".equalsIgnoreCase(wxMpPayRefundResult.getResultCode())
|| !"SUCCESS".equalsIgnoreCase(wxMpPayRefundResult.getReturnCode())) {
Expand All @@ -132,7 +94,7 @@ public WxMpPayRefundResult refund(WxMpPayRefundRequest request, File keyFile)
return wxMpPayRefundResult;
}

private void checkParameters(WxMpPayRefundRequest request) throws WxErrorException {
private void checkParameters(WxPayRefundRequest request) throws WxErrorException {
BeanUtils.checkRequiredFields(request);

if (StringUtils.isNotBlank(request.getRefundAccount())) {
Expand All @@ -154,11 +116,11 @@ public boolean checkJSSDKCallbackDataSignature(Map<String, String> kvm,
}

@Override
public WxRedpackResult sendRedpack(WxSendRedpackRequest request, File keyFile)
public WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request, File keyFile)
throws WxErrorException {
XStream xstream = XStreamInitializer.getInstance();
xstream.processAnnotations(WxSendRedpackRequest.class);
xstream.processAnnotations(WxRedpackResult.class);
xstream.processAnnotations(WxPaySendRedpackRequest.class);
xstream.processAnnotations(WxPaySendRedpackResult.class);

request.setWxAppid(this.wxMpService.getWxMpConfigStorage().getAppId());
String mchId = this.wxMpService.getWxMpConfigStorage().getPartnerId();
Expand All @@ -176,7 +138,7 @@ public WxRedpackResult sendRedpack(WxSendRedpackRequest request, File keyFile)
}

String responseContent = this.executeRequestWithKeyFile(url, keyFile, xstream.toXML(request), mchId);
WxRedpackResult redpackResult = (WxRedpackResult) xstream
WxPaySendRedpackResult redpackResult = (WxPaySendRedpackResult) xstream
.fromXML(responseContent);
if ("FAIL".equals(redpackResult.getResultCode())) {
throw new WxErrorException(WxError.newBuilder()
Expand Down Expand Up @@ -212,13 +174,49 @@ private String createSign(Map<String, String> packageParams, String signKey) {
}

@Override
public WxUnifiedOrderResult unifiedOrder(WxUnifiedOrderRequest request)
public WxPayOrderQueryResult queryOrder(String transactionId, String outTradeNo) throws WxErrorException {
if ((StringUtils.isBlank(transactionId) && StringUtils.isBlank(outTradeNo)) ||
(StringUtils.isNotBlank(transactionId) && StringUtils.isNotBlank(outTradeNo))) {
throw new IllegalArgumentException("transaction_id 和 out_trade_no 不能同时存在或同时为空,必须二选一");
}

XStream xstream = XStreamInitializer.getInstance();
xstream.processAnnotations(WxPayOrderQueryRequest.class);
xstream.processAnnotations(WxPayOrderQueryResult.class);

WxPayOrderQueryRequest request = new WxPayOrderQueryRequest();
request.setOutTradeNo(StringUtils.trimToNull(outTradeNo));
request.setTransactionId(StringUtils.trimToNull(transactionId));
request.setAppid(this.wxMpService.getWxMpConfigStorage().getAppId());
request.setMchId(this.wxMpService.getWxMpConfigStorage().getPartnerId());
request.setNonceStr(System.currentTimeMillis() + "");

String sign = this.createSign(BeanUtils.xmlBean2Map(request),
this.wxMpService.getWxMpConfigStorage().getPartnerKey());
request.setSign(sign);

String url = PAY_BASE_URL + "/pay/orderquery";

String responseContent = this.wxMpService.post(url, xstream.toXML(request));
WxPayOrderQueryResult result = (WxPayOrderQueryResult) xstream.fromXML(responseContent);
result.composeCoupons(responseContent);
if ("FAIL".equals(result.getResultCode())) {
throw new WxErrorException(WxError.newBuilder()
.setErrorMsg(result.getErrCode() + ":" + result.getErrCodeDes())
.build());
}

return result;
}

@Override
public WxPayUnifiedOrderResult unifiedOrder(WxPayUnifiedOrderRequest request)
throws WxErrorException {
checkParameters(request);

XStream xstream = XStreamInitializer.getInstance();
xstream.processAnnotations(WxUnifiedOrderRequest.class);
xstream.processAnnotations(WxUnifiedOrderResult.class);
xstream.processAnnotations(WxPayUnifiedOrderRequest.class);
xstream.processAnnotations(WxPayUnifiedOrderResult.class);

request.setAppid(this.wxMpService.getWxMpConfigStorage().getAppId());
request.setMchId(this.wxMpService.getWxMpConfigStorage().getPartnerId());
Expand All @@ -231,7 +229,7 @@ public WxUnifiedOrderResult unifiedOrder(WxUnifiedOrderRequest request)
String url = PAY_BASE_URL + "/pay/unifiedorder";

String responseContent = this.wxMpService.post(url, xstream.toXML(request));
WxUnifiedOrderResult result = (WxUnifiedOrderResult) xstream
WxPayUnifiedOrderResult result = (WxPayUnifiedOrderResult) xstream
.fromXML(responseContent);
if ("FAIL".equals(result.getResultCode())) {
throw new WxErrorException(WxError.newBuilder()
Expand All @@ -242,7 +240,7 @@ public WxUnifiedOrderResult unifiedOrder(WxUnifiedOrderRequest request)
return result;
}

private void checkParameters(WxUnifiedOrderRequest request) throws WxErrorException {
private void checkParameters(WxPayUnifiedOrderRequest request) throws WxErrorException {
BeanUtils.checkRequiredFields(request);

if (! ArrayUtils.contains(TRADE_TYPES, request.getTradeType())) {
Expand All @@ -259,8 +257,8 @@ private void checkParameters(WxUnifiedOrderRequest request) throws WxErrorExcept
}

@Override
public Map<String, String> getPayInfo(WxUnifiedOrderRequest request) throws WxErrorException {
WxUnifiedOrderResult unifiedOrderResult = this.unifiedOrder(request);
public Map<String, String> getPayInfo(WxPayUnifiedOrderRequest request) throws WxErrorException {
WxPayUnifiedOrderResult unifiedOrderResult = this.unifiedOrder(request);

if (!"SUCCESS".equalsIgnoreCase(unifiedOrderResult.getReturnCode())
|| !"SUCCESS".equalsIgnoreCase(unifiedOrderResult.getResultCode())) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,7 @@
* @author binarywang (https://github.com/binarywang)
*/
@XStreamAlias("xml")
public class WxEntPayQueryRequest {
/**
* <pre>
* Appid
* appid
* 是
* wxe062425f740d30d8
* String(32)
* 商户号的appid
* </pre>
*/
@XStreamAlias("appid")
private String appid;

public class WxEntPayQueryRequest extends WxPayBaseRequest {
/**
* <pre>
* 商户号
Expand All @@ -47,32 +34,6 @@ public class WxEntPayQueryRequest {
@XStreamAlias("mchid")
private String mchId;

/**
* <pre>
* 随机字符串
* nonce_str
* 是
* 5K8264ILTKCH16CQ2502SI8ZNMTM67VS
* String(32)
* 随机字符串,不长于32位
* </pre>
*/
@XStreamAlias("nonce_str")
private String nonceStr;

/**
* <pre>
* 签名
* sign
* 是
* C380BEC2BFD727A4B6845133519F3AD6
* String(32)
*签名,详见签名算法
* </pre>
*/
@XStreamAlias("sign")
private String sign;

/**
* <pre>
* 商户订单号
Expand Down

0 comments on commit e30138f

Please sign in to comment.