Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
T
travel-cloud
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
cloud
travel-cloud
Commits
7b568604
提交
7b568604
authored
12月 09, 2024
作者:
hzh
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
订单回调功能实现
上级
a2b2f4de
隐藏空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
227 行增加
和
1 行删除
+227
-1
pom.xml
ruoyi-modules/ruoyi-order/pom.xml
+7
-0
AbstractBaseService.java
...main/java/org/dromara/order/base/AbstractBaseService.java
+8
-0
IBaseService.java
...er/src/main/java/org/dromara/order/base/IBaseService.java
+8
-1
OrderController.java
...in/java/org/dromara/order/controller/OrderController.java
+54
-0
IOrderPayService.java
...main/java/org/dromara/order/service/IOrderPayService.java
+17
-0
WeChatOrderPayServiceImpl.java
...dromara/order/service/impl/WeChatOrderPayServiceImpl.java
+133
-0
没有找到文件。
ruoyi-modules/ruoyi-order/pom.xml
浏览文件 @
7b568604
...
@@ -109,6 +109,13 @@
...
@@ -109,6 +109,13 @@
<version>
2.9.9
</version>
<version>
2.9.9
</version>
</dependency>
</dependency>
<dependency>
<groupId>
javax.servlet
</groupId>
<artifactId>
servlet-api
</artifactId>
<version>
2.5
</version>
<scope>
provided
</scope>
</dependency>
</dependencies>
</dependencies>
<build>
<build>
...
...
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/base/AbstractBaseService.java
浏览文件 @
7b568604
package
org
.
dromara
.
order
.
base
;
package
org
.
dromara
.
order
.
base
;
import
cn.hutool.core.collection.CollectionUtil
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.toolkit.Wrappers
;
import
com.baomidou.mybatisplus.core.toolkit.Wrappers
;
import
com.baomidou.mybatisplus.extension.plugins.pagination.Page
;
import
com.baomidou.mybatisplus.extension.plugins.pagination.Page
;
...
@@ -39,6 +40,13 @@ public abstract class AbstractBaseService<V, B, T> implements IBaseService<V, B,
...
@@ -39,6 +40,13 @@ public abstract class AbstractBaseService<V, B, T> implements IBaseService<V, B,
return
mapper
().
selectVoList
(
lqw
);
return
mapper
().
selectVoList
(
lqw
);
}
}
@Override
public
V
getOne
(
B
bo
)
{
LambdaQueryWrapper
<
T
>
lqw
=
buildQueryWrapper
(
bo
);
List
<
V
>
list
=
mapper
().
selectVoList
(
lqw
);
return
CollectionUtil
.
isEmpty
(
list
)
?
null
:
list
.
get
(
0
);
}
@Override
@Override
public
Boolean
insertByBo
(
B
bo
)
{
public
Boolean
insertByBo
(
B
bo
)
{
Class
<
T
>
clazz
=
(
Class
<
T
>)
GenericsUtils
.
getSuperClassGenricType
(
this
.
getClass
(),
2
);
Class
<
T
>
clazz
=
(
Class
<
T
>)
GenericsUtils
.
getSuperClassGenricType
(
this
.
getClass
(),
2
);
...
...
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/base/IBaseService.java
浏览文件 @
7b568604
...
@@ -34,10 +34,17 @@ public interface IBaseService<V, B, T> {
...
@@ -34,10 +34,17 @@ public interface IBaseService<V, B, T> {
* 查询符合条件的列表
* 查询符合条件的列表
*
*
* @param bo 查询条件
* @param bo 查询条件
* @return
雷彪
* @return
结果
*/
*/
List
<
V
>
queryList
(
B
bo
);
List
<
V
>
queryList
(
B
bo
);
/**
* 查询符合条件的单个
* @param bo bo
* @return 结果
*/
V
getOne
(
B
bo
);
/**
/**
* 新增
* 新增
*
*
...
...
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/controller/OrderController.java
浏览文件 @
7b568604
package
org
.
dromara
.
order
.
controller
;
package
org
.
dromara
.
order
.
controller
;
import
cn.dev33.satoken.annotation.SaCheckPermission
;
import
cn.dev33.satoken.annotation.SaCheckPermission
;
import
cn.hutool.http.ContentType
;
import
cn.hutool.json.JSONUtil
;
import
com.alibaba.fastjson.JSON
;
import
com.google.common.collect.ImmutableMap
;
import
com.ijpay.core.kit.HttpKit
;
import
jakarta.servlet.http.HttpServletResponse
;
import
jakarta.servlet.http.HttpServletResponse
;
import
jakarta.validation.constraints.NotEmpty
;
import
jakarta.validation.constraints.NotEmpty
;
import
jakarta.validation.constraints.NotNull
;
import
jakarta.validation.constraints.NotNull
;
import
lombok.RequiredArgsConstructor
;
import
lombok.RequiredArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.dromara.common.core.domain.R
;
import
org.dromara.common.core.domain.R
;
import
org.dromara.common.core.validate.AddGroup
;
import
org.dromara.common.core.validate.AddGroup
;
import
org.dromara.common.core.validate.EditGroup
;
import
org.dromara.common.core.validate.EditGroup
;
...
@@ -17,11 +23,16 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
...
@@ -17,11 +23,16 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
import
org.dromara.common.web.core.BaseController
;
import
org.dromara.common.web.core.BaseController
;
import
org.dromara.order.domain.bo.OrderBo
;
import
org.dromara.order.domain.bo.OrderBo
;
import
org.dromara.order.domain.vo.OrderVo
;
import
org.dromara.order.domain.vo.OrderVo
;
import
org.dromara.order.service.IOrderPayService
;
import
org.dromara.order.service.IOrderService
;
import
org.dromara.order.service.IOrderService
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.bind.annotation.*
;
import
javax.servlet.http.HttpServletRequest
;
import
java.nio.charset.StandardCharsets
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
/**
/**
* 订单费用
* 订单费用
...
@@ -30,6 +41,7 @@ import java.util.List;
...
@@ -30,6 +41,7 @@ import java.util.List;
* @author hzh
* @author hzh
* @date 2024-12-05
* @date 2024-12-05
*/
*/
@Slf4j
@Validated
@Validated
@RequiredArgsConstructor
@RequiredArgsConstructor
@RestController
@RestController
...
@@ -37,6 +49,7 @@ import java.util.List;
...
@@ -37,6 +49,7 @@ import java.util.List;
public
class
OrderController
extends
BaseController
{
public
class
OrderController
extends
BaseController
{
private
final
IOrderService
orderService
;
private
final
IOrderService
orderService
;
private
final
IOrderPayService
orderPayService
;
/**
/**
* 查询订单费用列表
* 查询订单费用列表
...
@@ -104,4 +117,45 @@ public class OrderController extends BaseController {
...
@@ -104,4 +117,45 @@ public class OrderController extends BaseController {
@PathVariable
Long
[]
ids
)
{
@PathVariable
Long
[]
ids
)
{
return
toAjax
(
orderService
.
deleteWithValidByIds
(
List
.
of
(
ids
),
true
));
return
toAjax
(
orderService
.
deleteWithValidByIds
(
List
.
of
(
ids
),
true
));
}
}
/**
* 回调原函数
*
* @param request request
* @param response response
*/
@RequestMapping
(
value
=
"/v3/payNotify"
,
method
=
{
RequestMethod
.
POST
,
RequestMethod
.
GET
})
public
void
payNotify
(
HttpServletRequest
request
,
HttpServletResponse
response
)
{
Map
<
String
,
String
>
map
=
new
HashMap
<>(
12
);
try
{
log
.
info
(
"微信回调开始"
);
ImmutableMap
.
Builder
<
String
,
String
>
builder
=
ImmutableMap
.<
String
,
String
>
builder
()
.
put
(
"timestamp"
,
request
.
getHeader
(
"Wechatpay-Timestamp"
))
.
put
(
"nonce"
,
request
.
getHeader
(
"Wechatpay-Nonce"
))
.
put
(
"serialNo"
,
request
.
getHeader
(
"Wechatpay-Serial"
))
.
put
(
"signature"
,
request
.
getHeader
(
"Wechatpay-Signature"
))
.
put
(
"result"
,
HttpKit
.
readData
(
request
));
boolean
result
=
orderPayService
.
notify
(
JSON
.
toJSONString
(
builder
));
if
(
result
)
{
response
.
setStatus
(
200
);
map
.
put
(
"code"
,
"SUCCESS"
);
map
.
put
(
"message"
,
"SUCCESS"
);
}
else
{
response
.
setStatus
(
500
);
map
.
put
(
"code"
,
"ERROR"
);
map
.
put
(
"message"
,
"签名错误"
);
}
response
.
setHeader
(
"Content-type"
,
ContentType
.
JSON
.
toString
());
response
.
getOutputStream
().
write
(
JSONUtil
.
toJsonStr
(
map
).
getBytes
(
StandardCharsets
.
UTF_8
));
response
.
flushBuffer
();
}
catch
(
Exception
e
)
{
log
.
error
(
"系统异常"
,
e
);
}
}
}
}
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/IOrderPayService.java
0 → 100644
浏览文件 @
7b568604
package
org
.
dromara
.
order
.
service
;
/**
* @author hzh
* @date 2024-12-09
**/
public
interface
IOrderPayService
{
/**
* 支付回调
*
* @param body 回调参数
* @return 回调结果
*/
boolean
notify
(
String
body
);
}
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/WeChatOrderPayServiceImpl.java
0 → 100644
浏览文件 @
7b568604
package
org
.
dromara
.
order
.
service
.
impl
;
import
cn.hutool.core.bean.BeanUtil
;
import
cn.hutool.core.date.DatePattern
;
import
cn.hutool.core.date.DateUtil
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONObject
;
import
com.ijpay.core.kit.PayKit
;
import
com.ijpay.core.kit.WxPayKit
;
import
io.seata.spring.annotation.GlobalTransactional
;
import
lombok.RequiredArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
org.dromara.order.api.enums.OrderStatus
;
import
org.dromara.order.config.WechatPayConfiguration
;
import
org.dromara.order.domain.bo.OrderBo
;
import
org.dromara.order.domain.bo.OrderTradeBo
;
import
org.dromara.order.domain.vo.OrderTradeVo
;
import
org.dromara.order.domain.vo.OrderVo
;
import
org.dromara.order.service.IOrderPayService
;
import
org.dromara.order.service.IOrderService
;
import
org.dromara.order.service.IOrderTradeService
;
import
org.springframework.stereotype.Service
;
import
java.math.BigDecimal
;
import
java.math.RoundingMode
;
import
java.security.cert.X509Certificate
;
import
java.util.Date
;
import
java.util.Objects
;
/**
* @author hzh
* @date 2024-12-09
**/
@Slf4j
@Service
@RequiredArgsConstructor
public
class
WeChatOrderPayServiceImpl
implements
IOrderPayService
{
private
final
WechatPayConfiguration
config
;
private
final
IOrderTradeService
orderTradeService
;
private
final
IOrderService
orderService
;
@GlobalTransactional
(
rollbackFor
=
Exception
.
class
)
@Override
public
boolean
notify
(
String
body
)
{
log
.
info
(
"微信支付回调参数:{}"
,
body
);
JSONObject
bodyJson
=
JSONObject
.
parseObject
(
body
);
try
{
// 需要通过证书序列号查找对应的证书,verifyNotify 中有验证证书的序列号
String
plainText
=
WxPayKit
.
verifyNotify
(
getSerialNumber
(),
bodyJson
.
getString
(
"result"
),
bodyJson
.
getString
(
"signature"
),
bodyJson
.
getString
(
"nonce"
),
bodyJson
.
getString
(
"timestamp"
),
config
.
getApiKey3
(),
config
.
getPlatformCertPath
());
log
.
info
(
"支付通知明文 {}"
,
plainText
);
JSONObject
resJson
=
JSON
.
parseObject
(
plainText
);
//支付订单号
String
orderPayNo
=
resJson
.
getString
(
"out_trade_no"
);
String
tradeState
=
resJson
.
getString
(
"trade_state"
);
OrderTradeVo
orderTrade
=
orderTradeService
.
getOne
(
new
OrderTradeBo
().
setOrderPayNo
(
orderPayNo
));
if
(
Objects
.
isNull
(
orderTrade
))
{
throw
new
RuntimeException
(
"交易订单不存在"
);
}
if
(!
StringUtils
.
equals
(
tradeState
,
orderTrade
.
getTradeState
()))
{
//更新订单信息
String
successTimeStr
=
resJson
.
getString
(
"success_time"
);
//支付完成时间
Date
payTime
=
StringUtils
.
isEmpty
(
successTimeStr
)
?
null
:
DateUtil
.
parse
(
successTimeStr
);
//微信支付订单号
String
transactionId
=
resJson
.
getString
(
"transaction_id"
);
JSONObject
amount
=
JSON
.
parseObject
(
resJson
.
getString
(
"amount"
));
//支付金额
int
actualPayAmount
=
amount
.
getInteger
(
"payer_total"
);
//获取openId
String
payOpenId
=
JSON
.
parseObject
(
resJson
.
getString
(
"payer"
)).
getString
(
"openid"
);
orderTrade
.
setPayOpenId
(
payOpenId
);
orderTrade
.
setPayTime
(
payTime
);
orderTrade
.
setTransactionId
(
transactionId
);
orderTrade
.
setActualPayAmount
(
new
BigDecimal
(
actualPayAmount
).
divide
(
new
BigDecimal
(
100
),
2
,
RoundingMode
.
CEILING
));
orderTrade
.
setTradeState
(
tradeState
);
orderTrade
.
setTradeInfo
(
JSON
.
toJSONString
(
resJson
));
orderTradeService
.
updateByBo
(
BeanUtil
.
copyProperties
(
orderTrade
,
OrderTradeBo
.
class
));
//跟新主表信息
OrderVo
order
=
orderService
.
getOne
(
new
OrderBo
().
setOrderNo
(
orderTrade
.
getOrderNo
()));
order
.
setOrderPayNo
(
orderPayNo
);
order
.
setActualPayAmount
(
orderTrade
.
getActualPayAmount
());
order
.
setPayTime
(
new
Date
());
order
.
setStatus
(
OrderStatus
.
PAYED
.
getCode
());
orderService
.
updateByBo
(
BeanUtil
.
copyProperties
(
order
,
OrderBo
.
class
));
}
return
true
;
}
catch
(
Exception
e
)
{
log
.
error
(
"系统异常"
,
e
);
return
false
;
}
}
/**
* 商户 API 证书序列号
*/
private
String
serialNo
;
/**
* 获取证书序列号
*
* @return 证书序列号
*/
private
String
getSerialNumber
()
{
if
(
StringUtils
.
isEmpty
(
serialNo
))
{
// 获取证书序列号
X509Certificate
certificate
=
PayKit
.
getCertificate
(
config
.
getCertPath
());
if
(
null
!=
certificate
)
{
serialNo
=
certificate
.
getSerialNumber
().
toString
(
16
).
toUpperCase
();
// 提前两天检查证书是否有效
boolean
isValid
=
PayKit
.
checkCertificateIsValid
(
certificate
,
config
.
getMchId
(),
-
2
);
log
.
info
(
"证书是否可用 {} 证书有效期为 {}"
,
isValid
,
DateUtil
.
format
(
certificate
.
getNotAfter
(),
DatePattern
.
NORM_DATETIME_PATTERN
));
}
}
return
serialNo
;
}
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论