记得上下班打卡 | git大法好,push需谨慎
Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
liquidnet-bus-v1
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
董敬伟
liquidnet-bus-v1
Commits
1350071c
Commit
1350071c
authored
Mar 25, 2026
by
wangyifan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
收钱吧 回调验签
parent
c684296a
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
367 additions
and
12 deletions
+367
-12
CallbackParams.java
...vice/goblin/param/shouqianba/callback/CallbackParams.java
+26
-0
CouponCallbackContent.java
...blin/param/shouqianba/callback/CouponCallbackContent.java
+103
-0
OrderCallbackContent.java
...oblin/param/shouqianba/callback/OrderCallbackContent.java
+100
-0
RefundCallbackContent.java
...blin/param/shouqianba/callback/RefundCallbackContent.java
+70
-0
IGoblinShouQianBaService.java
...dnet/service/goblin/service/IGoblinShouQianBaService.java
+8
-0
GoblinShouqianbaController.java
...service/goblin/controller/GoblinShouqianbaController.java
+55
-3
GoblinShouQianBaServiceImpl.java
...vice/goblin/service/impl/GoblinShouQianBaServiceImpl.java
+5
-9
No files found.
liquidnet-bus-api/liquidnet-service-goblin-api/src/main/java/com/liquidnet/service/goblin/param/shouqianba/callback/CallbackParams.java
0 → 100644
View file @
1350071c
package
com
.
liquidnet
.
service
.
goblin
.
param
.
shouqianba
.
callback
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Data
;
@Data
@ApiModel
(
value
=
"CallbackParams"
,
description
=
"收钱吧微信小店订单推送请求体"
)
public
class
CallbackParams
{
@ApiModelProperty
(
value
=
"推送事件ID,全局唯一"
,
example
=
"2024013000594610646"
)
private
Long
eventId
;
@ApiModelProperty
(
value
=
"推送时间戳,当前时间毫秒值"
,
example
=
"1706679507593"
)
private
Long
timestamp
;
@ApiModelProperty
(
value
=
"随机字串,用于签名"
,
example
=
"j9xd5kc7ixcryy7at5rrrv24xty783th"
)
private
String
nonce
;
@ApiModelProperty
(
value
=
"订单数据 JSON字符串 (详见 SqbOrderContentDTO)"
)
private
String
content
;
@ApiModelProperty
(
value
=
"报文签名"
,
example
=
"bryyeKJ6opUothNTz1s3+F98LOl2Teji6T4XcEAejxdt..."
)
private
String
signature
;
}
liquidnet-bus-api/liquidnet-service-goblin-api/src/main/java/com/liquidnet/service/goblin/param/shouqianba/callback/CouponCallbackContent.java
0 → 100644
View file @
1350071c
package
com
.
liquidnet
.
service
.
goblin
.
param
.
shouqianba
.
callback
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Data
;
import
java.util.List
;
@Data
@ApiModel
(
value
=
"SqbVoucherStatusDTO"
,
description
=
"收钱吧券状态推送内容详情"
)
public
class
CouponCallbackContent
{
@ApiModelProperty
(
value
=
"订单Sn"
)
private
String
orderSn
;
@ApiModelProperty
(
value
=
"商城Sn"
)
private
String
mallSn
;
@ApiModelProperty
(
value
=
"商户Sn"
)
private
String
merchantSn
;
@ApiModelProperty
(
value
=
"门店id"
)
private
String
storeId
;
@ApiModelProperty
(
value
=
"券列表信息"
)
private
List
<
VoucherItem
>
voucherList
;
@Data
@ApiModel
(
"VoucherItem"
)
public
static
class
VoucherItem
{
@ApiModelProperty
(
value
=
"券号"
)
private
String
voucherNo
;
@ApiModelProperty
(
value
=
"类型"
)
private
String
type
;
@ApiModelProperty
(
value
=
"券状态 (0未核销, 1已核销, 2未核销退款, 3已核销退款中, 4未核销退款完成, 5已核销退款完成, 6已失效)"
)
private
Byte
targetState
;
@ApiModelProperty
(
value
=
"券原状态"
)
private
Byte
sourceState
;
@ApiModelProperty
(
value
=
"券名称"
)
private
String
voucherName
;
@ApiModelProperty
(
value
=
"操作时间 (yyyy-MM-dd HH:mm:ss)"
)
private
String
operationTime
;
@ApiModelProperty
(
value
=
"券对应的商品信息"
)
private
VoucherProductInfo
item
;
@ApiModelProperty
(
value
=
"券二维码地址"
)
private
String
qrCodeUrl
;
@ApiModelProperty
(
value
=
"券二维码内容"
)
private
String
qrCodeContent
;
@ApiModelProperty
(
value
=
"原金额 (单位:分)"
)
private
Long
oriAmount
;
@ApiModelProperty
(
value
=
"实收金额 (单位:分)"
)
private
Long
receivedAmount
;
@ApiModelProperty
(
value
=
"核销信息 (已核销会有这部分)"
)
private
RedeemInfo
redeemInfo
;
}
@Data
@ApiModel
(
"VoucherProductInfo"
)
public
static
class
VoucherProductInfo
{
@ApiModelProperty
(
value
=
"spuId"
)
private
Long
spuId
;
@ApiModelProperty
(
value
=
"skuId"
)
private
Long
skuId
;
@ApiModelProperty
(
value
=
"商品标题"
)
private
String
title
;
@ApiModelProperty
(
value
=
"商品图片地址"
)
private
String
img
;
}
@Data
@ApiModel
(
"RedeemInfo"
)
public
static
class
RedeemInfo
{
@ApiModelProperty
(
value
=
"操作来源 (如: EXTERN)"
)
private
String
redeemSource
;
@ApiModelProperty
(
value
=
"操作appId"
)
private
String
redeemAppId
;
@ApiModelProperty
(
value
=
"客户端编码"
)
private
String
redeemClientSn
;
@ApiModelProperty
(
value
=
"外部编码 (appId + 请求号)"
)
private
String
redeemExternalOrderSn
;
@ApiModelProperty
(
value
=
"操作商户 (userId)"
)
private
String
operatorMerchantId
;
}
}
liquidnet-bus-api/liquidnet-service-goblin-api/src/main/java/com/liquidnet/service/goblin/param/shouqianba/callback/OrderCallbackContent.java
0 → 100644
View file @
1350071c
package
com
.
liquidnet
.
service
.
goblin
.
param
.
shouqianba
.
callback
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Data
;
import
java.math.BigDecimal
;
import
java.util.List
;
@Data
@ApiModel
(
value
=
"OrderCallbackContent"
,
description
=
"收钱吧订单推送 Content 具体数据"
)
public
class
OrderCallbackContent
{
@ApiModelProperty
(
value
=
"订单号"
,
example
=
"71655367906162"
)
private
String
orderSn
;
@ApiModelProperty
(
value
=
"支付流水号列表"
,
example
=
"[\"7894259297368060\"]"
)
private
List
<
String
>
payTsnList
;
@ApiModelProperty
(
value
=
"终端号"
,
example
=
"2101056320290541156"
)
private
String
terminalSn
;
@ApiModelProperty
(
value
=
"门店号"
,
example
=
"21590000000630325"
)
private
String
storeSn
;
@ApiModelProperty
(
value
=
"商城名称"
,
example
=
"智能商城0206-17:35"
)
private
String
mallName
;
@ApiModelProperty
(
value
=
"订单金额"
,
example
=
"2"
)
private
BigDecimal
orderAmount
;
@ApiModelProperty
(
value
=
"创建时间"
,
example
=
"2024-02-20 10:46:32"
)
private
String
createdAt
;
@ApiModelProperty
(
value
=
"订单状态码 0:已创建 10:已支付 35:已完成 40:已取消"
,
example
=
"35"
)
private
Integer
orderStateCode
;
@ApiModelProperty
(
value
=
"商品明细列表"
)
private
List
<
Item
>
items
;
@ApiModelProperty
(
value
=
"收集的信息 JSON字符串"
,
example
=
"[{\"type\":\"text\",\"form\":\"basic\",\"fieldName\":\"姓名\",\"content\":\"\"}]"
)
private
String
collectedInfo
;
@ApiModelProperty
(
value
=
"预订单编码"
)
private
List
<
String
>
preOrderSns
;
@ApiModelProperty
(
value
=
"订单签名"
)
private
String
orderSignature
;
@ApiModelProperty
(
value
=
"支付的代客下单数据"
)
private
List
<
PreOrder
>
preOrderList
;
@Data
@ApiModel
(
value
=
"商品明细"
)
public
static
class
Item
{
@ApiModelProperty
(
value
=
"商品标题"
)
private
String
title
;
@ApiModelProperty
(
value
=
"规格描述"
)
private
String
skuDesc
;
@ApiModelProperty
(
value
=
"数量"
)
private
String
quantity
;
@ApiModelProperty
(
value
=
"单位"
)
private
String
unit
;
}
@Data
@ApiModel
(
value
=
"采集数据"
)
public
static
class
CollectedInfo
{
@ApiModelProperty
(
value
=
"控件类型"
)
private
String
type
;
@ApiModelProperty
(
value
=
"控件格式"
)
private
String
form
;
@ApiModelProperty
(
value
=
"字段名"
)
private
String
fieldName
;
@ApiModelProperty
(
value
=
"采集数据内容"
)
private
String
content
;
}
@Data
@ApiModel
(
value
=
"支付的代客下单数据"
)
public
static
class
PreOrder
{
@ApiModelProperty
(
value
=
"预订单id"
)
private
String
preOrderId
;
@ApiModelProperty
(
value
=
"预订单编号"
)
private
String
preOrderSn
;
@ApiModelProperty
(
value
=
"请求号"
)
private
String
requestId
;
}
}
liquidnet-bus-api/liquidnet-service-goblin-api/src/main/java/com/liquidnet/service/goblin/param/shouqianba/callback/RefundCallbackContent.java
0 → 100644
View file @
1350071c
package
com
.
liquidnet
.
service
.
goblin
.
param
.
shouqianba
.
callback
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Data
;
import
java.util.List
;
@Data
@ApiModel
(
value
=
"SqbRefundContentDTO"
,
description
=
"收钱吧退款推送内容详情"
)
public
class
RefundCallbackContent
{
@ApiModelProperty
(
value
=
"售后单号 (全局唯一)"
,
example
=
"71582143744560"
)
private
String
ticketSn
;
@ApiModelProperty
(
value
=
"订单号"
,
example
=
"2101056320290513285"
)
private
String
orderSn
;
@ApiModelProperty
(
value
=
"原状态"
)
private
Integer
sourceState
;
@ApiModelProperty
(
value
=
"目标状态 (20:完成, 15:退款完成, 0:创建, 10:退款中, 30:取消退款)"
,
example
=
"15"
)
private
Integer
targetState
;
@ApiModelProperty
(
value
=
"下单金额 (单位:分)"
,
example
=
"100"
)
private
Long
amount
;
@ApiModelProperty
(
value
=
"申请金额 (单位:分)"
,
example
=
"100"
)
private
Long
applyAmount
;
@ApiModelProperty
(
value
=
"请求号"
)
private
String
requestId
;
@ApiModelProperty
(
value
=
"来源 (如: EXTERN)"
)
private
String
requestSource
;
@ApiModelProperty
(
value
=
"退款的商品信息"
)
private
SqbRefundItemContainer
item
;
@Data
@ApiModel
(
"SqbRefundItemContainer"
)
public
static
class
SqbRefundItemContainer
{
@ApiModelProperty
(
value
=
"退款类型 (1:商品, 2:金额)"
)
private
Byte
type
;
@ApiModelProperty
(
value
=
"商品明细列表"
)
private
List
<
SqbRefundItemDetail
>
items
;
}
@Data
@ApiModel
(
"SqbRefundItemDetail"
)
public
static
class
SqbRefundItemDetail
{
@ApiModelProperty
(
value
=
"spu id"
)
private
String
spuId
;
@ApiModelProperty
(
value
=
"sku id"
)
private
String
skuId
;
@ApiModelProperty
(
value
=
"标题"
)
private
String
title
;
@ApiModelProperty
(
value
=
"数量"
)
private
String
quantity
;
@ApiModelProperty
(
value
=
"退款类型 (0:正常商品, 1:自定义商品)"
)
private
Byte
type
;
}
}
liquidnet-bus-api/liquidnet-service-goblin-api/src/main/java/com/liquidnet/service/goblin/service/IGoblinShouQianBaService.java
View file @
1350071c
package
com
.
liquidnet
.
service
.
goblin
.
service
;
import
com.liquidnet.service.goblin.param.shouqianba.callback.CallbackParams
;
import
com.liquidnet.service.goblin.param.shouqianba.request.*
;
import
com.liquidnet.service.goblin.param.shouqianba.response.data.*
;
...
...
@@ -95,4 +96,11 @@ public interface IGoblinShouQianBaService {
* @return
*/
List
<
MallProductsQueryData
>
queryMallProducts
(
MallProductsQueryRequest
request
);
/**
* 验签
* @param callbackParams
* @return
*/
boolean
verifySignature
(
CallbackParams
callbackParams
);
}
liquidnet-bus-service/liquidnet-service-goblin/liquidnet-service-goblin-impl/src/main/java/com/liquidnet/service/goblin/controller/GoblinShouqianbaController.java
View file @
1350071c
package
com
.
liquidnet
.
service
.
goblin
.
controller
;
import
com.liquidnet.commons.lang.util.JsonUtils
;
import
com.liquidnet.service.base.ResponseDto
;
import
com.liquidnet.service.goblin.param.shouqianba.callback.CallbackParams
;
import
com.liquidnet.service.goblin.param.shouqianba.callback.CouponCallbackContent
;
import
com.liquidnet.service.goblin.param.shouqianba.callback.OrderCallbackContent
;
import
com.liquidnet.service.goblin.param.shouqianba.callback.RefundCallbackContent
;
import
com.liquidnet.service.goblin.service.IGoblinShouQianBaService
;
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.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
;
...
...
@@ -14,22 +22,66 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping
(
"/sqb"
)
public
class
GoblinShouqianbaController
{
@Autowired
private
IGoblinShouQianBaService
shouQianBaService
;
@ApiOperation
(
"下单回调"
)
@PostMapping
(
"/order/callback"
)
public
ResponseDto
<
Boolean
>
orderCallback
()
{
public
ResponseDto
<
Boolean
>
orderCallback
(
@RequestBody
CallbackParams
callbackParams
)
{
if
(
null
==
callbackParams
)
{
log
.
error
(
"下单回调参数为空"
);
return
ResponseDto
.
failure
(
"下单回调参数为空"
);
}
boolean
verified
=
shouQianBaService
.
verifySignature
(
callbackParams
);
if
(!
verified
)
{
log
.
error
(
"下单回调验签失败"
);
return
ResponseDto
.
failure
(
"验签失败"
);
}
OrderCallbackContent
orderCallbackContent
=
JsonUtils
.
fromJson
(
callbackParams
.
getContent
(),
OrderCallbackContent
.
class
);
log
.
info
(
"下单回调content: {}"
,
callbackParams
.
getContent
());
//TODO 业务
return
ResponseDto
.
success
();
}
@ApiOperation
(
"退款回调"
)
@PostMapping
(
"/refund/callback"
)
public
ResponseDto
<
Boolean
>
refundCallback
()
{
public
ResponseDto
<
Boolean
>
refundCallback
(
@RequestBody
CallbackParams
callbackParams
)
{
if
(
null
==
callbackParams
)
{
log
.
error
(
"退款回调参数为空"
);
return
ResponseDto
.
failure
(
"退款回调参数为空"
);
}
boolean
verified
=
shouQianBaService
.
verifySignature
(
callbackParams
);
if
(!
verified
)
{
log
.
error
(
"退款回调验签失败"
);
return
ResponseDto
.
failure
(
"验签失败"
);
}
RefundCallbackContent
refundCallbackContent
=
JsonUtils
.
fromJson
(
callbackParams
.
getContent
(),
RefundCallbackContent
.
class
);
log
.
info
(
"退款回调content: {}"
,
callbackParams
.
getContent
());
//TODO 业务
return
ResponseDto
.
success
();
}
@ApiOperation
(
"券状态回调"
)
@PostMapping
(
"/coupon/callback"
)
public
ResponseDto
<
Boolean
>
couponCallback
()
{
public
ResponseDto
<
Boolean
>
couponCallback
(
@RequestBody
CallbackParams
callbackParams
)
{
if
(
null
==
callbackParams
)
{
log
.
error
(
"券状态回调参数为空"
);
return
ResponseDto
.
failure
(
"券状态回调参数为空"
);
}
boolean
verified
=
shouQianBaService
.
verifySignature
(
callbackParams
);
if
(!
verified
)
{
log
.
error
(
"券状态回调验签失败"
);
return
ResponseDto
.
failure
(
"验签失败"
);
}
CouponCallbackContent
callbackContent
=
JsonUtils
.
fromJson
(
callbackParams
.
getContent
(),
CouponCallbackContent
.
class
);
log
.
info
(
"券状态回调content: {}"
,
callbackParams
.
getContent
());
//TODO 业务
return
ResponseDto
.
success
();
}
...
...
liquidnet-bus-service/liquidnet-service-goblin/liquidnet-service-goblin-impl/src/main/java/com/liquidnet/service/goblin/service/impl/GoblinShouQianBaServiceImpl.java
View file @
1350071c
...
...
@@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import
com.liquidnet.commons.lang.util.HttpUtil
;
import
com.liquidnet.commons.lang.util.MD5Utils
;
import
com.liquidnet.service.goblin.config.properties.ShouqianbaProperties
;
import
com.liquidnet.service.goblin.param.shouqianba.callback.CallbackParams
;
import
com.liquidnet.service.goblin.param.shouqianba.request.*
;
import
com.liquidnet.service.goblin.param.shouqianba.response.*
;
import
com.liquidnet.service.goblin.param.shouqianba.response.data.*
;
...
...
@@ -223,17 +224,12 @@ public class GoblinShouQianBaServiceImpl implements IGoblinShouQianBaService {
/**
* 收钱吧回调推送验签
*
* @param signature 收钱吧推送来的签名 (signature)
* @param eventId 事件ID (eventId)
* @param timestamp 时间戳 (timestamp)
* @param nonce 随机数 (nonce)
* @param content 业务数据报文 (content)
* @return 验签是否通过
* @param callbackParams@return 验签是否通过
*/
public
boolean
verifySignature
(
String
signature
,
String
eventId
,
String
timestamp
,
String
nonce
,
String
content
)
{
public
boolean
verifySignature
(
CallbackParams
callbackParams
)
{
// 签名原串 = eventId + timestamp + nonce + content
String
plaintext
=
eventId
+
timestamp
+
nonce
+
content
;
return
verifySignatureSHA256WithRSA
(
plaintext
,
signature
,
shouqianbaProperties
.
getPublicKey
());
String
plaintext
=
callbackParams
.
getEventId
()
+
callbackParams
.
getTimestamp
()
+
callbackParams
.
getNonce
()
+
callbackParams
.
getContent
()
;
return
verifySignatureSHA256WithRSA
(
plaintext
,
callbackParams
.
getSignature
()
,
shouqianbaProperties
.
getPublicKey
());
}
public
boolean
verifySignatureSHA256WithRSA
(
String
plaintext
,
String
inputSignature
,
String
pubKey
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment