记得上下班打卡 | git大法好,push需谨慎

Commit 701d305a authored by jiangxiulong's avatar jiangxiulong

Merge remote-tracking branch 'origin/dev' into dev

parents ad7b0e2c f04cceac
...@@ -4,6 +4,17 @@ package com.liquidnet.service.dragon.constant; ...@@ -4,6 +4,17 @@ package com.liquidnet.service.dragon.constant;
* *
*/ */
public class DragonConstant { public class DragonConstant {
public static final String REFUND_TYPE_APP_ALIPAY="APPALIPAY";//,"App内支付宝支付"),
public static final String REFUND_TYPE_APP_WEPAY="APPWEPAY";//,"App内微信支付"),
public static final String REFUND_TYPE_APP_IAP="APPIAP";//,"App内IAP(In-App Purchase)支付,iOS虚拟道具支付"),
public static final String REFUND_TYPE_WAP_ALIPAY="WAPALIPAY";//,"手机网页内支付宝支付"),
public static final String REFUND_TYPE_WAP_WEPAY="WAPWEPAY";//,"手机网页调起微信支付"),
public static final String REFUND_TYPE_WEB_ALIPAY="WEBALIPAY";//,"电脑网页内支付宝即时到账支付"),
public static final String REFUND_TYPE_WEB_WEPAY="WEBWEPAY";//,"电脑网页内微信二维码支付,用户打开微信扫码支付"),
public static final String REFUND_TYPE_JS_WEPAY="JSWEPAY";//,"微信内网页、微信公众号"),
public static final String REFUND_TYPE_APPLET_WEPAY="APPLETWEPAY";//,"微信小程序");
public enum payChannelEnum{ public enum payChannelEnum{
ALIPAY("alipay","支付宝"), ALIPAY("alipay","支付宝"),
WEPAY ("wePay","微信"), WEPAY ("wePay","微信"),
...@@ -33,6 +44,33 @@ public class DragonConstant { ...@@ -33,6 +44,33 @@ public class DragonConstant {
} }
} }
/**
* 退款状态
*/
public enum refundStatusEnum{
STATUS_UNFILLED("0","未处理"),
STATUS_REFUNDED("1","退款成功"),
STATUS_SUCCESS("2","退款成功,通知成功,交易结束"),
STATUS_FAIL("3","退款成功,通知失败,交易结束"),
STATUS_EXPIRE("4","退款成功,通知超时,交易结束"),
STATUS_REFUNDING("5","正在退款"),
STATUS_ERROR("6","退款失败"),
STATUS_ERROR_SUCCESS("7","退款失败,通知成功,交易结束"),
STATUS_ERROR_FAIL("8","退款失败,通知失败,交易结束"),
STATUS_ERROR_EXPIRE("9","退款失败,通知超时,交易结束");
private String code;
private String message;
refundStatusEnum(String code, String message) {
this.code = code;
this.message = message;
}
public String getCode() {
return code;
}
}
/** /**
* 支付业务类型 * 支付业务类型
*/ */
...@@ -77,6 +115,32 @@ public class DragonConstant { ...@@ -77,6 +115,32 @@ public class DragonConstant {
} }
} }
/**
* 退款类型
*/
public enum refundTypeEnum{
REFUND_TYPE_APP_ALIPAY("APPALIPAY","App内支付宝支付"),
REFUND_TYPE_APP_WEPAY("APPWEPAY","App内微信支付"),
REFUND_TYPE_APP_IAP("APPIAP","App内IAP(In-App Purchase)支付,iOS虚拟道具支付"),
REFUND_TYPE_WAP_ALIPAY("WAPALIPAY","手机网页内支付宝支付"),
REFUND_TYPE_WAP_WEPAY("WAPWEPAY","手机网页调起微信支付"),
REFUND_TYPE_WEB_ALIPAY("WEBALIPAY","电脑网页内支付宝即时到账支付"),
REFUND_TYPE_WEB_WEPAY("WEBWEPAY","电脑网页内微信二维码支付,用户打开微信扫码支付"),
REFUND_TYPE_JS_WEPAY("JSWEPAY","微信内网页、微信公众号"),
REFUND_TYPE_APPLET_WEPAY("APPLETWEPAY","微信小程序");
private String code;
private String message;
refundTypeEnum(String code, String message) {
this.code = code;
this.message = message;
}
public String getCode() {
return code;
}
}
/** /**
* MYSQL_REDIS_QUEUE * MYSQL_REDIS_QUEUE
*/ */
...@@ -91,6 +155,10 @@ public class DragonConstant { ...@@ -91,6 +155,10 @@ public class DragonConstant {
this.code = code; this.code = code;
this.message = message; this.message = message;
} }
public String getCode() {
return code;
}
} }
/** /**
......
package com.liquidnet.service.dragon.dto;
import lombok.Data;
import java.io.Serializable;
@Data
public class DragonRefundAppDto implements Serializable {
private String orderCode;
private String code;
private String orderRefundCode;
private String refundCode;
}
package com.liquidnet.service.dragon.dto;
import lombok.Data;
import java.io.Serializable;
@Data
public class DragonRefundChannelDto implements Serializable {
private String result;
private String message;
private RefundContentDto content;
}
package com.liquidnet.service.dragon.dto;
import lombok.Data;
import java.io.Serializable;
@Data
public class RefundContentDto implements Serializable {
private String request;
private String response;
}
package com.liquidnet.service.dragon.service; package com.liquidnet.service.dragon.service;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.dragon.dto.DragonRefundAppDto;
import java.math.BigDecimal; import java.math.BigDecimal;
public interface IDragonOrderRefundsService { public interface IDragonOrderRefundsService {
...@@ -8,15 +11,13 @@ public interface IDragonOrderRefundsService { ...@@ -8,15 +11,13 @@ public interface IDragonOrderRefundsService {
/** /**
* *
* @param trade_no => refund_code * @param tradeNo => refundCode
* @param out_trade_no => pay_code * @param outTradeNo => pay_code
* @param reason * @param reason
* @param returnUrl * @param returnUrl
* @param price 退款金额 * @param price 退款金额
* @param paymentType 支付类型
*/ */
void dragonRefund(String trade_no, String out_trade_no, String reason, String returnUrl, BigDecimal price); ResponseDto<DragonRefundAppDto> dragonRefund(String orderCode, String tradeNo, String outTradeNo, String reason, String returnUrl, BigDecimal price, String paymentType,String paymentId);
void weyPayRefund();
void aliPayRefund(String trade_no, String out_trade_no, String reason, String returnUrl, BigDecimal price);
} }
package com.liquidnet.commons.lang.util; package com.liquidnet.commons.lang.util;
import org.apache.commons.lang3.StringUtils;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.UUID; import java.util.UUID;
...@@ -45,6 +47,13 @@ public class IDGenerator { ...@@ -45,6 +47,13 @@ public class IDGenerator {
return orderCode; return orderCode;
} }
public static String refundCode(){
String refundCode = System.currentTimeMillis()+"";
int randomCode = RandomUtil.getRandomInt(0,10000);
StringUtils.leftPad(refundCode, 3, "0");
return refundCode.concat(StringUtils.leftPad(randomCode+"", (randomCode/10), "0")+"R");
}
/** /**
* 根据 订单号生成qrCode * 根据 订单号生成qrCode
* *
......
package com.liquidnet.service.base;
import lombok.Data;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
@Data
public class PayMapping {
static {
reload();
}
private static Properties errorsProperties;
public static void reload() {
errorsProperties = new Properties();
InputStream in = PayMapping.class.getClassLoader().getResourceAsStream("apiclient_key.pem");
try {
errorsProperties.load(new InputStreamReader(in, StandardCharsets.UTF_8));
System.out.printf("errorsProperties init count: %s\n", errorsProperties.size());
} catch (IOException e) {
e.printStackTrace();
}
}
public static ErrorMessage get(long code) {
String value = errorsProperties != null ? errorsProperties.getProperty(code + "") : "-";
return ErrorMessage.getInstance().setCode(code + "").setMessage(value);
}
public static ErrorMessage get(String code) {
String value = errorsProperties != null ? errorsProperties.getProperty(code) : "-";
return ErrorMessage.getInstance().setCode(code).setMessage(value);
}
public static class ErrorMessage implements Cloneable, Serializable {
private static final long serialVersionUID = 2208924091512163151L;
private String code;
private String message;
private ErrorMessage() {
}
public String getCode() {
return code;
}
public String getMessage() {
return message;
}
private final static ErrorMessage instance = new ErrorMessage();
public static ErrorMessage getInstance() {
try {
return (ErrorMessage) instance.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return new ErrorMessage();
}
public ErrorMessage setCode(String code) {
this.code = code;
return this;
}
public ErrorMessage setMessage(String message) {
this.message = message;
return this;
}
}
}
...@@ -31,6 +31,11 @@ ...@@ -31,6 +31,11 @@
<artifactId>liquidnet-common-cache-redisson</artifactId> <artifactId>liquidnet-common-cache-redisson</artifactId>
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<groupId>com.liquidnet</groupId>
<artifactId>liquidnet-service-dragon-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
......
package com.liquidnet.service.consumer.dragon.service.config;
import com.liquidnet.service.consumer.dragon.service.receiver.RedisPayReceiver;
import com.liquidnet.service.consumer.dragon.service.receiver.RedisRefundReceiver;
import com.liquidnet.service.dragon.constant.DragonConstant;
import lombok.var;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.stream.Consumer;
import org.springframework.data.redis.connection.stream.ReadOffset;
import org.springframework.data.redis.connection.stream.StreamOffset;
import org.springframework.data.redis.stream.StreamMessageListenerContainer;
import org.springframework.data.redis.stream.Subscription;
import java.time.Duration;
@Configuration
public class RedisStreamConfig {
@Autowired
private RedisPayReceiver redisPayReceiver;
@Autowired
private RedisRefundReceiver redisRefundReceiver;
@Bean
public Subscription subscriptionPay0(RedisConnectionFactory factory) {
var options = StreamMessageListenerContainer
.StreamMessageListenerContainerOptions
.builder()
.pollTimeout(Duration.ofMillis(1))
.build();
var listenerContainer = StreamMessageListenerContainer.create(factory, options);
var subscription = listenerContainer.receiveAutoAck(Consumer.from(DragonConstant.mysqlRedisQueueEnum.DRAGON_PAY_GROUP.getCode(), "dragon-pay-0"),
StreamOffset.create(DragonConstant.mysqlRedisQueueEnum.DRAGON_PAY_KEY.getCode(), ReadOffset.lastConsumed()), redisPayReceiver);
listenerContainer.start();
return subscription;
}
@Bean
public Subscription subscriptionPay1(RedisConnectionFactory factory) {
var options = StreamMessageListenerContainer
.StreamMessageListenerContainerOptions
.builder()
.pollTimeout(Duration.ofMillis(1))
.build();
var listenerContainer = StreamMessageListenerContainer.create(factory, options);
var subscription = listenerContainer.receiveAutoAck(Consumer.from(DragonConstant.mysqlRedisQueueEnum.DRAGON_PAY_GROUP.getCode(), "dragon-pay-1"),
StreamOffset.create(DragonConstant.mysqlRedisQueueEnum.DRAGON_PAY_KEY.getCode(), ReadOffset.lastConsumed()), redisPayReceiver);
listenerContainer.start();
return subscription;
}
@Bean
public Subscription subscriptionRefund0(RedisConnectionFactory factory) {
var options = StreamMessageListenerContainer
.StreamMessageListenerContainerOptions
.builder()
.pollTimeout(Duration.ofMillis(1))
.build();
var listenerContainer = StreamMessageListenerContainer.create(factory, options);
var subscription = listenerContainer.receiveAutoAck(Consumer.from(DragonConstant.mysqlRedisQueueEnum.DRAGON_REFUND_GROUP.getCode(), "dragon-refund-0"),
StreamOffset.create(DragonConstant.mysqlRedisQueueEnum.DRAGON_REFUND_KEY.getCode(), ReadOffset.lastConsumed()), redisRefundReceiver);
listenerContainer.start();
return subscription;
}
@Bean
public Subscription subscriptionRefund1(RedisConnectionFactory factory) {
var options = StreamMessageListenerContainer
.StreamMessageListenerContainerOptions
.builder()
.pollTimeout(Duration.ofMillis(1))
.build();
var listenerContainer = StreamMessageListenerContainer.create(factory, options);
var subscription = listenerContainer.receiveAutoAck(Consumer.from(DragonConstant.mysqlRedisQueueEnum.DRAGON_REFUND_GROUP.getCode(), "dragon-refund-1"),
StreamOffset.create(DragonConstant.mysqlRedisQueueEnum.DRAGON_REFUND_KEY.getCode(), ReadOffset.lastConsumed()), redisRefundReceiver);
listenerContainer.start();
return subscription;
}
}
package com.liquidnet.service.consumer.dragon.service.receiver;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.connection.stream.MapRecord;
import org.springframework.data.redis.stream.StreamListener;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class RedisPayReceiver implements StreamListener<String, MapRecord<String, String, String>> {
@Override
public void onMessage(MapRecord<String, String, String> message) {
log.info("接受到来自redis PAY 的消息");
System.out.println("message id "+message.getId());
System.out.println("stream "+message.getStream());
System.out.println("body "+message.getValue());
}
}
package com.liquidnet.service.consumer.dragon.service.receiver;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.base.SqlMapping;
import com.liquidnet.service.consumer.dragon.service.IBaseDao;
import com.liquidnet.service.dragon.constant.DragonConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.stream.MapRecord;
import org.springframework.data.redis.connection.stream.StreamRecords;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.stream.StreamListener;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.LinkedList;
@Slf4j
@Component
public class RedisRefundReceiver implements StreamListener<String, MapRecord<String, String, String>> {
@Resource
IBaseDao baseDao;
@Autowired
StringRedisTemplate stringRedisTemplate;
@Override
public void onMessage(MapRecord<String, String, String> message) {
log.info("接受到来自redis REFUND 的消息");
System.out.println("message id " + message.getId());
System.out.println("stream " + message.getStream());
System.out.println("body " + message.getValue());
consumerSqlDaoHandler(message.getValue().get("message"));
}
private void consumerSqlDaoHandler(String msg) {
try {
SqlMapping.SqlMessage sqlMessage = JsonUtils.fromJson(msg, SqlMapping.SqlMessage.class);
log.debug("CONSUMER SQL ==> Preparing:{}", JsonUtils.toJson(sqlMessage.getSqls()));
log.debug("CONSUMER SQL ==> Parameters:{}", JsonUtils.toJson(sqlMessage.getArgs()));
Boolean rstBatchSqls = baseDao.batchSqls(sqlMessage.getSqls(), sqlMessage.getArgs());
log.debug("CONSUMER SQL result of execution:{}", rstBatchSqls);
if (rstBatchSqls) {
//应答
} else {
sendMySqlRedis(msg);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 给 REDIS 队列发送消息 数据库相关
*
* @param msg 接收到的内容
* @return
*/
private boolean sendMySqlRedis(String msg) {
try {
HashMap<String, String> map = new HashMap<>();
map.put("message", msg);
MapRecord<String, String, String> record = StreamRecords.mapBacked(map).withStreamKey(DragonConstant.mysqlRedisQueueEnum.DRAGON_REFUND_KEY.getCode());
stringRedisTemplate.opsForStream().add(record);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
...@@ -6,7 +6,8 @@ use ln_scene; ...@@ -6,7 +6,8 @@ use ln_scene;
drop TABLE if exists `dragon_orders`; drop TABLE if exists `dragon_orders`;
CREATE TABLE `dragon_orders` CREATE TABLE `dragon_orders`
( (
`mid` bigint unsigned NOT NULL AUTO_INCREMENT, `mid` bigint unsigned NOT NULL AUTO_INCREMENT,
`order_id` varchar(200) NOT NULL DEFAULT '0' COMMENT 'order_id',
`status` tinyint NOT NULL DEFAULT '0' COMMENT '订单状态', `status` tinyint NOT NULL DEFAULT '0' COMMENT '订单状态',
`code` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '订单支付编号', `code` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '订单支付编号',
`type` varchar(20) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '订单类型', `type` varchar(20) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '订单类型',
...@@ -38,7 +39,7 @@ CREATE TABLE `dragon_orders` ...@@ -38,7 +39,7 @@ CREATE TABLE `dragon_orders`
drop TABLE if exists `dragon_order_logs`; drop TABLE if exists `dragon_order_logs`;
CREATE TABLE `dragon_order_logs` CREATE TABLE `dragon_order_logs`
( (
`mid` bigint unsigned NOT NULL AUTO_INCREMENT, `mid` bigint unsigned NOT NULL AUTO_INCREMENT,
`order_id` bigint NOT NULL COMMENT '订单id', `order_id` bigint NOT NULL COMMENT '订单id',
`payment_type` varchar(20) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '支付类型', `payment_type` varchar(20) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '支付类型',
`content` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '支付通知内容', `content` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '支付通知内容',
...@@ -56,7 +57,8 @@ CREATE TABLE `dragon_order_logs` ...@@ -56,7 +57,8 @@ CREATE TABLE `dragon_order_logs`
drop TABLE if exists `dragon_order_refunds`; drop TABLE if exists `dragon_order_refunds`;
CREATE TABLE `dragon_order_refunds` CREATE TABLE `dragon_order_refunds`
( (
`mid` bigint unsigned NOT NULL AUTO_INCREMENT, `mid` bigint unsigned NOT NULL AUTO_INCREMENT,
`order_refund_id` varchar(200) NOT NULL DEFAULT '0' COMMENT 'order_refund_id',
`order_id` bigint NOT NULL COMMENT '订单id', `order_id` bigint NOT NULL COMMENT '订单id',
`status` tinyint NOT NULL DEFAULT '0' COMMENT '订单退款状态', `status` tinyint NOT NULL DEFAULT '0' COMMENT '订单退款状态',
`code` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '订单退款编号', `code` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '订单退款编号',
...@@ -85,7 +87,7 @@ CREATE TABLE `dragon_order_refunds` ...@@ -85,7 +87,7 @@ CREATE TABLE `dragon_order_refunds`
drop TABLE if exists `dragon_order_refund_logs`; drop TABLE if exists `dragon_order_refund_logs`;
CREATE TABLE `dragon_order_refund_logs` CREATE TABLE `dragon_order_refund_logs`
( (
`mid` bigint unsigned NOT NULL AUTO_INCREMENT, `mid` bigint unsigned NOT NULL AUTO_INCREMENT,
`order_id` bigint NOT NULL COMMENT '订单id', `order_id` bigint NOT NULL COMMENT '订单id',
`order_refund_id` bigint NOT NULL COMMENT '退款订单id', `order_refund_id` bigint NOT NULL COMMENT '退款订单id',
`refund_type` varchar(20) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '退款类型', `refund_type` varchar(20) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '退款类型',
......
...@@ -17,65 +17,65 @@ import java.time.Duration; ...@@ -17,65 +17,65 @@ import java.time.Duration;
@Configuration @Configuration
public class RedisStreamConfig { public class RedisStreamConfig {
//
@Autowired // @Autowired
private RedisPayReceiver redisPayReceiver; // private RedisPayReceiver redisPayReceiver;
@Autowired // @Autowired
private RedisRefundReceiver redisRefundReceiver; // private RedisRefundReceiver redisRefundReceiver;
//
@Bean // @Bean
public Subscription subscriptionPay0(RedisConnectionFactory factory) { // public Subscription subscriptionPay0(RedisConnectionFactory factory) {
var options = StreamMessageListenerContainer // var options = StreamMessageListenerContainer
.StreamMessageListenerContainerOptions // .StreamMessageListenerContainerOptions
.builder() // .builder()
.pollTimeout(Duration.ofMillis(1)) // .pollTimeout(Duration.ofMillis(1))
.build(); // .build();
var listenerContainer = StreamMessageListenerContainer.create(factory, options); // var listenerContainer = StreamMessageListenerContainer.create(factory, options);
var subscription = listenerContainer.receiveAutoAck(Consumer.from("dragon-pay-group", "dragon-pay-0"), // var subscription = listenerContainer.receiveAutoAck(Consumer.from("dragon-pay-group", "dragon-pay-0"),
StreamOffset.create("dragon-pay", ReadOffset.lastConsumed()), redisPayReceiver); // StreamOffset.create("dragon-pay", ReadOffset.lastConsumed()), redisPayReceiver);
listenerContainer.start(); // listenerContainer.start();
return subscription; // return subscription;
} // }
//
@Bean // @Bean
public Subscription subscriptionPay1(RedisConnectionFactory factory) { // public Subscription subscriptionPay1(RedisConnectionFactory factory) {
var options = StreamMessageListenerContainer // var options = StreamMessageListenerContainer
.StreamMessageListenerContainerOptions // .StreamMessageListenerContainerOptions
.builder() // .builder()
.pollTimeout(Duration.ofMillis(1)) // .pollTimeout(Duration.ofMillis(1))
.build(); // .build();
var listenerContainer = StreamMessageListenerContainer.create(factory, options); // var listenerContainer = StreamMessageListenerContainer.create(factory, options);
var subscription = listenerContainer.receiveAutoAck(Consumer.from("dragon-pay-group", "dragon-pay-1"), // var subscription = listenerContainer.receiveAutoAck(Consumer.from("dragon-pay-group", "dragon-pay-1"),
StreamOffset.create("dragon-pay", ReadOffset.lastConsumed()), redisPayReceiver); // StreamOffset.create("dragon-pay", ReadOffset.lastConsumed()), redisPayReceiver);
listenerContainer.start(); // listenerContainer.start();
return subscription; // return subscription;
} // }
//
@Bean // @Bean
public Subscription subscriptionRefund0(RedisConnectionFactory factory) { // public Subscription subscriptionRefund0(RedisConnectionFactory factory) {
var options = StreamMessageListenerContainer // var options = StreamMessageListenerContainer
.StreamMessageListenerContainerOptions // .StreamMessageListenerContainerOptions
.builder() // .builder()
.pollTimeout(Duration.ofMillis(1)) // .pollTimeout(Duration.ofMillis(1))
.build(); // .build();
var listenerContainer = StreamMessageListenerContainer.create(factory, options); // var listenerContainer = StreamMessageListenerContainer.create(factory, options);
var subscription = listenerContainer.receiveAutoAck(Consumer.from("dragon-refund-group", "dragon-refund-0"), // var subscription = listenerContainer.receiveAutoAck(Consumer.from("dragon-refund-group", "dragon-refund-0"),
StreamOffset.create("dragon-refund", ReadOffset.lastConsumed()), redisRefundReceiver); // StreamOffset.create("dragon-refund", ReadOffset.lastConsumed()), redisRefundReceiver);
listenerContainer.start(); // listenerContainer.start();
return subscription; // return subscription;
} // }
//
@Bean // @Bean
public Subscription subscriptionRefund1(RedisConnectionFactory factory) { // public Subscription subscriptionRefund1(RedisConnectionFactory factory) {
var options = StreamMessageListenerContainer // var options = StreamMessageListenerContainer
.StreamMessageListenerContainerOptions // .StreamMessageListenerContainerOptions
.builder() // .builder()
.pollTimeout(Duration.ofMillis(1)) // .pollTimeout(Duration.ofMillis(1))
.build(); // .build();
var listenerContainer = StreamMessageListenerContainer.create(factory, options); // var listenerContainer = StreamMessageListenerContainer.create(factory, options);
var subscription = listenerContainer.receiveAutoAck(Consumer.from("dragon-refund-group", "dragon-refund-1"), // var subscription = listenerContainer.receiveAutoAck(Consumer.from("dragon-refund-group", "dragon-refund-1"),
StreamOffset.create("dragon-refund", ReadOffset.lastConsumed()), redisRefundReceiver); // StreamOffset.create("dragon-refund", ReadOffset.lastConsumed()), redisRefundReceiver);
listenerContainer.start(); // listenerContainer.start();
return subscription; // return subscription;
} // }
} }
package com.liquidnet.service.dragon.controller; package com.liquidnet.service.dragon.controller;
import com.liquidnet.service.base.ResponseDto; import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.dragon.dto.DragonRefundAppDto;
import com.liquidnet.service.dragon.service.IDragonOrderRefundsService; import com.liquidnet.service.dragon.service.IDragonOrderRefundsService;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
@RestController @RestController
@RequestMapping("refund") @RequestMapping("refund")
...@@ -28,7 +30,20 @@ public class RefundController { ...@@ -28,7 +30,20 @@ public class RefundController {
@ApiOperation("支付宝退款") @ApiOperation("支付宝退款")
@ApiResponse(code = 200, message = "接口返回对象参数") @ApiResponse(code = 200, message = "接口返回对象参数")
public ResponseDto<String> refundAliPay() { public ResponseDto<String> refundAliPay() {
// orderRefundsService.aliPayRefund();
return ResponseDto.success(); return ResponseDto.success();
} }
@PostMapping("refundSingle")
@ApiOperation("单条退款")
@ApiResponse(code = 200, message = "接口返回对象参数")
public ResponseDto<DragonRefundAppDto> refundSingle(@RequestParam(value = "orderCode") @NotNull(message = "订单号不能为空") String orderCode,
@RequestParam(value = "code") @NotNull(message = "支付单能为空") String code,
@RequestParam(value = "orderRefundCode") @NotNull(message = "退款单号不能为空") String orderRefundCode,
@RequestParam(value = "reason") @NotNull(message = "退款原因不能为空") String reason,
@RequestParam(value = "notifyUrl") @NotNull(message = "回调地址不能为空") String returnUrl,
@RequestParam(value = "price") @NotNull(message = "价格不能为空") BigDecimal price,
@RequestParam(value = "paymentType") @NotNull(message = "支付类型不能为空") String paymentType,
@RequestParam(value = "paymentId") @NotNull(message = "支付订单号不能为空") String paymentId) {
return orderRefundsService.dragonRefund(orderCode, code, orderRefundCode, reason, returnUrl, price, paymentType, paymentId);
}
} }
package com.liquidnet.service.dragon.service.impl; package com.liquidnet.service.dragon.service.impl;
import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayClient; import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient; import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradeRefundRequest; import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundResponse; import com.alipay.api.response.AlipayTradeRefundResponse;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.base.SqlMapping;
import com.liquidnet.service.dragon.constant.DragonConstant;
import com.liquidnet.service.dragon.dto.DragonRefundAppDto;
import com.liquidnet.service.dragon.dto.DragonRefundChannelDto;
import com.liquidnet.service.dragon.dto.RefundContentDto;
import com.liquidnet.service.dragon.service.IDragonOrderRefundsService; import com.liquidnet.service.dragon.service.IDragonOrderRefundsService;
import com.liquidnet.service.dragon.utils.PayAlipayUtils; import com.liquidnet.service.dragon.utils.PayAlipayUtils;
import com.liquidnet.service.dragon.utils.PayWepayUtils; import com.liquidnet.service.dragon.utils.PayWepayUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity; import org.apache.http.entity.StringEntity;
import org.apache.http.util.EntityUtils; import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.stream.MapRecord;
import org.springframework.data.redis.connection.stream.StreamRecords;
import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.LinkedList;
@Slf4j
@Service @Service
public class DragonOrderRefundsServiceImpl implements IDragonOrderRefundsService { public class DragonOrderRefundsServiceImpl implements IDragonOrderRefundsService {
...@@ -28,15 +44,6 @@ public class DragonOrderRefundsServiceImpl implements IDragonOrderRefundsService ...@@ -28,15 +44,6 @@ public class DragonOrderRefundsServiceImpl implements IDragonOrderRefundsService
@Override @Override
public void sendRedisQueue() { public void sendRedisQueue() {
// try {
// HashMap<String ,String> map = new HashMap<>();
// map.put("message","测试 redis 订阅信息1");
// MapRecord<String, String, String> record = StreamRecords.mapBacked(map).withStreamKey("dragon-refund");
// stringRedisTemplate.opsForStream().add(record);
// }catch (Exception e){
// e.printStackTrace();
// }
try { try {
PayWepayUtils payWepayUtils = new PayWepayUtils(); PayWepayUtils payWepayUtils = new PayWepayUtils();
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi"); HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi");
...@@ -71,30 +78,158 @@ public class DragonOrderRefundsServiceImpl implements IDragonOrderRefundsService ...@@ -71,30 +78,158 @@ public class DragonOrderRefundsServiceImpl implements IDragonOrderRefundsService
} }
@Override @Override
public void dragonRefund(String trade_no, String out_trade_no, String reason, String returnUrl, BigDecimal price) { public ResponseDto<DragonRefundAppDto> dragonRefund(String orderCode, String code, String orderRefundCode, String reason, String notifyUrl, BigDecimal price, String paymentType, String paymentId) {
LocalDateTime nowTime = LocalDateTime.now();
String refundCode = IDGenerator.refundCode();
String orderRefundId = IDGenerator.nextSnowId();
//创建退款单
boolean insertResult = sendMySqlRedis(
SqlMapping.get("dragon_order_refund.insert"),
new Object[]{orderRefundId, refundCode, orderRefundCode, price, reason, notifyUrl, paymentType, nowTime, nowTime}
);
if (insertResult) {
switch (paymentType) {
case DragonConstant.REFUND_TYPE_APP_ALIPAY:
aliPayRefund(orderRefundId, orderRefundCode, code, reason, price, paymentId, paymentType, nowTime);
break;
case DragonConstant.REFUND_TYPE_WAP_ALIPAY:
aliPayRefund(orderRefundId, orderRefundCode, code, reason, price, paymentId, paymentType, nowTime);
break;
case DragonConstant.REFUND_TYPE_WEB_ALIPAY:
aliPayRefund(orderRefundId, orderRefundCode, code, reason, price, paymentId, paymentType, nowTime);
break;
}
DragonRefundAppDto refundAppDto = new DragonRefundAppDto();
refundAppDto.setOrderCode(orderCode);
refundAppDto.setCode(code);
refundAppDto.setOrderRefundCode(orderRefundCode);
refundAppDto.setRefundCode(refundCode);
return ResponseDto.success(refundAppDto);
} else {
return ResponseDto.failure("退款失败");
}
} }
@Override
public void weyPayRefund() { public void weyPayRefund() {
} }
@Override
public void aliPayRefund(String trade_no, String out_trade_no, String reason, String returnUrl, BigDecimal price) { public DragonRefundChannelDto aliPayRefund(String orderRefundId, String refundCode, String code, String reason, BigDecimal price, String paymentId, String paymentType, LocalDateTime nowTime) {
PayAlipayUtils payAlipayUtils = new PayAlipayUtils(); String refundStatus;
DragonRefundChannelDto channelDto = new DragonRefundChannelDto();
RefundContentDto contentDto = new RefundContentDto();
AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();//创建API对应的request类
try { try {
AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();//创建API对应的request类
request.setBizContent("{" + request.setBizContent("{" +
"\"out_trade_no\":\"20210708171331569350143233340P\"," + "\"out_trade_no\":\"" + code + "\"," +
"\"trade_no\":\"2021070822001417381433077659\"," + "\"trade_no\":\"" + paymentId + "\"," +
"\"out_request_no\":\"20210708145709112413077422058T\"," + "\"out_request_no\":\"" + refundCode + "\"," +
"\"refund_amount\":\"0.01\"}"); //设置业务参数 "\"refund_reason\":\"" + reason + "\"," +
AlipayTradeRefundResponse response = PayAlipayUtils.getHttpClient().execute(request);//通过alipayClient调用API,获得对应的response类 "\"refund_amount\":\"" + price.doubleValue() + "\"}"); //设置业务参数
AlipayTradeRefundResponse response = PayAlipayUtils.getHttpClient().execute(request);//通过alipayClient调用API,获得对应的response类
System.out.print(response.getBody()); System.out.print(response.getBody());
if (response.getFundChange().equals("N") || response.getFundChange() == null) {
try {
String refundError = "";
refundStatus = DragonConstant.refundStatusEnum.STATUS_ERROR.getCode();
if (null == response.getSubMsg()) {
refundError = "退款失败,原因未知";
} else {
refundError = response.getSubMsg();
}
// 修改退款订单
sendMySqlRedis(
SqlMapping.get("dragon_order_refund_error.update"),
new Object[]{nowTime, refundError, refundStatus, orderRefundId}
);
} catch (Exception e) {
e.printStackTrace();
//保存错误信息
log.error("");
channelDto.setResult("exception");
channelDto.setMessage("update order refund with db error: " + e.getMessage());
contentDto.setRequest(JSON.toJSONString(response.getParams()));
contentDto.setResponse(response.getBody());
channelDto.setContent(contentDto);
return channelDto;
}
channelDto.setResult("error");
channelDto.setMessage(paymentType + " refund error: ");
contentDto.setRequest(JSON.toJSONString(response.getParams()));
contentDto.setResponse(response.getBody());
channelDto.setContent(contentDto);
return channelDto;
}
// 创建退款日志
sendMySqlRedis(
SqlMapping.get("dragon_order_refund_log.insert"),
new Object[]{orderRefundId, paymentType, JSON.toJSONString(response.getBody()), nowTime, nowTime}
);
try {
String refundAt = "";
if (response.getFundChange().equals("Y")) {
refundStatus = DragonConstant.refundStatusEnum.STATUS_REFUNDED.getCode();
refundAt = DateUtil.format(response.getGmtRefundPay(), DateUtil.Formatter.yyyyMMddHHmmss);
} else {
refundStatus = DragonConstant.refundStatusEnum.STATUS_REFUNDING.getCode();
}
sendMySqlRedis(
SqlMapping.get("dragon_order_refund_success.update"),
new Object[]{nowTime, refundAt, refundStatus, orderRefundId}
);
} catch (Exception e) {
e.printStackTrace();
log.error("");
channelDto.setResult("exception");
channelDto.setMessage("update order refund with db error: " + e.getMessage());
contentDto.setRequest(JSON.toJSONString(response.getParams()));
contentDto.setResponse(response.getBody());
channelDto.setContent(contentDto);
return channelDto;
}
channelDto.setResult("refunded");
channelDto.setMessage(paymentType + " refund info: ");
contentDto.setRequest(JSON.toJSONString(response.getParams()));
contentDto.setResponse(response.getBody());
channelDto.setContent(contentDto);
return channelDto;
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
log.error("");
return null;
} }
} }
/**
* 给 REDIS 队列发送消息 数据库相关
*
* @param sql sql语句
* @param data 需要操作的数据
* @return
*/
private boolean sendMySqlRedis(String sql, Object[] data) {
try {
LinkedList<String> sqls = new LinkedList<>();
sqls.add(sql);
LinkedList<Object[]> sqlsData = new LinkedList();
sqlsData.add(data);
String sqlData = SqlMapping.gets(sqls, sqlsData);
HashMap<String, String> map = new HashMap<>();
map.put("message", sqlData);
MapRecord<String, String, String> record = StreamRecords.mapBacked(map).withStreamKey(DragonConstant.mysqlRedisQueueEnum.DRAGON_REFUND_KEY.getCode());
stringRedisTemplate.opsForStream().add(record);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
private void wePayRefundCallBack() {
}
} }
...@@ -32,7 +32,7 @@ public class PayAlipayUtils { ...@@ -32,7 +32,7 @@ public class PayAlipayUtils {
public PayAlipayUtils() { public PayAlipayUtils() {
httpClient = new DefaultAlipayClient(gatewayUrl, appId, merchant_private_key, "json", charset, httpClient = new DefaultAlipayClient(gatewayUrl, appId, merchant_private_key, "json", charset,
merchant_pub_key, sign_type); //获得初始化的AlipayClient merchant_pub_key, sign_type);
} }
private static PayAlipayUtils getInstance() { private static PayAlipayUtils getInstance() {
......
# ------------------------创建退款订单---------------------------- # ------------------------创建退款订单----------------------------
dragon_order_refund.insert=INSERT INTO `dragon_order_refunds`(`order_id` ,`status` ,`ticket_id` ,`code` ,`order_refund_code` ,`price` ,`reason` ,`notify_url` ,`refund_type`,`refund_id`,`refund_error`,`refund_at`,`finished_at`,`created_at`,`updated_at`)VALUES(? ,? ,? ,? ,? ,? ,? ,? ,?,?,?,?,?,?,?); dragon_order_refund.insert=INSERT INTO `dragon_order_refunds`(`order_refund_id`,`code` ,`order_refund_code` ,`price` ,`reason` ,`notify_url` ,`refund_type`,`created_at`,`updated_at`)VALUES(?,?,?,?,?,?,?,?,?);
# ------------------------修改退款订单----------------------------
dragon_order_refund_error.update=UPDATE `dragon_order_refunds` SET updated_at = ? , refund_error=? , status=? WHERE order_refund_id = ?
dragon_order_refund_success.update=UPDATE `dragon_order_refunds` SET updated_at = ? , refund_at=? , status=? WHERE order_refund_id = ?
# ------------------------创建退款订单日志---------------------------- # ------------------------创建退款订单日志----------------------------
dragon_order_refund_log.insert=INSERT INTO `dragon_order_refunds`(`order_refund_id` ,`refund_type` ,`content`,`created_at`,`updated_at`)VALUES(?,?,?,?,?);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment