Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
X
xinrenli
Overview
Overview
Details
Activity
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
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
郑云飞
xinrenli
Commits
c47aeba4
Commit
c47aeba4
authored
Apr 06, 2023
by
郑云飞
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
支付功能完善
parent
e86b0ede
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
232 additions
and
26 deletions
+232
-26
yongqi-admin/src/main/resources/application-dev.yml
+1
-0
yongqi-common/src/main/java/com/yongqi/common/core/config/WxPayConfiguration.java
+1
-0
yongqi-common/src/main/java/com/yongqi/common/core/config/WxPayProperties.java
+5
-0
yongqi-common/src/main/java/com/yongqi/common/utils/ip/AddressUtils.java
+46
-0
yongqi-common/src/main/java/com/yongqi/common/utils/redis/CodeUtils.java
+70
-0
yongqi-xinrenli/src/main/java/com/yongqi/xinrenli/controller/DbOrderController.java
+18
-2
yongqi-xinrenli/src/main/java/com/yongqi/xinrenli/domain/vo/WxPayOrderResult.java
+44
-0
yongqi-xinrenli/src/main/java/com/yongqi/xinrenli/enums/OrderStatusEnum.java
+4
-5
yongqi-xinrenli/src/main/java/com/yongqi/xinrenli/service/IDbOrderService.java
+9
-3
yongqi-xinrenli/src/main/java/com/yongqi/xinrenli/service/impl/DbOrderServiceImpl.java
+34
-16
No files found.
yongqi-admin/src/main/resources/application-dev.yml
View file @
c47aeba4
...
...
@@ -176,6 +176,7 @@ wx:
subAppId
:
#服务商模式下的子商户公众账号ID
subMchId
:
#服务商模式下的子商户号
keyPath
:
C:\\ProgramData\\certKey\xinrenli\\apiclient_cert.p12
# p12证书的位置,可以指定绝对路径,也可以指定类路径(以classpath:开头)
notifyUrl
:
http://xinrenli.nyinhong.com/api//xinrenli/order/notify
# 微信支付回调接口
# mp:
# useRedis: false
# redisConfig:
...
...
yongqi-common/src/main/java/com/yongqi/common/core/config/WxPayConfiguration.java
View file @
c47aeba4
...
...
@@ -31,6 +31,7 @@ public class WxPayConfiguration {
payConfig
.
setSubAppId
(
StringUtils
.
trimToNull
(
this
.
properties
.
getSubAppId
()));
payConfig
.
setSubMchId
(
StringUtils
.
trimToNull
(
this
.
properties
.
getSubMchId
()));
payConfig
.
setKeyPath
(
StringUtils
.
trimToNull
(
this
.
properties
.
getKeyPath
()));
payConfig
.
setNotifyUrl
(
StringUtils
.
trimToNull
(
this
.
properties
.
getNotifyUrl
()));
// 可以指定是否使用沙箱环境
payConfig
.
setUseSandboxEnv
(
false
);
...
...
yongqi-common/src/main/java/com/yongqi/common/core/config/WxPayProperties.java
View file @
c47aeba4
...
...
@@ -41,4 +41,9 @@ public class WxPayProperties {
*/
private
String
keyPath
;
/**
* 支付回调接口
*/
private
String
notifyUrl
;
}
yongqi-common/src/main/java/com/yongqi/common/utils/ip/AddressUtils.java
View file @
c47aeba4
...
...
@@ -12,6 +12,10 @@ import lombok.AccessLevel;
import
lombok.NoArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
javax.servlet.http.HttpServletRequest
;
import
java.net.InetAddress
;
import
java.net.UnknownHostException
;
/**
* 获取地址类
*
...
...
@@ -57,4 +61,46 @@ public class AddressUtils {
}
return
UNKNOWN
;
}
/**
* 获取ip
* @param request
* @return
*/
public
static
String
getIpAddr
(
HttpServletRequest
request
)
{
String
ipAddress
;
try
{
ipAddress
=
request
.
getHeader
(
"x-forwarded-for"
);
if
(
ipAddress
==
null
||
ipAddress
.
length
()
==
0
||
"unknown"
.
equalsIgnoreCase
(
ipAddress
))
{
ipAddress
=
request
.
getHeader
(
"Proxy-Client-IP"
);
}
if
(
ipAddress
==
null
||
ipAddress
.
length
()
==
0
||
"unknown"
.
equalsIgnoreCase
(
ipAddress
))
{
ipAddress
=
request
.
getHeader
(
"WL-Proxy-Client-IP"
);
}
if
(
ipAddress
==
null
||
ipAddress
.
length
()
==
0
||
"unknown"
.
equalsIgnoreCase
(
ipAddress
))
{
ipAddress
=
request
.
getRemoteAddr
();
if
(
ipAddress
.
equals
(
"127.0.0.1"
))
{
// 根据网卡取本机配置的IP
InetAddress
inet
=
null
;
try
{
inet
=
InetAddress
.
getLocalHost
();
}
catch
(
UnknownHostException
e
)
{
log
.
error
(
e
.
getMessage
(),
e
);
}
ipAddress
=
inet
.
getHostAddress
();
}
}
// 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
if
(
ipAddress
!=
null
&&
ipAddress
.
length
()
>
15
)
{
// "***.***.***.***".length()
// = 15
if
(
ipAddress
.
indexOf
(
","
)
>
0
)
{
ipAddress
=
ipAddress
.
substring
(
0
,
ipAddress
.
indexOf
(
","
));
}
}
}
catch
(
Exception
e
)
{
ipAddress
=
""
;
}
return
ipAddress
;
}
}
yongqi-common/src/main/java/com/yongqi/common/utils/redis/CodeUtils.java
0 → 100644
View file @
c47aeba4
package
com
.
yongqi
.
common
.
utils
.
redis
;
import
cn.hutool.core.util.ObjectUtil
;
import
cn.hutool.core.util.RandomUtil
;
import
com.yongqi.common.utils.DateUtils
;
import
lombok.extern.slf4j.Slf4j
;
import
java.time.Duration
;
import
java.util.Random
;
import
java.util.concurrent.TimeUnit
;
@Slf4j
public
class
CodeUtils
{
public
static
String
next
(
String
type
)
{
return
next
(
type
,
4
);
}
public
static
String
next
(
String
type
,
int
limit
)
{
return
type
+
DateUtils
.
dateTimeNow
(
"yyyyMMdd"
)
+
autoGenericCode
(
RandomUtil
.
randomInt
(
getMax
(
limit
)),
limit
);
}
private
static
String
autoGenericCode
(
int
code
,
int
num
)
{
// System.out.println(code);
String
result
=
""
;
// 保留num的位数
// num 代表长度为4
// d 代表参数为正数型
result
=
String
.
format
(
"%0"
+
num
+
"d"
,
code
);
return
result
;
}
private
static
Integer
getMax
(
int
limit
)
{
String
a
=
""
;
for
(
int
i
=
0
;
i
<
limit
;
i
++)
{
a
=
a
+
"9"
;
}
return
Integer
.
valueOf
(
a
);
}
private
static
String
random
(){
Random
random
=
new
Random
();
int
ends
=
random
.
nextInt
(
99
);
return
autoGenericCode
(
ends
,
2
);
}
public
static
String
createSerialNumber
(
String
type
)
{
Object
object
=
RedisUtils
.
getCacheObject
(
type
);
int
num
=
0
;
if
(
ObjectUtil
.
isEmpty
(
object
))
{
RedisUtils
.
setCacheObject
(
type
,
1
,
Duration
.
ofMillis
(-
1
));
num
=
1
;
}
else
{
num
=
Integer
.
parseInt
(
object
.
toString
());
}
log
.
info
(
"redis中的编码为:{}"
,
num
);
String
code
=
autoGenericCode
(
num
,
4
);
RedisUtils
.
setCacheObject
(
type
,
num
+
1
);
return
type
+
DateUtils
.
dateTimeNow
(
"yyMMdd"
)
+
code
+
random
();
}
public
static
void
main
(
String
[]
args
)
{
// System.out.println(next("KBHMD"));
// createSerialNumber("KBHMD");
System
.
out
.
println
(
createSerialNumber
(
"KBHMD"
));
}
}
yongqi-xinrenli/src/main/java/com/yongqi/xinrenli/controller/DbOrderController.java
View file @
c47aeba4
...
...
@@ -5,15 +5,18 @@ import java.util.Arrays;
import
com.yongqi.common.core.domain.model.LoginUser
;
import
com.yongqi.common.helper.LoginHelper
;
import
com.yongqi.common.utils.ip.AddressUtils
;
import
com.yongqi.xinrenli.domain.DbOrder
;
import
com.yongqi.xinrenli.domain.bo.DbOrderEditBo
;
import
com.yongqi.xinrenli.domain.vo.ReportFormsVo
;
import
lombok.RequiredArgsConstructor
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
javax.validation.constraints.*
;
import
cn.dev33.satoken.annotation.SaCheckPermission
;
import
org.aspectj.weaver.ast.Var
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.validation.annotation.Validated
;
import
com.yongqi.common.annotation.RepeatSubmit
;
...
...
@@ -146,10 +149,23 @@ public class DbOrderController extends BaseController {
@Log
(
title
=
"下单"
,
businessType
=
BusinessType
.
DELETE
)
@RequestMapping
(
"/orderPay"
)
public
R
orderPay
(
@NotNull
(
message
=
"主键不能为空"
)
@RequestParam
(
"id"
)
Long
orderId
,
@RequestParam
(
value
=
"id"
,
required
=
false
)
Long
couponId
)
{
,
@RequestParam
(
value
=
"id"
,
required
=
false
)
Long
couponId
,
HttpServletRequest
request
)
{
LoginUser
loginUser
=
LoginHelper
.
getLoginUser
();
return
iDbOrderService
.
orderPay
(
orderId
,
couponId
,
loginUser
);
String
ipAddr
=
AddressUtils
.
getIpAddr
(
request
);
return
iDbOrderService
.
orderPay
(
orderId
,
couponId
,
loginUser
,
ipAddr
);
}
/**
* 下单
*/
@SaCheckPermission
(
"xinrenli:order:notify"
)
@Log
(
title
=
"下单"
,
businessType
=
BusinessType
.
DELETE
)
@RequestMapping
(
"/notify"
)
public
R
payCallback
(
@RequestBody
String
xmlData
)
{
return
iDbOrderService
.
payCallback
(
xmlData
);
}
/**
* 报表
*/
...
...
yongqi-xinrenli/src/main/java/com/yongqi/xinrenli/domain/vo/WxPayOrderResult.java
0 → 100644
View file @
c47aeba4
package
com
.
yongqi
.
xinrenli
.
domain
.
vo
;
import
com.fasterxml.jackson.annotation.JsonFormat
;
import
lombok.Data
;
import
org.springframework.format.annotation.DateTimeFormat
;
import
java.time.LocalDateTime
;
/**
* @author Administrator
*/
@Data
public
class
WxPayOrderResult
{
/**
* 微信生成的预支付会话标识
*/
private
String
prepayId
;
/**
* 交易类型
*/
private
String
tradeType
;
private
String
timeStamp
;
/**
* 随机字符串
*/
private
String
nonceStr
;
/**
* 签名
*/
private
String
sign
;
/**
* 签名方式
*/
private
String
signType
=
"MD5"
;
/**
* 支付时间
*/
@DateTimeFormat
(
pattern
=
"yyyy/MM/dd HH:mm:ss"
)
@JsonFormat
(
pattern
=
"yyyy/MM/dd HH:mm:ss"
)
private
LocalDateTime
createTime
;
}
yongqi-xinrenli/src/main/java/com/yongqi/xinrenli/enums/OrderStatusEnum.java
View file @
c47aeba4
...
...
@@ -10,11 +10,10 @@ public enum OrderStatusEnum {
PUBLISHED
(
0
,
"已发布"
),
REJECTED
(
1
,
"已驳回"
),
TO_BE_PAID
(
2
,
"待支付"
),
PAYMENT_IN_PROGRESS
(
3
,
"支付中"
),
RECEIVED_ORDER
(
4
,
"已接单"
),
FINISHED
(
5
,
"已完成"
),
REFUBD_IN_PROGRESS
(
6
,
"退款中"
),
REFUNDED
(
7
,
"已退款"
),
RECEIVED_ORDER
(
3
,
"已接单"
),
FINISHED
(
4
,
"已完成"
),
REFUBD_IN_PROGRESS
(
5
,
"退款中"
),
REFUNDED
(
6
,
"已退款"
),
;
private
final
Integer
code
;
...
...
yongqi-xinrenli/src/main/java/com/yongqi/xinrenli/service/IDbOrderService.java
View file @
c47aeba4
package
com
.
yongqi
.
xinrenli
.
service
;
import
com.github.binarywang.wxpay.exception.WxPayException
;
import
com.yongqi.common.core.domain.R
;
import
com.yongqi.common.core.domain.model.LoginUser
;
import
com.yongqi.xinrenli.domain.DbOrder
;
import
com.yongqi.xinrenli.domain.bo.DbOrderEditBo
;
import
com.yongqi.xinrenli.domain.vo.DbOrderVo
;
import
com.yongqi.xinrenli.domain.bo.DbOrderBo
;
...
...
@@ -10,7 +10,6 @@ import com.yongqi.common.core.page.TableDataInfo;
import
com.yongqi.common.core.domain.PageQuery
;
import
com.yongqi.xinrenli.domain.vo.ReportFormsVo
;
import
java.util.Collection
;
import
java.util.List
;
/**
...
...
@@ -69,7 +68,7 @@ public interface IDbOrderService {
*/
TableDataInfo
<
DbOrderVo
>
homeList
(
DbOrderBo
bo
,
PageQuery
pageQuery
);
R
orderPay
(
Long
id
,
Long
couponId
,
LoginUser
loginUser
);
R
orderPay
(
Long
id
,
Long
couponId
,
LoginUser
loginUser
,
String
ipAddr
);
ReportFormsVo
reportForms
();
...
...
@@ -80,4 +79,11 @@ public interface IDbOrderService {
* @return
*/
Integer
unpaidJob
();
/**
* 支付回调
* @param xmlData
* @return
*/
R
payCallback
(
String
xmlData
)
throws
WxPayException
;
}
yongqi-xinrenli/src/main/java/com/yongqi/xinrenli/service/impl/DbOrderServiceImpl.java
View file @
c47aeba4
package
com
.
yongqi
.
xinrenli
.
service
.
impl
;
import
cn.binarywang.wx.miniapp.api.WxMaService
;
import
cn.hutool.core.bean.BeanUtil
;
import
com.alibaba.fastjson.JSON
;
import
com.baomidou.mybatisplus.core.toolkit.ObjectUtils
;
import
com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult
;
import
com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest
;
import
com.github.binarywang.wxpay.constant.WxPayConstants
;
import
com.github.binarywang.wxpay.exception.WxPayException
;
import
com.github.binarywang.wxpay.service.WxPayService
;
import
com.yongqi.common.core.domain.R
;
import
com.yongqi.common.core.domain.entity.SysUser
;
import
com.yongqi.common.core.domain.model.LoginUser
;
import
com.yongqi.common.utils.StringUtils
;
import
com.yongqi.common.core.page.TableDataInfo
;
...
...
@@ -16,19 +16,20 @@ import com.yongqi.common.core.domain.PageQuery;
import
com.baomidou.mybatisplus.extension.plugins.pagination.Page
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.toolkit.Wrappers
;
import
com.yongqi.common.utils.redis.CodeUtils
;
import
com.yongqi.xinrenli.domain.DbCoupon
;
import
com.yongqi.xinrenli.domain.DbFile
;
import
com.yongqi.xinrenli.domain.bo.DbFileBo
;
import
com.yongqi.xinrenli.domain.bo.DbOrderEditBo
;
import
com.yongqi.xinrenli.domain.vo.DbFileVo
;
import
com.yongqi.xinrenli.domain.vo.ReportFormsVo
;
import
com.yongqi.xinrenli.domain.vo.WxPayOrderResult
;
import
com.yongqi.xinrenli.enums.DeleteStatusEnum
;
import
com.yongqi.xinrenli.enums.FileEnumServiceType
;
import
com.yongqi.xinrenli.enums.OrderStatusEnum
;
import
com.yongqi.xinrenli.mapper.DbCouponMapper
;
import
com.yongqi.xinrenli.mapper.DbFileMapper
;
import
com.yongqi.xinrenli.service.IDbCouponService
;
import
lombok.Data
;
import
lombok.RequiredArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
com.yongqi.xinrenli.domain.bo.DbOrderBo
;
...
...
@@ -47,6 +48,7 @@ import java.util.*;
* @author zyf
* @date 2023-03-09
*/
@Slf4j
@RequiredArgsConstructor
@Service
public
class
DbOrderServiceImpl
implements
IDbOrderService
{
...
...
@@ -278,13 +280,15 @@ public class DbOrderServiceImpl implements IDbOrderService {
/**
* 下单
*
* @param orderId 订单id
* @param couponId 优惠券id
* @param loginUser 当前登录用户
* @param ipAddr
* @return
*/
@Override
public
R
orderPay
(
Long
orderId
,
Long
couponId
,
LoginUser
loginUser
)
{
public
R
orderPay
(
Long
orderId
,
Long
couponId
,
LoginUser
loginUser
,
String
ipAddr
)
{
// 1.根据订单id获取订单信息
DbOrder
dbOrder
=
this
.
baseMapper
.
selectById
(
orderId
);
// 2.根据卡券id获取卡券信息
...
...
@@ -296,7 +300,8 @@ public class DbOrderServiceImpl implements IDbOrderService {
BigDecimal
payAmount
=
dbOrder
.
getActualAmount
().
subtract
(
dbCoupon
.
getFullSubtraction
());
dbOrder
.
setPayAmount
(
payAmount
);
dbOrder
.
setUseCouponId
(
couponId
);
dbOrder
.
setStatus
();
String
orderNo
=
CodeUtils
.
createSerialNumber
(
"XQ"
);
dbOrder
.
setOrderNo
(
orderNo
);
// 4.组装支付数据
WxPayUnifiedOrderRequest
request
=
new
WxPayUnifiedOrderRequest
();
// 需求标题
...
...
@@ -306,30 +311,30 @@ public class DbOrderServiceImpl implements IDbOrderService {
}
request
.
setBody
(
join
);
// 商户订单号
request
.
setOutTradeNo
(
consumerOrder
.
getOrderCode
());
// 子商户号
request
.
setSubMchId
(
dealer
.
getWxShopNo
());
BigDecimal
actualPrice
=
consumerOrder
.
getFinalPrice
().
multiply
(
BigDecimal
.
valueOf
(
100
));
request
.
setOutTradeNo
(
orderNo
);
BigDecimal
actualPrice
=
payAmount
.
multiply
(
BigDecimal
.
valueOf
(
100
));
// 标价金额
request
.
setTotalFee
((
actualPrice
.
intValue
()));
// 客户端IP
request
.
setSpbillCreateIp
(
ip
);
request
.
setSpbillCreateIp
(
ip
Addr
);
// 交易类型
request
.
setTradeType
(
WxPayConstants
.
TradeType
.
JSAPI
);
// 签名类型,默认为MD5,支持HMAC-SHA256和MD5。
request
.
setSignType
(
WxPayConstants
.
SignType
.
MD5
);
// 用户标识
request
.
setOpenid
(
wx
User
.
getOpenId
());
request
.
setOpenid
(
login
User
.
getOpenId
());
// 5.调用微信统一下单接口
try
{
wxPayService
.
createOrder
(
request
);
Object
order
=
wxPayService
.
createOrder
(
request
);
String
json
=
JSON
.
toJSONString
(
order
);
WxPayOrderResult
result
=
JSON
.
parseObject
(
json
,
WxPayOrderResult
.
class
);
// 6.返回支付所需数据
return
R
.
ok
(
result
);
}
catch
(
WxPayException
e
)
{
throw
new
RuntimeException
(
e
);
}
return
null
;
}
/**
...
...
@@ -353,4 +358,17 @@ public class DbOrderServiceImpl implements IDbOrderService {
public
Integer
unpaidJob
()
{
return
baseMapper
.
unpaidJob
();
}
/**
* 支付回调
* @param xmlData
* @return
*/
@Override
public
R
payCallback
(
String
xmlData
)
throws
WxPayException
{
final
WxPayOrderNotifyResult
notifyResult
=
wxPayService
.
parseOrderNotifyResult
(
xmlData
);
log
.
info
(
"支付回调参数解析:{}"
,
notifyResult
);
// 1.查询订单信息
return
null
;
}
}
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