diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxEntrustPapService.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxEntrustPapService.java index 168e43696a27c884b8e96ad57bbfb187d77e66f2..1a1ddb120aee33222836e215937ef5e263047fb4 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxEntrustPapService.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxEntrustPapService.java @@ -166,4 +166,22 @@ public interface WxEntrustPapService { * @throws WxPayException the wx pay exception */ WxWithholdOrderQueryResult papOrderQuery(WxWithholdOrderQueryRequest wxWithholdOrderQueryRequest) throws WxPayException; + + /** + *
+ * 签约、解约结果通知解析 + * 详见:签约、解约结果通知 + * 注意: + * 1、同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。 推荐的做法是:当商户系统收到通知进行处理时,先检查对应业务数据的状态,并判断该通知是否已经处理。如果未处理,则再进行处理;如果已处理,则直接返回结果成功。在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱。 + * 2、如果在所有通知频率(0/10/10/10/30/30/30/300/300/300/300/300/300/300/300/300/300/300/300/300/300/300/300/300/300/300/300/300/300/300(单位:秒))后没有收到微信侧回调,商户应调用查询订单接口确认订单状态。 + * 特别提醒: + * 1、商户系统对于签约、解约结果通知的内容一定要做签名验证,并校验返回的商户协议号和用户openid信息是否一致,防止数据泄露导致出现“假通知”,造成损失。 + * 2、当收到通知进行处理时,首先检查对应业务数据的状态,判断该通知是否已经处理过,如果没有处理过再进行处理,如果处理过直接返回结果成功。在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱。 + *+ * + * @param xmlData the wx withhold order query request + * @return wx sign result + * @throws WxPayException the wx pay exception + */ + WxSignQueryResult parseSignNotifyResult(String xmlData) throws WxPayException; } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxEntrustPapServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxEntrustPapServiceImpl.java index 951c1d5a8c038d975d523bd9fc2a2ac00b978616..b70a7dee37aefbc7fdc1cf4bf15d6b2585f5c040 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxEntrustPapServiceImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxEntrustPapServiceImpl.java @@ -10,6 +10,7 @@ import com.github.binarywang.wxpay.util.SignUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.common.util.json.WxGsonBuilder; +import org.apache.commons.lang3.StringUtils; import java.net.URLEncoder; @@ -65,8 +66,13 @@ public class WxEntrustPapServiceImpl implements WxEntrustPapService { strBuilder.append("&contract_code=").append(wxH5EntrustRequest.getContractCode()); strBuilder.append("&contract_display_account=").append(URLEncoder.encode(wxH5EntrustRequest.getContractDisplayAccount())); strBuilder.append("&mch_id=").append(wxH5EntrustRequest.getMchId()).append("¬ify_url=").append(URLEncoder.encode(wxH5EntrustRequest.getNotifyUrl())); - strBuilder.append("&plan_id=").append(wxH5EntrustRequest.getPlanId()).append("&outerid=").append(URLEncoder.encode(wxH5EntrustRequest.getOuterId())); - strBuilder.append("&return_appid=").append(wxH5EntrustRequest.getReturnAppid()); + strBuilder.append("&plan_id=").append(wxH5EntrustRequest.getPlanId()); + if (StringUtils.isNotEmpty(wxH5EntrustRequest.getOuterId())) { + strBuilder.append("&outerid=").append(URLEncoder.encode(wxH5EntrustRequest.getOuterId())); + } + if (StringUtils.isNotEmpty(wxH5EntrustRequest.getReturnAppid())) { + strBuilder.append("&return_appid=").append(wxH5EntrustRequest.getReturnAppid()); + } strBuilder.append("&clientip=").append(wxH5EntrustRequest.getClientIp()); strBuilder.append("&request_serial=").append(wxH5EntrustRequest.getRequestSerial()).append("×tamp=").append(wxH5EntrustRequest.getTimestamp()); strBuilder.append("&version=").append(wxH5EntrustRequest.getVersion()).append("&sign=").append(sign); @@ -148,4 +154,11 @@ public class WxEntrustPapServiceImpl implements WxEntrustPapService { wxWithholdOrderQueryResult.checkResult(payService, wxWithholdOrderQueryRequest.getSignType(), true); return wxWithholdOrderQueryResult; } + + @Override + public WxSignQueryResult parseSignNotifyResult(String xmlData) throws WxPayException { + WxSignQueryResult result = BaseWxPayResult.fromXML(xmlData, WxSignQueryResult.class); + result.checkResult(payService, WxPayConstants.SignType.MD5, true); + return result; + } }