diff --git a/mallinkService/src/main/java/com/simple/domain/po/WxAppinfo.java b/mallinkService/src/main/java/com/simple/domain/po/WxAppinfo.java index 669aa90bf..5b625ece4 100644 --- a/mallinkService/src/main/java/com/simple/domain/po/WxAppinfo.java +++ b/mallinkService/src/main/java/com/simple/domain/po/WxAppinfo.java @@ -47,6 +47,9 @@ public class WxAppinfo implements Serializable { /*小程序ID**/ @io.swagger.annotations.ApiModelProperty(value="小程序ID",name="appId") private String appId; + /*公众号ID**/ + @io.swagger.annotations.ApiModelProperty(value="公众号ID",name="parentAppId") + private String parentAppId; /*小程序名**/ @io.swagger.annotations.ApiModelProperty(value="小程序名",name="name") private String name; @@ -80,7 +83,6 @@ public class WxAppinfo implements Serializable { public String getTenantId() { return tenantId; } - public void setTenantId(String _tenantId) { tenantId = _tenantId; } @@ -90,6 +92,13 @@ public class WxAppinfo implements Serializable { public void setAppId(String _appId) { appId = _appId; } + public String getParentAppId() { + return parentAppId; + } + + public void setParentAppId(String parentAppId) { + this.parentAppId = parentAppId; + } public String getName() { return name; } @@ -156,17 +165,18 @@ public class WxAppinfo implements Serializable { public static enum Field { Id_ASC("`id` ASC"),Id_DESC("`id` DESC") - ,TenantId_ASC("`tenantId` ASC"),TenantId_DESC("`tenantId` DESC") - ,AppId_ASC("`appId` ASC"),AppId_DESC("`appId` DESC") + ,TenantId_ASC("`tenant_id` ASC"),TenantId_DESC("`tenant_id` DESC") + ,AppId_ASC("`app_id` ASC"),AppId_DESC("`app_id` DESC") + ,ParentAppId_ASC("`parent_app_id` ASC"),ParentAppId_DESC("`parent_app_id` DESC") ,Name_ASC("`name` ASC"),Name_DESC("`name` DESC") ,Secret_ASC("`secret` ASC"),Secret_DESC("`secret` DESC") ,Token_ASC("`token` ASC"),Token_DESC("`token` DESC") ,AesKey_ASC("`aesKey` ASC"),AesKey_DESC("`aesKey` DESC") - ,MsgDataFormat_ASC("`msgDataFormat` ASC"),MsgDataFormat_DESC("`msgDataFormat` DESC") - ,AccessToken_ASC("`accessToken` ASC"),AccessToken_DESC("`accessToken` DESC") - ,LastTokenTime_ASC("`lastTokenTime` ASC"),LastTokenTime_DESC("`lastTokenTime` DESC") - ,ExpiresIn_ASC("`expiresIn` ASC"),ExpiresIn_DESC("`expiresIn` DESC") - ,PayId_ASC("`payId` ASC"),PayId_DESC("`payId` DESC") + ,MsgDataFormat_ASC("`msg_data_format` ASC"),MsgDataFormat_DESC("`msg_data_format` DESC") + ,AccessToken_ASC("`access_token` ASC"),AccessToken_DESC("`access_token` DESC") + ,LastTokenTime_ASC("`last_token_time` ASC"),LastTokenTime_DESC("`last_token_time` DESC") + ,ExpiresIn_ASC("`expires_in` ASC"),ExpiresIn_DESC("`expires_in` DESC") + ,PayId_ASC("`pay_id` ASC"),PayId_DESC("`pay_id` DESC") ,Type_ASC("`type` ASC"),Type_DESC("`type` DESC") ; @@ -201,7 +211,7 @@ public class WxAppinfo implements Serializable { sb.append(","); sb.append(fields[k].toString()); } - + this.sortColumns = sb.toString(); } public void setSortColumns(String sortColumns) diff --git a/mallinkService/src/main/java/com/simple/domain/po/WxPayAccount.java b/mallinkService/src/main/java/com/simple/domain/po/WxPayAccount.java index 95f7ee127..76668097f 100644 --- a/mallinkService/src/main/java/com/simple/domain/po/WxPayAccount.java +++ b/mallinkService/src/main/java/com/simple/domain/po/WxPayAccount.java @@ -42,24 +42,40 @@ public class WxPayAccount implements Serializable { - /*微信商户号**/ - @io.swagger.annotations.ApiModelProperty(value="微信商户号",name="mchId") + /**微信商户号/特约服务商号**/ + @io.swagger.annotations.ApiModelProperty(value="微信商户号/特约服务商号",name="mchId") private String mchId; - /*支付密钥**/ + /**微信服务商号*/ + @io.swagger.annotations.ApiModelProperty(value="微信服务商号",name="subMchId") + private String subMchId; + /**支付密钥**/ @io.swagger.annotations.ApiModelProperty(value="支付密钥",name="apiKey") private String apiKey; - /*微信回调,支持3种回调,(1.url/pay 2.url/refund3.url/separate)**/ + /**微信回调,支持3种回调,(1.url/pay 2.url/refund3.url/separate)**/ @io.swagger.annotations.ApiModelProperty(value="微信回调,支持3种回调,(1.url/pay 2.url/refund3.url/separate)",name="notifyUrl") private String notifyUrl; - /*证书本地存放位置**/ + /**证书本地存放位置**/ @io.swagger.annotations.ApiModelProperty(value="证书本地存放位置",name="certPath") private String certPath; + /**商户模式**/ + @io.swagger.annotations.ApiModelProperty(value="商户模式-0:普通商户模式1:服务商模式",name="type") + private Integer type; + public String getMchId() { return mchId; } public void setMchId(String _mchId) { mchId = _mchId; } + + public String getSubMchId() { + return subMchId; + } + + public void setSubMchId(String subMchId) { + this.subMchId = subMchId; + } + public String getApiKey() { return apiKey; } @@ -79,6 +95,14 @@ public class WxPayAccount implements Serializable { certPath = _certPath; } + public Integer getType() { + return type; + } + + public void setType(Integer type) { + this.type = type; + } + public String getPayNotifyUrl() { return notifyUrl + "/pay"; } @@ -92,11 +116,13 @@ public class WxPayAccount implements Serializable { public static enum Field { Id_ASC("`id` ASC"),Id_DESC("`id` DESC") - ,MchId_ASC("`mch_id` ASC"),MchId_DESC("`mch_id` DESC") - ,ApiKey_ASC("`api_key` ASC"),ApiKey_DESC("`api_key` DESC") - ,NotifyUrl_ASC("`notify_url` ASC"),NotifyUrl_DESC("`notify_url` DESC") - ,CertPath_ASC("`cert_path` ASC"),CertPath_DESC("`cert_path` DESC") - ; + ,MchId_ASC("`mch_id` ASC"),MchId_DESC("`mch_id` DESC") + ,SubMchId_ASC("`sub_mch_id` ASC"),SubMchId_DESC("`sub_mch_id` DESC") + ,ApiKey_ASC("`api_key` ASC"),ApiKey_DESC("`api_key` DESC") + ,NotifyUrl_ASC("`notify_url` ASC"),NotifyUrl_DESC("`notify_url` DESC") + ,CertPath_ASC("`cert_path` ASC"),CertPath_DESC("`cert_path` DESC") + ,Type_ASC("`type` ASC"),Type_DESC("`type` DESC") + ; private String value; Field(String value){ this.value = value; diff --git a/mallinkService/src/main/java/com/simple/enums/EnumPayMode.java b/mallinkService/src/main/java/com/simple/enums/EnumPayMode.java new file mode 100644 index 000000000..0c77dadf9 --- /dev/null +++ b/mallinkService/src/main/java/com/simple/enums/EnumPayMode.java @@ -0,0 +1,35 @@ +package com.simple.enums; + +/** + * Created by Stormeye on 2018/08/09. + */ +public enum EnumPayMode { + + MCH(0, "普通商户模式"), + MCH_S(1, "服务商模式"); + + public static EnumPayMode getEnum(Integer code) { + for (EnumPayMode value : values()) { + if (value.getCode().equals(code)) { + return value; + } + } + return null; + } + + private Integer code; + private String message; + + EnumPayMode(Integer code, String message) { + this.code = code; + this.message = message; + } + + public Integer getCode() { + return code; + } + + public String getMessage() { + return message; + } +} diff --git a/mallinkService/src/main/java/com/simple/pay/WxPayOrderP.java b/mallinkService/src/main/java/com/simple/pay/WxPayOrderP.java index d40500676..b2602bc0d 100644 --- a/mallinkService/src/main/java/com/simple/pay/WxPayOrderP.java +++ b/mallinkService/src/main/java/com/simple/pay/WxPayOrderP.java @@ -2,9 +2,10 @@ package com.simple.pay; /** * Created by Stormeye on 2018/8/10. + * 普通商户模式 */ public class WxPayOrderP { - private String appid; // 公众账号ID + private String appid; // 小程序ID private String mch_id; // 商户号 private String nonce_str; // 随机字符串 private String sign; // 签名 diff --git a/mallinkService/src/main/java/com/simple/pay/WxPayOrderQ.java b/mallinkService/src/main/java/com/simple/pay/WxPayOrderQ.java index 517b1dc23..114d15191 100644 --- a/mallinkService/src/main/java/com/simple/pay/WxPayOrderQ.java +++ b/mallinkService/src/main/java/com/simple/pay/WxPayOrderQ.java @@ -4,7 +4,7 @@ package com.simple.pay; * Created by Stormeye on 2018/8/10. */ public class WxPayOrderQ { - private String appid; // 公众账号ID + private String appid; // 小程序ID private String mch_id; // 商户号 private String nonce_str; // 随机字符串 private String sign; // 签名 diff --git a/mallinkService/src/main/java/com/simple/pay/WxPayOrderSP.java b/mallinkService/src/main/java/com/simple/pay/WxPayOrderSP.java new file mode 100644 index 000000000..89e0b1037 --- /dev/null +++ b/mallinkService/src/main/java/com/simple/pay/WxPayOrderSP.java @@ -0,0 +1,175 @@ +package com.simple.pay; + +/** + * Created by Stormeye on 2018/8/10. + * 服务商模式 + */ +public class WxPayOrderSP { + private String appid; // 公众账号ID + private String sub_appid; // 小程序ID + private String mch_id; // 服务商号 + private String sub_mch_id; // 特约商户号 + private String nonce_str; // 随机字符串 + private String sign; // 签名 + private String body; // 商品简单描述 128 + private String out_trade_no; // 商户订单号 + private Integer total_fee; // 支付金额 + private String spbill_create_ip; // 支付IP + private String notify_url; // 通知地址 + private String trade_type; // 支付类型 + private String product_id; // 商品ID - 扫码必传 + private String time_start; // 开始时间 + private String time_expire; // 失效时间 + private String sub_openid; // sub_openId + + public String getTime_start() { + return time_start; + } + + public void setTime_start(String time_start) { + this.time_start = time_start; + } + + public String getTime_expire() { + return time_expire; + } + + public void setTime_expire(String time_expire) { + this.time_expire = time_expire; + } + + public String getAppid() { + return appid; + } + + public void setAppid(String appid) { + this.appid = appid; + } + + public String getSub_appid() { + return sub_appid; + } + + public void setSub_appid(String sub_appid) { + this.sub_appid = sub_appid; + } + + public String getMch_id() { + return mch_id; + } + + public void setMch_id(String mch_id) { + this.mch_id = mch_id; + } + + public String getSub_mch_id() { + return sub_mch_id; + } + + public void setSub_mch_id(String sub_mch_id) { + this.sub_mch_id = sub_mch_id; + } + + public String getNonce_str() { + return nonce_str; + } + + public void setNonce_str(String nonce_str) { + this.nonce_str = nonce_str; + } + + public String getSign() { + return sign; + } + + public void setSign(String sign) { + this.sign = sign; + } + + public String getBody() { + return body; + } + + public void setBody(String body) { + this.body = body; + } + + public String getOut_trade_no() { + return out_trade_no; + } + + public void setOut_trade_no(String out_trade_no) { + this.out_trade_no = out_trade_no; + } + + public Integer getTotal_fee() { + return total_fee; + } + + public void setTotal_fee(Integer total_fee) { + this.total_fee = total_fee; + } + + public String getSpbill_create_ip() { + return spbill_create_ip; + } + + public void setSpbill_create_ip(String spbill_create_ip) { + this.spbill_create_ip = spbill_create_ip; + } + + public String getNotify_url() { + return notify_url; + } + + public void setNotify_url(String notify_url) { + this.notify_url = notify_url; + } + + public String getTrade_type() { + return trade_type; + } + + public void setTrade_type(String trade_type) { + this.trade_type = trade_type; + } + + public String getProduct_id() { + return product_id; + } + + public void setProduct_id(String product_id) { + this.product_id = product_id; + } + + public String getSub_openid() { + return sub_openid; + } + + public void setSub_openid(String sub_openid) { + this.sub_openid = sub_openid; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("WxPayOrder{"); + sb.append("appid='").append(appid).append('\''); + sb.append("sub_appid='").append(sub_appid).append('\''); + sb.append(", mch_id='").append(mch_id).append('\''); + sb.append(", sub_mch_id='").append(sub_mch_id).append('\''); + sb.append(", nonce_str='").append(nonce_str).append('\''); + sb.append(", sign='").append(sign).append('\''); + sb.append(", body='").append(body).append('\''); + sb.append(", out_trade_no='").append(out_trade_no).append('\''); + sb.append(", total_fee=").append(total_fee); + sb.append(", spbill_create_ip='").append(spbill_create_ip).append('\''); + sb.append(", notify_url='").append(notify_url).append('\''); + sb.append(", trade_type='").append(trade_type).append('\''); + sb.append(", product_id='").append(product_id).append('\''); + sb.append(", time_start='").append(time_start).append('\''); + sb.append(", time_expire='").append(time_expire).append('\''); + sb.append(", sub_openid='").append(sub_openid).append('\''); + sb.append('}'); + return sb.toString(); + } +} diff --git a/mallinkService/src/main/java/com/simple/pay/WxPayOrderSQ.java b/mallinkService/src/main/java/com/simple/pay/WxPayOrderSQ.java new file mode 100644 index 000000000..6cfdbca53 --- /dev/null +++ b/mallinkService/src/main/java/com/simple/pay/WxPayOrderSQ.java @@ -0,0 +1,85 @@ +package com.simple.pay; + +/** + * Created by Stormeye on 2018/8/10. + */ +public class WxPayOrderSQ { + private String appid; // 公众号ID + private String sub_appid; // 小程序ID + private String mch_id; // 服务号 + private String sub_mch_id; // 特约商户号 + private String nonce_str; // 随机字符串 + private String sign; // 签名 + private String out_trade_no; // 商户订单号 + + + public String getAppid() { + return appid; + } + + public void setAppid(String appid) { + this.appid = appid; + } + + public String getSub_appid() { + return sub_appid; + } + + public void setSub_appid(String sub_appid) { + this.sub_appid = sub_appid; + } + + public String getMch_id() { + return mch_id; + } + + public void setMch_id(String mch_id) { + this.mch_id = mch_id; + } + + public String getSub_mch_id() { + return sub_mch_id; + } + + public void setSub_mch_id(String sub_mch_id) { + this.sub_mch_id = sub_mch_id; + } + + public String getNonce_str() { + return nonce_str; + } + + public void setNonce_str(String nonce_str) { + this.nonce_str = nonce_str; + } + + public String getSign() { + return sign; + } + + public void setSign(String sign) { + this.sign = sign; + } + + public String getOut_trade_no() { + return out_trade_no; + } + + public void setOut_trade_no(String out_trade_no) { + this.out_trade_no = out_trade_no; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("WxPayOrder{"); + sb.append("appid='").append(appid).append('\''); + sb.append("sub_appid='").append(sub_appid).append('\''); + sb.append(", mch_id='").append(mch_id).append('\''); + sb.append(", sub_mch_id='").append(sub_mch_id).append('\''); + sb.append(", nonce_str='").append(nonce_str).append('\''); + sb.append(", sign='").append(sign).append('\''); + sb.append(", out_trade_no='").append(out_trade_no).append('\''); + sb.append('}'); + return sb.toString(); + } +} diff --git a/mallinkService/src/main/java/com/simple/pay/WxPayment.java b/mallinkService/src/main/java/com/simple/pay/WxPayment.java index 215e4bb5d..3c2bd5919 100644 --- a/mallinkService/src/main/java/com/simple/pay/WxPayment.java +++ b/mallinkService/src/main/java/com/simple/pay/WxPayment.java @@ -289,6 +289,37 @@ public class WxPayment { return buildSignAfterParasMap(params, paternerKey); } + /** + * 服务商查询退款 + * + * @param appid + * @param mch_id + * @param out_trade_no + * @param paternerKey + * @return + */ + public static Map buildSWeappRefundQueryMap(String appid, String sub_appid, String mch_id, String sub_mch_id, + String transaction_id, String out_trade_no, String out_refund_no, String refund_id, + String paternerKey) { + Map params = new HashMap(); + + params.put("appid", appid); + params.put("sub_appid", sub_appid); + params.put("mch_id", mch_id); + params.put("sub_mch_id", sub_mch_id); + if(!StringUtils.isBlank(refund_id)) { + params.put("refund_id", refund_id); + } else if (!StringUtils.isBlank(out_refund_no)) { + params.put("out_refund_no", out_refund_no); + } else if (!StringUtils.isBlank(transaction_id)) { + params.put("transaction_id", transaction_id); + } else if (!StringUtils.isBlank(out_trade_no)) { + params.put("out_trade_no", out_trade_no); + } + + return buildSignAfterParasMap(params, paternerKey); + } + /** * 组装签名的字段 * diff --git a/mallinkService/src/main/java/com/simple/pay/WxRefundOrderP.java b/mallinkService/src/main/java/com/simple/pay/WxRefundOrderP.java index 09aa173c2..a9d382da2 100644 --- a/mallinkService/src/main/java/com/simple/pay/WxRefundOrderP.java +++ b/mallinkService/src/main/java/com/simple/pay/WxRefundOrderP.java @@ -4,7 +4,7 @@ package com.simple.pay; * Created by Stormeye on 2018/8/10. */ public class WxRefundOrderP { - private String appid; // 公众账号ID + private String appid; // 小程序ID private String mch_id; // 商户号 private String nonce_str; // 随机字符串 private String sign; // 签名 diff --git a/mallinkService/src/main/java/com/simple/pay/WxRefundOrderSP.java b/mallinkService/src/main/java/com/simple/pay/WxRefundOrderSP.java new file mode 100644 index 000000000..426a1aff8 --- /dev/null +++ b/mallinkService/src/main/java/com/simple/pay/WxRefundOrderSP.java @@ -0,0 +1,139 @@ +package com.simple.pay; + +/** + * Created by Stormeye on 2018/8/10. + */ +public class WxRefundOrderSP { + private String appid; // 公众账号ID + private String sub_appid; // 小程序ID + private String mch_id; // 服务号 + private String sub_mch_id; // 特约商户号 + private String nonce_str; // 随机字符串 + private String sign; // 签名 + private String transaction_id; // 微信订单号 + private String out_trade_no; // 商户订单号 + private String out_refund_no; // 商户退款单号 + private Integer total_fee; // 支付金额 + private Integer refund_fee; // 退款金额 + private String refund_desc; // 退款原因 + private String notify_url; // 回调接口 + + public String getAppid() { + return appid; + } + + public void setAppid(String appid) { + this.appid = appid; + } + + public String getSub_appid() { + return sub_appid; + } + + public void setSub_appid(String sub_appid) { + this.sub_appid = sub_appid; + } + + public String getMch_id() { + return mch_id; + } + + public void setMch_id(String mch_id) { + this.mch_id = mch_id; + } + + public String getSub_mch_id() { + return sub_mch_id; + } + + public void setSub_mch_id(String sub_mch_id) { + this.sub_mch_id = sub_mch_id; + } + + public String getNonce_str() { + return nonce_str; + } + + public void setNonce_str(String nonce_str) { + this.nonce_str = nonce_str; + } + + public String getSign() { + return sign; + } + + public void setSign(String sign) { + this.sign = sign; + } + + public String getTransaction_id() { + return transaction_id; + } + + public void setTransaction_id(String transaction_id) { + this.transaction_id = transaction_id; + } + + public String getOut_trade_no() { + return out_trade_no; + } + + public void setOut_trade_no(String out_trade_no) { + this.out_trade_no = out_trade_no; + } + + public String getOut_refund_no() { + return out_refund_no; + } + + public void setOut_refund_no(String out_refund_no) { + this.out_refund_no = out_refund_no; + } + + public Integer getTotal_fee() { + return total_fee; + } + + public void setTotal_fee(Integer total_fee) { + this.total_fee = total_fee; + } + + public Integer getRefund_fee() { + return refund_fee; + } + + public void setRefund_fee(Integer refund_fee) { + this.refund_fee = refund_fee; + } + + public String getRefund_desc() { + return refund_desc; + } + + public void setRefund_desc(String refund_desc) { + this.refund_desc = refund_desc; + } + + public String getNotify_url() { + return notify_url; + } + + public void setNotify_url(String notify_url) { + this.notify_url = notify_url; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("WxRefundOrder{"); + sb.append("appid='").append(appid).append('\''); + sb.append(", mch_id='").append(mch_id).append('\''); + sb.append(", nonce_str='").append(nonce_str).append('\''); + sb.append(", sign='").append(sign).append('\''); + sb.append(", out_trade_no='").append(out_trade_no).append('\''); + sb.append(", out_refund_no='").append(out_refund_no).append('\''); + sb.append(", total_fee=").append(total_fee); + sb.append(", refund_fee=").append(refund_fee); + sb.append('}'); + return sb.toString(); + } +} diff --git a/mallinkService/src/main/java/com/simple/service/impl/WxPayOrderServiceImpl.java b/mallinkService/src/main/java/com/simple/service/impl/WxPayOrderServiceImpl.java index 17fc28e78..2a6472d4d 100644 --- a/mallinkService/src/main/java/com/simple/service/impl/WxPayOrderServiceImpl.java +++ b/mallinkService/src/main/java/com/simple/service/impl/WxPayOrderServiceImpl.java @@ -144,74 +144,126 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { WxPayAccount payAccount = wxPayAccountMapper.selectByPrimaryKey(appInfo.getPayId()); if (isReal) { - // 统一下单 - String noncestr = Utility.generate32UUID(); - WxPayOrderP wxPayOrderP = new WxPayOrderP(); - wxPayOrderP.setOpenid(user.getOpenId()); - wxPayOrderP.setAppid(user.getAppId()); - wxPayOrderP.setMch_id(payAccount.getMchId()); - wxPayOrderP.setNonce_str(noncestr); - wxPayOrderP.setBody(order.getDetail()); - wxPayOrderP.setOut_trade_no(record.getPayOrderNo()); - wxPayOrderP.setTotal_fee(order.getPayment()); - wxPayOrderP.setSpbill_create_ip(record.getIp()); // 终端IP - wxPayOrderP.setNotify_url(payAccount.getPayNotifyUrl()); - wxPayOrderP.setTrade_type(WxPay.TradeType.JSAPI.name()); // 终端类型 - wxPayOrderP.setProduct_id(String.valueOf(order.getId())); // 订单ID - wxPayOrderP.setTime_start(Utility.getDataFormatStringYYYYMMDDHHmmss(currentDate)); - Date futureDate = new Date(); - futureDate.setTime(currentDate.getTime() + 15*60*1000); - wxPayOrderP.setTime_expire(Utility.getDataFormatStringYYYYMMDDHHmmss(futureDate)); // 15分钟后结束 - Map payOrderMap = BeanUtils.toStringMap(wxPayOrderP); - if(isShare) - payOrderMap.put("profit_sharing", "Y"); - wxPayOrderP.setSign(WxPayment.createSign(payOrderMap, payAccount.getApiKey())); - String response = WxPay.pushOrder(BeanUtils.toStringMap(wxPayOrderP)); - logger.info("pay order, wechat pushOrder, " + wxPayOrderP.toString() + ", response: " + response.toString()); - Map returnMap = WxPayment.xmlToMap(response); - returnMap.put("payOrderId", payOrderNo); - String result_code = returnMap.get("result_code"); - if ("SUCCESS".equals(result_code)) { - /* - Map signMap = WxPayment.buildWeappSecondSignMap(returnMap.get("appid"), - String.valueOf(Utility.getCurrentTimeStamp()), - returnMap.get("prepay_id"), - payAccount.getApiKey()); - - String signAgent = signMap.remove("sign"); - returnMap.putAll(signMap); - returnMap.put("paySign", signAgent); - */ - String prepay_id = returnMap.get("prepay_id"); - // update payOrder with prepay_id - record.setPrepayId(prepay_id); - record.setUpdateTime(new Date()); - try { - wxPayOrderMapper.updateByPrimaryKeySelective(record); - } catch (Exception e) { - logger.error("pay order update error: " + record.toString()); - throw new MallinkException(ErrorCode.DB_FAIL); + // 微信实际支付 + if (payAccount.getType() == EnumPayMode.MCH.getCode()) { + // 统一下单 普通商户模式 + String noncestr = Utility.generate32UUID(); + WxPayOrderP wxPayOrderP = new WxPayOrderP(); + wxPayOrderP.setOpenid(user.getOpenId()); + wxPayOrderP.setAppid(user.getAppId()); + wxPayOrderP.setMch_id(payAccount.getMchId()); + wxPayOrderP.setNonce_str(noncestr); + wxPayOrderP.setBody(order.getDetail()); + wxPayOrderP.setOut_trade_no(record.getPayOrderNo()); + wxPayOrderP.setTotal_fee(order.getPayment()); + wxPayOrderP.setSpbill_create_ip(record.getIp()); // 终端IP + wxPayOrderP.setNotify_url(payAccount.getPayNotifyUrl()); + wxPayOrderP.setTrade_type(WxPay.TradeType.JSAPI.name()); // 终端类型 + wxPayOrderP.setProduct_id(String.valueOf(order.getId())); // 订单ID + wxPayOrderP.setTime_start(Utility.getDataFormatStringYYYYMMDDHHmmss(currentDate)); + Date futureDate = new Date(); + futureDate.setTime(currentDate.getTime() + 15*60*1000); + wxPayOrderP.setTime_expire(Utility.getDataFormatStringYYYYMMDDHHmmss(futureDate)); // 15分钟后结束 + Map payOrderMap = BeanUtils.toStringMap(wxPayOrderP); + wxPayOrderP.setSign(WxPayment.createSign(payOrderMap, payAccount.getApiKey())); + String response = WxPay.pushOrder(BeanUtils.toStringMap(wxPayOrderP)); + logger.info("pay order, wechat pushOrder, " + wxPayOrderP.toString() + ", response: " + response.toString()); + Map returnMap = WxPayment.xmlToMap(response); + returnMap.put("payOrderId", payOrderNo); + String result_code = returnMap.get("result_code"); + if ("SUCCESS".equals(result_code)) { + String prepay_id = returnMap.get("prepay_id"); + // update payOrder with prepay_id + record.setPrepayId(prepay_id); + record.setUpdateTime(new Date()); + try { + wxPayOrderMapper.updateByPrimaryKeySelective(record); + } catch (Exception e) { + logger.error("pay order update error: " + record.toString()); + throw new MallinkException(ErrorCode.DB_FAIL); + } + + String timestamp = String.valueOf(Utility.getCurrentTimeStamp()); + Map sighMap = MapUtil.getOrderMap(); + sighMap.put("appId", returnMap.get("appid")); + sighMap.put("timeStamp", timestamp); + sighMap.put("nonceStr", noncestr); + sighMap.put("package", "prepay_id=" + prepay_id); + sighMap.put("signType", "MD5"); + String signAgent = WxPayment.createSign(sighMap, payAccount.getApiKey()); + returnMap.put("timeStamp", timestamp); + returnMap.put("nonceStr", noncestr); + returnMap.put("package", "prepay_id=" + prepay_id); + returnMap.put("paySign", signAgent); + logger.info("back to UI: " +returnMap.toString()); + return new ResultData(Result.SUCCESS, "创建支付订单成功", returnMap); + } else { + JSONObject errObj = errorMap.getJSONObject(result_code); + return new ResultData(ErrorCode.PAY_ORDER_ERROR.getCode(), errObj.toJSONString(), returnMap); } - - String timestamp = String.valueOf(Utility.getCurrentTimeStamp()); - Map sighMap = MapUtil.getOrderMap(); - sighMap.put("appId", returnMap.get("appid")); - sighMap.put("timeStamp", timestamp); - sighMap.put("nonceStr", noncestr); - sighMap.put("package", "prepay_id=" + prepay_id); - sighMap.put("signType", "MD5"); - String signAgent = WxPayment.createSign(sighMap, payAccount.getApiKey()); - returnMap.put("timeStamp", timestamp); - returnMap.put("nonceStr", noncestr); - returnMap.put("package", "prepay_id=" + prepay_id); - returnMap.put("paySign", signAgent); - logger.info("back to UI: " +returnMap.toString()); - return new ResultData(Result.SUCCESS, "创建支付订单成功", returnMap); } else { - JSONObject errObj = errorMap.getJSONObject(result_code); - return new ResultData(ErrorCode.PAY_ORDER_ERROR.getCode(), errObj.toJSONString(), returnMap); + // 统一下单 // 服务商模式 + String noncestr = Utility.generate32UUID(); + WxPayOrderSP wxPayOrderSP = new WxPayOrderSP(); + wxPayOrderSP.setAppid(appInfo.getParentAppId()); + wxPayOrderSP.setMch_id(payAccount.getMchId()); + wxPayOrderSP.setSub_appid(user.getAppId()); + wxPayOrderSP.setSub_mch_id(payAccount.getSubMchId()); + wxPayOrderSP.setNonce_str(noncestr); + wxPayOrderSP.setBody(order.getDetail()); + wxPayOrderSP.setOut_trade_no(record.getPayOrderNo()); + wxPayOrderSP.setTotal_fee(order.getPayment()); + wxPayOrderSP.setSpbill_create_ip(record.getIp()); // 终端IP + wxPayOrderSP.setNotify_url(payAccount.getPayNotifyUrl()); + wxPayOrderSP.setTrade_type(WxPay.TradeType.JSAPI.name()); // 终端类型 + wxPayOrderSP.setProduct_id(String.valueOf(order.getId())); // 订单ID + wxPayOrderSP.setTime_start(Utility.getDataFormatStringYYYYMMDDHHmmss(currentDate)); + Date futureDate = new Date(); + futureDate.setTime(currentDate.getTime() + 15*60*1000); + wxPayOrderSP.setTime_expire(Utility.getDataFormatStringYYYYMMDDHHmmss(futureDate)); // 15分钟后结束 + Map payOrderMap = BeanUtils.toStringMap(wxPayOrderSP); + if(isShare) { + payOrderMap.put("profit_sharing", "Y"); + } + wxPayOrderSP.setSign(WxPayment.createSign(payOrderMap, payAccount.getApiKey())); + String response = WxPay.pushOrder(BeanUtils.toStringMap(wxPayOrderSP)); + logger.info("pay order, wechat pushOrder, " + wxPayOrderSP.toString() + ", response: " + response.toString()); + Map returnMap = WxPayment.xmlToMap(response); + returnMap.put("payOrderId", payOrderNo); + String result_code = returnMap.get("result_code"); + if ("SUCCESS".equals(result_code)) { + String prepay_id = returnMap.get("prepay_id"); + // update payOrder with prepay_id + record.setPrepayId(prepay_id); + record.setUpdateTime(new Date()); + try { + wxPayOrderMapper.updateByPrimaryKeySelective(record); + } catch (Exception e) { + logger.error("pay order update error: " + record.toString()); + throw new MallinkException(ErrorCode.DB_FAIL); + } + + String timestamp = String.valueOf(Utility.getCurrentTimeStamp()); + Map sighMap = MapUtil.getOrderMap(); + sighMap.put("appId", returnMap.get("appid")); + sighMap.put("timeStamp", timestamp); + sighMap.put("nonceStr", noncestr); + sighMap.put("package", "prepay_id=" + prepay_id); + sighMap.put("signType", "MD5"); + String signAgent = WxPayment.createSign(sighMap, payAccount.getApiKey()); + returnMap.put("timeStamp", timestamp); + returnMap.put("nonceStr", noncestr); + returnMap.put("package", "prepay_id=" + prepay_id); + returnMap.put("paySign", signAgent); + logger.info("back to UI: " +returnMap.toString()); + return new ResultData(Result.SUCCESS, "创建支付订单成功", returnMap); + } else { + JSONObject errObj = errorMap.getJSONObject(result_code); + return new ResultData(ErrorCode.PAY_ORDER_ERROR.getCode(), errObj.toJSONString(), returnMap); + } } } else { + // 虚拟支付 WxPayOrderP wxPayOrderP = new WxPayOrderP(); wxPayOrderP.setOpenid(user.getOpenId()); wxPayOrderP.setAppid(user.getAppId()); @@ -247,51 +299,104 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { public ResultData payOrderQuery(WxAppinfo appInfo, WxPayOrder record) { // get payAccount WxPayAccount payAccount = wxPayAccountMapper.selectByPrimaryKey(appInfo.getPayId()); - WxPayOrderQ payOrderQ = new WxPayOrderQ(); - String noncestr = Utility.generate32UUID(); - payOrderQ.setAppid(appInfo.getAppId()); - payOrderQ.setMch_id(payAccount.getMchId()); - payOrderQ.setNonce_str(noncestr); - payOrderQ.setOut_trade_no(record.getPayOrderNo()); + if (payAccount.getType() == EnumPayMode.MCH.getCode()) { + // 普通商户号模式 + WxPayOrderQ payOrderQ = new WxPayOrderQ(); + String noncestr = Utility.generate32UUID(); + payOrderQ.setAppid(appInfo.getAppId()); + payOrderQ.setMch_id(payAccount.getMchId()); + payOrderQ.setNonce_str(noncestr); + payOrderQ.setOut_trade_no(record.getPayOrderNo()); - try { - payOrderQ.setSign(WxPayment.createSign(BeanUtils.toStringMap(payOrderQ), payAccount.getApiKey())); - - String response = WxPay.orderQuery(BeanUtils.toStringMap(payOrderQ)); - - logger.info("pay order query, " + payOrderQ.toString() + ", response: " + response); - Map returnMap = WxPayment.xmlToMap(response); - String result_code = returnMap.get("result_code"); - if ("SUCCESS".equals(result_code)) { - String trade_state = returnMap.get("trade_state"); - //SUCCESS—支付成功 - //REFUND—转入退款 - //NOTPAY—未支付 - //CLOSED—已关闭 - //REVOKED—已撤销(刷卡支付) - //USERPAYING--用户支付中 - //PAYERROR--支付失败(其他原因,如银行返回失败) - if ("SUCCESS".equals(trade_state)) { - record.setPayOrderStatus(EnumPayStatus.PAY_WAY_SUCCESS.getCode()); - handlePayOrderStatusUpdate(record); - } else if ("USERPAYING".equals(trade_state)) { - //record.setPayOrderStatus(EnumPayStatus.PAY_WAY_WAIT.getCode()); - //handlePayOrderStatusUpdate(record); + try { + Map map = BeanUtils.toStringMap(payOrderQ); + payOrderQ.setSign(WxPayment.createSign(map, payAccount.getApiKey())); + map = BeanUtils.toStringMap(payOrderQ); + String response = WxPay.orderQuery(map); + + logger.info("pay order query, " + payOrderQ.toString() + ", response: " + response); + Map returnMap = WxPayment.xmlToMap(response); + String result_code = returnMap.get("result_code"); + if ("SUCCESS".equals(result_code)) { + String trade_state = returnMap.get("trade_state"); + //SUCCESS—支付成功 + //REFUND—转入退款 + //NOTPAY—未支付 + //CLOSED—已关闭 + //REVOKED—已撤销(刷卡支付) + //USERPAYING--用户支付中 + //PAYERROR--支付失败(其他原因,如银行返回失败) + if ("SUCCESS".equals(trade_state)) { + record.setPayOrderStatus(EnumPayStatus.PAY_WAY_SUCCESS.getCode()); + handlePayOrderStatusUpdate(record); + } else if ("USERPAYING".equals(trade_state)) { + //record.setPayOrderStatus(EnumPayStatus.PAY_WAY_WAIT.getCode()); + //handlePayOrderStatusUpdate(record); + } else { + record.setPayOrderStatus(EnumPayStatus.PAY_WAY_FAIL.getCode()); + handlePayOrderStatusUpdate(record); + } + return new ResultData(Result.SUCCESS, "订单查询成功", returnMap); } else { - record.setPayOrderStatus(EnumPayStatus.PAY_WAY_FAIL.getCode()); - handlePayOrderStatusUpdate(record); + JSONObject errObj = errorMap.getJSONObject(result_code); + return new ResultData(ErrorCode.PAY_ORDER_ERROR.getCode(), errObj.toJSONString(), returnMap); } - return new ResultData(Result.SUCCESS, "订单查询成功", returnMap); - } else { - JSONObject errObj = errorMap.getJSONObject(result_code); - return new ResultData(ErrorCode.PAY_ORDER_ERROR.getCode(), errObj.toJSONString(), returnMap); + } catch (RuntimeException e) { + throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); + } catch (Exception e){ + throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); } - } catch (RuntimeException e) { - throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); - } catch (Exception e){ - throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); - } + } else { + // 服务商模式 + WxPayOrderSQ payOrderSQ = new WxPayOrderSQ(); + String noncestr = Utility.generate32UUID(); + payOrderSQ.setAppid(appInfo.getParentAppId()); + payOrderSQ.setSub_appid(appInfo.getAppId()); + payOrderSQ.setMch_id(payAccount.getMchId()); + payOrderSQ.setSub_mch_id(payAccount.getSubMchId()); + payOrderSQ.setNonce_str(noncestr); + payOrderSQ.setOut_trade_no(record.getPayOrderNo()); + + try { + Map map = BeanUtils.toStringMap(payOrderSQ); + payOrderSQ.setSign(WxPayment.createSign(map, payAccount.getApiKey())); + map = BeanUtils.toStringMap(payOrderSQ); + + String response = WxPay.orderQuery(map); + logger.info("pay order query, " + payOrderSQ.toString() + ", response: " + response); + Map returnMap = WxPayment.xmlToMap(response); + String result_code = returnMap.get("result_code"); + if ("SUCCESS".equals(result_code)) { + String trade_state = returnMap.get("trade_state"); + //SUCCESS—支付成功 + //REFUND—转入退款 + //NOTPAY—未支付 + //CLOSED—已关闭 + //REVOKED—已撤销(刷卡支付) + //USERPAYING--用户支付中 + //PAYERROR--支付失败(其他原因,如银行返回失败) + if ("SUCCESS".equals(trade_state)) { + record.setPayOrderStatus(EnumPayStatus.PAY_WAY_SUCCESS.getCode()); + handlePayOrderStatusUpdate(record); + } else if ("USERPAYING".equals(trade_state)) { + //record.setPayOrderStatus(EnumPayStatus.PAY_WAY_WAIT.getCode()); + //handlePayOrderStatusUpdate(record); + } else { + record.setPayOrderStatus(EnumPayStatus.PAY_WAY_FAIL.getCode()); + handlePayOrderStatusUpdate(record); + } + return new ResultData(Result.SUCCESS, "订单查询成功", returnMap); + } else { + JSONObject errObj = errorMap.getJSONObject(result_code); + return new ResultData(ErrorCode.PAY_ORDER_ERROR.getCode(), errObj.toJSONString(), returnMap); + } + } catch (RuntimeException e) { + throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); + } catch (Exception e){ + throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); + } + } } /** * 微信关闭订单 @@ -300,33 +405,70 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { public ResultData payOrderClose(WxAppinfo appInfo, WxPayOrder record) { // get payAccount WxPayAccount payAccount = wxPayAccountMapper.selectByPrimaryKey(appInfo.getPayId()); - WxPayOrderQ payOrderC = new WxPayOrderQ(); - String noncestr = Utility.generate32UUID(); - payOrderC.setAppid(appInfo.getAppId()); - payOrderC.setMch_id(payAccount.getMchId()); - payOrderC.setNonce_str(noncestr); - payOrderC.setOut_trade_no(record.getPayOrderNo()); + if (payAccount.getType() == EnumPayMode.MCH.getCode()) { + // 普通商户号模式 + WxPayOrderQ payOrderC = new WxPayOrderQ(); + String noncestr = Utility.generate32UUID(); + payOrderC.setAppid(appInfo.getAppId()); + payOrderC.setMch_id(payAccount.getMchId()); + payOrderC.setNonce_str(noncestr); + payOrderC.setOut_trade_no(record.getPayOrderNo()); - try { - payOrderC.setSign(WxPayment.createSign(BeanUtils.toStringMap(payOrderC), payAccount.getApiKey())); + try { + Map map = BeanUtils.toStringMap(payOrderC); + payOrderC.setSign(WxPayment.createSign(map, payAccount.getApiKey())); + map = BeanUtils.toStringMap(payOrderC); + String response = WxPay.closeOrder(map); - String response = WxPay.closeOrder(BeanUtils.toStringMap(payOrderC)); + logger.info("pay order close, " + payOrderC.toString() + ", response: " + response); + Map returnMap = WxPayment.xmlToMap(response); + String result_code = returnMap.get("result_code"); + if ("SUCCESS".equals(result_code)) { + record.setPayOrderStatus(EnumPayStatus.PAY_WAY_FAIL.getCode()); + handlePayOrderStatusUpdate(record); + return new ResultData(Result.SUCCESS, "订单关闭成功", returnMap); + } else { + JSONObject errObj = errorMapClose.getJSONObject(result_code); + return new ResultData(ErrorCode.PAY_ORDER_ERROR.getCode(), errObj.toJSONString(), returnMap); + } + } catch (RuntimeException e) { + throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); + } catch (Exception e) { + throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); + } + } else { + // 服务商模式 + WxPayOrderSQ payOrderSC = new WxPayOrderSQ(); + String noncestr = Utility.generate32UUID(); + payOrderSC.setAppid(appInfo.getParentAppId()); + payOrderSC.setSub_appid(appInfo.getAppId()); + payOrderSC.setMch_id(payAccount.getMchId()); + payOrderSC.setSub_mch_id(payAccount.getSubMchId()); + payOrderSC.setNonce_str(noncestr); + payOrderSC.setOut_trade_no(record.getPayOrderNo()); - logger.info("pay order close, " + payOrderC.toString() + ", response: " + response); - Map returnMap = WxPayment.xmlToMap(response); - String result_code = returnMap.get("result_code"); - if ("SUCCESS".equals(result_code)) { - record.setPayOrderStatus(EnumPayStatus.PAY_WAY_FAIL.getCode()); - handlePayOrderStatusUpdate(record); - return new ResultData(Result.SUCCESS, "订单关闭成功", returnMap); - } else { - JSONObject errObj = errorMapClose.getJSONObject(result_code); - return new ResultData(ErrorCode.PAY_ORDER_ERROR.getCode(), errObj.toJSONString(), returnMap); + try { + Map map = BeanUtils.toStringMap(payOrderSC); + payOrderSC.setSign(WxPayment.createSign(map, payAccount.getApiKey())); + map = BeanUtils.toStringMap(payOrderSC); + String response = WxPay.closeOrder(map); + + logger.info("pay order close, " + payOrderSC.toString() + ", response: " + response); + Map returnMap = WxPayment.xmlToMap(response); + String result_code = returnMap.get("result_code"); + if ("SUCCESS".equals(result_code)) { + record.setPayOrderStatus(EnumPayStatus.PAY_WAY_FAIL.getCode()); + handlePayOrderStatusUpdate(record); + return new ResultData(Result.SUCCESS, "订单关闭成功", returnMap); + } else { + JSONObject errObj = errorMapClose.getJSONObject(result_code); + return new ResultData(ErrorCode.PAY_ORDER_ERROR.getCode(), errObj.toJSONString(), returnMap); + } + } catch (RuntimeException e) { + throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); + } catch (Exception e) { + throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); } - } catch (RuntimeException e) { - throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); - } catch (Exception e){ - throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); } } @@ -341,12 +483,24 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { @Override public String notify(Map paramMap, EnumPayWay payWay) { // how to get wechatAppId, wechatMchId, partnerKey - String wechatAppId = paramMap.get("appid"); - String wechatMchId = paramMap.get("mch_id"); - WxAppinfo appinfo = wxAppinfoMapper.findByAppId(wechatAppId); - if (appinfo == null) { - throw new MallinkException(ErrorCode.APP_ID_NOT_FOUND); + String appId = paramMap.get("appid"); + String subAppId = paramMap.get("sub_appid"); + String mchId = paramMap.get("mch_id"); + String subMchId = paramMap.get("sub_mch_id"); + WxAppinfo appinfo = null; + if (StringUtils.isBlank(subAppId) && StringUtils.isBlank(subMchId)) { + // 普通商户号 + appinfo = wxAppinfoMapper.findByAppId(appId); + if (appinfo == null) { + throw new MallinkException(ErrorCode.APP_ID_NOT_FOUND); + } + } else { + appinfo = wxAppinfoMapper.findByAppId(subAppId); + if (appinfo == null) { + throw new MallinkException(ErrorCode.APP_ID_NOT_FOUND); + } } + WxPayAccount payAccount = wxPayAccountMapper.selectByPrimaryKey(appinfo.getPayId()); if (payAccount == null) { throw new MallinkException(ErrorCode.MCH_INFO_NOT_FOUND); @@ -411,6 +565,7 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { logger.warn("notify order, checksign error, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString() + ", e:" + e.getMessage()); throw new MallinkException(ErrorCode.PAY_ORDER_ERROR); } + SortedMap resultMap = new TreeMap(); resultMap.put("return_code", "FAIL"); resultMap.put("return_msg", "FAILED"); diff --git a/mallinkService/src/main/java/com/simple/service/impl/WxRefundOrderServiceImpl.java b/mallinkService/src/main/java/com/simple/service/impl/WxRefundOrderServiceImpl.java index b43e02a01..196c3b571 100644 --- a/mallinkService/src/main/java/com/simple/service/impl/WxRefundOrderServiceImpl.java +++ b/mallinkService/src/main/java/com/simple/service/impl/WxRefundOrderServiceImpl.java @@ -16,6 +16,7 @@ import com.simple.mapper.*; import com.simple.pay.WxPay; import com.simple.pay.WxPayment; import com.simple.pay.WxRefundOrderP; +import com.simple.pay.WxRefundOrderSP; import com.simple.service.WxOrderService; import com.simple.service.WxRefundOrderService; import com.simple.utils.BeanUtils; @@ -397,81 +398,184 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { throw new MallinkException(ErrorCode.REFUND_ORDER_EXIST.getCode(), "退款订单已存在, 无法再提交退款申请"); } - // 向微信提交退款申请 - String noncestr = Utility.generate32UUID(); - WxRefundOrderP wxRefundOrderP = new WxRefundOrderP(); - wxRefundOrderP.setAppid(appInfo.getAppId()); - wxRefundOrderP.setMch_id(payAccount.getMchId()); - wxRefundOrderP.setNonce_str(noncestr); - // 微信内部订单号 - if (record.getTransactionId() != null) - wxRefundOrderP.setTransaction_id(record.getTransactionId()); - // 支付订单号 - wxRefundOrderP.setOut_trade_no(payOrder.getPayOrderNo()); - // 退款支付订单号 - wxRefundOrderP.setOut_refund_no(out_refund_id); - wxRefundOrderP.setTotal_fee(record.getTotalFee()); - wxRefundOrderP.setRefund_fee(record.getRefundFee()); - if (refundWay == EnumRefundWay.B) { - wxRefundOrderP.setRefund_desc("B端商户退款"); - } else if (refundWay == EnumRefundWay.ADMIN) { - wxRefundOrderP.setRefund_desc("管理端商户退款"); - } else if (refundWay == EnumRefundWay.AUTO) { - wxRefundOrderP.setRefund_desc("超期自动退款"); - } else { - wxRefundOrderP.setRefund_desc("用户自己退款"); - } - wxRefundOrderP.setNotify_url(payAccount.getNotifyUrl() + "/refund"); - if (isReal) { - Map signMap = null; - try { - signMap = BeanUtils.toStringMap(wxRefundOrderP); - } catch (Exception e) { - logger.error("退款命令生辰: " + e.getMessage()); - throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "退款签名异常"); - } + // 实际支付 + // 向微信提交退款申请 + if (payAccount.getType() == EnumPayMode.MCH.getCode()) { + String noncestr = Utility.generate32UUID(); + WxRefundOrderP wxRefundOrderP = new WxRefundOrderP(); + wxRefundOrderP.setAppid(appInfo.getAppId()); + wxRefundOrderP.setMch_id(payAccount.getMchId()); + wxRefundOrderP.setNonce_str(noncestr); + // 微信内部订单号 + if (record.getTransactionId() != null) + wxRefundOrderP.setTransaction_id(record.getTransactionId()); + // 支付订单号 + wxRefundOrderP.setOut_trade_no(payOrder.getPayOrderNo()); + // 退款支付订单号 + wxRefundOrderP.setOut_refund_no(out_refund_id); + wxRefundOrderP.setTotal_fee(record.getTotalFee()); + wxRefundOrderP.setRefund_fee(record.getRefundFee()); + if (refundWay == EnumRefundWay.B) { + wxRefundOrderP.setRefund_desc("B端商户退款"); + } else if (refundWay == EnumRefundWay.ADMIN) { + wxRefundOrderP.setRefund_desc("管理端商户退款"); + } else if (refundWay == EnumRefundWay.AUTO) { + wxRefundOrderP.setRefund_desc("超期自动退款"); + } else { + wxRefundOrderP.setRefund_desc("用户自己退款"); + } + wxRefundOrderP.setNotify_url(payAccount.getNotifyUrl() + "/refund"); - String signAgent = WxPayment.createSign(signMap, payAccount.getApiKey()); - signMap.put("sign", signAgent); - String response = null; - try { - response = WxPay.orderRefund(signMap, payAccount.getCertPath(), payAccount.getMchId()); - } catch (Exception e) { - logger.error("退款异常: " + e.getMessage()); - throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "退款异常"); - } - logger.info("微信退款订单:" + wxRefundOrderP.toString() + ", response: " + response.toString()); - Map returnMap = WxPayment.xmlToMap(response); - String result_no = returnMap.get("result_code"); - String refund_id = returnMap.get("refund_id"); - // 设置 微信退款订单号 - record.setRefundId(refund_id); - record.setRefundVendor(EnumPayWay.PAY_WAY_WEAPP.getCode()); - if ("SUCCESS".equals(result_no)) { - logger.error("微信退款订单申请成功: " + returnMap.toString()); + Map signMap = null; + try { + signMap = BeanUtils.toStringMap(wxRefundOrderP); + } catch (Exception e) { + logger.error("退款命令生辰: " + e.getMessage()); + throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "退款签名异常"); + } + + String signAgent = WxPayment.createSign(signMap, payAccount.getApiKey()); + signMap.put("sign", signAgent); + String response = null; try { - record.setRefundOrderStatus(EnumRefundStatus.REFUND_REQ_SUCCESS.getCode()); - wxRefundOrderMapper.updateByPrimaryKey(record); - return new ResultData(Result.SUCCESS, "退款订单申请成功", returnMap); + response = WxPay.orderRefund(signMap, payAccount.getCertPath(), payAccount.getMchId()); } catch (Exception e) { - logger.error("微信退款订单更新入库出错: " + e.getMessage() + ", record: " + record.toString()); - throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR); + logger.error("退款异常: " + e.getMessage()); + throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "退款异常"); + } + logger.info("微信退款订单:" + wxRefundOrderP.toString() + ", response: " + response.toString()); + Map returnMap = WxPayment.xmlToMap(response); + String result_no = returnMap.get("result_code"); + String refund_id = returnMap.get("refund_id"); + // 设置 微信退款订单号 + record.setRefundId(refund_id); + record.setRefundVendor(EnumPayWay.PAY_WAY_WEAPP.getCode()); + if ("SUCCESS".equals(result_no)) { + logger.error("微信退款订单申请成功: " + returnMap.toString()); + try { + record.setRefundOrderStatus(EnumRefundStatus.REFUND_REQ_SUCCESS.getCode()); + wxRefundOrderMapper.updateByPrimaryKey(record); + return new ResultData(Result.SUCCESS, "退款订单申请成功", returnMap); + } catch (Exception e) { + logger.error("微信退款订单更新入库出错: " + e.getMessage() + ", record: " + record.toString()); + throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR); + } + } else { + logger.error("微信退款订单申请失败: " + returnMap.toString()); + try { + record.setRefundOrderStatus(EnumRefundStatus.REFUND_REQ_FAIL.getCode()); + wxRefundOrderMapper.updateByPrimaryKey(record); + JSONObject errObj = errorRefundReqMap.getJSONObject(result_no); + return new ResultData(ErrorCode.PAY_ORDER_ERROR.getCode(), errObj.toJSONString(), returnMap); + } catch(Exception e) { + logger.error("微信退款订单更新入库出错: " + e.getMessage() + ", record: " + record.toString()); + throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR); + } } } else { - logger.error("微信退款订单申请失败: " + returnMap.toString()); + String noncestr = Utility.generate32UUID(); + WxRefundOrderSP wxRefundOrderSP = new WxRefundOrderSP(); + wxRefundOrderSP.setAppid(appInfo.getParentAppId()); + wxRefundOrderSP.setSub_appid(appInfo.getAppId()); + wxRefundOrderSP.setMch_id(payAccount.getMchId()); + wxRefundOrderSP.setSub_mch_id(payAccount.getSubMchId()); + wxRefundOrderSP.setNonce_str(noncestr); + // 微信内部订单号 + if (record.getTransactionId() != null) + wxRefundOrderSP.setTransaction_id(record.getTransactionId()); + // 支付订单号 + wxRefundOrderSP.setOut_trade_no(payOrder.getPayOrderNo()); + // 退款支付订单号 + wxRefundOrderSP.setOut_refund_no(out_refund_id); + wxRefundOrderSP.setTotal_fee(record.getTotalFee()); + wxRefundOrderSP.setRefund_fee(record.getRefundFee()); + if (refundWay == EnumRefundWay.B) { + wxRefundOrderSP.setRefund_desc("B端商户退款"); + } else if (refundWay == EnumRefundWay.ADMIN) { + wxRefundOrderSP.setRefund_desc("管理端商户退款"); + } else if (refundWay == EnumRefundWay.AUTO) { + wxRefundOrderSP.setRefund_desc("超期自动退款"); + } else { + wxRefundOrderSP.setRefund_desc("用户自己退款"); + } + wxRefundOrderSP.setNotify_url(payAccount.getNotifyUrl() + "/refund"); + + Map signMap = null; try { - record.setRefundOrderStatus(EnumRefundStatus.REFUND_REQ_FAIL.getCode()); - wxRefundOrderMapper.updateByPrimaryKey(record); - JSONObject errObj = errorRefundReqMap.getJSONObject(result_no); - return new ResultData(ErrorCode.PAY_ORDER_ERROR.getCode(), errObj.toJSONString(), returnMap); - } catch(Exception e) { - logger.error("微信退款订单更新入库出错: " + e.getMessage() + ", record: " + record.toString()); - throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR); + signMap = BeanUtils.toStringMap(wxRefundOrderSP); + } catch (Exception e) { + logger.error("退款命令生辰: " + e.getMessage()); + throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "退款签名异常"); + } + + String signAgent = WxPayment.createSign(signMap, payAccount.getApiKey()); + signMap.put("sign", signAgent); + String response = null; + try { + response = WxPay.orderRefund(signMap, payAccount.getCertPath(), payAccount.getMchId()); + } catch (Exception e) { + logger.error("退款异常: " + e.getMessage()); + throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "退款异常"); + } + logger.info("微信退款订单:" + wxRefundOrderSP.toString() + ", response: " + response.toString()); + Map returnMap = WxPayment.xmlToMap(response); + String result_no = returnMap.get("result_code"); + String refund_id = returnMap.get("refund_id"); + // 设置 微信退款订单号 + record.setRefundId(refund_id); + record.setRefundVendor(EnumPayWay.PAY_WAY_WEAPP.getCode()); + if ("SUCCESS".equals(result_no)) { + logger.error("微信退款订单申请成功: " + returnMap.toString()); + try { + record.setRefundOrderStatus(EnumRefundStatus.REFUND_REQ_SUCCESS.getCode()); + wxRefundOrderMapper.updateByPrimaryKey(record); + return new ResultData(Result.SUCCESS, "退款订单申请成功", returnMap); + } catch (Exception e) { + logger.error("微信退款订单更新入库出错: " + e.getMessage() + ", record: " + record.toString()); + throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR); + } + } else { + logger.error("微信退款订单申请失败: " + returnMap.toString()); + try { + record.setRefundOrderStatus(EnumRefundStatus.REFUND_REQ_FAIL.getCode()); + wxRefundOrderMapper.updateByPrimaryKey(record); + JSONObject errObj = errorRefundReqMap.getJSONObject(result_no); + return new ResultData(ErrorCode.PAY_ORDER_ERROR.getCode(), errObj.toJSONString(), returnMap); + } catch(Exception e) { + logger.error("微信退款订单更新入库出错: " + e.getMessage() + ", record: " + record.toString()); + throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR); + } } } } else { // 虚拟支付 + // 向微信提交退款申请 + String noncestr = Utility.generate32UUID(); + WxRefundOrderP wxRefundOrderP = new WxRefundOrderP(); + wxRefundOrderP.setAppid(appInfo.getAppId()); + wxRefundOrderP.setMch_id(payAccount.getMchId()); + wxRefundOrderP.setNonce_str(noncestr); + // 微信内部订单号 + if (record.getTransactionId() != null) + wxRefundOrderP.setTransaction_id(record.getTransactionId()); + // 支付订单号 + wxRefundOrderP.setOut_trade_no(payOrder.getPayOrderNo()); + // 退款支付订单号 + wxRefundOrderP.setOut_refund_no(out_refund_id); + wxRefundOrderP.setTotal_fee(record.getTotalFee()); + wxRefundOrderP.setRefund_fee(record.getRefundFee()); + if (refundWay == EnumRefundWay.B) { + wxRefundOrderP.setRefund_desc("B端商户退款"); + } else if (refundWay == EnumRefundWay.ADMIN) { + wxRefundOrderP.setRefund_desc("管理端商户退款"); + } else if (refundWay == EnumRefundWay.AUTO) { + wxRefundOrderP.setRefund_desc("超期自动退款"); + } else { + wxRefundOrderP.setRefund_desc("用户自己退款"); + } + wxRefundOrderP.setNotify_url(payAccount.getNotifyUrl() + "/refund"); + Map returnMap = null; try { returnMap = BeanUtils.toStringMap(wxRefundOrderP); @@ -498,19 +602,37 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { @Override public ResultData queryRefundOrder(WxAppinfo appInfo, WxRefundOrder record) { WxPayAccount payAccount = wxPayAccountMapper.selectByPrimaryKey(appInfo.getPayId()); - - Map paramMap = WxPayment.buildWeappRefundQueryMap(appInfo.getAppId(), payAccount.getMchId(), - record.getTransactionId(), record.getPayOrderNo(), String.valueOf(record.getId()), record.getRefundId(), payAccount.getApiKey()); - String response = WxPay.orderRefundQuery(paramMap); - Map returnMap = WxPayment.xmlToMap(response); - String result_no = returnMap.get("result_code"); - if ("SUCCESS".equals(result_no)) { - String refund_id = returnMap.get("refund_id"); - return new ResultData(Result.SUCCESS, "退款", returnMap); + if (payAccount.getType() == EnumPayMode.MCH.getCode()) { + Map paramMap = WxPayment.buildWeappRefundQueryMap( + appInfo.getAppId(), payAccount.getMchId(), + record.getTransactionId(), record.getPayOrderNo(), String.valueOf(record.getId()), + record.getRefundId(), payAccount.getApiKey()); + String response = WxPay.orderRefundQuery(paramMap); + Map returnMap = WxPayment.xmlToMap(response); + String result_no = returnMap.get("result_code"); + if ("SUCCESS".equals(result_no)) { + String refund_id = returnMap.get("refund_id"); + return new ResultData(Result.SUCCESS, "退款", returnMap); + } else { + wxRefundOrderMapper.updateByPrimaryKey(record); + JSONObject errObj = errorRefundReqMap.getJSONObject(result_no); + return new ResultData(ErrorCode.REFUND_ORDER_ERROR.getCode(), errObj.toJSONString(), returnMap); + } } else { - wxRefundOrderMapper.updateByPrimaryKey(record); - JSONObject errObj = errorRefundReqMap.getJSONObject(result_no); - return new ResultData(ErrorCode.REFUND_ORDER_ERROR.getCode(), errObj.toJSONString(), returnMap); + Map paramMap = WxPayment.buildSWeappRefundQueryMap( + appInfo.getParentAppId(), appInfo.getAppId(), payAccount.getMchId(), payAccount.getSubMchId(), + record.getTransactionId(), record.getPayOrderNo(), String.valueOf(record.getId()), record.getRefundId(), payAccount.getApiKey()); + String response = WxPay.orderRefundQuery(paramMap); + Map returnMap = WxPayment.xmlToMap(response); + String result_no = returnMap.get("result_code"); + if ("SUCCESS".equals(result_no)) { + String refund_id = returnMap.get("refund_id"); + return new ResultData(Result.SUCCESS, "退款", returnMap); + } else { + wxRefundOrderMapper.updateByPrimaryKey(record); + JSONObject errObj = errorRefundReqMap.getJSONObject(result_no); + return new ResultData(ErrorCode.REFUND_ORDER_ERROR.getCode(), errObj.toJSONString(), returnMap); + } } } @@ -523,97 +645,194 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { @Override public String notify(Map paramMap, EnumPayWay payWay) { // how to get wechatAppId, wechatMchId, partnerKey - String wechatAppId = paramMap.get("appid"); - String wechatMchId = paramMap.get("mch_id"); - WxAppinfo appinfo = wxAppinfoMapper.findByAppId(wechatAppId); - if (appinfo == null) { - logger.error("未找到appid信息:"+wechatAppId); - throw new MallinkException(ErrorCode.APP_ID_NOT_FOUND); - } - WxPayAccount payAccount = wxPayAccountMapper.selectByPrimaryKey(appinfo.getPayId()); - if (payAccount == null) { - logger.error("未找到mch_id信息:"+wechatMchId); - throw new MallinkException(ErrorCode.MCH_INFO_NOT_FOUND); - } - if (wechatMchId != payAccount.getMchId()) { - logger.error("mch_id不对应:"+wechatMchId + ",account:" + payAccount.getMchId()); - throw new MallinkException(ErrorCode.MCH_INFO_NOT_EQUAL); - } - String partnerKey = payAccount.getApiKey(); - try { - if (payWay == EnumPayWay.PAY_WAY_WEAPP) { - boolean signVerified = false; - // 微信支付 - signVerified = WxPayment.verifyNotify(paramMap, partnerKey); - if (!signVerified) { - logger.warn("notify order, wxpay checksign error, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); - throw new MallinkException(ErrorCode.PAY_ORDER_NOTIFY_CHECK_SIGN_ERROR); - } - if (!"SUCCESS".equals(paramMap.get("return_code"))) { - logger.warn("notify order, wxpay status not success, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); - SortedMap resultMap = new TreeMap(); - resultMap.put("return_code", "FAIL"); - resultMap.put("return_msg", "订单状态码非SUCCESS"); - return XmlUtil.getRequestXml(resultMap); - } - - String payOrderNo = paramMap.get("out_trade_no"); - Long payOrderId = Long.valueOf(payOrderNo); - WxPayOrder payOrder = wxPayOrderMapper.selectByPrimaryKey(payOrderId); - if (payOrder == null) { - logger.warn("notify order, wxpay check pay order not exists, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); - SortedMap resultMap = new TreeMap(); - resultMap.put("return_code", "FAIL"); - resultMap.put("return_msg", "支付订单不存在"); - return XmlUtil.getRequestXml(resultMap); - } - // 验证支付金额 - if(!paramMap.get("total_fee").equals(payOrder.getPayAmount().toString())) { - logger.warn("notify order, wxpay check total_fee is invalid, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); - SortedMap resultMap = new TreeMap(); - resultMap.put("return_code", "FAIL"); - resultMap.put("return_msg", "支付订单总金额不一致"); - return XmlUtil.getRequestXml(resultMap); - } - String refundIdStr = paramMap.get("out_refund_no"); - Long refundOrderId = Long.valueOf(refundIdStr); - WxRefundOrder refundOrder = wxRefundOrderMapper.selectByPrimaryKey(refundOrderId); - if (refundOrder == null) { - logger.warn("notify order, wxpay check pay order not exists, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); - SortedMap resultMap = new TreeMap(); - resultMap.put("return_code", "FAIL"); - resultMap.put("return_msg", "退款订单不存在"); - return XmlUtil.getRequestXml(resultMap); - } - // 验证支付金额 - if(!paramMap.get("total_fee").equals(refundOrder.getTotalFee().toString())) { - logger.warn("notify order, wxpay check total_fee is invalid, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); + String appId = paramMap.get("appid"); + String subAppId = paramMap.get("sub_appid"); + String mchId = paramMap.get("mch_id"); + String subMchId = paramMap.get("sub_mch_id"); + if (StringUtils.isBlank(subAppId) && StringUtils.isBlank(subMchId)) { + // 普通商户号 + WxAppinfo appinfo = wxAppinfoMapper.findByAppId(appId); + if (appinfo == null) { + logger.error("未找到appid信息:"+appId); + throw new MallinkException(ErrorCode.APP_ID_NOT_FOUND); + } + WxPayAccount payAccount = wxPayAccountMapper.selectByPrimaryKey(appinfo.getPayId()); + if (payAccount == null) { + logger.error("未找到mch_id信息:"+mchId); + throw new MallinkException(ErrorCode.MCH_INFO_NOT_FOUND); + } + if (mchId != payAccount.getMchId()) { + logger.error("mch_id不对应:"+mchId + ",account:" + payAccount.getMchId()); + throw new MallinkException(ErrorCode.MCH_INFO_NOT_EQUAL); + } + String partnerKey = payAccount.getApiKey(); + try { + if (payWay == EnumPayWay.PAY_WAY_WEAPP) { + boolean signVerified = false; + // 微信支付 + signVerified = WxPayment.verifyNotify(paramMap, partnerKey); + if (!signVerified) { + logger.warn("notify order, wxpay checksign error, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); + throw new MallinkException(ErrorCode.PAY_ORDER_NOTIFY_CHECK_SIGN_ERROR); + } + if (!"SUCCESS".equals(paramMap.get("return_code"))) { + logger.warn("notify order, wxpay status not success, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); + SortedMap resultMap = new TreeMap(); + resultMap.put("return_code", "FAIL"); + resultMap.put("return_msg", "订单状态码非SUCCESS"); + return XmlUtil.getRequestXml(resultMap); + } + + String payOrderNo = paramMap.get("out_trade_no"); + Long payOrderId = Long.valueOf(payOrderNo); + WxPayOrder payOrder = wxPayOrderMapper.selectByPrimaryKey(payOrderId); + if (payOrder == null) { + logger.warn("notify order, wxpay check pay order not exists, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); + SortedMap resultMap = new TreeMap(); + resultMap.put("return_code", "FAIL"); + resultMap.put("return_msg", "支付订单不存在"); + return XmlUtil.getRequestXml(resultMap); + } + // 验证支付金额 + if(!paramMap.get("total_fee").equals(payOrder.getPayAmount().toString())) { + logger.warn("notify order, wxpay check total_fee is invalid, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); + SortedMap resultMap = new TreeMap(); + resultMap.put("return_code", "FAIL"); + resultMap.put("return_msg", "支付订单总金额不一致"); + return XmlUtil.getRequestXml(resultMap); + } + String refundIdStr = paramMap.get("out_refund_no"); + Long refundOrderId = Long.valueOf(refundIdStr); + WxRefundOrder refundOrder = wxRefundOrderMapper.selectByPrimaryKey(refundOrderId); + if (refundOrder == null) { + logger.warn("notify order, wxpay check pay order not exists, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); + SortedMap resultMap = new TreeMap(); + resultMap.put("return_code", "FAIL"); + resultMap.put("return_msg", "退款订单不存在"); + return XmlUtil.getRequestXml(resultMap); + } + // 验证支付金额 + if(!paramMap.get("total_fee").equals(refundOrder.getTotalFee().toString())) { + logger.warn("notify order, wxpay check total_fee is invalid, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); + SortedMap resultMap = new TreeMap(); + resultMap.put("return_code", "FAIL"); + resultMap.put("return_msg", "订单总金额不一致"); + return XmlUtil.getRequestXml(resultMap); + } + // 验证退款金额 + if(!paramMap.get("refund_fee").equals(refundOrder.getRefundFee().toString())) { + logger.warn("notify order, wxpay check refund_fee is invalid, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); + SortedMap resultMap = new TreeMap(); + resultMap.put("return_code", "FAIL"); + resultMap.put("return_msg", "退款总金额不一致"); + return XmlUtil.getRequestXml(resultMap); + } + + // 处理支付成功 + handleRefundSuccess(refundOrder, paramMap.get("transaction_id"), paramMap.get("refund_id")); + logger.info("notify order, wxpay checksign success, paramMap:{}, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); SortedMap resultMap = new TreeMap(); - resultMap.put("return_code", "FAIL"); - resultMap.put("return_msg", "订单总金额不一致"); + resultMap.put("return_code", "SUCCESS"); + resultMap.put("return_msg", "OK"); return XmlUtil.getRequestXml(resultMap); } - // 验证退款金额 - if(!paramMap.get("refund_fee").equals(refundOrder.getRefundFee().toString())) { - logger.warn("notify order, wxpay check refund_fee is invalid, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); + } catch (RuntimeException e) { + logger.warn("notify order, alipay checksign error, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString() + ", e:" + e.getMessage()); + throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR); + } + } else { + // 服务号回调 + WxAppinfo appinfo = wxAppinfoMapper.findByAppId(subAppId); + if (appinfo == null) { + logger.error("未找到appid信息:"+appId); + throw new MallinkException(ErrorCode.APP_ID_NOT_FOUND); + } + WxPayAccount payAccount = wxPayAccountMapper.selectByPrimaryKey(appinfo.getPayId()); + if (payAccount == null) { + logger.error("未找到mch_id信息:"+mchId); + throw new MallinkException(ErrorCode.MCH_INFO_NOT_FOUND); + } + if (mchId != payAccount.getMchId()) { + logger.error("mch_id不对应:"+mchId + ",account:" + payAccount.getMchId()); + throw new MallinkException(ErrorCode.MCH_INFO_NOT_EQUAL); + } + String partnerKey = payAccount.getApiKey(); + try { + if (payWay == EnumPayWay.PAY_WAY_WEAPP) { + boolean signVerified = false; + // 微信支付 + signVerified = WxPayment.verifyNotify(paramMap, partnerKey); + if (!signVerified) { + logger.warn("notify order, wxpay checksign error, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); + throw new MallinkException(ErrorCode.PAY_ORDER_NOTIFY_CHECK_SIGN_ERROR); + } + if (!"SUCCESS".equals(paramMap.get("return_code"))) { + logger.warn("notify order, wxpay status not success, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); + SortedMap resultMap = new TreeMap(); + resultMap.put("return_code", "FAIL"); + resultMap.put("return_msg", "订单状态码非SUCCESS"); + return XmlUtil.getRequestXml(resultMap); + } + + String payOrderNo = paramMap.get("out_trade_no"); + Long payOrderId = Long.valueOf(payOrderNo); + WxPayOrder payOrder = wxPayOrderMapper.selectByPrimaryKey(payOrderId); + if (payOrder == null) { + logger.warn("notify order, wxpay check pay order not exists, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); + SortedMap resultMap = new TreeMap(); + resultMap.put("return_code", "FAIL"); + resultMap.put("return_msg", "支付订单不存在"); + return XmlUtil.getRequestXml(resultMap); + } + // 验证支付金额 + if(!paramMap.get("total_fee").equals(payOrder.getPayAmount().toString())) { + logger.warn("notify order, wxpay check total_fee is invalid, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); + SortedMap resultMap = new TreeMap(); + resultMap.put("return_code", "FAIL"); + resultMap.put("return_msg", "支付订单总金额不一致"); + return XmlUtil.getRequestXml(resultMap); + } + String refundIdStr = paramMap.get("out_refund_no"); + Long refundOrderId = Long.valueOf(refundIdStr); + WxRefundOrder refundOrder = wxRefundOrderMapper.selectByPrimaryKey(refundOrderId); + if (refundOrder == null) { + logger.warn("notify order, wxpay check pay order not exists, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); + SortedMap resultMap = new TreeMap(); + resultMap.put("return_code", "FAIL"); + resultMap.put("return_msg", "退款订单不存在"); + return XmlUtil.getRequestXml(resultMap); + } + // 验证支付金额 + if(!paramMap.get("total_fee").equals(refundOrder.getTotalFee().toString())) { + logger.warn("notify order, wxpay check total_fee is invalid, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); + SortedMap resultMap = new TreeMap(); + resultMap.put("return_code", "FAIL"); + resultMap.put("return_msg", "订单总金额不一致"); + return XmlUtil.getRequestXml(resultMap); + } + // 验证退款金额 + if(!paramMap.get("refund_fee").equals(refundOrder.getRefundFee().toString())) { + logger.warn("notify order, wxpay check refund_fee is invalid, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); + SortedMap resultMap = new TreeMap(); + resultMap.put("return_code", "FAIL"); + resultMap.put("return_msg", "退款总金额不一致"); + return XmlUtil.getRequestXml(resultMap); + } + + // 处理支付成功 + handleRefundSuccess(refundOrder, paramMap.get("transaction_id"), paramMap.get("refund_id")); + logger.info("notify order, wxpay checksign success, paramMap:{}, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); SortedMap resultMap = new TreeMap(); - resultMap.put("return_code", "FAIL"); - resultMap.put("return_msg", "退款总金额不一致"); + resultMap.put("return_code", "SUCCESS"); + resultMap.put("return_msg", "OK"); return XmlUtil.getRequestXml(resultMap); } - - // 处理支付成功 - handleRefundSuccess(refundOrder, paramMap.get("transaction_id"), paramMap.get("refund_id")); - logger.info("notify order, wxpay checksign success, paramMap:{}, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); - SortedMap resultMap = new TreeMap(); - resultMap.put("return_code", "SUCCESS"); - resultMap.put("return_msg", "OK"); - return XmlUtil.getRequestXml(resultMap); + } catch (RuntimeException e) { + logger.warn("notify order, alipay checksign error, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString() + ", e:" + e.getMessage()); + throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR); } - } catch (RuntimeException e) { - logger.warn("notify order, alipay checksign error, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString() + ", e:" + e.getMessage()); - throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR); } + SortedMap resultMap = new TreeMap(); resultMap.put("return_code", "FAIL"); resultMap.put("return_msg", "FAILED"); diff --git a/mallinkService/src/main/resources/mapper/WxAppinfoMapper.xml b/mallinkService/src/main/resources/mapper/WxAppinfoMapper.xml index e93efdad4..eb71667d2 100644 --- a/mallinkService/src/main/resources/mapper/WxAppinfoMapper.xml +++ b/mallinkService/src/main/resources/mapper/WxAppinfoMapper.xml @@ -1,116 +1,102 @@ - - - - - - - - - - - - - - - - - - - `id`,`tenant_id`,`app_id`,`name`,`secret`,`token`,`aes_key`,`msg_data_format`,`access_token`,`last_token_time`,`expires_in`,`pay_id`,`type` - + + + + + + + + + + + + + + + + - - where 1 = 1 - - - and `id` = #{id} - - - - - and `tenant_id` like concat('%', #{tenantId},'%') - - - - - and `app_id` like concat('%', #{appId},'%') - - - - - and `name` like concat('%', #{name},'%') - - - - - and `secret` like concat('%', #{secret},'%') - - - - - and `token` like concat('%', #{token},'%') - - - - - and `aes_key` like concat('%', #{aesKey},'%') - - - - - and `msg_data_format` like concat('%', #{msgDataFormat},'%') - - - - - and `access_token` like concat('%', #{accessToken},'%') - - - - - and `last_token_time` = #{lastTokenTime} - - - - - and `expires_in` = #{expiresIn} - - - - - and `pay_id` = #{payId} - - - - and `type` = #{type} - - - - and id in - - #{idItem} - - - order by ${sortColumns} + + `id`,`tenant_id`,`app_id`,`parent_app_id`,`name`,`secret`,`token`,`aes_key`,`msg_data_format`,`access_token`,`last_token_time`,`expires_in`,`pay_id`,`type` - - - - - - - - - - + + + where 1 = 1 + + + and `id` = #{id} + + + + and `tenant_id` like concat('%', #{tenantId},'%') + + + + and `app_id` like concat('%', #{appId},'%') + + + and `parent_app_id` like concat('%', #{parentAppId},'%') + + + + and `name` like concat('%', #{name},'%') + + + + and `secret` like concat('%', #{secret},'%') + + + + and `token` like concat('%', #{token},'%') + + + + and `aes_key` like concat('%', #{aesKey},'%') + + + + and `msg_data_format` like concat('%', #{msgDataFormat},'%') + + + + and `access_token` like concat('%', #{accessToken},'%') + + + + and `last_token_time` = #{lastTokenTime} + + + + and `expires_in` = #{expiresIn} + + + + and `pay_id` = #{payId} + + + and `type` = #{type} + + + and id in + + #{idItem} + + + order by ${sortColumns} + + + + + diff --git a/mallinkService/src/main/resources/mapper/WxPayAccountMapper.xml b/mallinkService/src/main/resources/mapper/WxPayAccountMapper.xml index fcd18d05e..1651b82c4 100644 --- a/mallinkService/src/main/resources/mapper/WxPayAccountMapper.xml +++ b/mallinkService/src/main/resources/mapper/WxPayAccountMapper.xml @@ -1,62 +1,64 @@ - - - - - - - - - - `id`,`mch_id`,`api_key`,`notify_url`,`cert_path` - + + + + + + + + + - - where 1 = 1 - - - and `id` = #{id} - - - - - and `mch_id` like concat('%', #{mchId},'%') - - - - - and `api_key` like concat('%', #{apiKey},'%') - - - - - and `notify_url` like concat('%', #{notifyUrl},'%') - - - - - and `cert_path` like concat('%', #{certPath},'%') - - - - and id in - - #{idItem} - - - order by ${sortColumns} + + `id`,`mch_id`,`parent_mch_id`,`api_key`,`notify_url`,`cert_path`,`type` - - - - - - - - + + + where 1 = 1 + + + and `id` = #{id} + + + + and `mch_id` like concat('%', #{mchId},'%') + + + + and `parent_mch_id` like concat('%', #{parentMchId},'%') + + + + and `api_key` like concat('%', #{apiKey},'%') + + + + and `notify_url` like concat('%', #{notifyUrl},'%') + + + + and `cert_path` like concat('%', #{certPath},'%') + + + and `type` like concat('%', #{type},'%') + + + and id in + + #{idItem} + + + order by ${sortColumns} + + + + +