Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
wwwanlingxiao
mall
Commits
b3bc051e
Commit
b3bc051e
authored
Sep 19, 2023
by
macro
Browse files
添加支付功能
parent
9b4343e4
Changes
13
Hide whitespace changes
Inline
Side-by-side
mall-portal/pom.xml
View file @
b3bc051e
...
...
@@ -41,6 +41,13 @@
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-amqp
</artifactId>
</dependency>
<!--支付宝支付Java SDK-->
<dependency>
<groupId>
com.alipay.sdk
</groupId>
<artifactId>
alipay-sdk-java
</artifactId>
<version>
${alipay-sdk.version}
</version>
</dependency>
</dependencies>
<build>
...
...
mall-portal/src/main/java/com/macro/mall/portal/config/AlipayClientConfig.java
0 → 100644
View file @
b3bc051e
package
com.macro.mall.portal.config
;
import
com.alipay.api.AlipayClient
;
import
com.alipay.api.DefaultAlipayClient
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
/**
* @auther macrozheng
* @description 支付宝请求客户端配置
* @date 2023/9/8
* @github https://github.com/macrozheng
*/
@Configuration
public
class
AlipayClientConfig
{
@Bean
public
AlipayClient
alipayClient
(
AlipayConfig
config
){
return
new
DefaultAlipayClient
(
config
.
getGatewayUrl
(),
config
.
getAppId
(),
config
.
getAppPrivateKey
(),
config
.
getFormat
(),
config
.
getCharset
(),
config
.
getAlipayPublicKey
(),
config
.
getSignType
());
}
}
mall-portal/src/main/java/com/macro/mall/portal/config/AlipayConfig.java
0 → 100644
View file @
b3bc051e
package
com.macro.mall.portal.config
;
import
lombok.Getter
;
import
lombok.Setter
;
import
org.springframework.boot.context.properties.ConfigurationProperties
;
import
org.springframework.stereotype.Component
;
/**
* @auther macrozheng
* @description 支付宝支付相关配置
* @date 2023/9/8
* @github https://github.com/macrozheng
*/
@Getter
@Setter
@Component
@ConfigurationProperties
(
prefix
=
"alipay"
)
public
class
AlipayConfig
{
/**
* 支付宝网关
*/
private
String
gatewayUrl
;
/**
* 应用ID
*/
private
String
appId
;
/**
* 应用私钥
*/
private
String
appPrivateKey
;
/**
* 支付宝公钥
*/
private
String
alipayPublicKey
;
/**
* 用户确认支付后,支付宝调用的页面返回路径
* 开发环境为:http://localhost:8060/#/pages/money/paySuccess
*/
private
String
returnUrl
;
/**
* 支付成功后,支付宝服务器主动通知商户服务器里的异步通知回调(需要公网能访问)
* 开发环境为:http://localhost:8085/alipay/notify
*/
private
String
notifyUrl
;
/**
* 参数返回格式,只支持JSON
*/
private
String
format
=
"JSON"
;
/**
* 请求使用的编码格式
*/
private
String
charset
=
"UTF-8"
;
/**
* 生成签名字符串所使用的签名算法类型
*/
private
String
signType
=
"RSA2"
;
}
mall-portal/src/main/java/com/macro/mall/portal/controller/AlipayController.java
0 → 100644
View file @
b3bc051e
package
com.macro.mall.portal.controller
;
import
com.macro.mall.common.api.CommonResult
;
import
com.macro.mall.portal.config.AlipayConfig
;
import
com.macro.mall.portal.domain.AliPayParam
;
import
com.macro.mall.portal.service.AlipayService
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
io.swagger.v3.oas.annotations.tags.Tag
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Controller
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMethod
;
import
org.springframework.web.bind.annotation.ResponseBody
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.IOException
;
import
java.util.HashMap
;
import
java.util.Map
;
/**
* @auther macrozheng
* @description 支付宝支付Controller
* @date 2023/9/8
* @github https://github.com/macrozheng
*/
@Controller
@Api
(
tags
=
"AlipayController"
)
@Tag
(
name
=
"AlipayController"
,
description
=
"支付宝支付相关接口"
)
@RequestMapping
(
"/alipay"
)
public
class
AlipayController
{
@Autowired
private
AlipayConfig
alipayConfig
;
@Autowired
private
AlipayService
alipayService
;
@ApiOperation
(
"支付宝电脑网站支付"
)
@RequestMapping
(
value
=
"/pay"
,
method
=
RequestMethod
.
GET
)
public
void
pay
(
AliPayParam
aliPayParam
,
HttpServletResponse
response
)
throws
IOException
{
response
.
setContentType
(
"text/html;charset="
+
alipayConfig
.
getCharset
());
response
.
getWriter
().
write
(
alipayService
.
pay
(
aliPayParam
));
response
.
getWriter
().
flush
();
response
.
getWriter
().
close
();
}
@ApiOperation
(
"支付宝手机网站支付"
)
@RequestMapping
(
value
=
"/webPay"
,
method
=
RequestMethod
.
GET
)
public
void
webPay
(
AliPayParam
aliPayParam
,
HttpServletResponse
response
)
throws
IOException
{
response
.
setContentType
(
"text/html;charset="
+
alipayConfig
.
getCharset
());
response
.
getWriter
().
write
(
alipayService
.
webPay
(
aliPayParam
));
response
.
getWriter
().
flush
();
response
.
getWriter
().
close
();
}
@ApiOperation
(
value
=
"支付宝异步回调"
,
notes
=
"必须为POST请求,执行成功返回success,执行失败返回failure"
)
@RequestMapping
(
value
=
"/notify"
,
method
=
RequestMethod
.
POST
)
public
String
notify
(
HttpServletRequest
request
){
Map
<
String
,
String
>
params
=
new
HashMap
<>();
Map
<
String
,
String
[]>
requestParams
=
request
.
getParameterMap
();
for
(
String
name
:
requestParams
.
keySet
())
{
params
.
put
(
name
,
request
.
getParameter
(
name
));
}
return
alipayService
.
notify
(
params
);
}
@ApiOperation
(
value
=
"支付宝统一收单线下交易查询"
,
notes
=
"订单支付成功返回:TRADE_SUCCESS"
)
@RequestMapping
(
value
=
"/query"
,
method
=
RequestMethod
.
GET
)
@ResponseBody
public
CommonResult
<
String
>
query
(
String
outTradeNo
,
String
tradeNo
){
return
CommonResult
.
success
(
alipayService
.
query
(
outTradeNo
,
tradeNo
));
}
}
mall-portal/src/main/java/com/macro/mall/portal/domain/AliPayParam.java
0 → 100644
View file @
b3bc051e
package
com.macro.mall.portal.domain
;
import
lombok.Data
;
import
java.math.BigDecimal
;
/**
* @auther macrozheng
* @description 支付宝支付请求参数
* @date 2023/9/8
* @github https://github.com/macrozheng
*/
@Data
public
class
AliPayParam
{
/**
* 商户订单号,商家自定义,保持唯一性
*/
private
String
outTradeNo
;
/**
* 商品的标题/交易标题/订单标题/订单关键字等
*/
private
String
subject
;
/**
* 订单总金额,单位为元,精确到小数点后两位
*/
private
BigDecimal
totalAmount
;
}
mall-portal/src/main/java/com/macro/mall/portal/service/AlipayService.java
0 → 100644
View file @
b3bc051e
package
com.macro.mall.portal.service
;
import
com.macro.mall.portal.domain.AliPayParam
;
import
java.util.Map
;
/**
* @auther macrozheng
* @description 支付宝支付Service
* @date 2023/9/8
* @github https://github.com/macrozheng
*/
public
interface
AlipayService
{
/**
* 根据提交参数生成电脑支付页面
*/
String
pay
(
AliPayParam
aliPayParam
);
/**
* 支付宝异步回调处理
*/
String
notify
(
Map
<
String
,
String
>
params
);
/**
* @param outTradeNo 商户订单编号
* @param tradeNo 支付宝交易编号
* @return 支付宝交易状态
*/
String
query
(
String
outTradeNo
,
String
tradeNo
);
/**
* 根据提交参数生成手机支付页面
*/
String
webPay
(
AliPayParam
aliPayParam
);
}
mall-portal/src/main/java/com/macro/mall/portal/service/OmsPortalOrderService.java
View file @
b3bc051e
...
...
@@ -67,4 +67,10 @@ public interface OmsPortalOrderService {
* 用户根据订单ID删除订单
*/
void
deleteOrder
(
Long
orderId
);
/**
* 根据orderSn来实现的支付成功逻辑
*/
@Transactional
void
paySuccessByOrderSn
(
String
orderSn
,
Integer
payType
);
}
mall-portal/src/main/java/com/macro/mall/portal/service/impl/AlipayServiceImpl.java
0 → 100644
View file @
b3bc051e
package
com.macro.mall.portal.service.impl
;
import
cn.hutool.core.util.StrUtil
;
import
com.alibaba.fastjson.JSONObject
;
import
com.alipay.api.AlipayApiException
;
import
com.alipay.api.AlipayClient
;
import
com.alipay.api.internal.util.AlipaySignature
;
import
com.alipay.api.request.AlipayTradePagePayRequest
;
import
com.alipay.api.request.AlipayTradeQueryRequest
;
import
com.alipay.api.request.AlipayTradeWapPayRequest
;
import
com.alipay.api.response.AlipayTradeQueryResponse
;
import
com.macro.mall.mapper.OmsOrderMapper
;
import
com.macro.mall.portal.config.AlipayConfig
;
import
com.macro.mall.portal.domain.AliPayParam
;
import
com.macro.mall.portal.service.AlipayService
;
import
com.macro.mall.portal.service.OmsPortalOrderService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
java.util.Map
;
/**
* @auther macrozheng
* @description 支付宝支付Service实现类
* @date 2023/9/8
* @github https://github.com/macrozheng
*/
@Slf4j
@Service
public
class
AlipayServiceImpl
implements
AlipayService
{
@Autowired
private
AlipayConfig
alipayConfig
;
@Autowired
private
AlipayClient
alipayClient
;
@Autowired
private
OmsOrderMapper
orderMapper
;
@Autowired
private
OmsPortalOrderService
portalOrderService
;
@Override
public
String
pay
(
AliPayParam
aliPayParam
)
{
AlipayTradePagePayRequest
request
=
new
AlipayTradePagePayRequest
();
if
(
StrUtil
.
isNotEmpty
(
alipayConfig
.
getNotifyUrl
())){
//异步接收地址,公网可访问
request
.
setNotifyUrl
(
alipayConfig
.
getNotifyUrl
());
}
if
(
StrUtil
.
isNotEmpty
(
alipayConfig
.
getReturnUrl
())){
//同步跳转地址
request
.
setReturnUrl
(
alipayConfig
.
getReturnUrl
());
}
//******必传参数******
JSONObject
bizContent
=
new
JSONObject
();
//商户订单号,商家自定义,保持唯一性
bizContent
.
put
(
"out_trade_no"
,
aliPayParam
.
getOutTradeNo
());
//支付金额,最小值0.01元
bizContent
.
put
(
"total_amount"
,
aliPayParam
.
getTotalAmount
());
//订单标题,不可使用特殊符号
bizContent
.
put
(
"subject"
,
aliPayParam
.
getSubject
());
//电脑网站支付场景固定传值FAST_INSTANT_TRADE_PAY
bizContent
.
put
(
"product_code"
,
"FAST_INSTANT_TRADE_PAY"
);
request
.
setBizContent
(
bizContent
.
toString
());
String
formHtml
=
null
;
try
{
formHtml
=
alipayClient
.
pageExecute
(
request
).
getBody
();
}
catch
(
AlipayApiException
e
)
{
e
.
printStackTrace
();
}
return
formHtml
;
}
@Override
public
String
notify
(
Map
<
String
,
String
>
params
)
{
String
result
=
"failure"
;
boolean
signVerified
=
false
;
try
{
//调用SDK验证签名
signVerified
=
AlipaySignature
.
rsaCheckV1
(
params
,
alipayConfig
.
getAlipayPublicKey
(),
alipayConfig
.
getCharset
(),
alipayConfig
.
getSignType
());
}
catch
(
AlipayApiException
e
)
{
log
.
error
(
"支付回调签名校验异常!"
,
e
);
e
.
printStackTrace
();
}
if
(
signVerified
)
{
String
tradeStatus
=
params
.
get
(
"trade_status"
);
if
(
"TRADE_SUCCESS"
.
equals
(
tradeStatus
)){
result
=
"success"
;
log
.
info
(
"notify方法被调用了,tradeStatus:{}"
,
tradeStatus
);
String
outTradeNo
=
params
.
get
(
"out_trade_no"
);
portalOrderService
.
paySuccessByOrderSn
(
outTradeNo
,
1
);
}
else
{
log
.
warn
(
"订单未支付成功,trade_status:{}"
,
tradeStatus
);
}
}
else
{
log
.
warn
(
"支付回调签名校验失败!"
);
}
return
result
;
}
@Override
public
String
query
(
String
outTradeNo
,
String
tradeNo
)
{
AlipayTradeQueryRequest
request
=
new
AlipayTradeQueryRequest
();
//******必传参数******
JSONObject
bizContent
=
new
JSONObject
();
//设置查询参数,out_trade_no和trade_no至少传一个
if
(
StrUtil
.
isNotEmpty
(
outTradeNo
)){
bizContent
.
put
(
"out_trade_no"
,
outTradeNo
);
}
if
(
StrUtil
.
isNotEmpty
(
tradeNo
)){
bizContent
.
put
(
"trade_no"
,
tradeNo
);
}
//交易结算信息: trade_settle_info
String
[]
queryOptions
=
{
"trade_settle_info"
};
bizContent
.
put
(
"query_options"
,
queryOptions
);
request
.
setBizContent
(
bizContent
.
toString
());
AlipayTradeQueryResponse
response
=
null
;
try
{
response
=
alipayClient
.
execute
(
request
);
}
catch
(
AlipayApiException
e
)
{
log
.
error
(
"查询支付宝账单异常!"
,
e
);
}
if
(
response
.
isSuccess
()){
log
.
info
(
"查询支付宝账单成功!"
);
portalOrderService
.
paySuccessByOrderSn
(
outTradeNo
,
1
);
}
else
{
log
.
error
(
"查询支付宝账单失败!"
);
}
//交易状态:WAIT_BUYER_PAY(交易创建,等待买家付款)、TRADE_CLOSED(未付款交易超时关闭,或支付完成后全额退款)、TRADE_SUCCESS(交易支付成功)、TRADE_FINISHED(交易结束,不可退款)
return
response
.
getTradeStatus
();
}
@Override
public
String
webPay
(
AliPayParam
aliPayParam
)
{
AlipayTradeWapPayRequest
request
=
new
AlipayTradeWapPayRequest
();
if
(
StrUtil
.
isNotEmpty
(
alipayConfig
.
getNotifyUrl
())){
//异步接收地址,公网可访问
request
.
setNotifyUrl
(
alipayConfig
.
getNotifyUrl
());
}
if
(
StrUtil
.
isNotEmpty
(
alipayConfig
.
getReturnUrl
())){
//同步跳转地址
request
.
setReturnUrl
(
alipayConfig
.
getReturnUrl
());
}
//******必传参数******
JSONObject
bizContent
=
new
JSONObject
();
//商户订单号,商家自定义,保持唯一性
bizContent
.
put
(
"out_trade_no"
,
aliPayParam
.
getOutTradeNo
());
//支付金额,最小值0.01元
bizContent
.
put
(
"total_amount"
,
aliPayParam
.
getTotalAmount
());
//订单标题,不可使用特殊符号
bizContent
.
put
(
"subject"
,
aliPayParam
.
getSubject
());
//手机网站支付默认传值FAST_INSTANT_TRADE_PAY
bizContent
.
put
(
"product_code"
,
"QUICK_WAP_WAY"
);
request
.
setBizContent
(
bizContent
.
toString
());
String
formHtml
=
null
;
try
{
formHtml
=
alipayClient
.
pageExecute
(
request
).
getBody
();
}
catch
(
AlipayApiException
e
)
{
e
.
printStackTrace
();
}
return
formHtml
;
}
}
mall-portal/src/main/java/com/macro/mall/portal/service/impl/OmsPortalOrderServiceImpl.java
View file @
b3bc051e
...
...
@@ -419,6 +419,20 @@ public class OmsPortalOrderServiceImpl implements OmsPortalOrderService {
}
}
@Override
public
void
paySuccessByOrderSn
(
String
orderSn
,
Integer
payType
)
{
OmsOrderExample
example
=
new
OmsOrderExample
();
example
.
createCriteria
()
.
andOrderSnEqualTo
(
orderSn
)
.
andStatusEqualTo
(
0
)
.
andDeleteStatusEqualTo
(
0
);
List
<
OmsOrder
>
orderList
=
orderMapper
.
selectByExample
(
example
);
if
(
CollUtil
.
isNotEmpty
(
orderList
)){
OmsOrder
order
=
orderList
.
get
(
0
);
paySuccess
(
order
.
getId
(),
payType
);
}
}
/**
* 生成18位订单编号:8位日期+2位平台号码+2位支付方式+6位以上自增id
*/
...
...
mall-portal/src/main/resources/application-dev.yml
View file @
b3bc051e
...
...
@@ -42,3 +42,11 @@ logstash:
host
:
localhost
enableInnerLog
:
false
alipay
:
gatewayUrl
:
https://openapi-sandbox.dl.alipaydev.com/gateway.do
appId
:
your appId
alipayPublicKey
:
your alipayPublicKey
appPrivateKey
:
your appPrivateKey
returnUrl
:
http://localhost:8060/#/pages/money/paySuccess
notifyUrl
:
mall-portal/src/main/resources/application-prod.yml
View file @
b3bc051e
...
...
@@ -50,3 +50,11 @@ logging:
logstash
:
host
:
logstash
alipay
:
gatewayUrl
:
https://openapi-sandbox.dl.alipaydev.com/gateway.do
appId
:
your appId
alipayPublicKey
:
your alipayPublicKey
appPrivateKey
:
your appPrivateKey
returnUrl
:
http://192.168.3.101:8060/#/pages/money/paySuccess
notifyUrl
:
mall-portal/src/main/resources/application.yml
View file @
b3bc051e
...
...
@@ -36,6 +36,7 @@ secure:
-
/home/**
-
/product/**
-
/brand/**
-
/alipay/**
# 自定义redis key
redis
:
...
...
pom.xml
View file @
b3bc051e
...
...
@@ -46,6 +46,7 @@
<spring-data-commons.version>
2.7.5
</spring-data-commons.version>
<jjwt.version>
0.9.1
</jjwt.version>
<aliyun-oss.version>
2.5.0
</aliyun-oss.version>
<alipay-sdk.version>
4.38.61.ALL
</alipay-sdk.version>
<logstash-logback.version>
7.2
</logstash-logback.version>
<minio.version>
8.4.5
</minio.version>
<jaxb-api.version>
2.3.1
</jaxb-api.version>
...
...
@@ -257,4 +258,18 @@
</pluginManagement>
</build>
<!--使用aliyun的Maven镜像源提升下载速度-->
<repositories>
<repository>
<id>
aliyunmaven
</id>
<name>
aliyun
</name>
<url>
https://maven.aliyun.com/repository/public
</url>
</repository>
<repository>
<id>
central2
</id>
<name>
central2
</name>
<url>
https://repo1.maven.org/maven2/
</url>
</repository>
</repositories>
</project>
\ No newline at end of file
Write
Preview
Supports
Markdown
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