|  |  | @ -12,15 +12,15 @@ import com.github.binarywang.wxpay.v3.util.RsaCryptoUtil; | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.common.base.CaseFormat; |  |  |  | import com.google.common.base.CaseFormat; | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.gson.Gson; |  |  |  | import com.google.gson.Gson; | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.gson.GsonBuilder; |  |  |  | import com.google.gson.GsonBuilder; | 
			
		
	
		
		
			
				
					
					|  |  |  | import org.apache.commons.lang3.StringUtils; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | import lombok.RequiredArgsConstructor; |  |  |  | import lombok.RequiredArgsConstructor; | 
			
		
	
		
		
			
				
					
					|  |  |  | import org.apache.commons.beanutils.BeanMap; |  |  |  | import org.apache.commons.beanutils.BeanMap; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | import org.apache.commons.lang3.StringUtils; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | import java.io.IOException; |  |  |  | import java.io.IOException; | 
			
		
	
		
		
			
				
					
					|  |  |  | import java.io.InputStream; |  |  |  | import java.io.InputStream; | 
			
		
	
		
		
			
				
					
					|  |  |  | import java.net.URI; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | import java.nio.charset.StandardCharsets; |  |  |  | import java.nio.charset.StandardCharsets; | 
			
		
	
		
		
			
				
					
					|  |  |  | import java.security.GeneralSecurityException; |  |  |  | import java.security.GeneralSecurityException; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | import java.text.DateFormat; | 
			
		
	
		
		
			
				
					
					|  |  |  | import java.util.Iterator; |  |  |  | import java.util.Iterator; | 
			
		
	
		
		
			
				
					
					|  |  |  | import java.util.Map; |  |  |  | import java.util.Map; | 
			
		
	
		
		
			
				
					
					|  |  |  | import java.util.Objects; |  |  |  | import java.util.Objects; | 
			
		
	
	
		
		
			
				
					
					|  |  | @ -30,6 +30,11 @@ import java.util.Set; | 
			
		
	
		
		
			
				
					
					|  |  |  | public class EcommerceServiceImpl implements EcommerceService { |  |  |  | public class EcommerceServiceImpl implements EcommerceService { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   private static final Gson GSON = new GsonBuilder().create(); |  |  |  |   private static final Gson GSON = new GsonBuilder().create(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   // https://stackoverflow.com/questions/6873020/gson-date-format | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   // gson default date format not match, so custom DateFormat | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   // detail DateFormat: FULL,LONG,SHORT,MEDIUM | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   private static final Gson GSON_CUSTOM = new GsonBuilder().setDateFormat(DateFormat.FULL, DateFormat.FULL).create(); | 
			
		
	
		
		
			
				
					
					|  |  |  |   private final WxPayService payService; |  |  |  |   private final WxPayService payService; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   @Override |  |  |  |   @Override | 
			
		
	
	
		
		
			
				
					
					|  |  | @ -71,7 +76,7 @@ public class EcommerceServiceImpl implements EcommerceService { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   @Override |  |  |  |   @Override | 
			
		
	
		
		
			
				
					
					|  |  |  |   public CombineTransactionsNotifyResult parseCombineNotifyResult(String notifyData, SignatureHeader header) throws WxPayException { |  |  |  |   public CombineTransactionsNotifyResult parseCombineNotifyResult(String notifyData, SignatureHeader header) throws WxPayException { | 
			
		
	
		
		
			
				
					
					|  |  |  |     if(Objects.nonNull(header) && !this.verifyNotifySign(header, notifyData)){ |  |  |  |     if (Objects.nonNull(header) && !this.verifyNotifySign(header, notifyData)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |       throw new WxPayException("非法请求,头部信息验证失败"); |  |  |  |       throw new WxPayException("非法请求,头部信息验证失败"); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     NotifyResponse response = GSON.fromJson(notifyData, NotifyResponse.class); |  |  |  |     NotifyResponse response = GSON.fromJson(notifyData, NotifyResponse.class); | 
			
		
	
	
		
		
			
				
					
					|  |  | @ -81,7 +86,7 @@ public class EcommerceServiceImpl implements EcommerceService { | 
			
		
	
		
		
			
				
					
					|  |  |  |     String nonce = resource.getNonce(); |  |  |  |     String nonce = resource.getNonce(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     String apiV3Key = this.payService.getConfig().getApiV3Key(); |  |  |  |     String apiV3Key = this.payService.getConfig().getApiV3Key(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     try { |  |  |  |     try { | 
			
		
	
		
		
			
				
					
					|  |  |  |       String result = AesUtils.decryptToString(associatedData, nonce,cipherText, apiV3Key); |  |  |  |       String result = AesUtils.decryptToString(associatedData, nonce, cipherText, apiV3Key); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |       CombineTransactionsResult transactionsResult = GSON.fromJson(result, CombineTransactionsResult.class); |  |  |  |       CombineTransactionsResult transactionsResult = GSON.fromJson(result, CombineTransactionsResult.class); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       CombineTransactionsNotifyResult notifyResult = new CombineTransactionsNotifyResult(); |  |  |  |       CombineTransactionsNotifyResult notifyResult = new CombineTransactionsNotifyResult(); | 
			
		
	
	
		
		
			
				
					
					|  |  | @ -117,7 +122,7 @@ public class EcommerceServiceImpl implements EcommerceService { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   @Override |  |  |  |   @Override | 
			
		
	
		
		
			
				
					
					|  |  |  |   public PartnerTransactionsNotifyResult parsePartnerNotifyResult(String notifyData, SignatureHeader header) throws WxPayException { |  |  |  |   public PartnerTransactionsNotifyResult parsePartnerNotifyResult(String notifyData, SignatureHeader header) throws WxPayException { | 
			
		
	
		
		
			
				
					
					|  |  |  |     if(Objects.nonNull(header) && !this.verifyNotifySign(header, notifyData)){ |  |  |  |     if (Objects.nonNull(header) && !this.verifyNotifySign(header, notifyData)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |       throw new WxPayException("非法请求,头部信息验证失败"); |  |  |  |       throw new WxPayException("非法请求,头部信息验证失败"); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     NotifyResponse response = GSON.fromJson(notifyData, NotifyResponse.class); |  |  |  |     NotifyResponse response = GSON.fromJson(notifyData, NotifyResponse.class); | 
			
		
	
	
		
		
			
				
					
					|  |  | @ -127,7 +132,7 @@ public class EcommerceServiceImpl implements EcommerceService { | 
			
		
	
		
		
			
				
					
					|  |  |  |     String nonce = resource.getNonce(); |  |  |  |     String nonce = resource.getNonce(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     String apiV3Key = this.payService.getConfig().getApiV3Key(); |  |  |  |     String apiV3Key = this.payService.getConfig().getApiV3Key(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     try { |  |  |  |     try { | 
			
		
	
		
		
			
				
					
					|  |  |  |       String result = AesUtils.decryptToString(associatedData, nonce,cipherText, apiV3Key); |  |  |  |       String result = AesUtils.decryptToString(associatedData, nonce, cipherText, apiV3Key); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |       PartnerTransactionsResult transactionsResult = GSON.fromJson(result, PartnerTransactionsResult.class); |  |  |  |       PartnerTransactionsResult transactionsResult = GSON.fromJson(result, PartnerTransactionsResult.class); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       PartnerTransactionsNotifyResult notifyResult = new PartnerTransactionsNotifyResult(); |  |  |  |       PartnerTransactionsNotifyResult notifyResult = new PartnerTransactionsNotifyResult(); | 
			
		
	
	
		
		
			
				
					
					|  |  | @ -277,7 +282,7 @@ public class EcommerceServiceImpl implements EcommerceService { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   @Override |  |  |  |   @Override | 
			
		
	
		
		
			
				
					
					|  |  |  |   public RefundNotifyResult parseRefundNotifyResult(String notifyData, SignatureHeader header) throws WxPayException { |  |  |  |   public RefundNotifyResult parseRefundNotifyResult(String notifyData, SignatureHeader header) throws WxPayException { | 
			
		
	
		
		
			
				
					
					|  |  |  |     if(Objects.nonNull(header) && !this.verifyNotifySign(header, notifyData)){ |  |  |  |     if (Objects.nonNull(header) && !this.verifyNotifySign(header, notifyData)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |       throw new WxPayException("非法请求,头部信息验证失败"); |  |  |  |       throw new WxPayException("非法请求,头部信息验证失败"); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     NotifyResponse response = GSON.fromJson(notifyData, NotifyResponse.class); |  |  |  |     NotifyResponse response = GSON.fromJson(notifyData, NotifyResponse.class); | 
			
		
	
	
		
		
			
				
					
					|  |  | @ -287,7 +292,7 @@ public class EcommerceServiceImpl implements EcommerceService { | 
			
		
	
		
		
			
				
					
					|  |  |  |     String nonce = resource.getNonce(); |  |  |  |     String nonce = resource.getNonce(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     String apiV3Key = this.payService.getConfig().getApiV3Key(); |  |  |  |     String apiV3Key = this.payService.getConfig().getApiV3Key(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     try { |  |  |  |     try { | 
			
		
	
		
		
			
				
					
					|  |  |  |       String result = AesUtils.decryptToString(associatedData, nonce,cipherText, apiV3Key); |  |  |  |       String result = AesUtils.decryptToString(associatedData, nonce, cipherText, apiV3Key); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |       RefundNotifyResult notifyResult = GSON.fromJson(result, RefundNotifyResult.class); |  |  |  |       RefundNotifyResult notifyResult = GSON.fromJson(result, RefundNotifyResult.class); | 
			
		
	
		
		
			
				
					
					|  |  |  |       notifyResult.setRawData(response); |  |  |  |       notifyResult.setRawData(response); | 
			
		
	
		
		
			
				
					
					|  |  |  |       return notifyResult; |  |  |  |       return notifyResult; | 
			
		
	
	
		
		
			
				
					
					|  |  | @ -359,8 +364,9 @@ public class EcommerceServiceImpl implements EcommerceService { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   /** |  |  |  |   /** | 
			
		
	
		
		
			
				
					
					|  |  |  |    * 校验通知签名 |  |  |  |    * 校验通知签名 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    * | 
			
		
	
		
		
			
				
					
					|  |  |  |    * @param header 通知头信息 |  |  |  |    * @param header 通知头信息 | 
			
		
	
		
		
			
				
					
					|  |  |  |    * @param data 通知数据 |  |  |  |    * @param data   通知数据 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |    * @return true:校验通过 false:校验不通过 |  |  |  |    * @return true:校验通过 false:校验不通过 | 
			
		
	
		
		
			
				
					
					|  |  |  |    */ |  |  |  |    */ | 
			
		
	
		
		
			
				
					
					|  |  |  |   private boolean verifyNotifySign(SignatureHeader header, String data) { |  |  |  |   private boolean verifyNotifySign(SignatureHeader header, String data) { | 
			
		
	
	
		
		
			
				
					
					|  |  | @ -374,8 +380,9 @@ public class EcommerceServiceImpl implements EcommerceService { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   /** |  |  |  |   /** | 
			
		
	
		
		
			
				
					
					|  |  |  |    * 对象拼接到url |  |  |  |    * 对象拼接到url | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    * | 
			
		
	
		
		
			
				
					
					|  |  |  |    * @param o 转换对象 |  |  |  |    * @param o 转换对象 | 
			
		
	
		
		
			
				
					
					|  |  |  |    * @return  拼接好的string |  |  |  |    * @return 拼接好的string | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |    */ |  |  |  |    */ | 
			
		
	
		
		
			
				
					
					|  |  |  |   private String parseURLPair(Object o) { |  |  |  |   private String parseURLPair(Object o) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     Map<Object, Object> map = new BeanMap(o); |  |  |  |     Map<Object, Object> map = new BeanMap(o); | 
			
		
	
	
		
		
			
				
					
					|  |  | @ -384,7 +391,7 @@ public class EcommerceServiceImpl implements EcommerceService { | 
			
		
	
		
		
			
				
					
					|  |  |  |     StringBuilder sb = new StringBuilder(); |  |  |  |     StringBuilder sb = new StringBuilder(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     while (it.hasNext()) { |  |  |  |     while (it.hasNext()) { | 
			
		
	
		
		
			
				
					
					|  |  |  |       Map.Entry<Object, Object> e = it.next(); |  |  |  |       Map.Entry<Object, Object> e = it.next(); | 
			
		
	
		
		
			
				
					
					|  |  |  |       if ( !"class".equals(e.getKey()) && e.getValue() != null) { |  |  |  |       if (!"class".equals(e.getKey()) && e.getValue() != null) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         sb.append(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, String.valueOf(e.getKey()))) |  |  |  |         sb.append(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, String.valueOf(e.getKey()))) | 
			
		
	
		
		
			
				
					
					|  |  |  |           .append("=").append(e.getValue()).append("&"); |  |  |  |           .append("=").append(e.getValue()).append("&"); | 
			
		
	
		
		
			
				
					
					|  |  |  |       } |  |  |  |       } | 
			
		
	
	
		
		
			
				
					
					|  |  | @ -392,5 +399,4 @@ public class EcommerceServiceImpl implements EcommerceService { | 
			
		
	
		
		
			
				
					
					|  |  |  |     return sb.deleteCharAt(sb.length() - 1).toString(); |  |  |  |     return sb.deleteCharAt(sb.length() - 1).toString(); | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |  | 
			
		
	
		
		
	
	
		
		
			
				
					
					| 
						
						
						
						 |  | 
 |