## Feat - 京东支付

This commit is contained in:
sangelxiu1 2025-07-01 14:57:00 +08:00
parent a781afc437
commit c037c4b535
24 changed files with 1286 additions and 14 deletions

View File

@ -0,0 +1,72 @@
package com.hzs.common.domain.third.pay;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableField;
import com.hzs.common.core.web.domain.BaseEntity;
import lombok.*;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
import java.util.List;
/**
* <p>
* 支付请求主表
* </p>
*
* @author bd
* @since 2025-07-01
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("T_ONLINE_PAYMENT_SEP_ACC")
@KeySequence("T_ONLINE_PAYMENT_SEP_ACC_SEQ")
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TOnlinePaymentSepAcc extends BaseEntity {
private static final long serialVersionUID = 1L;
@TableId("PK_ID")
private Long pkId;
/**
* 在线支付信息ID
*/
@TableField("PK_PAYMENT")
private Long pkPayment;
/**
* 版本号
*/
@TableField("VERSION")
private String version;
/**
* 支付请求信息
*/
@TableField("REQ_CONTENT")
private String reqContent;
/**
* 分账请求信息
*/
@TableField("REQ_CONTENT_SEP_ACC")
private String reqContentSepAcc;
/**
* 支付响应信息
*/
@TableField("RESP_CONTENT")
private String respContent;
@TableField("TRADE_AMOUNT")
private BigDecimal tradeAmount;
@TableField(exist = false)
private List<TOnlinePaymentSepAccD> sepAccDList;
}

View File

@ -0,0 +1,56 @@
package com.hzs.common.domain.third.pay;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableField;
import com.hzs.common.core.web.domain.BaseEntity;
import lombok.*;
import lombok.experimental.Accessors;
/**
* <p>
* 支付请求子表(分账)
* </p>
*
* @author bd
* @since 2025-07-01
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("T_ONLINE_PAYMENT_SEP_ACC_D")
@KeySequence("T_ONLINE_PAYMENT_SEP_ACC_D_SEQ")
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TOnlinePaymentSepAccD extends BaseEntity {
private static final long serialVersionUID = 1L;
@TableId("PK_ID")
private Long pkId;
/**
* 支付请求主表ID
*/
@TableField("PK_SEP_ACC")
private Long pkSepAcc;
/**
* 分账账号
*/
@TableField("ACCOUNT")
private String account;
/**
* 分账比例
*/
@TableField("PROPORTION")
private BigDecimal proportion;
@TableField("TRADE_AMOUNT")
private BigDecimal tradeAmount;
}

View File

@ -0,0 +1,17 @@
package com.hzs.third.pay.config;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
@Setter
@Getter
@Component
@ConfigurationProperties(prefix = "jd.pay") // 绑定jd.pay前缀的配置
public class JdPayProperties {
private List<JdPaySeparateAccountConfig> separateAccounts;
}

View File

@ -0,0 +1,14 @@
package com.hzs.third.pay.config;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
@Data
public class JdPaySeparateAccountConfig implements Serializable {
private String account;
@JsonFormat(shape = JsonFormat.Shape.STRING)
private BigDecimal proportion;
}

View File

@ -0,0 +1,91 @@
package com.hzs.third.pay.controller.api;
import com.hzs.common.core.enums.EPayChannel;
import com.hzs.common.core.enums.EPayStatus;
import com.hzs.common.core.utils.StringUtils;
import com.hzs.common.core.web.domain.AjaxResult;
import com.hzs.common.domain.third.pay.TOnlinePayment;
import com.hzs.common.security.utils.SecurityUtils;
import com.hzs.third.pay.controller.base.PayBaseController;
import com.hzs.third.pay.dto.RefundDTO;
import com.hzs.third.pay.param.PayParam;
import com.hzs.third.pay.service.IRefundService;
import com.hzs.third.pay.service.ITOnlinePaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Description: 京东退款控制器
* @Author: jiang chao
* @Time: 2023/8/17 15:11
* @Classname: JdRefundController
* @PackageName: com.hzs.third.pay.controller.api
*/
@Slf4j
@RestController
@RequestMapping("/jd-refund")
public class JdRefundController extends PayBaseController {
@Autowired
private IRefundService iRefundService;
@Autowired
private ITOnlinePaymentService itOnlinePaymentService;
/**
* 京东退款接口
*
* @param param
* @return
*/
@PostMapping("/refund")
public AjaxResult refund(@RequestBody PayParam param) {
if (null == param.getBusinessType() || StringUtils.isEmpty(param.getBusinessCode())) {
// 缺少参数
return AjaxResult.error("缺少参数");
}
// 查询在线支付明细
TOnlinePayment tOnlinePayment = itOnlinePaymentService.queryByBusiness(param.getBusinessType(), param.getBusinessCode(), SecurityUtils.getPkCountry());
if (null == tOnlinePayment || EPayStatus.UNPAID.getValue() == tOnlinePayment.getPayStatus()) {
// 在线支付明细为空 或者 未支付成功则不能进行退款
return AjaxResult.error("订单不存在或未支付成功,不能进行退款");
}
// 获取支付渠道
EPayChannel ePayChannel = EPayChannel.getEnumByValue(tOnlinePayment.getPayChannel());
if (null == ePayChannel) {
return AjaxResult.error("订单支付信息有误,不能进行退款");
}
try {
// 京东收银台退款处理
String str = iRefundService.jdCashRefundHandle(RefundDTO.builder()
.businessType(param.getBusinessType())
.businessCode(param.getBusinessCode())
.refundAmount(tOnlinePayment.getPayMoney())
.userId(SecurityUtils.getUserId())
.pkCountry(SecurityUtils.getPkCountry())
.build(),
tOnlinePayment);
// 京东银行卡退款处理 --
// String str = iRefundService.jdRefundHandle(RefundDTO.builder()
// .businessType(param.getBusinessType())
// .businessCode(param.getBusinessCode())
// .refundAmount(tOnlinePayment.getPayMoney())
// .userId(SecurityUtils.getUserId())
// .pkCountry(SecurityUtils.getPkCountry())
// .build(),
// tOnlinePayment);
if (null == str) {
return AjaxResult.success();
}
return AjaxResult.error("退款失败:" + str);
} catch (Exception e) {
log.error("调用京东退款处理返回异常!", e);
return AjaxResult.error("退款异常,请刷新后重试");
}
}
}

