diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app/TbUserMatchOrderAppController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app/TbUserMatchOrderAppController.java index 9b922d7a..af5677ca 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app/TbUserMatchOrderAppController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app/TbUserMatchOrderAppController.java @@ -1,12 +1,18 @@ package com.ruoyi.web.controller.app; +import com.huifu.adapay.core.AdapayCore; +import com.huifu.adapay.core.util.AdapaySign; import com.ruoyi.common.core.domain.Result; import com.ruoyi.web.request.AdapayReq; +import com.ruoyi.web.request.Event; import com.ruoyi.web.response.AdapayResp; import com.ruoyi.web.service.AdapayService; +import com.ruoyi.web.service.CallBackService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.Assert; import org.springframework.web.bind.annotation.*; import javax.validation.constraints.NotNull; @@ -15,6 +21,7 @@ import javax.validation.constraints.NotNull; *

开通合伙人相关接口

* @author clunt */ +@Slf4j @Api(tags = "App*开通合伙人相关接口") @RestController @RequestMapping(value = "/app/matchOrder") @@ -23,6 +30,9 @@ public class TbUserMatchOrderAppController { @Autowired private AdapayService adapayService; + @Autowired + private CallBackService callBackService; + @ResponseBody @PostMapping(value = "/pay") @ApiOperation(value = "支付接口", response = AdapayResp.class) @@ -35,4 +45,50 @@ public class TbUserMatchOrderAppController { } + @PostMapping("/callback") + public String callback(Event event) { + log.info(" 收单返回消息event" + event); + //验签请参data + String data = event.getData(); + log.info(" 收单返回消息data" + data); + //验签请参sign + String sign = event.getSign(); + boolean verifySign = false; + try { + verifySign = verifySign(data, sign); + } catch (Exception e) { + log.error("签名验证失败 {}", e.getMessage()); + } + if (verifySign) { + //Event事件类型 + String type = event.getType(); + if("payment.succeeded".equals(type) || "payment.failed".equals(type)){ + callBackService.onCallback(event); + }else{ + return "NG"; + } + return "OK"; + } + log.warn("签名验证失败 data=[{}], sign=[{}]", data, sign); + return "NG"; + } + + /** + * 校验签名 + * + * @param data AdapayCallback.data + * @param sign AdapayCallback.sign + * @return TRUE=校验成功 + */ + private boolean verifySign(String data, String sign) throws Exception { + Assert.hasText(data, "data is blank!"); + Assert.hasText(sign, "sign is blank!"); + //验签请参publicKey + String publicKey = AdapayCore.PUBLIC_KEY; + log.debug("验签请参:data={}sign={}", data, sign); + //验签 + return AdapaySign.verifySign(data, sign, publicKey); + } + + } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/request/Event.java b/ruoyi-admin/src/main/java/com/ruoyi/web/request/Event.java new file mode 100644 index 00000000..ae01da52 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/request/Event.java @@ -0,0 +1,35 @@ +package com.ruoyi.web.request; + +import com.alibaba.fastjson.annotation.JSONField; +import lombok.Data; + +@Data +public class Event { + /** + * 由 Adapay 生成的支付对象 id, 该 id 在 Adapay 系统内唯一 + */ + private String id; + /** + * 签名 + */ + private String sign; + /** + * 支付创建时的 10 位时间戳 + */ + @JSONField(name = "created_time") + private Long createdTime; + /** + * 是否 prod模式,true 是 prod模式,false 是 mock模式 + */ + @JSONField(name = "created_time") + private String prodMode; + /** + * Event 事件类型 + */ + private String type; + /** + * Adapay回调接口传过来的数据,内容为JSON字符串 + * 不同的Event事件有不同的data + */ + private String data; +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/service/CallBackService.java b/ruoyi-admin/src/main/java/com/ruoyi/web/service/CallBackService.java new file mode 100644 index 00000000..ad777299 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/service/CallBackService.java @@ -0,0 +1,15 @@ +package com.ruoyi.web.service; + +import com.ruoyi.web.request.Event; + +/** + *

adapy支付回调

+ * @author clunt + */ +public interface CallBackService { + /** + * @param event 回调 + */ + void onCallback(Event event); + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/service/impl/AdapayServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/web/service/impl/AdapayServiceImpl.java index 62659f1c..ec0ee7c6 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/service/impl/AdapayServiceImpl.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/service/impl/AdapayServiceImpl.java @@ -4,6 +4,8 @@ import com.alibaba.fastjson.JSONObject; import com.huifu.adapay.core.exception.BaseAdaPayException; import com.huifu.adapay.model.Payment; import com.ruoyi.common.utils.ExceptionUtil; +import com.ruoyi.system.domain.TbUserMatchOrder; +import com.ruoyi.system.service.ITbUserMatchOrderService; import com.ruoyi.web.core.config.AdapayConfig; import com.ruoyi.web.request.AdapayReq; import com.ruoyi.web.response.AdapayResp; @@ -12,6 +14,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.math.BigDecimal; import java.util.HashMap; import java.util.Map; @@ -22,16 +25,20 @@ public class AdapayServiceImpl implements AdapayService { @Autowired private AdapayConfig adapayConfig; + @Autowired + private ITbUserMatchOrderService tbUserMatchOrderService; + @Override public AdapayResp pay(AdapayReq adapayReq) throws Exception{ AdapayResp resp = new AdapayResp(); - + String orderNo = "match_order_" + adapayReq.getUserId() + "_" + adapayReq.getOrderType() + "_" + System.currentTimeMillis(); Map paymentParams = new HashMap<>(10); paymentParams.put("adapay_connection_request_timeout", 10000); paymentParams.put("adapay_connect_timeout", 30000); paymentParams.put("adapay_socket_timeout", 30000); + paymentParams.put("notify_url", "http://www.quanmingtuodan.xyz:18000/app/matchOrder/callback"); paymentParams.put("app_id", adapayConfig.getAppId()); - paymentParams.put("order_no", "match_order_" + adapayReq.getUserId() + "_" + adapayReq.getOrderType() + "_" + System.currentTimeMillis()); + paymentParams.put("order_no", orderNo); paymentParams.put("pay_channel", "alipay"); paymentParams.put("pay_amt", "0.01"); paymentParams.put("goods_title", "全民脱单合伙人开通"); @@ -53,7 +60,18 @@ public class AdapayServiceImpl implements AdapayService { JSONObject expendJson = JSONObject.parseObject(String.valueOf(payment.get("expend"))); resp.setQrcodeUrl(expendJson.getString("pay_info")); resp.setQueryUrl(expendJson.getString("query_url")); + }else { + throw new Exception("调用支付失败"); } + // 入库生成支付记录 + TbUserMatchOrder tbUserMatchOrder = new TbUserMatchOrder(); + tbUserMatchOrder.setUserId(adapayReq.getUserId()); + tbUserMatchOrder.setOrderType(adapayReq.getOrderType()); + tbUserMatchOrder.setOrderNo(orderNo); + tbUserMatchOrder.setPayStatus("Paying"); + // 测试订单,目前均为0.01元 + tbUserMatchOrder.setOrderMoney(BigDecimal.valueOf(0.01)); + tbUserMatchOrderService.insertTbUserMatchOrder(tbUserMatchOrder); return resp; } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/service/impl/CallBackServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/web/service/impl/CallBackServiceImpl.java new file mode 100644 index 00000000..0f7100d2 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/service/impl/CallBackServiceImpl.java @@ -0,0 +1,40 @@ +package com.ruoyi.web.service.impl; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.domain.TbUserMatchOrder; +import com.ruoyi.system.service.ITbUserMatchOrderService; +import com.ruoyi.web.request.Event; +import com.ruoyi.web.service.CallBackService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; + + +@Slf4j +@Service +public class CallBackServiceImpl implements CallBackService { + + @Autowired + private ITbUserMatchOrderService userMatchOrderService; + + @Override + public void onCallback(Event event) { + log.info("支付回调: {}", event); + String data = event.getData(); + JSONObject payment = JSON.parseObject(data); + TbUserMatchOrder tbUserMatchOrder = userMatchOrderService.lambdaQuery().eq(TbUserMatchOrder::getOrderNo, payment.getString("order_no")) + .one(); + // 校验是否是本系统发出去的支付请求 + if (tbUserMatchOrder != null && StringUtils.isNotEmpty(payment.getString("status"))) { + // 更新交易记录 + tbUserMatchOrder.setPayStatus(payment.getString("status")); + userMatchOrderService.updateById(tbUserMatchOrder); + } else { + log.warn("系统中不存在这条交易记录: {}", event); + } + } +} diff --git a/ruoyi-admin/src/main/resources/application-druid.yml b/ruoyi-admin/src/main/resources/application-druid.yml index 0179740b..58025ec0 100644 --- a/ruoyi-admin/src/main/resources/application-druid.yml +++ b/ruoyi-admin/src/main/resources/application-druid.yml @@ -7,7 +7,7 @@ spring: # 主库数据源 master: url: jdbc:mysql://121.62.23.77:3306/youban?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 - username: root + username: youban password: Clunt@12345 # 从库数据源 slave: diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index fe71764b..42dbba68 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -99,6 +99,14 @@ mybatis: mybatis-plus: mapper-locations: classpath*:mapper/**/*Mapper.xml type-aliases-package: com.ruoyi.**.domain + configuration: + cache-enabled: true + use-generated-keys: true + default-executor-type: simple + log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl + global-config: + db-config: + id-type: auto # PageHelper分页插件 pagehelper: diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/TbUser.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/TbUser.java index bccea353..f85e74a5 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/TbUser.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/TbUser.java @@ -1,5 +1,7 @@ package com.ruoyi.system.domain; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -23,6 +25,7 @@ public class TbUser extends BaseEntity private static final long serialVersionUID = 1L; /** 应用用户id */ + @TableId(value = "id", type = IdType.AUTO) private Long id; /** 用户手机号 */ diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/TbUserFollow.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/TbUserFollow.java index 96efd09a..71be1fb8 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/TbUserFollow.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/TbUserFollow.java @@ -1,5 +1,7 @@ package com.ruoyi.system.domain; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -23,6 +25,7 @@ public class TbUserFollow extends BaseEntity private static final long serialVersionUID = 1L; /** 主键id */ + @TableId(value = "id", type = IdType.AUTO) private Long id; /** 用户id */ diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/TbUserImg.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/TbUserImg.java index ed51180a..b71be240 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/TbUserImg.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/TbUserImg.java @@ -1,5 +1,7 @@ package com.ruoyi.system.domain; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -23,6 +25,7 @@ public class TbUserImg extends BaseEntity private static final long serialVersionUID = 1L; /** 应用用户id */ + @TableId(value = "id", type = IdType.AUTO) private Long id; /** 用户id */ diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/TbUserMatch.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/TbUserMatch.java index b8cace13..447f53ca 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/TbUserMatch.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/TbUserMatch.java @@ -1,6 +1,8 @@ package com.ruoyi.system.domain; +import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.ruoyi.common.annotation.Excel; import com.ruoyi.common.core.domain.BaseEntity; @@ -24,6 +26,7 @@ public class TbUserMatch extends BaseEntity private static final long serialVersionUID = 1L; /** 主键id */ + @TableId(value = "id", type = IdType.AUTO) private Long id; /** 用户id */ diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/TbUserMatchOrder.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/TbUserMatchOrder.java index 6d0b7676..88625789 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/TbUserMatchOrder.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/TbUserMatchOrder.java @@ -1,6 +1,9 @@ package com.ruoyi.system.domain; import java.math.BigDecimal; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import lombok.EqualsAndHashCode; @@ -21,8 +24,10 @@ public class TbUserMatchOrder extends BaseEntity private static final long serialVersionUID = 1L; /** 主键id */ + @TableId(value = "id", type = IdType.AUTO) private Long id; + /** 用户id */ @Excel(name = "用户id") private Long userId; diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/TbUserSingle.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/TbUserSingle.java index 67304e3c..37752766 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/TbUserSingle.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/TbUserSingle.java @@ -3,7 +3,9 @@ package com.ruoyi.system.domain; import java.util.Date; import java.util.List; +import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; import com.fasterxml.jackson.annotation.JsonFormat; import com.baomidou.mybatisplus.annotation.TableName; import io.swagger.annotations.ApiModel; @@ -28,6 +30,7 @@ public class TbUserSingle extends BaseEntity private static final long serialVersionUID = 1L; /** 主键 */ + @TableId(value = "id", type = IdType.AUTO) @ApiModelProperty(value = "主键id") private Long id;