|
|
|
@@ -0,0 +1,356 @@ |
|
|
|
package com.iformall.service.pay.service.share.douyin; |
|
|
|
|
|
|
|
import com.alibaba.fastjson.JSON; |
|
|
|
import com.alibaba.fastjson.JSONArray; |
|
|
|
import com.alibaba.fastjson.JSONObject; |
|
|
|
import com.iformall.common.ErrorCode; |
|
|
|
import com.iformall.domain.po.*; |
|
|
|
import com.iformall.douyin.pay.DouYinPayHelper; |
|
|
|
import com.iformall.douyin.pay.orderQuery.QuerySettleResult; |
|
|
|
import com.iformall.douyin.pay.preOrder.Settle; |
|
|
|
import com.iformall.douyin.pay.preOrder.SettleResult; |
|
|
|
import com.iformall.enums.*; |
|
|
|
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.entity.PayShareQueryResult; |
|
|
|
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.ShareNotifyAdapterResult; |
|
|
|
import com.iformall.utils.BeanUtils; |
|
|
|
import com.iformall.utils.Utility; |
|
|
|
import com.iformall.utils.XmlUtil; |
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
import org.apache.commons.lang3.StringUtils; |
|
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
|
import org.springframework.stereotype.Service; |
|
|
|
|
|
|
|
import java.text.ParseException; |
|
|
|
import java.util.Date; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.SortedMap; |
|
|
|
import java.util.TreeMap; |
|
|
|
|
|
|
|
@Slf4j |
|
|
|
@Service |
|
|
|
public class TtPayShareService extends PayShareBaseAdapterService{ |
|
|
|
|
|
|
|
final JSONObject statusMap = JSON.parseObject( |
|
|
|
"{\"ACCEPTED\":3," + |
|
|
|
"\"PROCESSING\": 4," + |
|
|
|
"\"FINISHED\": 5," + |
|
|
|
"\"CLOSED\": 6}"); |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
public Integer getSubsidyType() { |
|
|
|
return EnumMerchantSubsidyType.MANUAL.getCode(); |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public Integer getProfitSharingType() { |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public PayShareResult noReciverShare(WxAppinfo appInfo,WxPayAccount payAccount,WxProfitSharingOrder record,String transcationId,Integer amount) { |
|
|
|
Settle settle = new Settle(); |
|
|
|
settle.setAppId(appInfo.getAppId()); |
|
|
|
settle.setSalt(payAccount.getApiKey()); |
|
|
|
settle.setOutSettleNo(record.getId().toString()); |
|
|
|
settle.setOutOrderNo(transcationId); |
|
|
|
settle.setSettleDesc("自主完结分账"); |
|
|
|
// if(order.getSettlementAmount() != null && order.getSettlementAmount().intValue() > 0){ |
|
|
|
// List list = new ArrayList<>(); |
|
|
|
// Map<String,Object> settleParams = new HashMap<>(); |
|
|
|
// settleParams.put("merchant_uid",merchantUid); |
|
|
|
// settleParams.put("amount",order.getPayment()-order.getSettlementAmount()); |
|
|
|
// list.add(settleParams); |
|
|
|
// settle.setSettleParams(JSON.toJSONString(list)); |
|
|
|
// } |
|
|
|
SettleResult settleResult = DouYinPayHelper.settle(settle); |
|
|
|
|
|
|
|
if (settleResult.isSuccess()) { |
|
|
|
return new PayShareResult(true, null,"success", settleResult,settleResult.getSettleNo()); |
|
|
|
}else{ |
|
|
|
return new PayShareResult(false, EnumProfitSharingOrderStatus.PROFIT_SHARING_REQ_FAILED.getCode(),settleResult.getMsg(), null,null); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public PayShareResult haveReciversShare(WxAppinfo appInfo,WxPayAccount payAccount,WxProfitSharingOrder record,String transcationId,JSONArray receivers,EnumProfitSharingOrderType shareType ) throws MallinkException { |
|
|
|
// TODO: 2021/11/27抖音分账暂时不支持 需要处理添加分账帐号和分账方式 |
|
|
|
|
|
|
|
throw new MallinkException(ErrorCode.PROFIT_SHARING_REQUEST_FAILED); |
|
|
|
|
|
|
|
// Settle settle = new Settle(); |
|
|
|
// settle.setAppId(appInfo.getAppId()); |
|
|
|
// settle.setSalt(payAccount.getApiKey()); |
|
|
|
// settle.setOutSettleNo(record.getId().toString()); |
|
|
|
// settle.setOutOrderNo(transcationId); |
|
|
|
// settle.setSettleDesc("自主完结分账"); |
|
|
|
//// if(order.getSettlementAmount() != null && order.getSettlementAmount().intValue() > 0){ |
|
|
|
//// List list = new ArrayList<>(); |
|
|
|
//// Map<String,Object> settleParams = new HashMap<>(); |
|
|
|
//// settleParams.put("merchant_uid",merchantUid); |
|
|
|
//// settleParams.put("amount",order.getPayment()-order.getSettlementAmount()); |
|
|
|
//// list.add(settleParams); |
|
|
|
//// settle.setSettleParams(JSON.toJSONString(list)); |
|
|
|
//// } |
|
|
|
// |
|
|
|
// settle.setSettleParams(receivers.toJSONString()); |
|
|
|
// SettleResult settleResult = DouYinPayHelper.settle(settle); |
|
|
|
// |
|
|
|
// if (settleResult.isSuccess()) { |
|
|
|
// return new PayShareResult(true, null,"success", settleResult,settleResult.getSettleNo()); |
|
|
|
// }else{ |
|
|
|
// return new PayShareResult(false, EnumProfitSharingOrderStatus.PROFIT_SHARING_REQ_FAILED.getCode(),settleResult.getMsg(), null,null); |
|
|
|
// } |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public PayShareQueryResult shareQuery(WxAppinfo appInfo, WxPayAccount payAccount, WxProfitSharingOrder record) throws MallinkException { |
|
|
|
|
|
|
|
QuerySettleResult querySettleResult = DouYinPayHelper.settleQuery(appInfo.getAppId(), payAccount.getApiKey(), record.getId().toString(), null); |
|
|
|
if(querySettleResult != null){ |
|
|
|
if(querySettleResult.getSettleStatus().equals("SUCCESS")){ |
|
|
|
return new PayShareQueryResult(true, 5, "success",querySettleResult, null); |
|
|
|
}else if(querySettleResult.getSettleStatus().equals("FAIL")){ |
|
|
|
return new PayShareQueryResult(true, 6, "fail",querySettleResult, null); |
|
|
|
} |
|
|
|
} |
|
|
|
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 |
|
|
|
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"); |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
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); |
|
|
|
} |
|
|
|
|
|
|
|
@Autowired |
|
|
|
WxProfitSharingReceiverMapper wxProfitSharingReceiverMapper; |
|
|
|
|
|
|
|
@Override |
|
|
|
public ShareAccountResult deleteShareAccount(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()); |
|
|
|
|
|
|
|
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); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |