Compare commits
2 Commits
ee1e05a5d0
...
83b4744fbd
Author | SHA1 | Date | |
---|---|---|---|
83b4744fbd | |||
dd588457e0 |
@ -262,4 +262,5 @@ easypay:
|
|||||||
wechat-mchid: 804474446
|
wechat-mchid: 804474446
|
||||||
easypay-public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArgVerkGaSEQvZIOpLjeUoVpL0lSYLc04+txtPFtfm5r5XFbaNaf5Ahu0lziGEwWzrGONThSsnb3U9pqoY6BpqviN4h+Guw5oEdHr1T/eDkQD5urgQUaZA6lDoU9XC662r+0kpbKidvXIsK2CrShN+BF8HEJmRZuhglxh25OHWIWqQiUDjLZC+QJRZqUu9Uzy9RBBu7qa0f0xbqYl3hnYi+vH++SsyOavO2gUVQyKU5Kkt5ZJVpZFQvD3BXePgwJSpsvrjhj0hiYp2v6PScN9XHP1vXB4wtIYSFYwmVus1KkV/LfDzUm6zHjliHYTVl6lPMhveIVJlRIqInRZRHxg5QIDAQAB
|
easypay-public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArgVerkGaSEQvZIOpLjeUoVpL0lSYLc04+txtPFtfm5r5XFbaNaf5Ahu0lziGEwWzrGONThSsnb3U9pqoY6BpqviN4h+Guw5oEdHr1T/eDkQD5urgQUaZA6lDoU9XC662r+0kpbKidvXIsK2CrShN+BF8HEJmRZuhglxh25OHWIWqQiUDjLZC+QJRZqUu9Uzy9RBBu7qa0f0xbqYl3hnYi+vH++SsyOavO2gUVQyKU5Kkt5ZJVpZFQvD3BXePgwJSpsvrjhj0hiYp2v6PScN9XHP1vXB4wtIYSFYwmVus1KkV/LfDzUm6zHjliHYTVl6lPMhveIVJlRIqInRZRHxg5QIDAQAB
|
||||||
merRsaPrivateKey: MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCc1mku1mtfTc1vZM9z3TkRMZ9SaKP+6MdoQhjDHB9vJUOuG2Jnegej4gtzcm8MVYomV1azJMtCbPq4PN9aHegH13JthvrUPR3nAKp8AUp9Fh47ded//snNyAf7C7o8xKN5e7n89ROwacCAL2QDno76ngXzQQVj1TxY9pBdekZ03ezuDk1sv/u4FBlW8kRyaVdqyl4FdvP+EEljDe8gGxRikLyb3cK1B6G7w2BXgM/svft5SOoiqStx2XvgHRrFRB5w96TdoKNH9yxHU2clMJiz+5cej1VL6OHZspuY3cnPyJtyS+weYjDT+COLLBUe9UwbOV15DXDNpBLd34W4GiqtAgMBAAECggEAYaVwmVOwSAblp7wJGScb16OggStbJ2MAe93jEt7Yh1eZGrY7/xbP2O3smTUfBHvhZlusRB7dWf8F3l0v5iiGhRNTT/PhCPEARAl7G3emS9jQe869kkgslq06ose7bQg0i3dH5cEkQAqnameXClXWyRxHshrCY1SonO7uFPUDFtD2Z9GHu6dOWkOHfX7UETHV5/NTSqvner5M2YNsV/5To87zrmaeeNyvu91JgJSYofTD8IcMyhxcswxB9F3ECP7nulLDdCV+9mvE9zO0i4mPBxYb++87J0pu35TN9OY+gpiCK3Ed0gDqvvkTiCQEFu6y7OiqsQwy03CE5hAwWZR2YQKBgQDdb6e7+FWJSr9fIknfvZPPtKmbEkMHP1RYnVo3pmuVm14Z3UmostiSBRPMfVjeOX0N82SONM9P+1v9SDgSK3pL8rlk9Hx6D5KI7uj2IMtTVt00pO31KtxDLmXfgapDbWHK1RGEn1PDrnKYy5yOKJ8n0Wgp4lVEPIBN6uIud0A9iQKBgQC1UXdhEXFETyqEYWb9OnWbBjiVIw3D2/qW5c+WQGsHYdMEImC/0oTWIH9fKd4Azf26JjZ9nQvs5VcijJP6BXbGPqir5NgGVkwCj33PoNg4dDgIVE4BYaSp//7B6jCi5QiRTzCSOmUSkZ5L1Kz4SNEDe9r0MpLhxrsAzmR9aEJ/BQKBgHI71Ks63F2cSwd39+ZNtYA0cj7Gd/+4IvooCs+kseGXKj9rkkFOKj2CEwmuLHdP7vyQcHKQOdbIFFegtxRgi5G8oPm8yq5pdC3iGhpHJr1SlYFACGYu+zxJJlLcYIqyVf2+V3A0hZDwYLwEZjpMKHbxJ6xbz6MJFyObJZ3U9TYJAoGANXoGjJF5Z501u/+CQZN5VjSagZnqGGcL3G+BLx5msrGua9y7zjeHyCOjjWyqtnAKsllM3vVvq/nkHiN6DVaJNmUKmFARSqUvG944TAFzZAsa75H1w8CJsT34ZDbvC0wjn7/MYoRohPZ/ynu6XCwVwUJJTJaR7ZcQVmeJCdezLQUCgYEAszix6V9oL80Clb1nMwIly6I78+pcFKyk82yXxvySb6XPJvgoasbz9xYIeKlPyy6r8Aj/ujz5GVtDtkE6n6bsjekCdnUKUY3uTvFAX+YGQkuZnaPoisELJFI2Hal22tNnJyCOYh//AGAiHYpHNUKD4hsKBb45MhK1xwvTHpuLkdc=
|
merRsaPrivateKey: MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCc1mku1mtfTc1vZM9z3TkRMZ9SaKP+6MdoQhjDHB9vJUOuG2Jnegej4gtzcm8MVYomV1azJMtCbPq4PN9aHegH13JthvrUPR3nAKp8AUp9Fh47ded//snNyAf7C7o8xKN5e7n89ROwacCAL2QDno76ngXzQQVj1TxY9pBdekZ03ezuDk1sv/u4FBlW8kRyaVdqyl4FdvP+EEljDe8gGxRikLyb3cK1B6G7w2BXgM/svft5SOoiqStx2XvgHRrFRB5w96TdoKNH9yxHU2clMJiz+5cej1VL6OHZspuY3cnPyJtyS+weYjDT+COLLBUe9UwbOV15DXDNpBLd34W4GiqtAgMBAAECggEAYaVwmVOwSAblp7wJGScb16OggStbJ2MAe93jEt7Yh1eZGrY7/xbP2O3smTUfBHvhZlusRB7dWf8F3l0v5iiGhRNTT/PhCPEARAl7G3emS9jQe869kkgslq06ose7bQg0i3dH5cEkQAqnameXClXWyRxHshrCY1SonO7uFPUDFtD2Z9GHu6dOWkOHfX7UETHV5/NTSqvner5M2YNsV/5To87zrmaeeNyvu91JgJSYofTD8IcMyhxcswxB9F3ECP7nulLDdCV+9mvE9zO0i4mPBxYb++87J0pu35TN9OY+gpiCK3Ed0gDqvvkTiCQEFu6y7OiqsQwy03CE5hAwWZR2YQKBgQDdb6e7+FWJSr9fIknfvZPPtKmbEkMHP1RYnVo3pmuVm14Z3UmostiSBRPMfVjeOX0N82SONM9P+1v9SDgSK3pL8rlk9Hx6D5KI7uj2IMtTVt00pO31KtxDLmXfgapDbWHK1RGEn1PDrnKYy5yOKJ8n0Wgp4lVEPIBN6uIud0A9iQKBgQC1UXdhEXFETyqEYWb9OnWbBjiVIw3D2/qW5c+WQGsHYdMEImC/0oTWIH9fKd4Azf26JjZ9nQvs5VcijJP6BXbGPqir5NgGVkwCj33PoNg4dDgIVE4BYaSp//7B6jCi5QiRTzCSOmUSkZ5L1Kz4SNEDe9r0MpLhxrsAzmR9aEJ/BQKBgHI71Ks63F2cSwd39+ZNtYA0cj7Gd/+4IvooCs+kseGXKj9rkkFOKj2CEwmuLHdP7vyQcHKQOdbIFFegtxRgi5G8oPm8yq5pdC3iGhpHJr1SlYFACGYu+zxJJlLcYIqyVf2+V3A0hZDwYLwEZjpMKHbxJ6xbz6MJFyObJZ3U9TYJAoGANXoGjJF5Z501u/+CQZN5VjSagZnqGGcL3G+BLx5msrGua9y7zjeHyCOjjWyqtnAKsllM3vVvq/nkHiN6DVaJNmUKmFARSqUvG944TAFzZAsa75H1w8CJsT34ZDbvC0wjn7/MYoRohPZ/ynu6XCwVwUJJTJaR7ZcQVmeJCdezLQUCgYEAszix6V9oL80Clb1nMwIly6I78+pcFKyk82yXxvySb6XPJvgoasbz9xYIeKlPyy6r8Aj/ujz5GVtDtkE6n6bsjekCdnUKUY3uTvFAX+YGQkuZnaPoisELJFI2Hal22tNnJyCOYh//AGAiHYpHNUKD4hsKBb45MhK1xwvTHpuLkdc=
|
||||||
backUrl: http://192.168.1.71:8080/easypay/trade/callback
|
trade-backUrl: http://82.156.121.2:8880/trans/easypay/trade/callback
|
||||||
|
separate-backUrl: http://82.156.121.2:8880/trans/easypay/separate/callback
|
||||||
|
@ -31,7 +31,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||||||
* @author zcc
|
* @author zcc
|
||||||
* @date 2022-12-01
|
* @date 2022-12-01
|
||||||
*/
|
*/
|
||||||
//@Tag(name ="订单接口列表")
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/oms/order")
|
@RequestMapping("/oms/order")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@ -69,7 +68,11 @@ public class OrderController extends BaseController {
|
|||||||
return R.ok(util.writeExcel(convert.toVO(list), "订单列表数据"));
|
return R.ok(util.writeExcel(convert.toVO(list), "订单列表数据"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Tag(name ="获取订单表详细信息")
|
/**
|
||||||
|
* 获取订单详细信息
|
||||||
|
* @param id 订单id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
@GetMapping(value = "/{id}")
|
@GetMapping(value = "/{id}")
|
||||||
public R<ManagerOrderDetailVO> getInfo(@PathVariable("id") Long id) {
|
public R<ManagerOrderDetailVO> getInfo(@PathVariable("id") Long id) {
|
||||||
return R.ok(orderService.selectById(id));
|
return R.ok(orderService.selectById(id));
|
||||||
|
@ -40,8 +40,13 @@ public class EasypayConfig {
|
|||||||
private String merRsaPrivateKey;
|
private String merRsaPrivateKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 易生异步回调通知地址
|
* 支付结果异步回调通知地址
|
||||||
*/
|
*/
|
||||||
private String backUrl;
|
private String tradeBackUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分账结果异步回调通知地址
|
||||||
|
*/
|
||||||
|
private String separateBackUrl;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,23 +2,16 @@ package com.wzj.soopin.transaction.controller;
|
|||||||
|
|
||||||
import cn.dev33.satoken.annotation.SaIgnore;
|
import cn.dev33.satoken.annotation.SaIgnore;
|
||||||
import com.wzj.soopin.transaction.domain.bo.PaymentBO;
|
import com.wzj.soopin.transaction.domain.bo.PaymentBO;
|
||||||
|
import com.wzj.soopin.transaction.domain.bo.SeparateApplyBO;
|
||||||
import com.wzj.soopin.transaction.domain.bo.easypay.EasyPayRequest;
|
import com.wzj.soopin.transaction.domain.bo.easypay.EasyPayRequest;
|
||||||
import com.wzj.soopin.transaction.domain.entity.WxAuthResponse;
|
import com.wzj.soopin.transaction.domain.vo.EasypayTransResultVO;
|
||||||
import com.wzj.soopin.transaction.domain.vo.EasypayPaymentResultVO;
|
|
||||||
import com.wzj.soopin.transaction.domain.vo.EasypayPrePayVO;
|
import com.wzj.soopin.transaction.domain.vo.EasypayPrePayVO;
|
||||||
import com.wzj.soopin.transaction.service.IEasypayService;
|
import com.wzj.soopin.transaction.service.IEasypayService;
|
||||||
import com.wzj.soopin.transaction.service.impl.WxAuthService;
|
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
|
||||||
import io.swagger.v3.oas.annotations.Parameters;
|
|
||||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.dromara.common.core.domain.R;
|
import org.dromara.common.core.domain.R;
|
||||||
import org.dromara.common.log.annotation.Log;
|
import org.dromara.common.log.annotation.Log;
|
||||||
import org.dromara.common.log.enums.BusinessType;
|
import org.dromara.common.log.enums.BusinessType;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.rmi.ServerException;
|
import java.rmi.ServerException;
|
||||||
@ -61,6 +54,7 @@ public class TransEasypayController {
|
|||||||
*/
|
*/
|
||||||
@Log(title = "易生支付-发起支付", businessType = BusinessType.OTHER)
|
@Log(title = "易生支付-发起支付", businessType = BusinessType.OTHER)
|
||||||
@PostMapping("/trade")
|
@PostMapping("/trade")
|
||||||
|
@SaIgnore
|
||||||
public R<EasypayPrePayVO> trade(@RequestBody PaymentBO paymentBO) throws ServerException {
|
public R<EasypayPrePayVO> trade(@RequestBody PaymentBO paymentBO) throws ServerException {
|
||||||
EasypayPrePayVO easypayPrePayVO = easypayService.payment(paymentBO);
|
EasypayPrePayVO easypayPrePayVO = easypayService.payment(paymentBO);
|
||||||
return R.ok(easypayPrePayVO);
|
return R.ok(easypayPrePayVO);
|
||||||
@ -73,9 +67,10 @@ public class TransEasypayController {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@GetMapping("/paymentQuery/{orderId}")
|
@GetMapping("/paymentQuery/{orderId}")
|
||||||
public R<EasypayPaymentResultVO> paymentQuery(@PathVariable("orderId") Long orderId) throws ServerException {
|
@SaIgnore
|
||||||
EasypayPaymentResultVO easypayPaymentResultVO = easypayService.paymentQuery(orderId);
|
public R<EasypayTransResultVO> paymentQuery(@PathVariable("orderId") Long orderId) throws ServerException {
|
||||||
return R.ok(easypayPaymentResultVO);
|
EasypayTransResultVO easypayTransResultVO = easypayService.paymentQuery(orderId);
|
||||||
|
return R.ok(easypayTransResultVO);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -86,8 +81,43 @@ public class TransEasypayController {
|
|||||||
*/
|
*/
|
||||||
@Log(title = "易生支付-实时退款", businessType = BusinessType.OTHER)
|
@Log(title = "易生支付-实时退款", businessType = BusinessType.OTHER)
|
||||||
@PostMapping("/refund/{orderId}")
|
@PostMapping("/refund/{orderId}")
|
||||||
public R<EasypayPrePayVO> refund(@PathVariable("orderId") Long orderId) throws ServerException {
|
@SaIgnore
|
||||||
|
public R refund(@PathVariable("orderId") Long orderId) throws ServerException {
|
||||||
easypayService.refund(orderId);
|
easypayService.refund(orderId);
|
||||||
return R.ok();
|
return R.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询退款结果
|
||||||
|
*
|
||||||
|
* @param orderId 订单id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/refundQuery/{orderId}")
|
||||||
|
@SaIgnore
|
||||||
|
public R<EasypayTransResultVO> refundQuery(@PathVariable("orderId") Long orderId) throws ServerException {
|
||||||
|
EasypayTransResultVO easypayTransResultVO = easypayService.refundQuery(orderId);
|
||||||
|
return R.ok(easypayTransResultVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理易生分账结果通知回调 处理
|
||||||
|
*
|
||||||
|
* @param easyPayRequest
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@SaIgnore
|
||||||
|
@Log(title = "易生支付-分账结果通知回调", businessType = BusinessType.UPDATE)
|
||||||
|
@PostMapping("/separate/callback")
|
||||||
|
public Map separateCallback(@RequestBody EasyPayRequest easyPayRequest) {
|
||||||
|
easypayService.handleSeparateCallback(easyPayRequest);
|
||||||
|
HashMap<Object, Object> map = new HashMap<>();
|
||||||
|
map.put("code", "000000");
|
||||||
|
map.put("msg", "Success");
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
package com.wzj.soopin.transaction.domain.bo;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分账请求参数
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class SeparateApplyBO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单id
|
||||||
|
*/
|
||||||
|
private Long orderId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单id
|
||||||
|
*/
|
||||||
|
private Long payId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付完成时间
|
||||||
|
*/
|
||||||
|
private Date transDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分账订单总金额.单位分
|
||||||
|
*/
|
||||||
|
private Long transSumAmt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分账订单总笔数
|
||||||
|
*/
|
||||||
|
private Long transSumCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分账总单流水号
|
||||||
|
*/
|
||||||
|
private String separateBatchTrace;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分账项
|
||||||
|
*/
|
||||||
|
private List<SeparateItemBO> separateItemBOList;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
package com.wzj.soopin.transaction.domain.bo;
|
||||||
|
|
||||||
|
import com.wzj.soopin.transaction.enums.easypay.SepaStatus;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分账项
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class SeparateItemBO {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分账子单流水号
|
||||||
|
*/
|
||||||
|
private String separateTrade;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分账收款方商户号
|
||||||
|
*/
|
||||||
|
private String receiveMchtCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分账金额,单位分
|
||||||
|
*/
|
||||||
|
private Integer sepaTransAmount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手续费对应本金(原交易订单)金额
|
||||||
|
* 当前分账接收方拟承担的手续费本金金额,金额和比例2选1必填。
|
||||||
|
* 当前收款方不承担,则送0;
|
||||||
|
* 当前收款方全额承担,则送原订单金额;
|
||||||
|
* 当前收款方仅承担自己接收金额的手续费,则送分账金额。。
|
||||||
|
*/
|
||||||
|
private Integer sepaFeeAmount;
|
||||||
|
|
||||||
|
|
||||||
|
// =============== 分账结果参数 ==============
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分账单状态
|
||||||
|
*/
|
||||||
|
private SepaStatus sepaStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分账平台应结金额,单位分
|
||||||
|
*/
|
||||||
|
private Long sepaPlatStlmAmount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分账实际结算金额,单位分
|
||||||
|
*/
|
||||||
|
private Long sepaStlmAmount;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -75,10 +75,6 @@ public class SeparateInfo {
|
|||||||
* 分账比例,分账金额和分账比例2选一必填,30代表30%,仅可上送整数
|
* 分账比例,分账金额和分账比例2选一必填,30代表30%,仅可上送整数
|
||||||
*/
|
*/
|
||||||
private Long sepaRatio;
|
private Long sepaRatio;
|
||||||
/**
|
|
||||||
* 分账金额,分账金额和分账比例2选一必填,单位分
|
|
||||||
*/
|
|
||||||
private Long sepaTransAmount;
|
|
||||||
/**
|
/**
|
||||||
* 分账订单描述
|
* 分账订单描述
|
||||||
*/
|
*/
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
package com.wzj.soopin.transaction.domain.entity;
|
package com.wzj.soopin.transaction.domain.entity;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
public class WxAuthResponse {
|
public class WxAuthResponse {
|
||||||
private String openid;
|
private String openid;
|
||||||
private String session_key;
|
private String session_key;
|
||||||
|
@ -85,9 +85,9 @@ public class DivideDetail extends BaseEntity {
|
|||||||
@ExcelProperty(value = "状态", order = 5)
|
@ExcelProperty(value = "状态", order = 5)
|
||||||
private Integer status;
|
private Integer status;
|
||||||
|
|
||||||
@Schema(description = "账户id")
|
@Schema(description = "账户code")
|
||||||
@ExcelProperty(value = "账户id", order = 6)
|
@ExcelProperty(value = "账户code", order = 6)
|
||||||
private Long accountId;
|
private String accountCode;
|
||||||
/**
|
/**
|
||||||
* 账户名称
|
* 账户名称
|
||||||
* */
|
* */
|
||||||
|
@ -4,6 +4,7 @@ package com.wzj.soopin.transaction.domain.po;
|
|||||||
import com.alibaba.excel.annotation.ExcelProperty;
|
import com.alibaba.excel.annotation.ExcelProperty;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.wzj.soopin.transaction.enums.DivideRuleFeeType;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||||
@ -46,6 +47,13 @@ public class DivideRule extends BaseEntity {
|
|||||||
private Long regionId;
|
private Long regionId;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手续费承担方式类型见 {@link DivideRuleFeeType}
|
||||||
|
*/
|
||||||
|
@Schema(description = "手续费承担方式")
|
||||||
|
private Integer feeType;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 状态
|
* 状态
|
||||||
*/
|
*/
|
||||||
|
@ -83,11 +83,11 @@ public class PayOrder extends BaseAudit {
|
|||||||
private String unTrace;
|
private String unTrace;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否支付完成
|
* 交易状态 0->待支付,1->支付中,2->已支付,3->退款中,4->已退款
|
||||||
*/
|
*/
|
||||||
@TableField(value = "trans_over")
|
@TableField(value = "trans_state")
|
||||||
@Schema(description = "是否支付完成")
|
@Schema(description = "交易状态 0->待支付,1->支付中,2->已支付,3->退款中,4->已退款")
|
||||||
private Boolean transOver;
|
private Integer transState;
|
||||||
|
|
||||||
@TableField(value = "del_flag")
|
@TableField(value = "del_flag")
|
||||||
private String delFlag;
|
private String delFlag;
|
||||||
|
@ -74,9 +74,9 @@ public class DivideDetailVO extends BaseEntity {
|
|||||||
private Integer type;
|
private Integer type;
|
||||||
|
|
||||||
|
|
||||||
@Schema(description = "账户id")
|
@Schema(description = "账户code")
|
||||||
@ExcelProperty(value = "账户id", order = 6)
|
@ExcelProperty(value = "账户code", order = 6)
|
||||||
private Long accountId;
|
private String accountCode;
|
||||||
/**
|
/**
|
||||||
* 账户名称
|
* 账户名称
|
||||||
* */
|
* */
|
||||||
|
@ -2,6 +2,7 @@ package com.wzj.soopin.transaction.domain.vo;
|
|||||||
|
|
||||||
|
|
||||||
import com.alibaba.excel.annotation.ExcelProperty;
|
import com.alibaba.excel.annotation.ExcelProperty;
|
||||||
|
import com.wzj.soopin.transaction.enums.DivideRuleFeeType;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||||
@ -56,6 +57,12 @@ public class DivideRuleVO extends BaseEntity {
|
|||||||
@Schema(description = "区域id")
|
@Schema(description = "区域id")
|
||||||
private Long regionId;
|
private Long regionId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手续费承担方式类型见 {@link DivideRuleFeeType}
|
||||||
|
*/
|
||||||
|
@Schema(description = "手续费承担方式")
|
||||||
|
private Integer feeType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 类型
|
* 类型
|
||||||
*/
|
*/
|
||||||
|
@ -14,7 +14,7 @@ import java.math.BigDecimal;
|
|||||||
@Builder
|
@Builder
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class EasypayPaymentResultVO {
|
public class EasypayTransResultVO {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 订单id
|
* 订单id
|
||||||
@ -27,9 +27,9 @@ public class EasypayPaymentResultVO {
|
|||||||
public Long payId;
|
public Long payId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付是否完成
|
* 交易状态 0->待支付,1->已支付,2->退款中,3->已退款
|
||||||
*/
|
*/
|
||||||
public boolean paymentComplete;
|
public int transState;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 订单总金额
|
* 订单总金额
|
@ -1,5 +1,13 @@
|
|||||||
package com.wzj.soopin.transaction.enums;
|
package com.wzj.soopin.transaction.enums;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分账规则的商户类型
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
public enum DivideRuleDetailType {
|
public enum DivideRuleDetailType {
|
||||||
|
|
||||||
|
|
||||||
@ -15,25 +23,14 @@ public enum DivideRuleDetailType {
|
|||||||
* 代理
|
* 代理
|
||||||
*/
|
*/
|
||||||
PROXY(3, "代理"),
|
PROXY(3, "代理"),
|
||||||
|
/**
|
||||||
|
* 达人
|
||||||
|
*/
|
||||||
|
REFERENCE(4, "达人"),;
|
||||||
|
|
||||||
REFERENCE(4, "推广"),;
|
private final int value;
|
||||||
|
|
||||||
private int value;
|
private final String desc;
|
||||||
private String desc;
|
|
||||||
|
|
||||||
DivideRuleDetailType(int value, String desc) {
|
|
||||||
this.value = value;
|
|
||||||
this.desc = desc;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDesc() {
|
|
||||||
return desc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DivideRuleDetailType getEnum(int value) {
|
public static DivideRuleDetailType getEnum(int value) {
|
||||||
for (DivideRuleDetailType type : DivideRuleDetailType.values()) {
|
for (DivideRuleDetailType type : DivideRuleDetailType.values()) {
|
||||||
|
@ -1,33 +1,44 @@
|
|||||||
package com.wzj.soopin.transaction.enums;
|
package com.wzj.soopin.transaction.enums;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import org.dromara.common.core.exception.ServiceException;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
public enum DivideRuleFeeType {
|
public enum DivideRuleFeeType {
|
||||||
/**
|
/**
|
||||||
* 按比例分配
|
* 按比例分配
|
||||||
*/
|
*/
|
||||||
RATE(1, "按比例分配"),
|
RATE(0, "按比例分配"),
|
||||||
/**
|
/**
|
||||||
* 商家承担
|
* 商家承担
|
||||||
*/
|
*/
|
||||||
SELLER(2, "商家承担"),
|
SELLER(1, "商家承担"),
|
||||||
/**
|
/**
|
||||||
* 平台承担
|
* 平台承担
|
||||||
*/
|
*/
|
||||||
PLATFORM(3, "平台承担"),
|
PLATFORM(2, "平台承担"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 平台代理承担
|
||||||
|
*/
|
||||||
|
PROXY(3, "代理承担"),
|
||||||
|
|
||||||
|
/**
|
||||||
PROXY(4, "平台代理承担");
|
* 平台代理承担
|
||||||
|
*/
|
||||||
|
REFERENCE(4, "达人承担");
|
||||||
private String desc;
|
|
||||||
|
|
||||||
private int value;
|
private int value;
|
||||||
|
|
||||||
DivideRuleFeeType(int value, String desc) {
|
private String desc;
|
||||||
this.value = value;
|
|
||||||
this.desc = desc;
|
public static DivideRuleFeeType getByValue(int value) {
|
||||||
|
return Arrays.stream(values()).filter(e -> e.value == value).findFirst().orElseThrow(() -> new ServiceException("手续费分配方式" + value + "不存在"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
package com.wzj.soopin.transaction.enums;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付单交易状态
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum TransState {
|
||||||
|
|
||||||
|
PENDING(0, "待支付"),
|
||||||
|
|
||||||
|
Payment(1, "支付中"),
|
||||||
|
|
||||||
|
PAID(2, "已支付"),
|
||||||
|
|
||||||
|
REFUND_PENDING(3, "退款中"),
|
||||||
|
|
||||||
|
REFUNDED(4, "已退款");
|
||||||
|
|
||||||
|
|
||||||
|
private final int code;
|
||||||
|
|
||||||
|
private final String desc;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -1,27 +1,42 @@
|
|||||||
package com.wzj.soopin.transaction.enums.easypay;
|
package com.wzj.soopin.transaction.enums.easypay;
|
||||||
|
|
||||||
import java.io.IOException;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.dromara.common.core.exception.ServiceException;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分账单状态,(处理中、成功、失败、已退款)
|
* 分账单状态,(处理中、成功、失败、已退款)
|
||||||
*/
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
public enum SepaStatus {
|
public enum SepaStatus {
|
||||||
PENDING, REFUNDED, SUCCESS;
|
|
||||||
|
|
||||||
public String toValue() {
|
SUCCESS("SUCCESS", "成功"),
|
||||||
return switch (this) {
|
FAIL("FAIL", "失败"),
|
||||||
case PENDING -> "PENDING";
|
PENDING("PENDING", "处理中"),
|
||||||
case REFUNDED -> "REFUNDED";
|
PROCESSING("PROCESSING", "处理中"),
|
||||||
case SUCCESS -> "SUCCESS";
|
REFUNDED("REFUNDED", "已退款");
|
||||||
};
|
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* 状态code
|
||||||
|
*/
|
||||||
|
private final String value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态描述
|
||||||
|
*/
|
||||||
|
private final String info;
|
||||||
|
|
||||||
|
public static SepaStatus getByValue(String value) {
|
||||||
|
return Arrays.stream(SepaStatus.values())
|
||||||
|
.filter(e -> StrUtil.equals(e.getValue(), value))
|
||||||
|
.findFirst()
|
||||||
|
.orElseThrow(() -> new ServiceException("分账状态不存在"));
|
||||||
|
|
||||||
public static SepaStatus forValue(String value) throws IOException {
|
|
||||||
return switch (value) {
|
|
||||||
case "PENDING" -> PENDING;
|
|
||||||
case "REFUNDED" -> REFUNDED;
|
|
||||||
case "SUCCESS" -> SUCCESS;
|
|
||||||
default -> throw new IOException("Cannot deserialize SepaStatus");
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package com.wzj.soopin.transaction.mapper;
|
|||||||
|
|
||||||
import com.wzj.soopin.transaction.domain.po.DivideDetail;
|
import com.wzj.soopin.transaction.domain.po.DivideDetail;
|
||||||
import com.wzj.soopin.transaction.domain.vo.DivideDetailVO;
|
import com.wzj.soopin.transaction.domain.vo.DivideDetailVO;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -9,6 +10,7 @@ import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
|||||||
*
|
*
|
||||||
* @author zcc
|
* @author zcc
|
||||||
*/
|
*/
|
||||||
|
@Mapper
|
||||||
public interface DivideDetailMapper extends BaseMapperPlus<DivideDetail, DivideDetailVO> {
|
public interface DivideDetailMapper extends BaseMapperPlus<DivideDetail, DivideDetailVO> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,20 @@ package com.wzj.soopin.transaction.mapper;
|
|||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import com.wzj.soopin.transaction.domain.po.Divide;
|
import com.wzj.soopin.transaction.domain.po.Divide;
|
||||||
import com.wzj.soopin.transaction.domain.vo.DivideVO;
|
import com.wzj.soopin.transaction.domain.vo.DivideVO;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 意见反馈Mapper接口
|
* 意见反馈Mapper接口
|
||||||
*
|
*
|
||||||
* @author zcc
|
* @author zcc
|
||||||
*/
|
*/
|
||||||
public interface DivideMapper extends BaseMapper <Divide> {
|
@Mapper
|
||||||
|
public interface DivideMapper extends BaseMapper<Divide> {
|
||||||
|
|
||||||
DivideVO getVOById( Long divideId);
|
DivideVO getVOById(Long divideId);
|
||||||
|
|
||||||
|
@Select("select * from trans_divide where order_id = #{orderId}")
|
||||||
|
Divide selectByOrderId(@Param("orderId") Long orderId);
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,6 @@ package com.wzj.soopin.transaction.mapper;
|
|||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import com.wzj.soopin.transaction.domain.po.PayOrder;
|
import com.wzj.soopin.transaction.domain.po.PayOrder;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
import org.apache.ibatis.annotations.Param;
|
|
||||||
import org.apache.ibatis.annotations.Select;
|
|
||||||
|
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface PayOrderMapper extends BaseMapper<PayOrder> {
|
public interface PayOrderMapper extends BaseMapper<PayOrder> {
|
||||||
|
@ -2,9 +2,10 @@ package com.wzj.soopin.transaction.service;
|
|||||||
|
|
||||||
|
|
||||||
import com.wzj.soopin.transaction.domain.bo.PaymentBO;
|
import com.wzj.soopin.transaction.domain.bo.PaymentBO;
|
||||||
|
import com.wzj.soopin.transaction.domain.bo.SeparateApplyBO;
|
||||||
import com.wzj.soopin.transaction.domain.bo.easypay.EasyPayRequest;
|
import com.wzj.soopin.transaction.domain.bo.easypay.EasyPayRequest;
|
||||||
import com.wzj.soopin.transaction.domain.vo.EasypayAccountVO;
|
import com.wzj.soopin.transaction.domain.vo.EasypayAccountVO;
|
||||||
import com.wzj.soopin.transaction.domain.vo.EasypayPaymentResultVO;
|
import com.wzj.soopin.transaction.domain.vo.EasypayTransResultVO;
|
||||||
import com.wzj.soopin.transaction.domain.vo.EasypayPrePayVO;
|
import com.wzj.soopin.transaction.domain.vo.EasypayPrePayVO;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
@ -24,7 +25,7 @@ public interface IEasypayService {
|
|||||||
* @param orderId
|
* @param orderId
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
EasypayPaymentResultVO paymentQuery(Long orderId) throws ServerException;
|
EasypayTransResultVO paymentQuery(Long orderId) throws ServerException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理易生支付结果通知回调
|
* 处理易生支付结果通知回调
|
||||||
@ -38,6 +39,27 @@ public interface IEasypayService {
|
|||||||
*/
|
*/
|
||||||
void refund(Long orderId);
|
void refund(Long orderId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款查询
|
||||||
|
* @param orderId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
EasypayTransResultVO refundQuery(Long orderId);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发起分账
|
||||||
|
* @param separateApplyBO
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
SeparateApplyBO separateApply(SeparateApplyBO separateApplyBO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理易生分账结果通知回调
|
||||||
|
* @param easyPayRequest
|
||||||
|
*/
|
||||||
|
void handleSeparateCallback(EasyPayRequest easyPayRequest);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取易生账户
|
* 获取易生账户
|
||||||
* @param memberId
|
* @param memberId
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.wzj.soopin.transaction.service.impl;
|
package com.wzj.soopin.transaction.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.wzj.soopin.transaction.convert.DivideRuleConvert;
|
import com.wzj.soopin.transaction.convert.DivideRuleConvert;
|
||||||
@ -104,15 +105,9 @@ public class DivideRuleServiceImpl extends ServiceImpl<DivideRuleMapper, DivideR
|
|||||||
List<DivideRule> divideRuleList = baseMapper.selectList(new QueryWrapper<DivideRule>().lambda()
|
List<DivideRule> divideRuleList = baseMapper.selectList(new QueryWrapper<DivideRule>().lambda()
|
||||||
.eq(DivideRule::getType,orderType)
|
.eq(DivideRule::getType,orderType)
|
||||||
.eq(DivideRule::getStatus,DivideRuleStatus.ON.getCode()));
|
.eq(DivideRule::getStatus,DivideRuleStatus.ON.getCode()));
|
||||||
if (CollectionUtils.isEmpty(divideRuleList)) {
|
Assert.notEmpty(divideRuleList, () -> new ServiceException("未找到品类的分账规则"));
|
||||||
return null;
|
Assert.isTrue(divideRuleList.size() == 1, () -> new ServiceException("品类分账规则不唯一"));
|
||||||
}
|
|
||||||
if(divideRuleList.size()>1){
|
|
||||||
throw new ServiceException("分账规则不唯一");
|
|
||||||
}
|
|
||||||
|
|
||||||
DivideRule divideRule = divideRuleList.get(0);
|
DivideRule divideRule = divideRuleList.get(0);
|
||||||
|
|
||||||
List<DivideRuleDetail> detailList = detailMapper.selectList(new QueryWrapper<DivideRuleDetail>().lambda()
|
List<DivideRuleDetail> detailList = detailMapper.selectList(new QueryWrapper<DivideRuleDetail>().lambda()
|
||||||
.eq(DivideRuleDetail::getRuleId, divideRule.getId()));
|
.eq(DivideRuleDetail::getRuleId, divideRule.getId()));
|
||||||
DivideRuleVO vo = convert.toVO(divideRule);
|
DivideRuleVO vo = convert.toVO(divideRule);
|
||||||
|
@ -1,30 +1,35 @@
|
|||||||
package com.wzj.soopin.transaction.service.impl;
|
package com.wzj.soopin.transaction.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.wzj.soopin.member.domain.po.Member;
|
|
||||||
import com.wzj.soopin.member.domain.po.MemberAccount;
|
|
||||||
import com.wzj.soopin.member.service.IMemberAccountService;
|
import com.wzj.soopin.member.service.IMemberAccountService;
|
||||||
import com.wzj.soopin.member.service.IMemberService;
|
import com.wzj.soopin.member.service.IMemberService;
|
||||||
import com.wzj.soopin.order.domain.entity.Order;
|
import com.wzj.soopin.order.domain.entity.Order;
|
||||||
import com.wzj.soopin.order.service.OrderItemService;
|
import com.wzj.soopin.order.service.OrderItemService;
|
||||||
import com.wzj.soopin.order.service.OrderService;
|
import com.wzj.soopin.order.service.OrderService;
|
||||||
import com.wzj.soopin.order.utils.StringUtils;
|
|
||||||
import com.wzj.soopin.transaction.convert.DivideConvert;
|
import com.wzj.soopin.transaction.convert.DivideConvert;
|
||||||
import com.wzj.soopin.transaction.convert.DivideDetailConvert;
|
import com.wzj.soopin.transaction.convert.DivideDetailConvert;
|
||||||
import com.wzj.soopin.transaction.domain.bo.DivideBO;
|
import com.wzj.soopin.transaction.domain.bo.DivideBO;
|
||||||
|
import com.wzj.soopin.transaction.domain.bo.SeparateApplyBO;
|
||||||
|
import com.wzj.soopin.transaction.domain.bo.SeparateItemBO;
|
||||||
import com.wzj.soopin.transaction.domain.po.Divide;
|
import com.wzj.soopin.transaction.domain.po.Divide;
|
||||||
import com.wzj.soopin.transaction.domain.po.DivideDetail;
|
import com.wzj.soopin.transaction.domain.po.DivideDetail;
|
||||||
|
import com.wzj.soopin.transaction.domain.po.PayOrder;
|
||||||
import com.wzj.soopin.transaction.domain.vo.DivideRuleDetailVO;
|
import com.wzj.soopin.transaction.domain.vo.DivideRuleDetailVO;
|
||||||
import com.wzj.soopin.transaction.domain.vo.DivideRuleVO;
|
import com.wzj.soopin.transaction.domain.vo.DivideRuleVO;
|
||||||
import com.wzj.soopin.transaction.domain.vo.DivideVO;
|
import com.wzj.soopin.transaction.domain.vo.DivideVO;
|
||||||
import com.wzj.soopin.transaction.enums.DivideRuleDetailType;
|
import com.wzj.soopin.transaction.enums.DivideRuleDetailType;
|
||||||
|
import com.wzj.soopin.transaction.enums.DivideRuleFeeType;
|
||||||
import com.wzj.soopin.transaction.enums.DivideStatus;
|
import com.wzj.soopin.transaction.enums.DivideStatus;
|
||||||
|
import com.wzj.soopin.transaction.enums.TransState;
|
||||||
import com.wzj.soopin.transaction.mapper.DivideDetailMapper;
|
import com.wzj.soopin.transaction.mapper.DivideDetailMapper;
|
||||||
import com.wzj.soopin.transaction.mapper.DivideMapper;
|
import com.wzj.soopin.transaction.mapper.DivideMapper;
|
||||||
import com.wzj.soopin.transaction.service.IDivideRuleService;
|
import com.wzj.soopin.transaction.service.IDivideRuleService;
|
||||||
import com.wzj.soopin.transaction.service.IDivideService;
|
import com.wzj.soopin.transaction.service.IDivideService;
|
||||||
import com.wzj.soopin.transaction.service.IEasypayService;
|
import com.wzj.soopin.transaction.service.IEasypayService;
|
||||||
|
import com.wzj.soopin.transaction.service.PayOrderService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.dromara.common.core.exception.ServiceException;
|
import org.dromara.common.core.exception.ServiceException;
|
||||||
@ -36,9 +41,8 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.HashMap;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分账服务实现类
|
* 分账服务实现类
|
||||||
@ -56,23 +60,17 @@ public class DivideServiceImpl extends ServiceImpl<DivideMapper, Divide> impleme
|
|||||||
|
|
||||||
private final DivideConvert divideConvert;
|
private final DivideConvert divideConvert;
|
||||||
|
|
||||||
|
|
||||||
private final OrderService orderService;
|
private final OrderService orderService;
|
||||||
|
|
||||||
|
private final PayOrderService payOrderService;
|
||||||
|
|
||||||
private final IDivideRuleService ruleService;
|
private final IDivideRuleService ruleService;
|
||||||
|
|
||||||
private final OrderItemService orderItemService;
|
|
||||||
|
|
||||||
|
|
||||||
private final ConfigService configService;
|
|
||||||
|
|
||||||
private final IEasypayService easypayService;
|
private final IEasypayService easypayService;
|
||||||
|
|
||||||
private final IMemberAccountService accountService;
|
|
||||||
|
|
||||||
private final ISysTenantService sysTenantService;
|
private final ISysTenantService sysTenantService;
|
||||||
|
|
||||||
private final IMemberService memberService;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
@ -138,177 +136,270 @@ public class DivideServiceImpl extends ServiceImpl<DivideMapper, Divide> impleme
|
|||||||
return baseMapper.selectOne(new QueryWrapper<Divide>().lambda().eq(Divide::getOrderSn, orderNo));
|
return baseMapper.selectOne(new QueryWrapper<Divide>().lambda().eq(Divide::getOrderSn, orderNo));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单金额分账
|
||||||
|
* 商家先从订单总金额中分走租户中配置的比例后,剩余的按分账规则分给平台和推广等账户
|
||||||
|
*
|
||||||
|
* @param orderId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public boolean divide(Long orderId) {
|
public boolean divide(Long orderId) {
|
||||||
//获取订单信息
|
//获取订单信息
|
||||||
Order order = orderService.getById(orderId);
|
Order order = orderService.getById(orderId);
|
||||||
|
Assert.notNull(order, () -> new ServiceException("订单不存在"));
|
||||||
if (order == null) {
|
Assert.isTrue(order.getStatus() == 3, () -> new ServiceException("订单未支付"));
|
||||||
throw new ServiceException("订单不存在");
|
PayOrder payOrder = payOrderService.getById(order.getPayId());
|
||||||
}
|
Assert.notNull(payOrder, () -> new ServiceException("支付单不存在"));
|
||||||
if (order.getStatus() != 3) { //订单状态为已完成
|
Assert.isTrue(payOrder.getTransState() == TransState.PAID.getCode(), () -> new ServiceException("订单未支付"));
|
||||||
throw new ServiceException("订单状态不正确");
|
Assert.isFalse(this.exists(Wrappers.lambdaQuery(Divide.class).eq(Divide::getOrderId, orderId)), () -> new ServiceException("已存在分账记录,无需再次分账"));
|
||||||
}
|
|
||||||
Divide divide = this.getById(orderId);
|
|
||||||
if (divide != null) {
|
|
||||||
throw new ServiceException("已存在分账记录,无需再次分账");
|
|
||||||
}
|
|
||||||
//查找分账规则
|
//查找分账规则
|
||||||
DivideRuleVO rule = ruleService.getVOByOrderType(order.getType());
|
DivideRuleVO rule = ruleService.getVOByOrderType(order.getType());
|
||||||
if (rule == null) {
|
Integer feeType = rule.getFeeType();
|
||||||
throw new ServiceException("未找到分账规则");
|
DivideRuleFeeType divideRuleFeeType = DivideRuleFeeType.getByValue(feeType);
|
||||||
}
|
List<DivideRuleDetailVO> details = rule.getDetails();
|
||||||
//开始分账
|
checkRule(details, divideRuleFeeType);
|
||||||
|
|
||||||
//根据易生支付的合同查看手续费金额
|
//根据易生支付的合同查看手续费金额
|
||||||
BigDecimal totalAmount = order.getTotalAmount();
|
BigDecimal totalAmount = order.getTotalAmount();
|
||||||
BigDecimal totalFee = new BigDecimal(0);
|
|
||||||
String feeRate = configService.getConfigValue("transaction.divide.feeRate");
|
|
||||||
if (StringUtils.isNotBlank(feeRate)) {
|
|
||||||
totalFee = totalAmount.multiply(new BigDecimal(feeRate)).divide(new BigDecimal(1000), 2, BigDecimal.ROUND_HALF_UP);
|
|
||||||
}
|
|
||||||
BigDecimal actualMoney = totalAmount.subtract(totalFee);
|
|
||||||
//计算订单可分配金额,订单只考虑整单退,不考虑单独退,所以直接计算订单金额
|
//计算订单可分配金额,订单只考虑整单退,不考虑单独退,所以直接计算订单金额
|
||||||
//先生成主表信息
|
//先生成主表信息
|
||||||
divide = Divide.builder()
|
Divide divide = Divide.builder()
|
||||||
.ruleId(rule.getId())
|
.ruleId(rule.getId())
|
||||||
.orderMoney(totalAmount)
|
.orderMoney(totalAmount)
|
||||||
.fee(totalFee)
|
// .fee(totalFee)
|
||||||
.actualMoney(actualMoney)
|
// .actualMoney(actualMoney)
|
||||||
.orderSn(order.getOrderSn())
|
.orderSn(order.getOrderSn())
|
||||||
.status(DivideStatus.PENDING.getCode())
|
.status(DivideStatus.PENDING.getCode())
|
||||||
.build();
|
.build();
|
||||||
super.save(divide);
|
super.save(divide);
|
||||||
|
List<DivideDetail> detailList = new ArrayList<>();
|
||||||
//计算商户的手续费
|
List<SeparateItemBO> separateItemBOList = new ArrayList<>();
|
||||||
|
// 从租户信息得到商户的分账比例,先分给商户
|
||||||
SysTenantVo tenant = sysTenantService.queryById(order.getTenantId());
|
SysTenantVo tenant = sysTenantService.queryById(order.getTenantId());
|
||||||
if (tenant == null) {
|
DivideDetail sellerDivideDetail = divideSeller(totalAmount, divide.getId(), tenant, divideRuleFeeType, detailList, separateItemBOList);
|
||||||
throw new ServiceException("租户信息不存在");
|
detailList.add(sellerDivideDetail);
|
||||||
}
|
// 商户分完后分给代理和达人,最后剩余都给平台
|
||||||
BigDecimal sellerFee = new BigDecimal(0);
|
rule.getDetails().stream()
|
||||||
BigDecimal platformFee = new BigDecimal(0);
|
.filter(item -> item.getType() == DivideRuleDetailType.PROXY.getValue())
|
||||||
if (tenant.getBearFeeFlag() == 1) {
|
.findFirst()
|
||||||
//如果承担手续费,计算手续费
|
.ifPresent(ruleDetailVO -> {
|
||||||
sellerFee = totalFee;
|
DivideDetail proxyDivideDetail = divideProxy(totalAmount, ruleDetailVO, divide.getId(), order.getTenantId(),divideRuleFeeType, detailList, separateItemBOList);
|
||||||
} else {
|
});
|
||||||
platformFee = totalFee;
|
rule.getDetails().stream()
|
||||||
}
|
.filter(item -> item.getType() == DivideRuleDetailType.REFERENCE.getValue())
|
||||||
|
.findFirst()
|
||||||
|
.ifPresent(ruleDetailVO -> {
|
||||||
|
DivideDetail divideReference = divideReference(totalAmount, ruleDetailVO, divide.getId(), order.getMemberId(),divideRuleFeeType, detailList, separateItemBOList);
|
||||||
|
detailList.add(divideReference);
|
||||||
|
});
|
||||||
|
|
||||||
//生成商户的分账明细
|
rule.getDetails().stream()
|
||||||
BigDecimal sellerAmount = divideSeller(actualMoney, sellerFee, divide.getId(), tenant);
|
.filter(item -> item.getType() == DivideRuleDetailType.PLATFORM.getValue())
|
||||||
|
.findFirst()
|
||||||
|
.ifPresent(ruleDetailVO -> {
|
||||||
BigDecimal platformAmount = actualMoney.subtract(sellerAmount);
|
DivideDetail dividePlatform = dividePlatform(totalAmount, ruleDetailVO, divide.getId(),divideRuleFeeType, detailList, separateItemBOList);
|
||||||
BigDecimal finalAmount = new BigDecimal(0);
|
detailList.add(dividePlatform);
|
||||||
//按规则进行分账
|
});
|
||||||
//先分代理 然后达人 最后的剩余都给平台
|
|
||||||
DivideRuleDetailVO divideRuleDetail = rule.getDetails().stream().filter(item -> item.getType() == DivideRuleDetailType.PROXY.getValue()).findFirst().orElse(null);
|
|
||||||
|
|
||||||
if ((divideRuleDetail != null)) {
|
|
||||||
finalAmount = platformAmount.subtract(divideproxy(platformAmount, divideRuleDetail, divide.getId(), order.getTenantId()));
|
|
||||||
}
|
|
||||||
divideRuleDetail = rule.getDetails().stream().filter(item -> item.getType() == DivideRuleDetailType.REFERENCE.getValue()).findFirst().orElse(null);
|
|
||||||
|
|
||||||
if ((divideRuleDetail != null)) {
|
|
||||||
finalAmount = finalAmount.subtract(divideDarren(platformAmount, divideRuleDetail, divide.getId(), order.getMemberId()));
|
|
||||||
}
|
|
||||||
dividePlatform(finalAmount, platformFee, divideRuleDetail, divide.getId(), tenant.getBearFeeFlag() == 1);
|
|
||||||
|
|
||||||
//同步订单状态
|
//同步订单状态
|
||||||
syncOrderStatus(order);
|
syncOrderStatus(order);
|
||||||
|
|
||||||
//同步易生支付
|
// 调用易生支付实时分账
|
||||||
syncYisheng(null);
|
SeparateApplyBO separateApplyBO = SeparateApplyBO.builder()
|
||||||
|
.orderId(order.getId())
|
||||||
|
.payId(order.getPayId())
|
||||||
|
.transDate(payOrder.getEndTransDate())
|
||||||
|
.transSumAmt(payOrder.getTransAmount())
|
||||||
|
.transSumCount((long) separateItemBOList.size())
|
||||||
|
.separateBatchTrace(String.valueOf(divide.getId()))
|
||||||
|
.separateItemBOList(separateItemBOList)
|
||||||
|
.build();
|
||||||
|
easypayService.separateApply(separateApplyBO);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private BigDecimal divideSeller(BigDecimal actualMoney, BigDecimal sellerFee, Long divideId, SysTenantVo tenant) {
|
/**
|
||||||
//获取商户的账户信息
|
* 校验分账规则详情和规则中的手续费承担类型是否一致
|
||||||
Map<String, String> account = getSellerAccount(tenant.getId());
|
*
|
||||||
if (account == null) {
|
* @param details
|
||||||
log.error("商户信息不存在,不参与分账");
|
* @param divideRuleFeeType
|
||||||
|
*/
|
||||||
|
private void checkRule(List<DivideRuleDetailVO> details, DivideRuleFeeType divideRuleFeeType) {
|
||||||
|
if (DivideRuleFeeType.SELLER == divideRuleFeeType) {
|
||||||
|
long count = details.stream().filter(item -> item.getType() == DivideRuleDetailType.SELLER.getValue()).count();
|
||||||
|
Assert.isTrue(count == 1, () -> new ServiceException("分账总规则中已配置商户承担手续费,但未配置商户分账规则详情"));
|
||||||
}
|
}
|
||||||
|
if (DivideRuleFeeType.PLATFORM == divideRuleFeeType) {
|
||||||
|
long count = details.stream().filter(item -> item.getType() == DivideRuleDetailType.PLATFORM.getValue()).count();
|
||||||
|
Assert.isTrue(count == 1, () -> new ServiceException("分账总规则中已配置平台承担手续费,但未配置平台分账规则详情"));
|
||||||
|
}
|
||||||
|
if (DivideRuleFeeType.PROXY == divideRuleFeeType) {
|
||||||
|
long count = details.stream().filter(item -> item.getType() == DivideRuleDetailType.PROXY.getValue()).count();
|
||||||
|
Assert.isTrue(count == 1, () -> new ServiceException("分账总规则中已配置代理承担手续费,但未配置代理分账规则详情"));
|
||||||
|
}
|
||||||
|
if (DivideRuleFeeType.REFERENCE == divideRuleFeeType) {
|
||||||
|
long count = details.stream().filter(item -> item.getType() == DivideRuleDetailType.REFERENCE.getValue()).count();
|
||||||
|
Assert.isTrue(count == 1, () -> new ServiceException("分账总规则中已配置达人承担手续费,但未配置达人分账规则详情"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商户分账
|
||||||
|
*
|
||||||
|
* @param totalAmount 总金额
|
||||||
|
* @param divideId 分账总表id
|
||||||
|
* @param divideRuleFeeType
|
||||||
|
* @param tenant 商户所属租户
|
||||||
|
* @param detailList
|
||||||
|
* @param separateItemBOList
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private DivideDetail divideSeller(BigDecimal totalAmount, Long divideId, SysTenantVo tenant,
|
||||||
|
DivideRuleFeeType divideRuleFeeType, List<DivideDetail> detailList,
|
||||||
|
List<SeparateItemBO> separateItemBOList) {
|
||||||
|
//获取商户的账户信息
|
||||||
|
String mchtCode = getMchtCode(tenant.getId());
|
||||||
//计算商户的分账金额
|
//计算商户的分账金额
|
||||||
BigDecimal divideRate = tenant.getDivideRate();
|
BigDecimal divideRate = tenant.getDivideRate();
|
||||||
Integer bearFeeFlag = tenant.getBearFeeFlag();
|
|
||||||
|
|
||||||
//计算商户的分账金额
|
//计算商户的分账金额
|
||||||
BigDecimal sellerAmount = actualMoney.multiply(divideRate).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
|
BigDecimal sellerAmount = totalAmount.multiply(divideRate).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
|
||||||
|
|
||||||
//生成商户的分账明细
|
//生成商户的分账明细
|
||||||
DivideDetail sellerDetail = DivideDetail.builder()
|
DivideDetail sellerDetail = DivideDetail.builder()
|
||||||
.divideId(divideId)
|
.divideId(divideId)
|
||||||
|
.accountCode(mchtCode)
|
||||||
.money(sellerAmount)
|
.money(sellerAmount)
|
||||||
.fee(sellerFee)
|
|
||||||
.feePercent(bearFeeFlag == 1 ? new BigDecimal(100) : new BigDecimal(0))
|
|
||||||
.moneyPercent(divideRate)
|
.moneyPercent(divideRate)
|
||||||
.type(DivideRuleDetailType.SELLER.getValue()).build();
|
.type(DivideRuleDetailType.SELLER.getValue()).build();
|
||||||
|
|
||||||
detailMapper.insert(sellerDetail);
|
detailMapper.insert(sellerDetail);
|
||||||
|
detailList.add(sellerDetail);
|
||||||
return sellerAmount;
|
Integer sepaFeeAmount = 0;
|
||||||
|
if (divideRuleFeeType == DivideRuleFeeType.SELLER) {
|
||||||
|
sepaFeeAmount = totalAmount.multiply(BigDecimal.valueOf(100)).intValue();
|
||||||
|
} else if (divideRuleFeeType == DivideRuleFeeType.RATE) {
|
||||||
|
sepaFeeAmount = sellerAmount.multiply(BigDecimal.valueOf(100)).intValue();
|
||||||
|
}
|
||||||
|
separateItemBOList.add(SeparateItemBO.builder()
|
||||||
|
.separateTrade(String.valueOf(sellerDetail.getId()))
|
||||||
|
.receiveMchtCode(mchtCode)
|
||||||
|
.sepaTransAmount(sellerAmount.multiply(BigDecimal.valueOf(100)).intValue())
|
||||||
|
.sepaFeeAmount(sepaFeeAmount)
|
||||||
|
.build());
|
||||||
|
return sellerDetail;
|
||||||
}
|
}
|
||||||
|
|
||||||
private BigDecimal divideproxy(BigDecimal platformMoney, DivideRuleDetailVO rule, Long divideId, Long tenantId) {
|
/**
|
||||||
|
* 代理商分账
|
||||||
|
*
|
||||||
|
* @param totalAmount 总金额
|
||||||
|
* @param rule 代理商的分账规则详情
|
||||||
|
* @param divideId 分账总表id
|
||||||
|
* @param tenantId 代理商所属租户id
|
||||||
|
* @param divideRuleFeeType
|
||||||
|
* @param detailList
|
||||||
|
* @param separateItemBOList
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private DivideDetail divideProxy(BigDecimal totalAmount, DivideRuleDetailVO rule, Long divideId, Long tenantId, DivideRuleFeeType divideRuleFeeType, List<DivideDetail> detailList, List<SeparateItemBO> separateItemBOList) {
|
||||||
//获取代理人的账户信息
|
//获取代理人的账户信息
|
||||||
Map<String, String> account = getProxyAccount(tenantId);
|
String mchtCode = getMchtCode(tenantId);
|
||||||
if (account == null) {
|
|
||||||
log.error("代理人信息不存在,不参与分账");
|
|
||||||
return new BigDecimal(0);
|
|
||||||
}
|
|
||||||
//计算代理人的分账金额
|
//计算代理人的分账金额
|
||||||
BigDecimal proxyAmount = platformMoney.multiply(rule.getMoneyPercent()).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
|
BigDecimal proxyAmount = totalAmount.multiply(rule.getMoneyPercent()).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
|
||||||
DivideDetail proxyDetail = DivideDetail.builder()
|
DivideDetail proxyDetail = DivideDetail.builder()
|
||||||
.divideId(divideId)
|
.divideId(divideId)
|
||||||
|
.accountCode(mchtCode)
|
||||||
.money(proxyAmount)
|
.money(proxyAmount)
|
||||||
.fee(new BigDecimal(0))
|
|
||||||
.feePercent(new BigDecimal(0))
|
|
||||||
.moneyPercent(rule.getMoneyPercent())
|
.moneyPercent(rule.getMoneyPercent())
|
||||||
.type(DivideRuleDetailType.PROXY.getValue())
|
.type(DivideRuleDetailType.PROXY.getValue())
|
||||||
.build();
|
.build();
|
||||||
detailMapper.insert(proxyDetail);
|
detailMapper.insert(proxyDetail);
|
||||||
return proxyAmount;
|
detailList.add(proxyDetail);
|
||||||
|
Integer sepaFeeAmount = 0;
|
||||||
|
if (divideRuleFeeType == DivideRuleFeeType.PROXY) {
|
||||||
|
sepaFeeAmount = totalAmount.multiply(BigDecimal.valueOf(100)).intValue();
|
||||||
|
} else if (divideRuleFeeType == DivideRuleFeeType.RATE) {
|
||||||
|
sepaFeeAmount = proxyAmount.multiply(BigDecimal.valueOf(100)).intValue();
|
||||||
|
}
|
||||||
|
separateItemBOList.add(SeparateItemBO.builder()
|
||||||
|
.separateTrade(String.valueOf(proxyDetail.getId()))
|
||||||
|
.receiveMchtCode(mchtCode)
|
||||||
|
.sepaTransAmount(proxyAmount.multiply(BigDecimal.valueOf(100)).intValue())
|
||||||
|
.sepaFeeAmount(sepaFeeAmount)
|
||||||
|
.build());
|
||||||
|
return proxyDetail;
|
||||||
}
|
}
|
||||||
|
|
||||||
private BigDecimal divideDarren(BigDecimal platformMoney, DivideRuleDetailVO rule, Long divideId, Long tenantId) {
|
/**
|
||||||
|
* 达人分账
|
||||||
|
*
|
||||||
|
* @param totalAmount
|
||||||
|
* @param rule
|
||||||
|
* @param divideId
|
||||||
|
* @param tenantId
|
||||||
|
* @param divideRuleFeeType
|
||||||
|
* @param detailList
|
||||||
|
* @param separateItemBOList
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private DivideDetail divideReference(BigDecimal totalAmount, DivideRuleDetailVO rule, Long divideId, Long tenantId, DivideRuleFeeType divideRuleFeeType, List<DivideDetail> detailList, List<SeparateItemBO> separateItemBOList) {
|
||||||
//获取达人的账户信息
|
//获取达人的账户信息
|
||||||
Map<String, String> account = getReferenceAccount(tenantId);
|
String mchtCode = getMchtCode(tenantId);
|
||||||
if (account == null) {
|
|
||||||
log.error("达人信息不存在,不参与分账");
|
|
||||||
return new BigDecimal(0);
|
|
||||||
}
|
|
||||||
//计算达人的分账金额
|
//计算达人的分账金额
|
||||||
BigDecimal proxyAmount = platformMoney.multiply(rule.getMoneyPercent()).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
|
BigDecimal proxyAmount = totalAmount.multiply(rule.getMoneyPercent()).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
|
||||||
DivideDetail proxyDetail = DivideDetail.builder()
|
DivideDetail referenceDetail = DivideDetail.builder()
|
||||||
.divideId(divideId)
|
.divideId(divideId)
|
||||||
|
.accountCode(mchtCode)
|
||||||
.money(proxyAmount)
|
.money(proxyAmount)
|
||||||
.fee(new BigDecimal(0))
|
|
||||||
.feePercent(new BigDecimal(0))
|
|
||||||
.moneyPercent(rule.getMoneyPercent())
|
.moneyPercent(rule.getMoneyPercent())
|
||||||
.type(DivideRuleDetailType.REFERENCE.getValue())
|
.type(DivideRuleDetailType.REFERENCE.getValue())
|
||||||
.build();
|
.build();
|
||||||
detailMapper.insert(proxyDetail);
|
detailMapper.insert(referenceDetail);
|
||||||
return proxyAmount;
|
detailList.add(referenceDetail);
|
||||||
|
Integer sepaFeeAmount = 0;
|
||||||
|
if (divideRuleFeeType == DivideRuleFeeType.REFERENCE) {
|
||||||
|
sepaFeeAmount = totalAmount.multiply(BigDecimal.valueOf(100)).intValue();
|
||||||
|
} else if (divideRuleFeeType == DivideRuleFeeType.RATE) {
|
||||||
|
sepaFeeAmount = proxyAmount.multiply(BigDecimal.valueOf(100)).intValue();
|
||||||
|
}
|
||||||
|
separateItemBOList.add(SeparateItemBO.builder()
|
||||||
|
.separateTrade(String.valueOf(referenceDetail.getId()))
|
||||||
|
.receiveMchtCode(mchtCode)
|
||||||
|
.sepaTransAmount(proxyAmount.multiply(BigDecimal.valueOf(100)).intValue())
|
||||||
|
.sepaFeeAmount(sepaFeeAmount)
|
||||||
|
.build());
|
||||||
|
return referenceDetail;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dividePlatform(BigDecimal platformMoney, BigDecimal fee, DivideRuleDetailVO rule, Long divideId, boolean feeFlag) {
|
private DivideDetail dividePlatform(BigDecimal totalAmount, DivideRuleDetailVO rule, Long divideId, DivideRuleFeeType divideRuleFeeType, List<DivideDetail> detailList, List<SeparateItemBO> separateItemBOList) {
|
||||||
//获取平台的账户信息
|
//获取平台的账户信息
|
||||||
Map<String, String> account = getPlatformAccount();
|
String mchtCode = getMchtCode(1L);
|
||||||
if (account == null) {
|
|
||||||
log.error("平台信息不存在,不参与分账");
|
|
||||||
}
|
|
||||||
//计算平台的分账金额
|
//计算平台的分账金额
|
||||||
BigDecimal proxyAmount = platformMoney.multiply(rule.getMoneyPercent()).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
|
BigDecimal platformAmount = totalAmount.multiply(rule.getMoneyPercent()).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
|
||||||
DivideDetail proxyDetail = DivideDetail.builder()
|
DivideDetail platformDetail = DivideDetail.builder()
|
||||||
.divideId(divideId)
|
.divideId(divideId)
|
||||||
.money(proxyAmount)
|
.accountCode(mchtCode)
|
||||||
.fee(fee)
|
.money(platformAmount)
|
||||||
.feePercent(feeFlag ? new BigDecimal(100) : new BigDecimal(0))
|
|
||||||
.moneyPercent(rule.getMoneyPercent())
|
.moneyPercent(rule.getMoneyPercent())
|
||||||
.type(DivideRuleDetailType.REFERENCE.getValue())
|
.type(DivideRuleDetailType.PLATFORM.getValue())
|
||||||
.build();
|
.build();
|
||||||
detailMapper.insert(proxyDetail);
|
detailMapper.insert(platformDetail);
|
||||||
|
detailList.add(platformDetail);
|
||||||
|
Integer sepaFeeAmount = 0;
|
||||||
|
if (divideRuleFeeType == DivideRuleFeeType.PLATFORM) {
|
||||||
|
sepaFeeAmount = totalAmount.multiply(BigDecimal.valueOf(100)).intValue();
|
||||||
|
} else if (divideRuleFeeType == DivideRuleFeeType.RATE) {
|
||||||
|
sepaFeeAmount = platformAmount.multiply(BigDecimal.valueOf(100)).intValue();
|
||||||
|
}
|
||||||
|
separateItemBOList.add(SeparateItemBO.builder()
|
||||||
|
.separateTrade(String.valueOf(platformDetail.getId()))
|
||||||
|
.receiveMchtCode(mchtCode)
|
||||||
|
.sepaTransAmount(platformAmount.multiply(BigDecimal.valueOf(100)).intValue())
|
||||||
|
.sepaFeeAmount(sepaFeeAmount)
|
||||||
|
.build());
|
||||||
|
return platformDetail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -327,84 +418,22 @@ public class DivideServiceImpl extends ServiceImpl<DivideMapper, Divide> impleme
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Map<String, String> getPlatformAccount() {
|
|
||||||
return new HashMap<>() {{
|
|
||||||
put("account", "123456");
|
|
||||||
put("name", "平台");
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取达人的账户信息
|
* 获取平台或商家或推广或达人在易生侧的商户号
|
||||||
*
|
*
|
||||||
* @param memberId
|
* @param tenantId
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private Map<String, String> getReferenceAccount(Long memberId) {
|
private String getMchtCode(Long tenantId) {
|
||||||
Member member = memberService.getById(memberId);
|
SysTenantVo tenant = sysTenantService.queryById(tenantId);
|
||||||
if (member == null) {
|
Assert.notNull(tenant, () -> new ServiceException("商户信息异常"));
|
||||||
return null;
|
// todo 需要从租户信息中获得商家在易生侧的商户号
|
||||||
}
|
String mchtCode = "";
|
||||||
//推广人
|
Assert.notBlank(mchtCode, () -> new ServiceException("未维护商户在易生侧的商户号信息"));
|
||||||
Long inviteUserId = member.getSpreadUid();
|
return mchtCode;
|
||||||
if (inviteUserId == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
MemberAccount account = accountService.getMemberAccount(inviteUserId);
|
|
||||||
if (account == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return new HashMap<>() {{
|
|
||||||
put("accountId", account.getId() + "");
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取代理的账户信息
|
|
||||||
*
|
|
||||||
* @param
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private Map<String, String> getProxyAccount(Long memberId) {
|
|
||||||
if (memberId != null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
MemberAccount account = accountService.getMemberAccount(memberId);
|
|
||||||
|
|
||||||
if (account == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return new HashMap<>() {{
|
|
||||||
put("accountId", account.getId() + "");
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取商家的账户信息
|
|
||||||
*
|
|
||||||
* @param sellerId
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private Map<String, String> getSellerAccount(Long sellerId) {
|
|
||||||
|
|
||||||
SysTenantVo tenant = sysTenantService.queryById(sellerId);
|
|
||||||
if (tenant != null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
MemberAccount account = accountService.getMemberAccount(tenant.getId());
|
|
||||||
|
|
||||||
// if (account == null)
|
|
||||||
//
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
return new HashMap<>() {{
|
|
||||||
put("accountId", account.getId() + "");
|
|
||||||
}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void syncOrderStatus(Order order) {
|
private void syncOrderStatus(Order order) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void syncYisheng(List<DivideDetail> divideDetails) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -18,17 +18,21 @@ import com.alibaba.fastjson2.JSON;
|
|||||||
import com.alibaba.fastjson2.JSONArray;
|
import com.alibaba.fastjson2.JSONArray;
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.tencentcloudapi.dlc.v20210125.models.Asset;
|
|
||||||
import com.wzj.soopin.order.domain.entity.Order;
|
import com.wzj.soopin.order.domain.entity.Order;
|
||||||
import com.wzj.soopin.order.emum.OrderStatusEnum;
|
import com.wzj.soopin.order.emum.OrderStatusEnum;
|
||||||
import com.wzj.soopin.order.mapper.OrderMapper;
|
import com.wzj.soopin.order.mapper.OrderMapper;
|
||||||
import com.wzj.soopin.transaction.config.EasypayConfig;
|
import com.wzj.soopin.transaction.config.EasypayConfig;
|
||||||
import com.wzj.soopin.transaction.config.WechatMiniProgramConfig;
|
import com.wzj.soopin.transaction.config.WechatMiniProgramConfig;
|
||||||
import com.wzj.soopin.transaction.domain.bo.PaymentBO;
|
import com.wzj.soopin.transaction.domain.bo.PaymentBO;
|
||||||
|
import com.wzj.soopin.transaction.domain.bo.SeparateApplyBO;
|
||||||
import com.wzj.soopin.transaction.domain.bo.easypay.*;
|
import com.wzj.soopin.transaction.domain.bo.easypay.*;
|
||||||
import com.wzj.soopin.transaction.domain.bo.easypay.refund.apply.req.RefundApplyReqBody;
|
import com.wzj.soopin.transaction.domain.bo.easypay.refund.apply.req.RefundApplyReqBody;
|
||||||
import com.wzj.soopin.transaction.domain.bo.easypay.refund.apply.req.RefundReqOrderInfo;
|
import com.wzj.soopin.transaction.domain.bo.easypay.refund.apply.req.RefundReqOrderInfo;
|
||||||
import com.wzj.soopin.transaction.domain.bo.easypay.refund.apply.resp.RefundApplyRespBody;
|
import com.wzj.soopin.transaction.domain.bo.easypay.refund.apply.resp.RefundApplyRespBody;
|
||||||
|
import com.wzj.soopin.transaction.domain.bo.easypay.separate.apply.req.SeparateApplyReqBody;
|
||||||
|
import com.wzj.soopin.transaction.domain.bo.easypay.separate.apply.req.SeparateReqOrderInfo;
|
||||||
|
import com.wzj.soopin.transaction.domain.bo.easypay.separate.apply.resp.SeparateApplyRespBody;
|
||||||
|
import com.wzj.soopin.transaction.domain.bo.easypay.separate.apply.resp.SeparateRespOrderInfo;
|
||||||
import com.wzj.soopin.transaction.domain.bo.easypay.trade.jsapi.req.*;
|
import com.wzj.soopin.transaction.domain.bo.easypay.trade.jsapi.req.*;
|
||||||
import com.wzj.soopin.transaction.domain.bo.easypay.trade.jsapi.resp.JsApiRespBody;
|
import com.wzj.soopin.transaction.domain.bo.easypay.trade.jsapi.resp.JsApiRespBody;
|
||||||
import com.wzj.soopin.transaction.domain.bo.easypay.trade.jsapi.resp.JsapiRespOrderInfo;
|
import com.wzj.soopin.transaction.domain.bo.easypay.trade.jsapi.resp.JsapiRespOrderInfo;
|
||||||
@ -39,34 +43,30 @@ import com.wzj.soopin.transaction.domain.bo.easypay.trade.query.resp.TradeQueryR
|
|||||||
import com.wzj.soopin.transaction.domain.entity.WxAuthResponse;
|
import com.wzj.soopin.transaction.domain.entity.WxAuthResponse;
|
||||||
import com.wzj.soopin.transaction.domain.po.PayOrder;
|
import com.wzj.soopin.transaction.domain.po.PayOrder;
|
||||||
import com.wzj.soopin.transaction.domain.vo.EasypayAccountVO;
|
import com.wzj.soopin.transaction.domain.vo.EasypayAccountVO;
|
||||||
import com.wzj.soopin.transaction.domain.vo.EasypayPaymentResultVO;
|
import com.wzj.soopin.transaction.domain.vo.EasypayTransResultVO;
|
||||||
import com.wzj.soopin.transaction.domain.vo.EasypayPrePayVO;
|
import com.wzj.soopin.transaction.domain.vo.EasypayPrePayVO;
|
||||||
|
import com.wzj.soopin.transaction.enums.TransState;
|
||||||
import com.wzj.soopin.transaction.enums.easypay.DelaySettleFlag;
|
import com.wzj.soopin.transaction.enums.easypay.DelaySettleFlag;
|
||||||
import com.wzj.soopin.transaction.enums.easypay.PatnerSettleFlag;
|
import com.wzj.soopin.transaction.enums.easypay.PatnerSettleFlag;
|
||||||
import com.wzj.soopin.transaction.enums.easypay.PayType;
|
import com.wzj.soopin.transaction.enums.easypay.PayType;
|
||||||
import com.wzj.soopin.transaction.enums.easypay.SplitSettleFlag;
|
import com.wzj.soopin.transaction.enums.easypay.SplitSettleFlag;
|
||||||
|
import com.wzj.soopin.transaction.mapper.DivideDetailMapper;
|
||||||
import com.wzj.soopin.transaction.mapper.DivideMapper;
|
import com.wzj.soopin.transaction.mapper.DivideMapper;
|
||||||
import com.wzj.soopin.transaction.mapper.PayOrderMapper;
|
import com.wzj.soopin.transaction.mapper.PayOrderMapper;
|
||||||
|
import com.wzj.soopin.transaction.service.IDivideService;
|
||||||
import com.wzj.soopin.transaction.service.IEasypayService;
|
import com.wzj.soopin.transaction.service.IEasypayService;
|
||||||
import com.wzj.soopin.transaction.service.PayOrderService;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.dromara.common.core.enums.FormatsType;
|
import org.dromara.common.core.enums.FormatsType;
|
||||||
import org.dromara.common.core.exception.ServiceException;
|
import org.dromara.common.core.exception.ServiceException;
|
||||||
import org.dromara.common.core.utils.DateUtils;
|
import org.dromara.common.core.utils.DateUtils;
|
||||||
import org.dromara.common.core.utils.ServletUtils;
|
import org.dromara.common.core.utils.ServletUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.rmi.ServerException;
|
import java.rmi.ServerException;
|
||||||
import java.time.LocalDateTime;
|
import java.util.*;
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.TreeMap;
|
|
||||||
|
|
||||||
import static com.wzj.soopin.transaction.constans.EasypayConstants.*;
|
import static com.wzj.soopin.transaction.constans.EasypayConstants.*;
|
||||||
|
|
||||||
@ -80,18 +80,17 @@ import static com.wzj.soopin.transaction.constans.EasypayConstants.*;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class EasypayServiceImpl implements IEasypayService {
|
public class EasypayServiceImpl implements IEasypayService {
|
||||||
|
|
||||||
private EasypayConfig easypayConfig;
|
private final EasypayConfig easypayConfig;
|
||||||
|
|
||||||
private WechatMiniProgramConfig wechatMiniProgramConfig;
|
private final WechatMiniProgramConfig wechatMiniProgramConfig;
|
||||||
|
|
||||||
private WxAuthService wxAuthService;
|
private final WxAuthService wxAuthService;
|
||||||
|
|
||||||
private final OrderMapper orderMapper;
|
private final OrderMapper orderMapper;
|
||||||
|
|
||||||
private final DivideMapper divideMapper;
|
|
||||||
|
|
||||||
private final PayOrderMapper payOrderMapper;
|
private final PayOrderMapper payOrderMapper;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成易生接口请求头参数
|
* 生成易生接口请求头参数
|
||||||
*
|
*
|
||||||
@ -165,7 +164,7 @@ public class EasypayServiceImpl implements IEasypayService {
|
|||||||
*/
|
*/
|
||||||
private void verify(Object header, Object body, String signStr) {
|
private void verify(Object header, Object body, String signStr) {
|
||||||
TreeMap<String, Object> hearMap = new TreeMap<>(JSONObject.from(header));
|
TreeMap<String, Object> hearMap = new TreeMap<>(JSONObject.from(header));
|
||||||
TreeMap<String, Object>bodyMap = new TreeMap<>(JSONObject.from(body));
|
TreeMap<String, Object> bodyMap = new TreeMap<>(JSONObject.from(body));
|
||||||
// 递归排序
|
// 递归排序
|
||||||
sortMap(hearMap);
|
sortMap(hearMap);
|
||||||
sortMap(bodyMap);
|
sortMap(bodyMap);
|
||||||
@ -211,27 +210,32 @@ public class EasypayServiceImpl implements IEasypayService {
|
|||||||
.reqBody(apiReqBody)
|
.reqBody(apiReqBody)
|
||||||
.reqSign(reqSign)
|
.reqSign(reqSign)
|
||||||
.build();
|
.build();
|
||||||
log.debug("调用易生发起支付接口请求:{}",JSONObject.toJSONString(easyPayRequest));
|
log.debug("调用易生发起支付接口请求:{}", JSONObject.toJSONString(easyPayRequest));
|
||||||
String url = StrBuilder.create(easypayConfig.getApiPathPrefix()).append("/trade/jsapi").toString();
|
String url = StrBuilder.create(easypayConfig.getApiPathPrefix()).append("/trade/jsapi").toString();
|
||||||
String body = HttpRequest.post(url)
|
String body = HttpRequest.post(url)
|
||||||
.timeout(3000)
|
.timeout(3000)
|
||||||
.body(JSON.toJSONString(easyPayRequest))
|
.body(JSON.toJSONString(easyPayRequest))
|
||||||
.execute()
|
.execute()
|
||||||
.body();
|
.body();
|
||||||
log.debug("调用易生发起支付接口响应:{}",body);
|
log.debug("调用易生发起支付接口响应:{}", body);
|
||||||
EasyPayResponse easyPayResponse = JSONObject.parseObject(body, EasyPayResponse.class);
|
EasyPayResponse easyPayResponse = JSONObject.parseObject(body, EasyPayResponse.class);
|
||||||
if (StrUtil.equals(RSP_HEADER_OK, easyPayResponse.getRspHeader().getRspCode())) {
|
if (StrUtil.equals(RSP_HEADER_OK, easyPayResponse.getRspHeader().getRspCode())) {
|
||||||
verify(easyPayResponse.getRspHeader(), easyPayResponse.getRspBody(), easyPayResponse.getRspSign());
|
verify(easyPayResponse.getRspHeader(), easyPayResponse.getRspBody(), easyPayResponse.getRspSign());
|
||||||
JsApiRespBody jsApiRespBody = JSON.parseObject(JSONObject.toJSONString(easyPayResponse.getRspBody()), JsApiRespBody.class);
|
JsApiRespBody jsApiRespBody = JSON.parseObject(JSONObject.toJSONString(easyPayResponse.getRspBody()), JsApiRespBody.class);
|
||||||
RespStateInfo respStateInfo = jsApiRespBody.getRespStateInfo();
|
RespStateInfo respStateInfo = jsApiRespBody.getRespStateInfo();
|
||||||
if (StrUtil.equals(RSP_BODY_RESP_OK, respStateInfo.getRespCode())) {
|
if (StrUtil.equals(RSP_BODY_RESP_OK, respStateInfo.getRespCode())) {
|
||||||
if (StrUtil.equalsAny(respStateInfo.getTransState(), RSP_BODY_TRANS_OK,RSP_BODY_TRANS_PARTIALLY_OK, RSP_BODY_TRANS_OK_WETCAT, RSP_BODY_TRANS_PROCESSING)) {
|
if (StrUtil.equalsAny(respStateInfo.getTransState(), RSP_BODY_TRANS_OK, RSP_BODY_TRANS_PARTIALLY_OK, RSP_BODY_TRANS_OK_WETCAT, RSP_BODY_TRANS_PROCESSING)) {
|
||||||
//保存支付单信息到数据库
|
//保存支付单信息到数据库
|
||||||
JsapiRespOrderInfo respOrderInfo = jsApiRespBody.getRespOrderInfo();
|
JsapiRespOrderInfo respOrderInfo = jsApiRespBody.getRespOrderInfo();
|
||||||
payOrder.setPayType(paymentBO.getPayType().getValue());
|
payOrder.setPayType(paymentBO.getPayType().getValue());
|
||||||
payOrder.setStartTransDate(new Date());
|
payOrder.setStartTransDate(new Date());
|
||||||
payOrder.setEasypayTrace(respOrderInfo.getOutTrace());
|
payOrder.setEasypayTrace(respOrderInfo.getOutTrace());
|
||||||
|
payOrder.setTransState(TransState.Payment.getCode());
|
||||||
payOrderMapper.updateById(payOrder);
|
payOrderMapper.updateById(payOrder);
|
||||||
|
//关联订单的最新支付单
|
||||||
|
orderMapper.updateById(Order.builder().id(payOrder.getOrderId()).payId(payOrder.getId()).build());
|
||||||
|
// 产生待分账记录
|
||||||
|
generateDivideRecord(payOrder);
|
||||||
// 生成返回前端的预支付信息
|
// 生成返回前端的预支付信息
|
||||||
return generatePrePayVO(paymentBO.getPayType(), jsApiRespBody);
|
return generatePrePayVO(paymentBO.getPayType(), jsApiRespBody);
|
||||||
} else {
|
} else {
|
||||||
@ -248,6 +252,14 @@ public class EasypayServiceImpl implements IEasypayService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成待分账记录
|
||||||
|
* @param payOrder
|
||||||
|
*/
|
||||||
|
private void generateDivideRecord(PayOrder payOrder) {
|
||||||
|
//TODO 待完善
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据支付类型校验请求参数是否完整
|
* 根据支付类型校验请求参数是否完整
|
||||||
*
|
*
|
||||||
@ -255,9 +267,12 @@ public class EasypayServiceImpl implements IEasypayService {
|
|||||||
*/
|
*/
|
||||||
private void checkPaymentParamByPayType(PaymentBO paymentBO) throws ServerException {
|
private void checkPaymentParamByPayType(PaymentBO paymentBO) throws ServerException {
|
||||||
switch (paymentBO.getPayType()) {
|
switch (paymentBO.getPayType()) {
|
||||||
case ALI_PAY_JSAPI, ALI_PAY_MINI_APP -> Assert.notBlank(paymentBO.getBuyerId(), () -> new ServiceException("支付宝支付缺少必要参数:buyerId"));
|
case ALI_PAY_JSAPI, ALI_PAY_MINI_APP ->
|
||||||
case WE_CHAT_JSAPI, WE_CHAT_MINI_APP -> Assert.notBlank(paymentBO.getWxLoginCode(), () -> new ServiceException("微信支付缺少必要参数:微信登录授权code"));
|
Assert.notBlank(paymentBO.getBuyerId(), () -> new ServiceException("支付宝支付缺少必要参数:buyerId"));
|
||||||
case UNION_PAY_JSAPI, UNION_PAY_Js_MINI -> Assert.isTrue(StrUtil.isAllNotBlank(paymentBO.getTransType(), paymentBO.getUserAuthCode(),
|
case WE_CHAT_JSAPI, WE_CHAT_MINI_APP ->
|
||||||
|
Assert.notBlank(paymentBO.getWxLoginCode(), () -> new ServiceException("微信支付缺少必要参数:微信登录授权code"));
|
||||||
|
case UNION_PAY_JSAPI, UNION_PAY_Js_MINI ->
|
||||||
|
Assert.isTrue(StrUtil.isAllNotBlank(paymentBO.getTransType(), paymentBO.getUserAuthCode(),
|
||||||
paymentBO.getUserId(), paymentBO.getAreaInfo(), paymentBO.getPaymentValidTime(),
|
paymentBO.getUserId(), paymentBO.getAreaInfo(), paymentBO.getPaymentValidTime(),
|
||||||
paymentBO.getQrCode(), paymentBO.getQrCodeType()), () -> new ServiceException("银联支付缺少必要参数"));
|
paymentBO.getQrCode(), paymentBO.getQrCodeType()), () -> new ServiceException("银联支付缺少必要参数"));
|
||||||
default -> throw new ServerException("不支持的支付方式");
|
default -> throw new ServerException("不支持的支付方式");
|
||||||
@ -272,13 +287,14 @@ public class EasypayServiceImpl implements IEasypayService {
|
|||||||
*/
|
*/
|
||||||
private void setPayInfo(JsApiReqBody apiReqBody, PaymentBO paymentBO) throws ServerException {
|
private void setPayInfo(JsApiReqBody apiReqBody, PaymentBO paymentBO) throws ServerException {
|
||||||
switch (paymentBO.getPayType()) {
|
switch (paymentBO.getPayType()) {
|
||||||
case ALI_PAY_JSAPI, ALI_PAY_MINI_APP -> apiReqBody.setAliBizParam(AliBizParam.builder().buyerId(paymentBO.getBuyerId()).build());
|
case ALI_PAY_JSAPI, ALI_PAY_MINI_APP ->
|
||||||
|
apiReqBody.setAliBizParam(AliBizParam.builder().buyerId(paymentBO.getBuyerId()).build());
|
||||||
case WE_CHAT_JSAPI, WE_CHAT_MINI_APP -> {
|
case WE_CHAT_JSAPI, WE_CHAT_MINI_APP -> {
|
||||||
WxAuthResponse wxAuthResponse = wxAuthService.getOpenIdByMiniProgramCode(paymentBO.getWxLoginCode());
|
WxAuthResponse wxAuthResponse = wxAuthService.getOpenIdByMiniProgramCode(paymentBO.getWxLoginCode());
|
||||||
Assert.isTrue(StrUtil.equals(wxAuthResponse.getErrcode(), "0"), () -> new ServiceException("微信小程序登录异常"));
|
|
||||||
apiReqBody.setWxBizParam(WxBizParam.builder().subAppid(wechatMiniProgramConfig.getAppId()).subOpenId(wxAuthResponse.getOpenid()).build());
|
apiReqBody.setWxBizParam(WxBizParam.builder().subAppid(wechatMiniProgramConfig.getAppId()).subOpenId(wxAuthResponse.getOpenid()).build());
|
||||||
}
|
}
|
||||||
case UNION_PAY_JSAPI, UNION_PAY_Js_MINI -> apiReqBody.setQrBizParam(BeanUtil.copyProperties(paymentBO, QrBizParam.class));
|
case UNION_PAY_JSAPI, UNION_PAY_Js_MINI ->
|
||||||
|
apiReqBody.setQrBizParam(BeanUtil.copyProperties(paymentBO, QrBizParam.class));
|
||||||
default -> throw new ServerException("不支持的支付方式");
|
default -> throw new ServerException("不支持的支付方式");
|
||||||
}
|
}
|
||||||
PayInfo payInfo = PayInfo.builder()
|
PayInfo payInfo = PayInfo.builder()
|
||||||
@ -297,27 +313,27 @@ public class EasypayServiceImpl implements IEasypayService {
|
|||||||
Order order = orderMapper.selectById(paymentBO.getOrderId());
|
Order order = orderMapper.selectById(paymentBO.getOrderId());
|
||||||
Assert.notNull(order, () -> new ServiceException("订单不存在"));
|
Assert.notNull(order, () -> new ServiceException("订单不存在"));
|
||||||
Assert.isTrue(Objects.equals(order.getStatus(), OrderStatusEnum.UNPAID.getValue()), () -> new ServiceException("订单已支付"));
|
Assert.isTrue(Objects.equals(order.getStatus(), OrderStatusEnum.UNPAID.getValue()), () -> new ServiceException("订单已支付"));
|
||||||
PayOrder payOrder;
|
|
||||||
// 订单首次支付,创建支付订单记录
|
|
||||||
if(order.getPayId() == null){
|
|
||||||
payOrder = PayOrder.builder()
|
|
||||||
.orderId(order.getId())
|
|
||||||
.transAmount(apiReqBody.getReqOrderInfo().getTransAmount())
|
|
||||||
.startTransDate(new Date())
|
|
||||||
.transOver(false)
|
|
||||||
.build();
|
|
||||||
payOrderMapper.insert(payOrder);
|
|
||||||
orderMapper.updateById(Order.builder().id(order.getId()).payId(payOrder.getId()).build());
|
|
||||||
}else {
|
|
||||||
payOrder = payOrderMapper.selectById(order.getPayId());
|
|
||||||
Assert.notNull(payOrder, () -> new ServiceException("订单异常"));
|
|
||||||
}
|
|
||||||
// 订单中的金额单位为元,需转换为分
|
// 订单中的金额单位为元,需转换为分
|
||||||
long transAmount = order.getTotalAmount().multiply(BigDecimal.valueOf(100)).longValue();
|
long transAmount = order.getTotalAmount().multiply(BigDecimal.valueOf(100)).longValue();
|
||||||
|
PayOrder payOrder;
|
||||||
|
// 订单已拉起过支付,支付中或已支付状态不可再次支付
|
||||||
|
if (order.getPayId() != null) {
|
||||||
|
payOrder = payOrderMapper.selectById(order.getPayId());
|
||||||
|
Assert.notNull(payOrder, () -> new ServiceException("订单异常"));
|
||||||
|
Assert.isTrue(Objects.equals(payOrder.getTransState(), TransState.PENDING.getCode()), () -> new ServiceException("订单支付中或已支付"));
|
||||||
|
}
|
||||||
|
payOrder = PayOrder.builder()
|
||||||
|
.orderId(order.getId())
|
||||||
|
.transAmount(transAmount)
|
||||||
|
.startTransDate(new Date())
|
||||||
|
.transState(TransState.PENDING.getCode())
|
||||||
|
.payType(paymentBO.getPayType().getValue())
|
||||||
|
.build();
|
||||||
|
payOrderMapper.insert(payOrder);
|
||||||
JsapiReqOrderInfo jsapiReqOrderInfo = JsapiReqOrderInfo.builder()
|
JsapiReqOrderInfo jsapiReqOrderInfo = JsapiReqOrderInfo.builder()
|
||||||
.orgTrace(String.valueOf(payOrder.getId()))
|
.orgTrace(String.valueOf(payOrder.getId()))
|
||||||
.transAmount(transAmount)
|
.transAmount(transAmount)
|
||||||
.backUrl(easypayConfig.getBackUrl())
|
.backUrl(easypayConfig.getTradeBackUrl())
|
||||||
.timeout(String.valueOf(TRACE_TIMEOUT))
|
.timeout(String.valueOf(TRACE_TIMEOUT))
|
||||||
.orderSub("无终街支付订单")
|
.orderSub("无终街支付订单")
|
||||||
.orderDes("无终街支付订单:" + order.getMerchantNote())
|
.orderDes("无终街支付订单:" + order.getMerchantNote())
|
||||||
@ -357,23 +373,22 @@ public class EasypayServiceImpl implements IEasypayService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询支付结果
|
* 查询支付结果
|
||||||
|
*
|
||||||
* @param orderId
|
* @param orderId
|
||||||
* @return
|
* @return
|
||||||
* @throws ServerException
|
* @throws ServerException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public EasypayPaymentResultVO paymentQuery(Long orderId) throws ServerException {
|
public EasypayTransResultVO paymentQuery(Long orderId) throws ServerException {
|
||||||
Order order = orderMapper.selectById(orderId);
|
Order order = orderMapper.selectById(orderId);
|
||||||
Assert.notNull(order, () -> new ServiceException("订单不存在"));
|
Assert.notNull(order, () -> new ServiceException("订单不存在"));
|
||||||
PayOrder payOrder = payOrderMapper.selectOne(Wrappers.lambdaQuery(PayOrder.class)
|
PayOrder payOrder = payOrderMapper.selectById(order.getPayId());
|
||||||
.eq(PayOrder::getOrderId, orderId)
|
|
||||||
.last("limit 1"));
|
|
||||||
Assert.notNull(payOrder, () -> new ServiceException("订单不存在"));
|
Assert.notNull(payOrder, () -> new ServiceException("订单不存在"));
|
||||||
EasypayPaymentResultVO paymentResultVO = EasypayPaymentResultVO.builder()
|
EasypayTransResultVO paymentResultVO = EasypayTransResultVO.builder()
|
||||||
.orderId(order.getId())
|
.orderId(order.getId())
|
||||||
.payId(order.getPayId())
|
.payId(order.getPayId())
|
||||||
.totalAmount(order.getTotalAmount())
|
.totalAmount(order.getTotalAmount())
|
||||||
.paymentComplete(false)
|
.transState(TransState.PENDING.getCode())
|
||||||
.build();
|
.build();
|
||||||
EasyPayRequestHeader reqHeader = generateEasyPayRequestHeader();
|
EasyPayRequestHeader reqHeader = generateEasyPayRequestHeader();
|
||||||
TradeQueryReqBody queryReqBody = TradeQueryReqBody.builder()
|
TradeQueryReqBody queryReqBody = TradeQueryReqBody.builder()
|
||||||
@ -382,7 +397,7 @@ public class EasypayServiceImpl implements IEasypayService {
|
|||||||
.reqOrderInfo(TradeQueryReqBody.ReqOrderInfo.builder()
|
.reqOrderInfo(TradeQueryReqBody.ReqOrderInfo.builder()
|
||||||
.orgTrace(StrBuilder.create(TRACE_PREFIX).append(System.currentTimeMillis()).append(RandomUtil.randomString(4)).toString())
|
.orgTrace(StrBuilder.create(TRACE_PREFIX).append(System.currentTimeMillis()).append(RandomUtil.randomString(4)).toString())
|
||||||
.oriOrgTrace(String.valueOf(order.getPayId()))
|
.oriOrgTrace(String.valueOf(order.getPayId()))
|
||||||
.oriTransDate(DateUtils.parseDateToStr(FormatsType.YYYYMMDD,payOrder.getStartTransDate()))
|
.oriTransDate(DateUtils.parseDateToStr(FormatsType.YYYYMMDD, payOrder.getStartTransDate()))
|
||||||
.build())
|
.build())
|
||||||
.build();
|
.build();
|
||||||
String reqSign = getSignStr(reqHeader, queryReqBody);
|
String reqSign = getSignStr(reqHeader, queryReqBody);
|
||||||
@ -391,34 +406,34 @@ public class EasypayServiceImpl implements IEasypayService {
|
|||||||
.reqBody(queryReqBody)
|
.reqBody(queryReqBody)
|
||||||
.reqSign(reqSign)
|
.reqSign(reqSign)
|
||||||
.build();
|
.build();
|
||||||
log.debug("调用易生查询支付接口请求:{}",JSONObject.toJSONString(easyRequest));
|
log.debug("调用易生查询支付接口请求:{}", JSONObject.toJSONString(easyRequest));
|
||||||
String url = StrBuilder.create(easypayConfig.getApiPathPrefix()).append("/trade/tradeQuery").toString();
|
String url = StrBuilder.create(easypayConfig.getApiPathPrefix()).append("/trade/tradeQuery").toString();
|
||||||
String body = HttpRequest.post(url)
|
String body = HttpRequest.post(url)
|
||||||
.timeout(3000)
|
.timeout(3000)
|
||||||
.body(JSON.toJSONString(easyRequest))
|
.body(JSON.toJSONString(easyRequest))
|
||||||
.execute()
|
.execute()
|
||||||
.body();
|
.body();
|
||||||
log.debug("调用易生查询支付接口响应:{}",body);
|
log.debug("调用易生查询支付接口响应:{}", body);
|
||||||
EasyPayResponse easyPayResponse = JSONObject.parseObject(body, EasyPayResponse.class);
|
EasyPayResponse easyPayResponse = JSONObject.parseObject(body, EasyPayResponse.class);
|
||||||
if (StrUtil.equals(RSP_HEADER_OK, easyPayResponse.getRspHeader().getRspCode())) {
|
if (StrUtil.equals(RSP_HEADER_OK, easyPayResponse.getRspHeader().getRspCode())) {
|
||||||
verify(easyPayResponse.getRspHeader(), easyPayResponse.getRspBody(),easyPayResponse.getRspSign());
|
verify(easyPayResponse.getRspHeader(), easyPayResponse.getRspBody(), easyPayResponse.getRspSign());
|
||||||
TradeQueryRespBody tradeQueryRespBody = JSON.parseObject(JSONObject.toJSONString(easyPayResponse.getRspBody()), TradeQueryRespBody.class);
|
TradeQueryRespBody tradeQueryRespBody = JSON.parseObject(JSONObject.toJSONString(easyPayResponse.getRspBody()), TradeQueryRespBody.class);
|
||||||
RespStateInfo respStateInfo = tradeQueryRespBody.getRespStateInfo();
|
RespStateInfo respStateInfo = tradeQueryRespBody.getRespStateInfo();
|
||||||
if (StrUtil.equals(RSP_BODY_RESP_OK, respStateInfo.getRespCode())) {
|
if (StrUtil.equals(RSP_BODY_RESP_OK, respStateInfo.getRespCode())) {
|
||||||
// 支付完成 进入终态
|
// 支付完成 进入终态
|
||||||
if (StrUtil.equalsAny(respStateInfo.getTransState(), RSP_BODY_TRANS_OK, RSP_BODY_TRANS_OK_WETCAT,RSP_BODY_TRANS_PARTIALLY_OK)) {
|
if (StrUtil.equalsAny(respStateInfo.getTransState(), RSP_BODY_TRANS_OK, RSP_BODY_TRANS_OK_WETCAT, RSP_BODY_TRANS_PARTIALLY_OK)) {
|
||||||
TradeQueryRespOrderInfo respOrderInfo = tradeQueryRespBody.getRespOrderInfo();
|
TradeQueryRespOrderInfo respOrderInfo = tradeQueryRespBody.getRespOrderInfo();
|
||||||
// 更新支付订单信息到数据库
|
// 更新支付订单信息到数据库
|
||||||
PayOrder payOrderUpdate = PayOrder.builder()
|
PayOrder payOrderUpdate = PayOrder.builder()
|
||||||
.id(payOrder.getId())
|
.id(payOrder.getId())
|
||||||
.endTransDate(DateUtil.parse(StrBuilder.create(respOrderInfo.getDateEnd()).append(respOrderInfo.getTimeEnd()),toString()))
|
.endTransDate(DateUtil.parse(StrBuilder.create(respOrderInfo.getDateEnd()).append(respOrderInfo.getTimeEnd()), toString()))
|
||||||
.easypayTrace(respOrderInfo.getOutTrace())
|
.easypayTrace(respOrderInfo.getOutTrace())
|
||||||
.pcTrace(respOrderInfo.getPcTrace())
|
.pcTrace(respOrderInfo.getPcTrace())
|
||||||
.unTrace(respOrderInfo.getUnTrace())
|
.unTrace(respOrderInfo.getUnTrace())
|
||||||
.transOver(true)
|
.transState(TransState.PAID.getCode())
|
||||||
.build();
|
.build();
|
||||||
payOrderMapper.updateById(payOrderUpdate);
|
payOrderMapper.updateById(payOrderUpdate);
|
||||||
paymentResultVO.setPaymentComplete(true);
|
paymentResultVO.setTransState(TransState.PAID.getCode());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.error("查询支付结果失败:{}", respStateInfo.getRespDesc());
|
log.error("查询支付结果失败:{}", respStateInfo.getRespDesc());
|
||||||
@ -434,25 +449,26 @@ public class EasypayServiceImpl implements IEasypayService {
|
|||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void handleTradeCallback(EasyPayRequest easyPayRequest) {
|
public void handleTradeCallback(EasyPayRequest easyPayRequest) {
|
||||||
verify(easyPayRequest.getReqHeader(),easyPayRequest.getReqBody(), easyPayRequest.getReqSign());
|
log.debug("易生支付结果通知回调:{}", JSONObject.toJSONString(easyPayRequest));
|
||||||
|
verify(easyPayRequest.getReqHeader(), easyPayRequest.getReqBody(), easyPayRequest.getReqSign());
|
||||||
TradeQueryRespBody tradeQueryRespBody = BeanUtil.toBean(easyPayRequest.getReqBody(), TradeQueryRespBody.class);
|
TradeQueryRespBody tradeQueryRespBody = BeanUtil.toBean(easyPayRequest.getReqBody(), TradeQueryRespBody.class);
|
||||||
RespStateInfo respStateInfo = tradeQueryRespBody.getRespStateInfo();
|
RespStateInfo respStateInfo = tradeQueryRespBody.getRespStateInfo();
|
||||||
if (StrUtil.equals(RSP_BODY_RESP_OK, respStateInfo.getRespCode())) {
|
if (StrUtil.equals(RSP_BODY_RESP_OK, respStateInfo.getRespCode())) {
|
||||||
// 支付完成 进入终态
|
// 支付完成 进入终态
|
||||||
if (StrUtil.equalsAny(respStateInfo.getTransState(), RSP_BODY_TRANS_OK, RSP_BODY_TRANS_OK_WETCAT,RSP_BODY_TRANS_PARTIALLY_OK)) {
|
if (StrUtil.equalsAny(respStateInfo.getTransState(), RSP_BODY_TRANS_OK, RSP_BODY_TRANS_OK_WETCAT, RSP_BODY_TRANS_PARTIALLY_OK)) {
|
||||||
TradeQueryRespOrderInfo respOrderInfo = tradeQueryRespBody.getRespOrderInfo();
|
TradeQueryRespOrderInfo respOrderInfo = tradeQueryRespBody.getRespOrderInfo();
|
||||||
PayOrder payOrder = payOrderMapper.selectById(String.valueOf(respOrderInfo.getOrgTrace()));
|
PayOrder payOrder = payOrderMapper.selectById(String.valueOf(respOrderInfo.getOrgTrace()));
|
||||||
if(payOrder != null){
|
if (payOrder != null) {
|
||||||
Order order = orderMapper.selectById(payOrder.getOrderId());
|
Order order = orderMapper.selectById(payOrder.getOrderId());
|
||||||
if(order != null){
|
if (order != null) {
|
||||||
// 更新支付订单信息
|
// 更新支付订单信息
|
||||||
payOrderMapper.updateById(PayOrder.builder()
|
payOrderMapper.updateById(PayOrder.builder()
|
||||||
.id(payOrder.getId())
|
.id(payOrder.getId())
|
||||||
.endTransDate(DateUtil.parse(StrBuilder.create(respOrderInfo.getDateEnd()).append(respOrderInfo.getTimeEnd()),toString()))
|
.endTransDate(DateUtil.parse(StrBuilder.create(respOrderInfo.getDateEnd()).append(respOrderInfo.getTimeEnd()), toString()))
|
||||||
.easypayTrace(respOrderInfo.getOutTrace())
|
.easypayTrace(respOrderInfo.getOutTrace())
|
||||||
.pcTrace(respOrderInfo.getPcTrace())
|
.pcTrace(respOrderInfo.getPcTrace())
|
||||||
.unTrace(respOrderInfo.getUnTrace())
|
.unTrace(respOrderInfo.getUnTrace())
|
||||||
.transOver(true)
|
.transState(TransState.PAID.getCode())
|
||||||
.build());
|
.build());
|
||||||
// 更新订单信息
|
// 更新订单信息
|
||||||
orderMapper.updateById(Order.builder()
|
orderMapper.updateById(Order.builder()
|
||||||
@ -461,10 +477,10 @@ public class EasypayServiceImpl implements IEasypayService {
|
|||||||
.paymentTime(LocalDateTimeUtil.parse(StrBuilder.create(respOrderInfo.getDateEnd()).append(respOrderInfo.getTimeEnd()).toString(), "yyyyMMddHHmmss"))
|
.paymentTime(LocalDateTimeUtil.parse(StrBuilder.create(respOrderInfo.getDateEnd()).append(respOrderInfo.getTimeEnd()).toString(), "yyyyMMddHHmmss"))
|
||||||
.payType(PayType.getByValue(payOrder.getPayType()).getChannel())
|
.payType(PayType.getByValue(payOrder.getPayType()).getChannel())
|
||||||
.build());
|
.build());
|
||||||
}else{
|
} else {
|
||||||
log.warn("回调通知的支付订单不存在:{}", respOrderInfo.getOrgTrace());
|
log.warn("回调通知的支付订单不存在:{}", respOrderInfo.getOrgTrace());
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
log.warn("回调通知的支付订单不存在:{}", respOrderInfo.getOrgTrace());
|
log.warn("回调通知的支付订单不存在:{}", respOrderInfo.getOrgTrace());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -474,11 +490,18 @@ public class EasypayServiceImpl implements IEasypayService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void refund(Long orderId) {
|
public void refund(Long orderId) {
|
||||||
Order order = orderMapper.selectById(orderId);
|
Order order = orderMapper.selectById(orderId);
|
||||||
Assert.notNull(order, () -> new ServiceException("订单不存在"));
|
Assert.notNull(order, () -> new ServiceException("订单不存在"));
|
||||||
PayOrder payOrder = payOrderMapper.selectOne(Wrappers.lambdaQuery(PayOrder.class).eq(PayOrder::getOrderId, orderId).last("limit 1"));
|
PayOrder payOrder = payOrderMapper.selectById(order.getPayId());
|
||||||
Assert.notNull(payOrder, () -> new ServiceException("订单不存在"));
|
Assert.notNull(payOrder, () -> new ServiceException("订单不存在"));
|
||||||
|
Assert.isTrue(payOrder.getTransState() == TransState.PAID.getCode(), () -> new ServiceException("订单未支付,不可发起退款"));
|
||||||
|
// 更新支付订单状态为退款中
|
||||||
|
payOrderMapper.updateById(PayOrder.builder()
|
||||||
|
.id(payOrder.getId())
|
||||||
|
.transState(TransState.REFUND_PENDING.getCode())
|
||||||
|
.build());
|
||||||
EasyPayRequestHeader reqHeader = generateEasyPayRequestHeader();
|
EasyPayRequestHeader reqHeader = generateEasyPayRequestHeader();
|
||||||
RefundApplyReqBody refundApplyReqBody = RefundApplyReqBody.builder()
|
RefundApplyReqBody refundApplyReqBody = RefundApplyReqBody.builder()
|
||||||
.reqInfo(ReqInfo.builder().mchtCode(easypayConfig.getMchtCode()).build())
|
.reqInfo(ReqInfo.builder().mchtCode(easypayConfig.getMchtCode()).build())
|
||||||
@ -486,7 +509,7 @@ public class EasypayServiceImpl implements IEasypayService {
|
|||||||
.reqOrderInfo(RefundReqOrderInfo.builder()
|
.reqOrderInfo(RefundReqOrderInfo.builder()
|
||||||
.orgTrace(StrBuilder.create(TRACE_PREFIX).append(System.currentTimeMillis()).append(RandomUtil.randomString(4)).toString())
|
.orgTrace(StrBuilder.create(TRACE_PREFIX).append(System.currentTimeMillis()).append(RandomUtil.randomString(4)).toString())
|
||||||
.oriOrgTrace(String.valueOf(order.getPayId()))
|
.oriOrgTrace(String.valueOf(order.getPayId()))
|
||||||
.oriTransDate(DateUtils.parseDateToStr(FormatsType.YYYYMMDD,payOrder.getStartTransDate()))
|
.oriTransDate(DateUtils.parseDateToStr(FormatsType.YYYYMMDD, payOrder.getEndTransDate()))
|
||||||
.refundAmount(payOrder.getTransAmount())
|
.refundAmount(payOrder.getTransAmount())
|
||||||
.build())
|
.build())
|
||||||
.build();
|
.build();
|
||||||
@ -496,15 +519,165 @@ public class EasypayServiceImpl implements IEasypayService {
|
|||||||
.reqBody(refundApplyReqBody)
|
.reqBody(refundApplyReqBody)
|
||||||
.reqSign(reqSign)
|
.reqSign(reqSign)
|
||||||
.build();
|
.build();
|
||||||
log.debug("调用易生实时退款接口请求:{}",JSONObject.toJSONString(easyRequest));
|
log.debug("调用易生实时退款接口请求:{}", JSONObject.toJSONString(easyRequest));
|
||||||
String url = StrBuilder.create(easypayConfig.getApiPathPrefix()).append("/trade/refund/apply").toString();
|
String url = StrBuilder.create(easypayConfig.getApiPathPrefix()).append("/trade/refund/apply").toString();
|
||||||
String body = HttpRequest.post(url)
|
String body = HttpRequest.post(url)
|
||||||
.timeout(3000)
|
.timeout(3000)
|
||||||
.body(JSON.toJSONString(easyRequest))
|
.body(JSON.toJSONString(easyRequest))
|
||||||
.execute()
|
.execute()
|
||||||
.body();
|
.body();
|
||||||
log.debug("调用易实时退款接口响应:{}",body);
|
log.debug("调用易实时退款接口响应:{}", body);
|
||||||
RefundApplyRespBody refundApplyRespBody = JSONObject.parseObject(body, RefundApplyRespBody.class);
|
EasyPayResponse easyPayResponse = JSONObject.parseObject(body, EasyPayResponse.class);
|
||||||
|
if (StrUtil.equals(RSP_HEADER_OK, easyPayResponse.getRspHeader().getRspCode())) {
|
||||||
|
verify(easyPayResponse.getRspHeader(), easyPayResponse.getRspBody(), easyPayResponse.getRspSign());
|
||||||
|
RefundApplyRespBody refundApplyRespBody = JSON.parseObject(JSONObject.toJSONString(easyPayResponse.getRspBody()), RefundApplyRespBody.class);
|
||||||
|
RespStateInfo respStateInfo = refundApplyRespBody.getRespStateInfo();
|
||||||
|
if (StrUtil.equals(RSP_BODY_RESP_OK, respStateInfo.getRespCode())) {
|
||||||
|
if (StrUtil.equalsAny(respStateInfo.getTransState(), RSP_BODY_TRANS_OK)) {
|
||||||
|
// 更新支付单退款状态
|
||||||
|
payOrderMapper.updateById(PayOrder.builder().id(payOrder.getId()).transState(TransState.REFUNDED.getCode()).build());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.error("易生退款失败:{}", respStateInfo.getRespDesc());
|
||||||
|
payOrderMapper.updateById(PayOrder.builder().id(payOrder.getId()).transState(TransState.PAID.getCode()).build());
|
||||||
|
throw new ServiceException("易生退款失败:" + respStateInfo.getRespDesc());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.error("易生退款通讯失败:{}", easyPayResponse.getRspHeader().getRspInfo());
|
||||||
|
payOrderMapper.updateById(PayOrder.builder().id(payOrder.getId()).transState(TransState.PAID.getCode()).build());
|
||||||
|
throw new ServiceException("易生退款通讯失败:" + easyPayResponse.getRspHeader().getRspInfo());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EasypayTransResultVO refundQuery(Long orderId) {
|
||||||
|
Order order = orderMapper.selectById(orderId);
|
||||||
|
Assert.notNull(order, () -> new ServiceException("订单不存在"));
|
||||||
|
PayOrder payOrder = payOrderMapper.selectById(order.getPayId());
|
||||||
|
Assert.notNull(payOrder, () -> new ServiceException("订单不存在"));
|
||||||
|
EasypayTransResultVO easypayTransResultVO = EasypayTransResultVO.builder()
|
||||||
|
.orderId(order.getId())
|
||||||
|
.payId(payOrder.getId())
|
||||||
|
.totalAmount(order.getTotalAmount())
|
||||||
|
.transState(payOrder.getTransState())
|
||||||
|
.build();
|
||||||
|
if (payOrder.getTransState() == TransState.REFUNDED.getCode()) {
|
||||||
|
return easypayTransResultVO;
|
||||||
|
}
|
||||||
|
Assert.isTrue(payOrder.getTransState() == TransState.PAID.getCode() || payOrder.getTransState() == TransState.REFUND_PENDING.getCode(), () -> new ServiceException("订单未支付"));
|
||||||
|
EasyPayRequestHeader reqHeader = generateEasyPayRequestHeader();
|
||||||
|
RefundApplyReqBody refundApplyReqBody = RefundApplyReqBody.builder()
|
||||||
|
.reqInfo(ReqInfo.builder().mchtCode(easypayConfig.getMchtCode()).build())
|
||||||
|
.payInfo(PayInfo.builder().transDate(DateUtils.parseDateToStr(FormatsType.YYYYMMDD, new Date())).build())
|
||||||
|
.reqOrderInfo(RefundReqOrderInfo.builder()
|
||||||
|
.orgTrace(StrBuilder.create(TRACE_PREFIX).append(System.currentTimeMillis()).append(RandomUtil.randomString(4)).toString())
|
||||||
|
.oriOrgTrace(String.valueOf(order.getPayId()))
|
||||||
|
.oriTransDate(DateUtils.parseDateToStr(FormatsType.YYYYMMDD, payOrder.getEndTransDate()))
|
||||||
|
.refundAmount(payOrder.getTransAmount())
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
String reqSign = getSignStr(reqHeader, refundApplyReqBody);
|
||||||
|
EasyPayRequest easyRequest = EasyPayRequest.builder()
|
||||||
|
.reqHeader(reqHeader)
|
||||||
|
.reqBody(refundApplyReqBody)
|
||||||
|
.reqSign(reqSign)
|
||||||
|
.build();
|
||||||
|
log.debug("调用易生实时退款接口请求:{}", JSONObject.toJSONString(easyRequest));
|
||||||
|
String url = StrBuilder.create(easypayConfig.getApiPathPrefix()).append("/trade/refund/query").toString();
|
||||||
|
String body = HttpRequest.post(url)
|
||||||
|
.timeout(3000)
|
||||||
|
.body(JSON.toJSONString(easyRequest))
|
||||||
|
.execute()
|
||||||
|
.body();
|
||||||
|
log.debug("调用易实时退款接口响应:{}", body);
|
||||||
|
EasyPayResponse easyPayResponse = JSONObject.parseObject(body, EasyPayResponse.class);
|
||||||
|
if (StrUtil.equals(RSP_HEADER_OK, easyPayResponse.getRspHeader().getRspCode())) {
|
||||||
|
verify(easyPayResponse.getRspHeader(), easyPayResponse.getRspBody(), easyPayResponse.getRspSign());
|
||||||
|
RefundApplyRespBody refundApplyRespBody = JSON.parseObject(JSONObject.toJSONString(easyPayResponse.getRspBody()), RefundApplyRespBody.class);
|
||||||
|
RespStateInfo respStateInfo = refundApplyRespBody.getRespStateInfo();
|
||||||
|
if (StrUtil.equals(RSP_BODY_RESP_OK, respStateInfo.getRespCode())) {
|
||||||
|
if (StrUtil.equalsAny(respStateInfo.getTransState(), RSP_BODY_TRANS_OK)) {
|
||||||
|
easypayTransResultVO.setTransState(TransState.REFUNDED.getCode());
|
||||||
|
// 更新支付单退款状态
|
||||||
|
payOrderMapper.updateById(PayOrder.builder().id(payOrder.getId()).transState(TransState.REFUNDED.getCode()).build());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.error("查询支付结果失败:{}", respStateInfo.getRespDesc());
|
||||||
|
throw new ServiceException("查询支付结果失败:" + respStateInfo.getRespDesc());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.error("查询支付结果通讯失败:{}", easyPayResponse.getRspHeader().getRspInfo());
|
||||||
|
throw new ServiceException("查询支付结果通讯失败:" + easyPayResponse.getRspHeader().getRspInfo());
|
||||||
|
}
|
||||||
|
return easypayTransResultVO;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SeparateApplyBO separateApply(SeparateApplyBO separateApplyBO) {
|
||||||
|
EasyPayRequestHeader reqHeader = generateEasyPayRequestHeader();
|
||||||
|
List<SeparateInfo.SeparateOrderDetailList> separateOrderDetailListList = separateApplyBO.getSeparateItemBOList().stream().map(item -> BeanUtil.copyProperties(item, SeparateInfo.SeparateOrderDetailList.class)).toList();
|
||||||
|
SeparateApplyReqBody separateApplyReqBody = SeparateApplyReqBody.builder()
|
||||||
|
.reqInfo(ReqInfo.builder().mchtCode(easypayConfig.getMchtCode()).build())
|
||||||
|
.payInfo(PayInfo.builder().transDate(DateUtils.parseDateToStr(FormatsType.YYYYMMDD, new Date())).build())
|
||||||
|
.reqOrderInfo(SeparateReqOrderInfo.builder()
|
||||||
|
.backUrl(easypayConfig.getSeparateBackUrl())
|
||||||
|
.oriOrgTrace(String.valueOf(separateApplyBO.getPayId()))
|
||||||
|
.oriTransDate(DateUtils.parseDateToStr(FormatsType.YYYYMMDD, separateApplyBO.getTransDate()))
|
||||||
|
.separateBatchTrace(separateApplyBO.getSeparateBatchTrace())
|
||||||
|
.transSumAmt(separateApplyBO.getTransSumAmt())
|
||||||
|
.transSumCount(separateApplyBO.getSeparateItemBOList().size())
|
||||||
|
.separateOrderDetailList(separateOrderDetailListList)
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
String reqSign = getSignStr(reqHeader, separateApplyReqBody);
|
||||||
|
EasyPayRequest easyRequest = EasyPayRequest.builder()
|
||||||
|
.reqHeader(reqHeader)
|
||||||
|
.reqBody(separateApplyReqBody)
|
||||||
|
.reqSign(reqSign)
|
||||||
|
.build();
|
||||||
|
log.debug("调用易生请求分账接口请求:{}", JSONObject.toJSONString(easyRequest));
|
||||||
|
String url = StrBuilder.create(easypayConfig.getApiPathPrefix()).append("/trade/separate/orderApply").toString();
|
||||||
|
String body = HttpRequest.post(url)
|
||||||
|
.timeout(3000)
|
||||||
|
.body(JSON.toJSONString(easyRequest))
|
||||||
|
.execute()
|
||||||
|
.body();
|
||||||
|
log.debug("调用易生请求分账接口响应:{}", body);
|
||||||
|
EasyPayResponse easyPayResponse = JSONObject.parseObject(body, EasyPayResponse.class);
|
||||||
|
if (StrUtil.equals(RSP_HEADER_OK, easyPayResponse.getRspHeader().getRspCode())) {
|
||||||
|
verify(easyPayResponse.getRspHeader(), easyPayResponse.getRspBody(), easyPayResponse.getRspSign());
|
||||||
|
SeparateApplyRespBody separateApplyRespBody = JSON.parseObject(JSONObject.toJSONString(easyPayResponse.getRspBody()), SeparateApplyRespBody.class);
|
||||||
|
RespStateInfo respStateInfo = separateApplyRespBody.getRespStateInfo();
|
||||||
|
if (StrUtil.equals(RSP_BODY_RESP_OK, respStateInfo.getRespCode())) {
|
||||||
|
if (StrUtil.equalsAny(respStateInfo.getTransState(), RSP_BODY_TRANS_OK)) {
|
||||||
|
// 更新分账状态
|
||||||
|
SeparateRespOrderInfo respOrderInfo = separateApplyRespBody.getRespOrderInfo();
|
||||||
|
handleSeparateInfo(separateApplyBO, respOrderInfo);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.error("请求分账失败:{}", respStateInfo.getRespDesc());
|
||||||
|
throw new ServiceException("请求分账失败:" + respStateInfo.getRespDesc());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.error("易生请求分账通讯失败:{}", easyPayResponse.getRspHeader().getRspInfo());
|
||||||
|
throw new ServiceException("易生请求分账通讯失败:" + easyPayResponse.getRspHeader().getRspInfo());
|
||||||
|
}
|
||||||
|
return separateApplyBO;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleSeparateCallback(EasyPayRequest easyPayRequest) {
|
||||||
|
// TODO 处理回调分账结果信息,更新分账详情表
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理分账结果信息,更新分账详情表
|
||||||
|
* @param respOrderInfo
|
||||||
|
*/
|
||||||
|
private SeparateApplyBO handleSeparateInfo(SeparateApplyBO separateApplyBO, SeparateRespOrderInfo respOrderInfo) {
|
||||||
|
//TODO 处理分账结果信息,更新分账详情表
|
||||||
|
return separateApplyBO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package com.wzj.soopin.transaction.service.impl;
|
package com.wzj.soopin.transaction.service.impl;
|
||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import java.util.List;
|
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.wzj.soopin.transaction.domain.po.PayOrder;
|
import com.wzj.soopin.transaction.domain.po.PayOrder;
|
||||||
import com.wzj.soopin.transaction.mapper.PayOrderMapper;
|
import com.wzj.soopin.transaction.mapper.PayOrderMapper;
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
package com.wzj.soopin.transaction.service.impl;
|
package com.wzj.soopin.transaction.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.hutool.core.text.StrBuilder;
|
import cn.hutool.core.text.StrBuilder;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.http.HttpRequest;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.wzj.soopin.transaction.domain.entity.WxAuthResponse;
|
import com.wzj.soopin.transaction.domain.entity.WxAuthResponse;
|
||||||
import com.wzj.soopin.transaction.config.WechatMiniProgramConfig;
|
import com.wzj.soopin.transaction.config.WechatMiniProgramConfig;
|
||||||
import com.wzj.soopin.transaction.wechat.WechatPayConfig;
|
import com.wzj.soopin.transaction.wechat.WechatPayConfig;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.dromara.common.core.exception.ServiceException;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
@ -55,10 +60,10 @@ public class WxAuthService {
|
|||||||
.append(code)
|
.append(code)
|
||||||
.append("&grant_type=authorization_code")
|
.append("&grant_type=authorization_code")
|
||||||
.toString();
|
.toString();
|
||||||
WxAuthResponse response = restTemplate.getForObject(url, WxAuthResponse.class);
|
String body = HttpRequest.get(url).timeout(3000).execute().body();
|
||||||
if (response == null || response.getOpenid() == null) {
|
Assert.notBlank(body, () -> new ServiceException("微信小程序登录异常"));
|
||||||
throw new RuntimeException("Failed to get openid from WeChat");
|
WxAuthResponse response = JSONObject.parseObject(body, WxAuthResponse.class);
|
||||||
}
|
Assert.notBlank(response.getOpenid(), () -> new ServiceException("微信小程序登录异常:" + response.getErrmsg()));
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user