updates 抖音退款功能
This commit is contained in:
parent
efde1157db
commit
774d539630
|
|
@ -0,0 +1,23 @@
|
||||||
|
package org.jeecg.config;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ZhouWenTao
|
||||||
|
* @create 2024-06-26-13:03
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Component
|
||||||
|
@ConfigurationProperties(prefix = "dy")
|
||||||
|
public class DouYinConfig implements Serializable {
|
||||||
|
private String appId;
|
||||||
|
private String appSecret;
|
||||||
|
private String token;
|
||||||
|
private String notifyUrl;// 支付回调地址
|
||||||
|
private String refundNotifyUrl;// 退款回调地址
|
||||||
|
private String salt;
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,8 @@ package org.jeecg.modules.mini.douyin.model;
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
|
@ -11,6 +13,7 @@ import java.io.Serializable;
|
||||||
* 官方文档 https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/server/ecpay/pay-list/pay
|
* 官方文档 https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/server/ecpay/pay-list/pay
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
|
@Component
|
||||||
public class DouYinOrderModel implements Serializable {
|
public class DouYinOrderModel implements Serializable {
|
||||||
//小程序APPID
|
//小程序APPID
|
||||||
private String app_id;
|
private String app_id;
|
||||||
|
|
|
||||||
|
|
@ -103,14 +103,14 @@ public class DouYinUtil {
|
||||||
/**
|
/**
|
||||||
* 订单同步
|
* 订单同步
|
||||||
*/
|
*/
|
||||||
public static void orderRefund(String orderCode,String appId,Long refundAmount,String salt,String notifyUrl){
|
public static String orderRefund(String orderCode,String appId,Long refundAmount,String refundReason,String salt,String notifyUrl){
|
||||||
log.debug("抖音订单退款----订单号:"+orderCode);
|
log.debug("抖音订单退款----订单号:"+orderCode);
|
||||||
//文档 https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/server/ecpay/refund-list/refund
|
//文档 https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/server/ecpay/refund-list/refund
|
||||||
Map<String, Object> testCase = new HashMap<String, Object>() {{
|
Map<String, Object> testCase = new HashMap<String, Object>() {{
|
||||||
put("app_id", appId);
|
put("app_id", appId);
|
||||||
put("out_order_no", orderCode);// 商户分配支付单号,标识进行退款的订单
|
put("out_order_no", orderCode);// 商户分配支付单号,标识进行退款的订单
|
||||||
put("out_refund_no","tk_"+orderCode);// 商户分配退款号,保证在商户中唯一
|
put("out_refund_no","tk_"+orderCode);// 商户分配退款号,保证在商户中唯一
|
||||||
put("reason","不想要了");// 退款原因
|
put("reason",refundReason);// 退款原因
|
||||||
put("refund_amount", refundAmount);// 退款金额
|
put("refund_amount", refundAmount);// 退款金额
|
||||||
put("cp_extra", "一些附加信息");
|
put("cp_extra", "一些附加信息");
|
||||||
put("notify_url", notifyUrl);
|
put("notify_url", notifyUrl);
|
||||||
|
|
@ -121,7 +121,12 @@ public class DouYinUtil {
|
||||||
String douyinUrl="https://developer.toutiao.com/api/apps/ecpay/v1/create_refund";
|
String douyinUrl="https://developer.toutiao.com/api/apps/ecpay/v1/create_refund";
|
||||||
testCase.put("sign",sign);
|
testCase.put("sign",sign);
|
||||||
JSONObject post = RestUtil.post(douyinUrl, JSONObject.parseObject(JSONObject.toJSONString(testCase)));
|
JSONObject post = RestUtil.post(douyinUrl, JSONObject.parseObject(JSONObject.toJSONString(testCase)));
|
||||||
|
Integer errNo = post.getInteger("err_no");
|
||||||
log.debug("抖音退款结果----:"+post.toJSONString());
|
log.debug("抖音退款结果----:"+post.toJSONString());
|
||||||
|
if (!errNo.equals(0)) {
|
||||||
|
return post.getString("err_tips");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|
@ -130,7 +135,7 @@ public class DouYinUtil {
|
||||||
// String notifyUrl = "https://yitisheng.vip/py/dy/payNotify";
|
// String notifyUrl = "https://yitisheng.vip/py/dy/payNotify";
|
||||||
Long refundAmount = 100l;
|
Long refundAmount = 100l;
|
||||||
String appId = "tt59a72f1ac6964bfa01";
|
String appId = "tt59a72f1ac6964bfa01";
|
||||||
orderRefund(orderCode,appId,refundAmount,"wODf6Bg5BXndJ3IELXNb1w5CDMRjatXAmZVP2DQ7",notifyUrl);
|
orderRefund(orderCode,appId,refundAmount,"不想要了","wODf6Bg5BXndJ3IELXNb1w5CDMRjatXAmZVP2DQ7",notifyUrl);
|
||||||
/* long time = new Date().getTime();
|
/* long time = new Date().getTime();
|
||||||
String js="{\"count\":7800,\"dates\":[\"2016-09\",\"2018-06\",\"2019-07\",\"2020-01\",\"2022-03\",\"2024-05\"],\"description\":\"☘\uFE0F 如果喜欢秒达工具箱,请收藏和分享本网址MDGJX.COM(首拼缩写)\",\"info\":{\"codeGenTarget\":\"ES5\",\"extraLibs\":[],\"info\":{\"codeGenTarget\":\"ES5\",\"extraLibs\":[],\"info\":{\"codeGenTarget\":\"ES5\",\"extraLibs\":[],\"info\":{\"codeGenTarget\":\"ES5\",\"extraLibs\":[],\"moduleGenTarget\":\"\",\"noImplicitAny\":true,\"noLib\":false,\"scope\":\"/\",\"semanticValidation\":true,\"syntaxValidation\":true},\"moduleGenTarget\":\"\",\"noImplicitAny\":true,\"noLib\":false,\"scope\":\"/\",\"semanticValidation\":true,\"syntaxValidation\":true},\"moduleGenTarget\":\"\",\"noImplicitAny\":true,\"noLib\":false,\"scope\":\"/\",\"semanticValidation\":true,\"syntaxValidation\":true},\"moduleGenTarget\":\"\",\"noImplicitAny\":true,\"noLib\":false,\"scope\":\"/\",\"semanticValidation\":true,\"syntaxValidation\":true},\"link\":\"https://mdgjx.com\",\"name\":\"秒达工具箱\"}";
|
String js="{\"count\":7800,\"dates\":[\"2016-09\",\"2018-06\",\"2019-07\",\"2020-01\",\"2022-03\",\"2024-05\"],\"description\":\"☘\uFE0F 如果喜欢秒达工具箱,请收藏和分享本网址MDGJX.COM(首拼缩写)\",\"info\":{\"codeGenTarget\":\"ES5\",\"extraLibs\":[],\"info\":{\"codeGenTarget\":\"ES5\",\"extraLibs\":[],\"info\":{\"codeGenTarget\":\"ES5\",\"extraLibs\":[],\"info\":{\"codeGenTarget\":\"ES5\",\"extraLibs\":[],\"moduleGenTarget\":\"\",\"noImplicitAny\":true,\"noLib\":false,\"scope\":\"/\",\"semanticValidation\":true,\"syntaxValidation\":true},\"moduleGenTarget\":\"\",\"noImplicitAny\":true,\"noLib\":false,\"scope\":\"/\",\"semanticValidation\":true,\"syntaxValidation\":true},\"moduleGenTarget\":\"\",\"noImplicitAny\":true,\"noLib\":false,\"scope\":\"/\",\"semanticValidation\":true,\"syntaxValidation\":true},\"moduleGenTarget\":\"\",\"noImplicitAny\":true,\"noLib\":false,\"scope\":\"/\",\"semanticValidation\":true,\"syntaxValidation\":true},\"link\":\"https://mdgjx.com\",\"name\":\"秒达工具箱\"}";
|
||||||
JSONObject jsonObject = null;
|
JSONObject jsonObject = null;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package org.jeecg.modules.yx.controller;
|
package org.jeecg.modules.yx.controller;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
@ -7,13 +8,18 @@ import java.util.stream.Collectors;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.jeecg.common.api.vo.Result;
|
import org.jeecg.common.api.vo.Result;
|
||||||
import org.jeecg.common.system.query.QueryGenerator;
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
import org.jeecg.common.util.AssertUtils;
|
||||||
import org.jeecg.common.util.oConvertUtils;
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.config.DouYinConfig;
|
||||||
|
import org.jeecg.modules.mini.douyin.util.DouYinUtil;
|
||||||
|
import org.jeecg.modules.yx.constant.YxConstant;
|
||||||
import org.jeecg.modules.yx.entity.YxOrder;
|
import org.jeecg.modules.yx.entity.YxOrder;
|
||||||
import org.jeecg.modules.yx.service.IYxOrderService;
|
import org.jeecg.modules.yx.service.IYxOrderService;
|
||||||
|
|
||||||
|
|
@ -29,6 +35,7 @@ import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
import org.jeecg.common.system.base.controller.JeecgController;
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
|
@ -52,7 +59,8 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
public class YxOrderController extends JeecgController<YxOrder, IYxOrderService> {
|
public class YxOrderController extends JeecgController<YxOrder, IYxOrderService> {
|
||||||
@Autowired
|
@Autowired
|
||||||
private IYxOrderService yxOrderService;
|
private IYxOrderService yxOrderService;
|
||||||
|
@Resource
|
||||||
|
private DouYinConfig douYinConfig;
|
||||||
/**
|
/**
|
||||||
* 分页列表查询
|
* 分页列表查询
|
||||||
*
|
*
|
||||||
|
|
@ -108,6 +116,38 @@ public class YxOrderController extends JeecgController<YxOrder, IYxOrderService>
|
||||||
return Result.OK("编辑成功!");
|
return Result.OK("编辑成功!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @param yxOrder
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "订单表-退款")
|
||||||
|
@ApiOperation(value="订单表-退款", notes="订单表-退款")
|
||||||
|
@RequiresPermissions("yx:yx_order:edit")
|
||||||
|
@RequestMapping(value = "/refund", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||||
|
public Result<String> refund(@RequestBody YxOrder yxOrder) {
|
||||||
|
AssertUtils.notNull(yxOrder.getId(),"请求参数有误");
|
||||||
|
AssertUtils.notNull(yxOrder.getRefundAmount(),"请输入退款金额");
|
||||||
|
AssertUtils.notNull(yxOrder.getRefundReason(),"请输入退款原因");
|
||||||
|
YxOrder order = yxOrderService.getById(yxOrder.getId());
|
||||||
|
AssertUtils.notNull(order,"请求参数有误");
|
||||||
|
// 目前仅支持抖音退款
|
||||||
|
AssertUtils.isTrue("toutiao".equals(order.getProvider()),"暂不支持该平台退款");
|
||||||
|
//处理金额为分单位
|
||||||
|
BigDecimal refundAmount = yxOrder.getRefundAmount();
|
||||||
|
BigDecimal multiply = refundAmount.multiply(YxConstant.bigDecimal100);
|
||||||
|
long refundAmountLong = multiply.longValue();
|
||||||
|
String refundOverMessage = DouYinUtil.orderRefund(order.getOrderCode(), douYinConfig.getAppId(), refundAmountLong,yxOrder.getRefundReason(), douYinConfig.getSalt(), douYinConfig.getRefundNotifyUrl());
|
||||||
|
if (StringUtils.isNotBlank(refundOverMessage)) {
|
||||||
|
// 退款失败
|
||||||
|
return Result.error(refundOverMessage);
|
||||||
|
}
|
||||||
|
// 退款成功,等待抖音回调
|
||||||
|
/*yxOrderService.updateById(yxOrder);*/
|
||||||
|
return Result.OK("操作成功,请等待后刷新!");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过id删除
|
* 通过id删除
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,9 @@ public class YxOrder implements Serializable {
|
||||||
@ApiModelProperty(value = "抖音商户退款号")
|
@ApiModelProperty(value = "抖音商户退款号")
|
||||||
private String refundNo;
|
private String refundNo;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "退款原因")
|
||||||
|
private String refundReason;
|
||||||
|
|
||||||
//==================
|
//==================
|
||||||
@TableField(exist = false)
|
@TableField(exist = false)
|
||||||
private String skuName;
|
private String skuName;
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ dy:
|
||||||
appId: tt59a72f1ac6964bfa01
|
appId: tt59a72f1ac6964bfa01
|
||||||
appSecret: 46882267247ca02561cf899d03adf562aa93ad3e
|
appSecret: 46882267247ca02561cf899d03adf562aa93ad3e
|
||||||
token: a1b2c3
|
token: a1b2c3
|
||||||
# 回调接口地址
|
#支付 回调接口地址
|
||||||
notifyUrl: https://yitisheng.vip/jbt/mini/pay/v1/payNotify
|
notifyUrl: https://yitisheng.vip/jbt/mini/pay/v1/payNotify
|
||||||
|
refundNotifyUrl: https://yitisheng.vip/jbt/mini/pay/v1/dy/payNotify
|
||||||
salt: wODf6Bg5BXndJ3IELXNb1w5CDMRjatXAmZVP2DQ7
|
salt: wODf6Bg5BXndJ3IELXNb1w5CDMRjatXAmZVP2DQ7
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue