| @@ -1,8 +1,6 @@ | |||||
| package com.iformall.service.pay.service.share.douyin; | package com.iformall.service.pay.service.share.douyin; | ||||
| import com.alibaba.fastjson.JSON; | |||||
| import com.alibaba.fastjson.JSONArray; | import com.alibaba.fastjson.JSONArray; | ||||
| import com.alibaba.fastjson.JSONObject; | |||||
| import com.iformall.common.ErrorCode; | import com.iformall.common.ErrorCode; | ||||
| import com.iformall.domain.po.*; | import com.iformall.domain.po.*; | ||||
| import com.iformall.douyin.pay.DouYinPayHelper; | import com.iformall.douyin.pay.DouYinPayHelper; | ||||
| @@ -11,41 +9,20 @@ import com.iformall.douyin.pay.preOrder.Settle; | |||||
| import com.iformall.douyin.pay.preOrder.SettleResult; | import com.iformall.douyin.pay.preOrder.SettleResult; | ||||
| import com.iformall.enums.*; | import com.iformall.enums.*; | ||||
| import com.iformall.exception.MallinkException; | import com.iformall.exception.MallinkException; | ||||
| import com.iformall.mapper.WxAppinfoMapper; | |||||
| import com.iformall.mapper.WxPayAccountMapper; | |||||
| import com.iformall.mapper.WxPayOrderMapper; | |||||
| import com.iformall.mapper.WxProfitSharingReceiverMapper; | |||||
| import com.iformall.pay.*; | |||||
| import com.iformall.service.pay.service.share.PayShareBaseAdapterService; | import com.iformall.service.pay.service.share.PayShareBaseAdapterService; | ||||
| import com.iformall.service.pay.service.share.entity.PayShareQueryResult; | import com.iformall.service.pay.service.share.entity.PayShareQueryResult; | ||||
| import com.iformall.service.pay.service.share.entity.PayShareResult; | import com.iformall.service.pay.service.share.entity.PayShareResult; | ||||
| import com.iformall.service.pay.service.share.entity.ShareAccountResult; | import com.iformall.service.pay.service.share.entity.ShareAccountResult; | ||||
| import com.iformall.service.pay.service.share.entity.ShareNotifyAdapterResult; | import com.iformall.service.pay.service.share.entity.ShareNotifyAdapterResult; | ||||
| import com.iformall.utils.BeanUtils; | |||||
| import com.iformall.utils.Utility; | |||||
| import com.iformall.utils.XmlUtil; | |||||
| import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||
| import org.apache.commons.lang3.StringUtils; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||
| import java.text.ParseException; | |||||
| import java.util.Date; | |||||
| import java.util.Map; | import java.util.Map; | ||||
| import java.util.SortedMap; | |||||
| import java.util.TreeMap; | |||||
| @Slf4j | @Slf4j | ||||
| @Service | @Service | ||||
| public class TtPayShareService extends PayShareBaseAdapterService{ | public class TtPayShareService extends PayShareBaseAdapterService{ | ||||
| final JSONObject statusMap = JSON.parseObject( | |||||
| "{\"ACCEPTED\":3," + | |||||
| "\"PROCESSING\": 4," + | |||||
| "\"FINISHED\": 5," + | |||||
| "\"CLOSED\": 6}"); | |||||
| @Override | @Override | ||||
| public Integer getSubsidyType() { | public Integer getSubsidyType() { | ||||
| return EnumMerchantSubsidyType.MANUAL.getCode(); | return EnumMerchantSubsidyType.MANUAL.getCode(); | ||||
| @@ -127,230 +104,23 @@ public class TtPayShareService extends PayShareBaseAdapterService{ | |||||
| throw new MallinkException(ErrorCode.PROFIT_SHARING_QUERY_REQUEST_FAILED.getCode(), querySettleResult.getMsg()); | throw new MallinkException(ErrorCode.PROFIT_SHARING_QUERY_REQUEST_FAILED.getCode(), querySettleResult.getMsg()); | ||||
| } | } | ||||
| @Autowired | |||||
| WxAppinfoMapper wxAppinfoMapper; | |||||
| @Autowired | |||||
| WxPayAccountMapper wxPayAccountMapper; | |||||
| @Autowired | |||||
| WxPayOrderMapper wxPayOrderMapper; | |||||
| private ShareNotifyAdapterResult getErrorResult(String msg) { | |||||
| SortedMap resultMap = new TreeMap(); | |||||
| resultMap.put("return_code", "FAIL"); | |||||
| resultMap.put("return_msg", msg); | |||||
| return new ShareNotifyAdapterResult(false,ErrorCode.PAY_ORDER_NOTIFY_CHECK_SIGN_ERROR.getCode(),msg,XmlUtil.getRequestXml(resultMap)); | |||||
| } | |||||
| private ShareNotifyAdapterResult getSuccessResult(WxPayOrder payOrder, String transcationId){ | |||||
| SortedMap resultMap = new TreeMap(); | |||||
| resultMap.put("return_code", "SUCCESS"); | |||||
| resultMap.put("return_msg", "OK"); | |||||
| return new ShareNotifyAdapterResult(transcationId, payOrder, XmlUtil.getRequestXml(resultMap)); | |||||
| } | |||||
| @Override | @Override | ||||
| public ShareNotifyAdapterResult notify(Map<String, String> paramMap,EnumPayWay payWay) { | public ShareNotifyAdapterResult notify(Map<String, String> paramMap,EnumPayWay payWay) { | ||||
| // how to get wechatAppId, wechatMchId, partnerKey | |||||
| 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; | |||||
| boolean isNormal = true; | |||||
| if (StringUtils.isBlank(subAppId) && StringUtils.isBlank(subMchId)) { | |||||
| // 普通商户号 | |||||
| appinfo = wxAppinfoMapper.findByAppId(appId); | |||||
| if (appinfo == null) { | |||||
| log.error("appid not found: " + appId); | |||||
| throw new MallinkException(ErrorCode.APP_ID_NOT_FOUND); | |||||
| } | |||||
| isNormal = true; | |||||
| } else { | |||||
| // 服务号 现在用hmac-sha256 | |||||
| appinfo = wxAppinfoMapper.findByAppId(subAppId); | |||||
| if (appinfo == null) { | |||||
| log.error("subappid not found: " + subAppId); | |||||
| throw new MallinkException(ErrorCode.APP_ID_NOT_FOUND); | |||||
| } | |||||
| isNormal = false; | |||||
| } | |||||
| WxPayAccount payAccount = wxPayAccountMapper.selectById(appinfo.getPayId()); | |||||
| if (payAccount == null) { | |||||
| throw new MallinkException(ErrorCode.MCH_INFO_NOT_FOUND); | |||||
| } | |||||
| String partnerKey = payAccount.getApiKey(); | |||||
| try { | |||||
| if (payWay == EnumPayWay.PAY_WAY_WECHAT) { | |||||
| boolean signVerified = false; | |||||
| if (isNormal) { | |||||
| // 普通商户号支付 | |||||
| signVerified = WxPayment.verifyNotify(paramMap, partnerKey); | |||||
| if (!signVerified) { | |||||
| log.warn("notify order, wxpay checksign error, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||||
| throw new MallinkException(ErrorCode.PAY_ORDER_NOTIFY_CHECK_SIGN_ERROR); | |||||
| } | |||||
| } else { | |||||
| // 服务号 现在用hmac-sha256 | |||||
| signVerified = WxPayment.verifyNotifyHMAC(paramMap, partnerKey); | |||||
| if (!signVerified) { | |||||
| log.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"))) { | |||||
| log.warn("notify order, wxpay status not success, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||||
| return getErrorResult("订单状态码非SUCCESS"); | |||||
| } | |||||
| String payOrderNo = paramMap.get("out_trade_no"); | |||||
| String timEndStr = paramMap.get("time_end"); | |||||
| Long payOrderId = Long.valueOf(payOrderNo); | |||||
| WxPayOrder payOrder = wxPayOrderMapper.selectById(payOrderId,payAccount.getTenantId()); | |||||
| if (payOrder == null) { | |||||
| log.warn("notify order, wxpay check pay order not exists, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||||
| return getErrorResult("订单不存在"); | |||||
| } | |||||
| // 验证支付金额 | |||||
| if (!paramMap.get("total_fee").equals(payOrder.getPayAmount().toString())) { | |||||
| log.warn("notify order, wxpay check total_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||||
| return getErrorResult("订单总金额不一致"); | |||||
| } | |||||
| Date timeEnd = null; | |||||
| try { | |||||
| timeEnd = Utility.getDateFromString(timEndStr); | |||||
| } catch (ParseException e) { | |||||
| log.error("解析timeEnd失败"); | |||||
| timeEnd = new Date(); | |||||
| } | |||||
| payOrder.setPayTimeEnd(timeEnd); | |||||
| log.info("notify order, wxpay checksign success, paramMap:{}, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||||
| return getSuccessResult(payOrder, paramMap.get("transaction_id")); | |||||
| } | |||||
| } catch (RuntimeException e) { | |||||
| log.warn("notify order, checksign error, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString() + ", e:" + e.getMessage()); | |||||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR); | |||||
| } | |||||
| return getErrorResult("FAILED"); | |||||
| //抖音不支持 | |||||
| throw new MallinkException(ErrorCode.PROFIT_SHARING_QUERY_UNKNOWN_TYPE); | |||||
| } | } | ||||
| @Override | @Override | ||||
| public ShareAccountResult createShareAccount(WxAppinfo appInfo,WxPayAccount payAccount,WxProfitSharingReceiver receiver) { | public ShareAccountResult createShareAccount(WxAppinfo appInfo,WxPayAccount payAccount,WxProfitSharingReceiver receiver) { | ||||
| WxProfitSharingReceiverP wxProfitSharingReceiverP = new WxProfitSharingReceiverP(); | |||||
| if (StringUtils.isNotBlank(appInfo.getParentAppId())) { | |||||
| wxProfitSharingReceiverP.setAppid(appInfo.getParentAppId()); | |||||
| wxProfitSharingReceiverP.setMch_id(payAccount.getMchId()); | |||||
| wxProfitSharingReceiverP.setSub_appid(appInfo.getAppId()); | |||||
| wxProfitSharingReceiverP.setSub_mch_id(payAccount.getSubMchId()); | |||||
| } else { | |||||
| wxProfitSharingReceiverP.setAppid(appInfo.getAppId()); | |||||
| wxProfitSharingReceiverP.setMch_id(payAccount.getMchId()); | |||||
| } | |||||
| wxProfitSharingReceiverP.setNonce_str(Utility.generate32UUID()); | |||||
| wxProfitSharingReceiverP.setSign_type("HMAC-SHA256"); | |||||
| JSONObject receiverJSON = new JSONObject(); | |||||
| receiverJSON.put("type", EnumProfitSharingReceiverType.getEnum(receiver.getReceiverType()).getMessage()); | |||||
| receiverJSON.put("account", receiver.getReceiverAccount()); | |||||
| receiverJSON.put("name", receiver.getTrueName()); | |||||
| wxProfitSharingReceiverP.setReceiver(receiverJSON.toJSONString()); | |||||
| String response; | |||||
| try { | |||||
| wxProfitSharingReceiverP.setSign(WxPayment.createSignHMAC(BeanUtils.toStringMap(wxProfitSharingReceiverP), payAccount.getApiKey())); | |||||
| response = WxProfitSharing.addReceiver(BeanUtils.toStringMap(wxProfitSharingReceiverP)); | |||||
| log.info(response); | |||||
| } catch (Exception e) { | |||||
| log.error(ErrorCode.PROFIT_SHARING_RECEIVER_ADD_FAILED.getMessage() + e.getMessage()); | |||||
| return new ShareAccountResult(false, ErrorCode.PROFIT_SHARING_RECEIVER_ADD_FAILED.getCode(), e.getMessage(), null); | |||||
| } | |||||
| Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||||
| String return_code = returnMap.get("return_code"); | |||||
| if (!"SUCCESS".equals(return_code)) { | |||||
| log.error(ErrorCode.PROFIT_SHARING_RECEIVER_ADD_FAILED.getMessage() + returnMap.get("return_msg")+":"+JSON.toJSONString(returnMap)); | |||||
| return new ShareAccountResult(false, ErrorCode.PROFIT_SHARING_RECEIVER_ADD_FAILED.getCode(), returnMap.get("return_msg"), null); | |||||
| } | |||||
| String result_code = returnMap.get("result_code"); | |||||
| if (!"SUCCESS".equals(result_code)) { | |||||
| log.error(ErrorCode.PROFIT_SHARING_RECEIVER_ADD_FAILED.getMessage() + returnMap.get("err_code_des")+":"+JSON.toJSONString(returnMap)); | |||||
| return new ShareAccountResult(false, ErrorCode.PROFIT_SHARING_RECEIVER_ADD_FAILED.getCode(), returnMap.get("err_code_des"), null); | |||||
| } | |||||
| if (!WxPayment.verifyNotifyHMAC(returnMap, payAccount.getApiKey())) { | |||||
| log.error(ErrorCode.PROFIT_SHARING_RECEIVER_ADD_FAILED.getMessage() + "verifyNotifyHMAC"+":"+JSON.toJSONString(returnMap)); | |||||
| return new ShareAccountResult(false, ErrorCode.PROFIT_SHARING_RECEIVER_ADD_FAILED.getCode(), ErrorCode.PROFIT_SHARING_RECEIVER_ADD_FAILED.getMessage(), null); | |||||
| } | |||||
| return new ShareAccountResult(true, null, "success", returnMap); | |||||
| //抖音需要页面添加帐号 | |||||
| throw new MallinkException(ErrorCode.PROFIT_SHARING_QUERY_UNKNOWN_TYPE); | |||||
| } | } | ||||
| @Autowired | |||||
| WxProfitSharingReceiverMapper wxProfitSharingReceiverMapper; | |||||
| @Override | @Override | ||||
| public ShareAccountResult deleteShareAccount(WxAppinfo appInfo, WxPayAccount payAccount, | public ShareAccountResult deleteShareAccount(WxAppinfo appInfo, WxPayAccount payAccount, | ||||
| WxProfitSharingReceiver receiver) { | WxProfitSharingReceiver receiver) { | ||||
| //删除分账账户从微信服务器 | |||||
| WxProfitSharingReceiverP wxProfitSharingReceiverP = new WxProfitSharingReceiverP(); | |||||
| if (StringUtils.isNotBlank(appInfo.getParentAppId())) { | |||||
| wxProfitSharingReceiverP.setAppid(appInfo.getParentAppId()); | |||||
| wxProfitSharingReceiverP.setMch_id(payAccount.getMchId()); | |||||
| wxProfitSharingReceiverP.setSub_appid(appInfo.getAppId()); | |||||
| wxProfitSharingReceiverP.setSub_mch_id(payAccount.getSubMchId()); | |||||
| } else { | |||||
| wxProfitSharingReceiverP.setAppid(appInfo.getAppId()); | |||||
| wxProfitSharingReceiverP.setMch_id(payAccount.getMchId()); | |||||
| } | |||||
| wxProfitSharingReceiverP.setNonce_str(Utility.generate32UUID()); | |||||
| wxProfitSharingReceiverP.setSign_type("HMAC-SHA256"); | |||||
| JSONObject receiverJSON = new JSONObject(); | |||||
| receiverJSON.put("type", EnumProfitSharingReceiverType.getEnum(receiver.getReceiverType()).getMessage()); | |||||
| receiverJSON.put("account", receiver.getReceiverAccount()); | |||||
| wxProfitSharingReceiverP.setReceiver(receiverJSON.toJSONString()); | |||||
| String response; | |||||
| try { | |||||
| wxProfitSharingReceiverP.setSign(WxPayment.createSignHMAC(BeanUtils.toStringMap(wxProfitSharingReceiverP), payAccount.getApiKey())); | |||||
| response = WxProfitSharing.delReceiver(BeanUtils.toStringMap(wxProfitSharingReceiverP)); | |||||
| } catch (Exception e) { | |||||
| log.error(ErrorCode.PROFIT_SHARING_RECEIVER_DEL_FAILED.getMessage() + e.getMessage()); | |||||
| return new ShareAccountResult(false, ErrorCode.PROFIT_SHARING_RECEIVER_DEL_FAILED.getCode(), e.getMessage(), null); | |||||
| } | |||||
| Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||||
| String return_code = returnMap.get("return_code"); | |||||
| if (!"SUCCESS".equals(return_code)) { | |||||
| log.error(ErrorCode.PROFIT_SHARING_RECEIVER_DEL_FAILED.getMessage() + returnMap.get("return_msg")+":"+JSON.toJSONString(returnMap)); | |||||
| return new ShareAccountResult(false, ErrorCode.PROFIT_SHARING_RECEIVER_DEL_FAILED.getCode(), returnMap.get("return_msg"), null); | |||||
| } | |||||
| String result_code = returnMap.get("result_code"); | |||||
| if (!"SUCCESS".equals(result_code)) { | |||||
| if (returnMap.get("err_code").contains("USER_NOT_EXIST")) { | |||||
| receiver.setStatus(EnumProfitSharingReceiverStatus.PROFIT_SHARING_RECEIVER_STATUS_INVALID.getCode()); | |||||
| receiver.setUpdateTime(new Date()); | |||||
| wxProfitSharingReceiverMapper.updateById(receiver); | |||||
| } | |||||
| log.error(ErrorCode.PROFIT_SHARING_RECEIVER_DEL_FAILED.getMessage() + returnMap.get("err_code_des")+":"+JSON.toJSONString(returnMap)); | |||||
| return new ShareAccountResult(false, ErrorCode.PROFIT_SHARING_RECEIVER_DEL_FAILED.getCode(), returnMap.get("err_code_des"), null); | |||||
| } | |||||
| if (!WxPayment.verifyNotifyHMAC(returnMap, payAccount.getApiKey())) { | |||||
| log.error(ErrorCode.PROFIT_SHARING_RECEIVER_DEL_FAILED.getMessage()+":"+JSON.toJSONString(returnMap)); | |||||
| return new ShareAccountResult(false, ErrorCode.PROFIT_SHARING_RECEIVER_DEL_FAILED.getCode(), "verifyNotifyHMAC", null); | |||||
| } | |||||
| return new ShareAccountResult(true, null, "success", returnMap); | |||||
| //抖音不支持 | |||||
| throw new MallinkException(ErrorCode.PROFIT_SHARING_QUERY_UNKNOWN_TYPE); | |||||
| } | } | ||||
| } | } | ||||