View File

@ -252,8 +252,8 @@ public class PayController {
if (null != payResult) {
if (payResult.isSuccess()) {
// 实际支付金额在支付之前不需要入库实际以取支付回调为准
onlinePayment.setPayMoney(null);
itOnlinePaymentService.saveOrUpdate(onlinePayment);
// onlinePayment.setPayMoney(null);
// itOnlinePaymentService.saveOrUpdate(onlinePayment);
return AjaxResult.success(payResult.getData());
}
@ -275,13 +275,13 @@ public class PayController {
}
// 业务类型校验业务类型
EPayBusinessType ePayBusinessType = EPayBusinessType.getEnumByValue(param.getBusinessType());
if (null == ePayBusinessType) {
return AjaxResult.success("支付业务类型错误", 0);
}
// EPayBusinessType ePayBusinessType = EPayBusinessType.getEnumByValue(param.getBusinessType());
// if (null == ePayBusinessType) {
// return AjaxResult.success("支付业务类型错误", 0);
// }
QueryWrapper<TOnlinePayment> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("BUSINESS_TYPE", param.getBusinessType());
// queryWrapper.eq("BUSINESS_TYPE", param.getBusinessType());
queryWrapper.eq("BUSINESS_CODE", param.getBusinessCode());
TOnlinePayment onlinePayment = itOnlinePaymentService.getOne(queryWrapper);
if (null == onlinePayment) {

View File

@ -0,0 +1,210 @@
package com.hzs.third.pay.controller.notify;
import cn.hutool.json.JSONUtil;
import com.hzs.common.core.enums.EPayChannel;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.third.pay.config.JdPayConfig;
import com.hzs.third.pay.constants.JdPayConstants;
import com.hzs.third.pay.controller.base.JdBaseController;
import com.hzs.third.pay.dto.jd.JdPayNotifyBody;
import com.hzs.third.pay.jdpay.dto.JdPayTradeSuccessNotify;
import com.hzs.third.pay.jdpay.sdk.JdPay;
import com.hzs.third.pay.jdpay.util.GsonUtil;
import com.hzs.third.pay.service.IPayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
/**
* 京东支付回调控制器
*/
@Slf4j
@RestController
@RequestMapping("/jd")
public class JdPayNotifyController extends JdBaseController {
@Autowired
private JdPayConfig jdPayConfig;
@Autowired
private IPayService iPayService;
/**
* 京东支付回调
*
* @param request
*/
@PostMapping("/notify")
public String notify(HttpServletRequest request) {
try {
String reqBody = this.getRequestBody(request);
log.info("京东支付回调! body {}", reqBody);
if (this.checkToken(request, reqBody, jdPayConfig.getSecretKey())) {
// 签名校验通过
JdPayNotifyBody notifyBody = JSONUtil.toBean(reqBody, JdPayNotifyBody.class);
// 支付流水号
String payNumber = notifyBody.getOrderNum();
// 支付时间
Date payTime = DateUtils.parseDate(notifyBody.getCompleteTime(), DateUtils.YYYY_MM_DD_HH_MM_SS);
// 支付金额
BigDecimal payMoney = new BigDecimal(notifyBody.getOrderAmount());
// 支付扩展类型
String type = notifyBody.getExtraInfo();
// 回调订单编号
String thirdOrderCode = notifyBody.getRequestNum();
// 支付信息编号
String orderCode = thirdOrderCode;
// 处理订单号以及扩展类型
if (orderCode.indexOf("-") > 0) {
// 带有分隔需要处理
orderCode = orderCode.split("-")[0];
}
// 支付后续业务处理
if (iPayService.notifyHandle(type, orderCode, thirdOrderCode, payNumber, payTime, payMoney, EPayChannel.JD, "")) {
return JdPayConstants.RETURN_SUCCESS;
}
} else {
log.error("京东支付回调签名校验失败!");
}
} catch (Exception e) {
log.error("京东支付回调处理异常", e);
}
return JdPayConstants.RETURN_FAIL;
}
@Resource
private JdPay jdPay;
/**
* 京东收银台处理成功返回
*/
private static final String SUCCESS = "SUCCESS";
/**
* 京东收银台处理失败返回
*/
private static final String ERROR = "ERROR";
/**
* 京东收银台异步支付回调
*
* @param reqText
* @return 成功返回"SUCCESS", 失败返回"ERROR",京东支付会再次发起通知通知频次见接口文档
*/
@PostMapping("/trade-notify")
public String tradeNotify(@RequestBody String reqText) {
log.info("京东收银台支付异步回调! reqText {}", reqText);
try {
// 验证签名与解密
String interData = jdPay.verifyResponse(reqText);
JdPayTradeSuccessNotify successNotify = GsonUtil.fromJson(interData, JdPayTradeSuccessNotify.class);
if (null != successNotify) {
if ("FINI".equals(successNotify.getTradeStatus())) {
// 支付成功处理
// 商户订单号
String payNumber = successNotify.getTradeNo();
// 渠道流水号
String channelNumber = "";
// 支付完成时间
Date payTime = DateUtils.parseDateOne(successNotify.getFinishDate(), DateUtils.YAMMERERS);
// 支付扩展类型
String type = successNotify.getReturnParams();
// 回调订单编号
String thirdOrderCode = successNotify.getOutTradeNo();
// 订单编号
String orderCode = thirdOrderCode;
// 订单金额
int tradeAmount = Integer.parseInt(successNotify.getTradeAmount());
BigDecimal payMoney = new BigDecimal(tradeAmount).divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_UP);
// 支付后续业务处理
if (iPayService.notifyHandle(type, orderCode, thirdOrderCode, payNumber, payTime, payMoney, EPayChannel.JD, channelNumber)) {
return SUCCESS;
}
} else {
log.error("京东收银台支付异步回调失败resultDesc: {}", successNotify.getResultDesc());
}
} else {
log.error("京东收银台支付异步回调解密为空");
}
} catch (Exception e) {
log.error("京东收银台支付异步回调异常", e);
}
return ERROR;
}
/**
* 京东收银台页面回调
*
* @param request
* @return
*/
@PostMapping("/sync-notify")
public String syncNotify(HttpServletRequest request) {
// 签名验证逻辑需要支持添加通知字段不影响结果
Map<String, String> respMap = getAllRequestParam(request);
log.info("京东收银台支付页面回调! request: {}", respMap);
try {
if (jdPay.verifyPageCallBack(respMap)) {
if ("FINI".equals(respMap.get("status"))) {
// todo 支付成功
return SUCCESS;
} else if ("WPAR".equals(respMap.get("status"))) {
// todo 支付处理中
log.error("京东支付页面回调,支付处理中");
} else {
// todo 支付失败
log.error("京东支付页面回调,支付失败");
}
} else {
// 签名异常报错
log.error("京东收银台支付页面回调!签名异常!");
}
} catch (Exception e) {
log.error("京东支付页面回调参数", e);
}
return ERROR;
}
/**
* 获取客户端请求参数中所有的信息
*/
private Map<String, String> getAllRequestParam(final HttpServletRequest request) {
Map<String, String> respMap = new HashMap<>();
Enumeration<?> temp = request.getParameterNames();
if (null != temp) {
while (temp.hasMoreElements()) {
String en = (String) temp.nextElement();
String value = request.getParameter(en);
respMap.put(en, value);
//如果字段的值为空判断若值为空则删除这个字段>
if (null == respMap.get(en) || "".equals(respMap.get(en))) {
respMap.remove(en);
}
}
}
return respMap;
}
}

View File

@ -0,0 +1,148 @@
package com.hzs.third.pay.controller.notify;
import cn.hutool.json.JSONUtil;
import com.hzs.common.core.enums.EPayChannel;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.third.pay.config.JdPayConfig;
import com.hzs.third.pay.constants.JdPayConstants;
import com.hzs.third.pay.controller.base.JdBaseController;
import com.hzs.third.pay.jdpay.dto.JdPayRefundSuccessNotify;
import com.hzs.third.pay.jdpay.sdk.JdPay;
import com.hzs.third.pay.jdpay.util.GsonUtil;
import com.hzs.third.pay.service.IRefundService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @Description: 京东退填回调控制器
* @Author: jiang chao
* @Time: 2023/8/17 15:50
* @Classname: JdRefundNotifyController
* @PackageName: com.hzs.third.pay.controller.notify
*/
@Slf4j
@RestController
@RequestMapping("/jd-refund")
public class JdRefundNotifyController extends JdBaseController {
@Autowired
private JdPayConfig jdPayConfig;
@Autowired
private IRefundService iRefundService;
/**
* 京东退款回调
*
* @param request
* @return
* @throws Exception
*/
@PostMapping("/notify")
public String refundNotify(HttpServletRequest request) {
try {
String reqBody = this.getRequestBody(request);
log.info("京东退款回调! body {}", reqBody);
if (this.checkToken(request, reqBody, jdPayConfig.getSecretKey())) {
// 签名校验通过
Map<String, String> dataMap = JSONUtil.toBean(reqBody, HashMap.class);
// 退款编号
String refundCode = dataMap.get("refundRequestNum");
// 京东交易流水号
String refundNumber = dataMap.get("orderNum");
// 退款完成时间
Date finishTime = DateUtils.parseDate(dataMap.get("refundSuccessTime"), DateUtils.YYYY_MM_DD_HH_MM_SS);
// 退款金额
BigDecimal finishMoney = new BigDecimal(dataMap.get("refundAmount"));
if (JdPayConstants.ORDER_SUCCESS.equals(dataMap.get("refundStatus"))) {
// 退款成功
// 退款后续业务处理
if (iRefundService.notifyHandle(EPayChannel.JD, refundCode, refundNumber, finishTime, finishMoney)) {
return JdPayConstants.RETURN_SUCCESS;
}
} else {
// 退款失败
log.error("京东退款失败: {}", dataMap.get("failReason"));
if (iRefundService.notifyErrorHandle(EPayChannel.JD, refundCode, refundNumber, dataMap.get("failReason"))) {
return JdPayConstants.RETURN_SUCCESS;
}
}
} else {
log.error("京东支付回调签名校验失败!");
}
} catch (Exception e) {
log.error("京东支付回调处理异常", e);
}
return JdPayConstants.RETURN_FAIL;
}
@Resource
private JdPay jdPay;
/**
* 京东收银台处理成功返回
*/
private static final String SUCCESS = "SUCCESS";
/**
* 京东收银台处理失败返回
*/
private static final String ERROR = "ERROR";
/**
* 京东收银台退款异步支付回调
*
* @param reqText
* @return 成功返回"SUCCESS", 失败返回"ERROR",退款通知会再次发起通知通知频次见接口文档
*/
@PostMapping("/trade-notify")
public String tradeNotify(@RequestBody String reqText) {
log.info("京东收银台退款异步回调! reqText {}", reqText);
try {
// 验证签名与解密
String interData = jdPay.verifyResponse(reqText);
JdPayRefundSuccessNotify successNotify = GsonUtil.fromJson(interData, JdPayRefundSuccessNotify.class);
if (null != successNotify) {
if ("FINI".equals(successNotify.getTradeStatus())) {
// 退款编号
String refundCode = successNotify.getOutTradeNo();
// 京东交易流水号
String refundNumber = successNotify.getTradeNo();
// 退款完成时间
Date finishTime = DateUtils.parseDate(successNotify.getFinishDate(), DateUtils.YAMMERERS);
// 退款金额
int tradeAmount = Integer.parseInt(successNotify.getTradeAmount());
BigDecimal finishMoney = new BigDecimal(tradeAmount).divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_UP);
// 退款后续业务处理
if (iRefundService.notifyHandle(EPayChannel.JD, refundCode, refundNumber, finishTime, finishMoney)) {
return SUCCESS;
}
} else {
log.error("京东收银台退款异步回调失败resultDesc: {}", successNotify.getResultDesc());
}
} else {
log.error("京东收银台退款异步回调解密为空");
}
} catch (Exception e) {
log.error("京东收银台退款异步回调异常", e);
}
return ERROR;
}
}

View File

@ -0,0 +1,66 @@
package com.hzs.third.pay.jdpay.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @Description: 退款成功通知
* @Author: jiang chao
* @Time: 2025/3/21 10:24
* @Classname: JdPayRefundSuccessNotify
* @PackageName: com.hzs.third.pay.jdpay.dto
*/
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
public class JdPayRefundSuccessNotify implements Serializable {
/**
* 业务结果
*/
private String resultCode;
/**
* 响应描述
*/
private String resultDesc;
/**
* 京东退款订单号
*/
private String tradeNo;
/**
* 商户退款订单号
*/
private String outTradeNo;
/**
* 商户原正单订单号
*/
private String originalOutTradeNo;
/**
* 订单总金额
*/
private String tradeAmount;
/**
* 退款完成时间
*/
private String finishDate;
/**
* 交易状态
*/
private String tradeStatus;
/**
* 回传字段
*/
private String returnParams;
/**
* 币种
*/
private String currency;
}

View File

@ -0,0 +1,98 @@
package com.hzs.third.pay.jdpay.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @Description: 交易成功通知
* @Author: jiang chao
* @Time: 2025/3/21 10:24
* @Classname: JdPayRefundSuccessNotify
* @PackageName: com.hzs.third.pay.jdpay.dto
*/
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
public class JdPayTradeSuccessNotify implements Serializable {
/**
* 业务结果
*/
private String resultCode;
/**
* 响应描述
*/
private String resultDesc;
/**
* 京东交易订单号
*/
private String tradeNo;
/**
* 商户订单号
*/
private String outTradeNo;
/**
* 订单总金额
*/
private String tradeAmount;
/**
* 币种
*/
private String currency;
/**
* 支付完成时间
*/
private String finishDate;
/**
* 交易类型
*/
private String tradeType;
/**
* 交易状态
*/
private String tradeStatus;
/**
* 回传字段
*/
private String returnParams;
/**
* 请求的端
*/
private String clientType;
/**
* 商户用户标识
*/
private String userId;
/**
* 优惠金额
*/
private String discountAmount;
/**
* 支付工具
*/
private String payTool;
/**
* 掩码卡号
*/
private String maskCardNo;
/**
* 卡类型
*/
private String cardType;
/**
* 银行编码
*/
private String bankCode;
/**
* 白条分期数
*/
private String installmentNum;
}

View File

@ -0,0 +1,16 @@
package com.hzs.third.pay.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.hzs.common.domain.third.pay.TOnlinePaymentSepAccD;
/**
* <p>
* 支付请求子表(分账) Mapper 接口
* </p>
*
* @author bd
* @since 2025-07-01
*/
public interface TOnlinePaymentSepAccDMapper extends BaseMapper<TOnlinePaymentSepAccD> {
}

View File

@ -0,0 +1,16 @@
package com.hzs.third.pay.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.hzs.common.domain.third.pay.TOnlinePaymentSepAcc;
/**
* <p>
* 支付请求主表 Mapper 接口
* </p>
*
* @author bd
* @since 2025-07-01
*/
public interface TOnlinePaymentSepAccMapper extends BaseMapper<TOnlinePaymentSepAcc> {
}

View File

@ -44,4 +44,23 @@ public interface IRefundService {
*/
boolean notifyErrorHandle(EPayChannel ePayChannel, String refundCode, String refundNumber, String errorMsg);
/**
* 京东退款处理
*
* @param refundDTO 业务类型
* @param tOnlinePayment 退款对应支付信息
* @return
*/
String jdRefundHandle(RefundDTO refundDTO, TOnlinePayment tOnlinePayment);
/**
* 京东收银台退款处理
*
* @param refundDTO 业务类型
* @param tOnlinePayment 退款对应支付信息
* @return
*/
String jdCashRefundHandle(RefundDTO refundDTO, TOnlinePayment tOnlinePayment);
}

View File

@ -0,0 +1,16 @@
package com.hzs.third.pay.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.hzs.common.domain.third.pay.TOnlinePaymentSepAccD;
/**
* <p>
* 支付请求子表(分账) 服务类
* </p>
*
* @author bd
* @since 2025-07-01
*/
public interface ITOnlinePaymentSepAccDService extends IService<TOnlinePaymentSepAccD> {
}

View File

@ -0,0 +1,16 @@
package com.hzs.third.pay.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.hzs.common.domain.third.pay.TOnlinePaymentSepAcc;
/**
* <p>
* 支付请求主表 服务类
* </p>
*
* @author bd
* @since 2025-07-01
*/
public interface ITOnlinePaymentSepAccService extends IService<TOnlinePaymentSepAcc> {
void saveOrUpdateReq(TOnlinePaymentSepAcc tOnlinePaymentSepAcc);
}

View File

@ -1,5 +1,6 @@
package com.hzs.third.pay.service.impl;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.hzs.common.core.config.BdConfig;
import com.hzs.common.core.domain.R;
@ -9,7 +10,11 @@ import com.hzs.common.core.enums.EEnv;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.common.domain.third.pay.TOnlineCard;
import com.hzs.common.domain.third.pay.TOnlinePayment;
import com.hzs.common.domain.third.pay.TOnlinePaymentSepAcc;
import com.hzs.common.domain.third.pay.TOnlinePaymentSepAccD;
import com.hzs.third.pay.config.JdPayConfig;
import com.hzs.third.pay.config.JdPayProperties;
import com.hzs.third.pay.config.JdPaySeparateAccountConfig;
import com.hzs.third.pay.constants.JdPayConstants;
import com.hzs.third.pay.constants.PayRedisConstants;
import com.hzs.third.pay.dto.jd.JdFastDTO;
@ -20,9 +25,14 @@ import com.hzs.third.pay.enums.EJdAppType;
import com.hzs.third.pay.enums.EJdTerminalType;
import com.hzs.third.pay.jdpay.dto.JdPayAggregateCreateOrderRequest;
import com.hzs.third.pay.jdpay.dto.JdPayAggregateCreateOrderResponse;
import com.hzs.third.pay.jdpay.dto.JdPayDivisionAccount;
import com.hzs.third.pay.jdpay.dto.JdPayDivisionAccountTradeInfo;
import com.hzs.third.pay.jdpay.sdk.JdPay;
import com.hzs.third.pay.jdpay.util.GsonUtil;
import com.hzs.third.pay.service.IJdPayService;
import com.hzs.third.pay.service.ITOnlineCardService;
import com.hzs.third.pay.service.ITOnlinePaymentSepAccService;
import com.hzs.third.pay.service.ITOnlinePaymentService;
import com.hzs.third.pay.util.JdPayUtil;
import com.hzs.third.pay.util.PayUtil;
import lombok.extern.slf4j.Slf4j;
@ -34,6 +44,8 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
@ -49,9 +61,15 @@ public class JdPayServiceImpl implements IJdPayService {
private ITOnlineCardService itOnlineCardService;
@Resource
private JdPay jdPay;
@Autowired
private JdPayProperties jdPayProperties;
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private ITOnlinePaymentSepAccService itOnlinePaymentSepAccService;
@Autowired
private ITOnlinePaymentService itOnlinePaymentService;
/**
* 页面回调地址
@ -241,12 +259,24 @@ public class JdPayServiceImpl implements IJdPayService {
// 请求京东支付接口
JdPayAggregateCreateOrderResponse response = jdPay.aggregateCreateOrder(request);
TOnlinePaymentSepAcc sepAcc = TOnlinePaymentSepAcc.builder()
.sepAccDList(sepAccDList)
.reqContent(request.getDivisionAccount())
.reqContentSepAcc(JSONUtil.toJsonStr(divisionAccountTradeInfoList))
.version(divisionAccount.getVersion())
.respContent(JSONUtil.toJsonStr(response))
.tradeAmount(onlinePayment.getPayMoney())
.build();
if ("0000".equals(response.getResultCode())) {
// 请求响应成功
// 京东唯一订单号
onlinePayment.setPayNumber(response.getTradeNo());
// 将controller内入库逻辑移至此为止
onlinePayment.setPayMoney(null);
itOnlinePaymentService.saveOrUpdate(onlinePayment);
// 2025年7月1日 保存分账主表&子表
sepAcc.setPkPayment(onlinePayment.getPkId());
itOnlinePaymentSepAccService.saveOrUpdateReq(sepAcc);
if ("AGGRE_QR".equals(tradeType)) {
return R.ok(response.getQrCode());
}
@ -261,4 +291,5 @@ public class JdPayServiceImpl implements IJdPayService {
}
}
}

View File

@ -1,5 +1,6 @@
package com.hzs.third.pay.service.impl;
import cn.hutool.json.JSONUtil;
import com.hzs.common.core.domain.R;
import com.hzs.common.core.enums.*;
import com.hzs.common.core.utils.*;
@ -10,14 +11,20 @@ import com.hzs.sale.refund.ISaRefundServiceApi;
import com.hzs.third.pay.config.*;
import com.hzs.third.pay.constants.*;
import com.hzs.third.pay.dto.RefundDTO;
import com.hzs.third.pay.jdpay.dto.JdPayRefundRequest;
import com.hzs.third.pay.jdpay.dto.JdPayRefundResponse;
import com.hzs.third.pay.jdpay.sdk.JdPay;
import com.hzs.third.pay.service.IAllInPayService;
import com.hzs.third.pay.service.IRefundService;
import com.hzs.third.pay.service.ITOnlineRefundService;
import com.hzs.third.pay.util.JdPayUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.util.*;
@ -35,9 +42,17 @@ public class RefundServiceImpl implements IRefundService {
private IAllInPayService iAllInPayService;
@Autowired
private ITOnlineRefundService itOnlineRefundService;
@Autowired
private JdPayConfig jdPayConfig;
@DubboReference
ISaRefundServiceApi iSaRefundServiceApi;
@Value("${jd.pay.refundNotifyUrl}")
private String refundNotifyUrl;
@Resource
private JdPay jdPay;
@Override
public String allInRefundHandle(RefundDTO refundDTO, TOnlinePayment tOnlinePayment) {
@ -251,4 +266,135 @@ public class RefundServiceImpl implements IRefundService {
return false;
}
@Override
public String jdRefundHandle(RefundDTO refundDTO, TOnlinePayment tOnlinePayment) {
try {
// 退款金额默认按全款退
BigDecimal amount = tOnlinePayment.getPayMoney();
if (null != refundDTO.getRefundAmount()) {
// 如果传入实际退款金额则按实际退款金额处理
amount = refundDTO.getRefundAmount();
}
// 退款编号
String refundCode = CommonUtil.createSerialNumber(EOrderPrefix.REFUND_CODE);
Map<String, String> requestMap = new HashMap<>();
requestMap.put("version", JdPayConstants.PAY_VERSION);
// 商户编号
requestMap.put("customerNum", jdPayConfig.getCustomerNum());
// 店铺编号
requestMap.put("shopNum", jdPayConfig.getShopNum());
// 商户订单号
requestMap.put("requestNum", tOnlinePayment.getOriginalOrder());
// 商户退款订单号
requestMap.put("refundRequestNum", refundCode);
// 退款金额
requestMap.put("refundPartAmount", amount.toString());
// 退款回调地址
requestMap.put("callbackUrl", jdPayConfig.getRefundCallbackUrl());
String body = JSONUtil.toJsonStr(requestMap);
log.info("京东退款请求参数: {}", body);
String postResult = JdPayUtil.requestOrder(JdPayConstants.REFUND_ORDER, body, jdPayConfig.getSecretKey(), jdPayConfig.getAccessKey());
log.info("京东退款返回数据: {}", postResult);
Map<String, Object> resultMap = JSONUtil.toBean(postResult, HashMap.class);
if (JdPayConstants.RESULT_SUCCESS.equals(resultMap.get("result").toString())) {
// 返回成功
// 返回业务数据
cn.hutool.json.JSONObject jsonObject = JSONUtil.parseObj(resultMap.get("data"));
// 申请退款成功保存退款
TOnlineRefund tOnlineRefund = new TOnlineRefund();
tOnlineRefund.setRefundCode(refundCode);
tOnlineRefund.setPkOnlinePayment(tOnlinePayment.getPkId());
tOnlineRefund.setBusinessCode(refundDTO.getRefundBusinessCode());
tOnlineRefund.setRefundMoney(amount);
tOnlineRefund.setRefundChannel(tOnlinePayment.getPayChannel());
tOnlineRefund.setRefundNumber(jsonObject.getStr("orderNum"));
tOnlineRefund.setPkCountry(refundDTO.getPkCountry());
tOnlineRefund.setPkCreator(refundDTO.getUserId());
if (itOnlineRefundService.save(tOnlineRefund)) {
return null;
}
log.error("调用京东退款入库失败, tOnlineRefund: {}", tOnlineRefund);
} else {
log.error("调用京东退款返回失败:{}", resultMap.get("errorMsg"));
}
return "退款失败,请重试";
} catch (Exception e) {
log.error("调用京东退款处理返回异常!", e);
return "退款异常,请重试";
}
}
@Override
public String jdCashRefundHandle(RefundDTO refundDTO, TOnlinePayment tOnlinePayment) {
try {
// 退款金额默认按全款退
BigDecimal amount = tOnlinePayment.getPayMoney();
if (null != refundDTO.getRefundAmount()) {
// 如果传入实际退款金额则按实际退款金额处理
amount = refundDTO.getRefundAmount();
}
// 退款编号
String refundCode = CommonUtil.createSerialNumber(EOrderPrefix.REFUND_CODE);
// 当前时间
Date nowDate = new Date();
JdPayRefundRequest request = JdPayRefundRequest.builder()
// 退款订单号
.outTradeNo(refundCode)
// 原订单号需要退款的订单号
.originalOutTradeNo(tOnlinePayment.getBusinessCode())
// 退款时间
.tradeDate(DateUtils.parseDateToFormat(DateUtils.YAMMERERS, nowDate))
// 退款金额
.tradeAmount(amount.multiply(new BigDecimal("100")).intValue() + "")
// 货币种类
.currency("CNY")
// 退款回调地址
.notifyUrl(this.refundNotifyUrl)
// 回传信息
// .returnParams("")
.build();
// 请求京东退款接口
JdPayRefundResponse response = jdPay.refund(request);
if ("0000".equals(response.getResultCode())) {
// 请求响应成功
// 申请退款成功保存退款
TOnlineRefund tOnlineRefund = new TOnlineRefund();
tOnlineRefund.setRefundCode(refundCode);
tOnlineRefund.setPkOnlinePayment(tOnlinePayment.getPkId());
tOnlineRefund.setBusinessCode(refundDTO.getRefundBusinessCode());
tOnlineRefund.setRefundMoney(amount);
tOnlineRefund.setRefundChannel(tOnlinePayment.getPayChannel());
tOnlineRefund.setRefundNumber(response.getTradeNo());
tOnlineRefund.setPkCountry(refundDTO.getPkCountry());
tOnlineRefund.setPkCreator(refundDTO.getUserId());
if (itOnlineRefundService.save(tOnlineRefund)) {
return null;
} else {
log.error("调用京东收银台退款入库处理失败desc: {}", response.getResultDesc());
return "退款失败,请联系系统管理员处理";
}
}
log.error("调用京东收银台退款处理失败desc: {}", response.getResultDesc());
return "退款失败,请重试";
} catch (Exception e) {
log.error("调用京东收银台退款处理返回异常!", e);
return "退款异常,请重试";
}
}
}

View File

@ -0,0 +1,20 @@
package com.hzs.third.pay.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzs.common.domain.third.pay.TOnlinePaymentSepAccD;
import com.hzs.third.pay.mapper.TOnlinePaymentSepAccDMapper;
import com.hzs.third.pay.service.ITOnlinePaymentSepAccDService;
import org.springframework.stereotype.Service;
/**
* <p>
* 支付请求子表(分账) 服务实现类
* </p>
*
* @author bd
* @since 2025-07-01
*/
@Service
public class TOnlinePaymentSepAccDServiceImpl extends ServiceImpl<TOnlinePaymentSepAccDMapper, TOnlinePaymentSepAccD> implements ITOnlinePaymentSepAccDService {
}

View File

@ -0,0 +1,59 @@
package com.hzs.third.pay.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.common.domain.third.pay.TOnlinePaymentSepAcc;
import com.hzs.common.domain.third.pay.TOnlinePaymentSepAccD;
import com.hzs.common.security.utils.SecurityUtils;
import com.hzs.third.pay.mapper.TOnlinePaymentSepAccMapper;
import com.hzs.third.pay.service.ITOnlinePaymentSepAccDService;
import com.hzs.third.pay.service.ITOnlinePaymentSepAccService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* <p>
* 支付请求主表 服务实现类
* </p>
*
* @author bd
* @since 2025-07-01
*/
@Service
public class TOnlinePaymentSepAccServiceImpl extends ServiceImpl<TOnlinePaymentSepAccMapper, TOnlinePaymentSepAcc> implements ITOnlinePaymentSepAccService {
@Autowired
private ITOnlinePaymentSepAccDService itOnlinePaymentSepAccDService;
@Override
public void saveOrUpdateReq(TOnlinePaymentSepAcc tOnlinePaymentSepAcc) {
LambdaQueryWrapper<TOnlinePaymentSepAcc> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(TOnlinePaymentSepAcc::getPkPayment, tOnlinePaymentSepAcc.getPkPayment());
TOnlinePaymentSepAcc source = this.getOne(wrapper, false);
if(ObjectUtil.isNotEmpty(source)){
tOnlinePaymentSepAcc.setPkId(source.getPkId());
}else{
tOnlinePaymentSepAcc.setCreationTime(DateUtils.currentDateTime());
tOnlinePaymentSepAcc.setPkCreator(SecurityUtils.getUserId());
}
tOnlinePaymentSepAcc.setModifiedTime(DateUtils.currentDateTime());
tOnlinePaymentSepAcc.setPkModified(SecurityUtils.getUserId());
this.save(tOnlinePaymentSepAcc);
LambdaQueryWrapper<TOnlinePaymentSepAccD> wrapperD = new LambdaQueryWrapper<>();
wrapperD.eq(TOnlinePaymentSepAccD::getPkSepAcc, tOnlinePaymentSepAcc.getPkId());
itOnlinePaymentSepAccDService.remove(wrapperD);
if(CollUtil.isNotEmpty(tOnlinePaymentSepAcc.getSepAccDList())){
for (TOnlinePaymentSepAccD tOnlinePaymentSepAccD : tOnlinePaymentSepAcc.getSepAccDList()) {
tOnlinePaymentSepAccD.setPkSepAcc(tOnlinePaymentSepAcc.getPkId());
tOnlinePaymentSepAccD.setCreationTime(DateUtils.currentDateTime());
tOnlinePaymentSepAccD.setPkCreator(SecurityUtils.getUserId());
tOnlinePaymentSepAccD.setModifiedTime(DateUtils.currentDateTime());
tOnlinePaymentSepAccD.setPkModified(SecurityUtils.getUserId());
}
itOnlinePaymentSepAccDService.saveBatch(tOnlinePaymentSepAcc.getSepAccDList());
}
}
}

View File

@ -101,12 +101,19 @@ jd:
## 生产环境api接口域名
apiDomain: http://wapi.jd.com
## 页面回调地址
pageBackUrl: https://t-app.beida666.com/prod-api/pay/jd/sync-notify
# pageBackUrl: https://t-app.beida666.com/prod-api/pay/jd/sync-notify
pageBackUrl: https://t-app.beida666.com/#/pages/pay/index
## 支付回调地址
notifyUrl: https://t-app.beida666.com/prod-api/pay/jd/trade-notify
# notifyUrl: https://t-app.beida666.com/prod-api/pay/jd/trade-notify
notifyUrl: https://b747-218-57-66-5.ngrok-free.app/pay/jd/trade-notify
## 退款回调地下
refundNotifyUrl: https://t-app.beida666.com/prod-api/pay/jd-refund/trade-notify
# refundNotifyUrl: https://t-app.beida666.com/prod-api/pay/jd-refund/trade-notify
refundNotifyUrl: https://b747-218-57-66-5.ngrok-free.app/pay/jd-refund/trade-notify
separateAccounts:
- account: 153428607007
proportion: 0.5
- account: 153428607005
proportion: 0.5
## 通联支付配置
allinpay:
# #################### 基础支付相关(正式) ####################

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hzs.com.hzs.common.domain.mapper.TOnlinePaymentSepAccDMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.hzs.common.domain.third.pay.TOnlinePaymentSepAccD">
<id column="PK_ID" property="pkId" />
<result column="DEL_FLAG" property="delFlag" />
<result column="CREATION_TIME" property="creationTime" />
<result column="MODIFIED_TIME" property="modifiedTime" />
<result column="PK_CREATOR" property="pkCreator" />
<result column="PK_MODIFIED" property="pkModified" />
<result column="PK_SEP_ACC" property="pkSepAcc" />
<result column="ACCOUNT" property="account" />
<result column="PROPORTION" property="proportion" />
<result column="TRADE_AMOUNT" property="tradeAmount" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
DEL_FLAG,
CREATION_TIME,
MODIFIED_TIME,
PK_CREATOR,
PK_MODIFIED,
PK_ID, PK_SEP_ACC, ACCOUNT, PROPORTION
</sql>
</mapper>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hzs.com.hzs.common.domain.mapper.TOnlinePaymentSepAccMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.hzs.common.domain.third.pay.TOnlinePaymentSepAcc">
<id column="PK_ID" property="pkId" />
<result column="DEL_FLAG" property="delFlag" />
<result column="CREATION_TIME" property="creationTime" />
<result column="MODIFIED_TIME" property="modifiedTime" />
<result column="PK_CREATOR" property="pkCreator" />
<result column="PK_MODIFIED" property="pkModified" />
<result column="PK_PAYMENT" property="pkPayment" />
<result column="VERSION" property="version" />
<result column="REQ_CONTENT" property="reqContent" />
<result column="REQ_CONTENT_SEP_ACC" property="reqContentSepAcc" />
<result column="RESP_CONTENT" property="respContent" />
<result column="TRADE_AMOUNT" property="tradeAmount" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
DEL_FLAG,
CREATION_TIME,
MODIFIED_TIME,
PK_CREATOR,
PK_MODIFIED,
PK_ID, PK_PAYMENT, VERSION, REQ_CONTENT, REQ_CONTENT_SEP_ACC, RESP_CONTENT
</sql>
</mapper>

View File

@ -0,0 +1,89 @@
CREATE TABLE "CLOUD_2"."T_ONLINE_PAYMENT_SEP_ACC" (
"PK_ID" NUMBER(20,0),
"PK_PAYMENT" NUMBER(20,0),
"VERSION" VARCHAR2(255),
"REQ_CONTENT" VARCHAR2(1024),
"REQ_CONTENT_SEP_ACC" VARCHAR2(1024),
"RESP_CONTENT" VARCHAR2(2048),
"DEL_FLAG" NUMBER(1),
"PK_COUNTRY" NUMBER(4,0) DEFAULT 1 NOT NULL ENABLE,
"CREATION_TIME" DATE,
"MODIFIED_TIME" DATE,
"PK_CREATOR" NUMBER(20,0),
"PK_MODIFIED" NUMBER(20,0),
PRIMARY KEY ("PK_ID")
)
;
COMMENT ON COLUMN "CLOUD_2"."T_ONLINE_PAYMENT_SEP_ACC"."PK_PAYMENT" IS '在线支付信息ID';
COMMENT ON COLUMN "CLOUD_2"."T_ONLINE_PAYMENT_SEP_ACC"."VERSION" IS '版本号';
COMMENT ON COLUMN "CLOUD_2"."T_ONLINE_PAYMENT_SEP_ACC"."REQ_CONTENT" IS '支付请求信息';
COMMENT ON COLUMN "CLOUD_2"."T_ONLINE_PAYMENT_SEP_ACC"."REQ_CONTENT_SEP_ACC" IS '分账请求信息';
COMMENT ON COLUMN "CLOUD_2"."T_ONLINE_PAYMENT_SEP_ACC"."RESP_CONTENT" IS '支付响应信息';
COMMENT ON COLUMN "CLOUD_2"."T_ONLINE_PAYMENT_SEP_ACC"."DEL_FLAG" IS '逻辑删除 (0=未删除,1已删除)';
COMMENT ON COLUMN "CLOUD_2"."T_ONLINE_PAYMENT_SEP_ACC"."CREATION_TIME" IS '创建时间';
COMMENT ON COLUMN "CLOUD_2"."T_ONLINE_PAYMENT_SEP_ACC"."MODIFIED_TIME" IS '修改时间';
COMMENT ON COLUMN "CLOUD_2"."T_ONLINE_PAYMENT_SEP_ACC"."PK_CREATOR" IS '创建者';
COMMENT ON COLUMN "CLOUD_2"."T_ONLINE_PAYMENT_SEP_ACC"."PK_MODIFIED" IS '更新者';
COMMENT ON TABLE "CLOUD_2"."T_ONLINE_PAYMENT_SEP_ACC" IS '支付请求主表';
CREATE SEQUENCE T_ONLINE_PAYMENT_SEP_ACC_SEQ
START WITH 1
INCREMENT BY 1;
CREATE TABLE "CLOUD_2"."T_ONLINE_PAYMENT_SEP_ACC_D" (
"PK_ID" NUMBER(20,0),
"PK_SEP_ACC" NUMBER(20,0),
"ACCOUNT" VARCHAR2(255),
"PROPORTION" NUMBER(10, 2),
"DEL_FLAG" NUMBER(1),
"PK_COUNTRY" NUMBER(4,0) DEFAULT 1 NOT NULL ENABLE,
"CREATION_TIME" DATE,
"MODIFIED_TIME" DATE,
"PK_CREATOR" NUMBER(20,0),
"PK_MODIFIED" NUMBER(20,0),
PRIMARY KEY ("PK_ID")
)
;
COMMENT ON COLUMN "CLOUD_2"."T_ONLINE_PAYMENT_SEP_ACC_D"."PK_SEP_ACC" IS '支付请求主表ID';
COMMENT ON COLUMN "CLOUD_2"."T_ONLINE_PAYMENT_SEP_ACC_D"."ACCOUNT" IS '分账账号';
COMMENT ON COLUMN "CLOUD_2"."T_ONLINE_PAYMENT_SEP_ACC_D"."PROPORTION" IS '分账比例';
COMMENT ON COLUMN "CLOUD_2"."T_ONLINE_PAYMENT_SEP_ACC_D"."DEL_FLAG" IS '逻辑删除 (0=未删除,1已删除)';
COMMENT ON COLUMN "CLOUD_2"."T_ONLINE_PAYMENT_SEP_ACC_D"."CREATION_TIME" IS '创建时间';
COMMENT ON COLUMN "CLOUD_2"."T_ONLINE_PAYMENT_SEP_ACC_D"."MODIFIED_TIME" IS '修改时间';
COMMENT ON COLUMN "CLOUD_2"."T_ONLINE_PAYMENT_SEP_ACC_D"."PK_CREATOR" IS '创建者';
COMMENT ON COLUMN "CLOUD_2"."T_ONLINE_PAYMENT_SEP_ACC_D"."PK_MODIFIED" IS '更新者';
COMMENT ON TABLE "CLOUD_2"."T_ONLINE_PAYMENT_SEP_ACC_D" IS '支付请求子表(分账)';
CREATE SEQUENCE T_ONLINE_PAYMENT_SEP_ACC_D_SEQ
START WITH 1
INCREMENT BY 1;
ALTER TABLE "CLOUD_2"."T_ONLINE_PAYMENT_SEP_ACC"
ADD ("TRADE_AMOUNT" NUMBER(16,2));
COMMENT ON COLUMN "CLOUD_2"."T_ONLINE_PAYMENT_SEP_ACC"."TRADE_AMOUNT" IS '总金额';
ALTER TABLE "CLOUD_2"."T_ONLINE_PAYMENT_SEP_ACC_D"
ADD ("TRADE_AMOUNT" NUMBER(16,2));
COMMENT ON COLUMN "CLOUD_2"."T_ONLINE_PAYMENT_SEP_ACC_D"."TRADE_AMOUNT" IS '分账金额';

View File

@ -0,0 +1,5 @@
正常支付回调:
{"signData":"CFC402DAEBC319048859760C3C1076E252A0AA8E06480D33ABE8E9E4F6F64942","charset":"UTF-8","encType":"AP7","code":"00000","signType":"SHA-256","respData":"eyJiYW5rQ29kZSI6IkNDQiIsInRyYWRlTm8iOiIyMDI1MDcwMTE0MDI0MzIwMTE4MzAyNzYyOTk0MTkiLCJyZXN1bHRDb2RlIjoiMDAwMCIsImNhcmRUeXBlIjoiREUiLCJtYXNrQ2FyZE5vIjoiMDMwNSIsInJlc3VsdERlc2MiOiLmiJDlip8iLCJiYW5rU3VibWl0Tm8iOiIwNzAxNjU5MDI3NDk2MTUzIiwidXNlcklkIjoiVF8xMDkiLCJleHRJbmZvIjoie30iLCJwYXlUb29sIjoiRVhQUiIsInRyYWRlQW1vdW50IjoiMiIsInJldHVyblBhcmFtcyI6IjEiLCJvdXRUcmFkZU5vIjoiQkRTTzE3NTEzNDk3NTE0MDk2MDgiLCJ0cmFkZVN0YXR1cyI6IkZJTkkiLCJmaW5pc2hEYXRlIjoiMjAyNTA3MDExNDAzMTciLCJjdXJyZW5jeSI6IkNOWSIsInRyYWRlVHlwZSI6IkFHR1JFIn0=","formatType":"JSON","desc":"成功","merchantNo":"153428607005"}
退款回调: 入口(my-order/self-revoke-order)