Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
Y
yudao-cloud
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
hblj
yudao-cloud
Commits
7d423c8e
提交
7d423c8e
authored
3月 13, 2019
作者:
YunaiV
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
支付模块,调通对 ping++ 的调用,以实现模拟支付。
当然,整体代码还是有点乱,后面花点时间重构下~ 现在,缺一个异步 MQ 通知业务方订单支付成功
上级
c772da67
隐藏空白字符变更
内嵌
并排
正在显示
24 个修改的文件
包含
596 行增加
和
16 行删除
+596
-16
pom.xml
common/common-framework/pom.xml
+6
-0
DateUtil.java
.../main/java/cn/iocoder/common/framework/util/DateUtil.java
+21
-0
MathUtil.java
.../main/java/cn/iocoder/common/framework/util/MathUtil.java
+33
-0
PayDemoController.java
...l/pay/application/controller/users/PayDemoController.java
+53
-1
PayTransactionController.java
...pplication/controller/users/PayTransactionController.java
+40
-2
DubboGenericInvokerTest.java
...ay-application/src/test/java/DubboGenericInvokerTest.java
+33
-0
PayDemoService.java
...src/main/java/cn/iocoder/mall/pay/api/PayDemoService.java
+8
-0
PayTransactionService.java
...n/java/cn/iocoder/mall/pay/api/PayTransactionService.java
+13
-0
PayErrorCodeEnum.java
...va/cn/iocoder/mall/pay/api/constant/PayErrorCodeEnum.java
+2
-0
pom.xml
pay/pay-service-impl/pom.xml
+0
-1
AbstractPaySDK.java
.../main/java/cn/iocoder/mall/pay/client/AbstractPaySDK.java
+4
-0
PingxxPaySDK.java
...rc/main/java/cn/iocoder/mall/pay/client/PingxxPaySDK.java
+14
-1
TransactionPaySuccessBO.java
...a/cn/iocoder/mall/pay/client/TransactionPaySuccessBO.java
+53
-0
ServiceExceptionConfiguration.java
...ocoder/mall/pay/config/ServiceExceptionConfiguration.java
+2
-2
PayTransactionExtensionMapper.java
...n/iocoder/mall/pay/dao/PayTransactionExtensionMapper.java
+8
-1
PayTransactionMapper.java
...in/java/cn/iocoder/mall/pay/dao/PayTransactionMapper.java
+6
-0
PayTransactionNotifyTaskMapper.java
.../iocoder/mall/pay/dao/PayTransactionNotifyTaskMapper.java
+14
-0
PayTransactionNotifyTaskDO.java
...coder/mall/pay/dataobject/PayTransactionNotifyTaskDO.java
+13
-3
PayDemoServiceImpl.java
.../java/cn/iocoder/mall/pay/service/PayDemoServiceImpl.java
+16
-0
PayServiceImpl.java
...main/java/cn/iocoder/mall/pay/service/PayServiceImpl.java
+95
-3
PayAppMapper.xml
...y-service-impl/src/main/resources/mapper/PayAppMapper.xml
+2
-2
PayTransactionExtensionMapper.xml
...c/main/resources/mapper/PayTransactionExtensionMapper.xml
+45
-0
PayTransactionMapper.xml
...e-impl/src/main/resources/mapper/PayTransactionMapper.xml
+70
-0
PayTransactionNotifyTaskMapper.xml
.../main/resources/mapper/PayTransactionNotifyTaskMapper.xml
+45
-0
没有找到文件。
common/common-framework/pom.xml
浏览文件 @
7d423c8e
...
...
@@ -55,6 +55,12 @@
<!--<version>2.3</version>-->
<!--</dependency>-->
<dependency>
<groupId>
com.alibaba
</groupId>
<artifactId>
fastjson
</artifactId>
<version>
1.2.56
</version>
</dependency>
</dependencies>
...
...
common/common-framework/src/main/java/cn/iocoder/common/framework/util/DateUtil.java
0 → 100644
浏览文件 @
7d423c8e
package
cn
.
iocoder
.
common
.
framework
.
util
;
import
java.text.SimpleDateFormat
;
import
java.util.Date
;
public
class
DateUtil
{
/**
* @param date 时间。若为空,则返回空串
* @param pattern 时间格式化
* @return 格式化后的时间字符串.
*/
public
static
String
format
(
Date
date
,
String
pattern
)
{
if
(
date
==
null
)
{
return
""
;
}
return
new
SimpleDateFormat
(
pattern
).
format
(
date
);
}
}
\ No newline at end of file
common/common-framework/src/main/java/cn/iocoder/common/framework/util/MathUtil.java
0 → 100644
浏览文件 @
7d423c8e
package
cn
.
iocoder
.
common
.
framework
.
util
;
import
java.util.Random
;
public
class
MathUtil
{
/**
* 随机对象
*/
private
static
final
Random
RANDOM
=
new
Random
();
// TODO 后续优化
/**
* 随机[min, max]范围内的数字
*
* @param min 随机开始
* @param max 随机结束
* @return 数字
*/
public
static
int
random
(
int
min
,
int
max
)
{
if
(
min
==
max
)
{
return
min
;
}
if
(
min
>
max
)
{
int
temp
=
min
;
min
=
max
;
max
=
temp
;
}
// 随即开始
int
diff
=
max
-
min
+
1
;
return
RANDOM
.
nextInt
(
diff
)
+
min
;
}
}
pay/pay-application/src/main/java/cn/iocoder/mall/pay/application/controller/users/PayDemoController.java
浏览文件 @
7d423c8e
...
...
@@ -31,7 +31,7 @@ public class PayDemoController {
// 调用【支付服务】,创建交易订单
PayTransactionCreateDTO
payTransactionCreateDTO
=
new
PayTransactionCreateDTO
()
.
setAppId
(
"
1024
"
)
.
setAppId
(
"
POd4RC6a
"
)
.
setCreateIp
(
HttpUtil
.
getIp
(
request
))
.
setOrderId
(
"1"
)
.
setOrderSubject
(
"商品名"
)
...
...
@@ -43,4 +43,55 @@ public class PayDemoController {
Assert
.
isTrue
(
result
.
isSuccess
(),
"一定会成功的"
);
}
@PostMapping
(
"/pingxx"
)
public
String
pingxx
()
{
return
"{\n"
+
" \"id\": \"ch_n5COmHGG8iX5TWf5qDynvTaP\",\n"
+
" \"object\": \"charge\",\n"
+
" \"created\": 1552445643,\n"
+
" \"livemode\": false,\n"
+
" \"paid\": false,\n"
+
" \"refunded\": false,\n"
+
" \"reversed\": false,\n"
+
" \"app\": \"app_aTyfXDjrvzDSbLuz\",\n"
+
" \"channel\": \"wx_pub\",\n"
+
" \"order_no\": \"1552445643093\",\n"
+
" \"client_ip\": \"127.0.0.1\",\n"
+
" \"amount\": 1,\n"
+
" \"amount_settle\": 1,\n"
+
" \"currency\": \"cny\",\n"
+
" \"subject\": \"测试商品\",\n"
+
" \"body\": \"测试描述\",\n"
+
" \"time_paid\": null,\n"
+
" \"time_expire\": 1552452843,\n"
+
" \"time_settle\": null,\n"
+
" \"transaction_no\": null,\n"
+
" \"refunds\": {\n"
+
" \"object\": \"list\",\n"
+
" \"url\": \"/v1/charges/ch_n5COmHGG8iX5TWf5qDynvTaP/refunds\",\n"
+
" \"has_more\": false,\n"
+
" \"data\": []\n"
+
" },\n"
+
" \"amount_refunded\": 0,\n"
+
" \"failure_code\": null,\n"
+
" \"failure_msg\": null,\n"
+
" \"metadata\": {},\n"
+
" \"credential\": {\n"
+
" \"object\": \"credential\",\n"
+
" \"wx_pub\": {\n"
+
" \"appId\": \"wxytom5krtuf54qjff\",\n"
+
" \"timeStamp\": \"1552445643\",\n"
+
" \"nonceStr\": \"5cc0206f78d8bf931980f5132d5ce394\",\n"
+
" \"package\": \"prepay_id=1101000000190313rx9y5oahkkcsm5gg\",\n"
+
" \"signType\": \"MD5\",\n"
+
" \"paySign\": \"9F6E80E89439575B8414FA56ADB07228\"\n"
+
" }\n"
+
" },\n"
+
" \"extra\": {\n"
+
" \"open_id\": \"just_for_test\"\n"
+
" },\n"
+
" \"description\": null\n"
+
"}"
;
}
}
\ No newline at end of file
pay/pay-application/src/main/java/cn/iocoder/mall/pay/application/controller/users/PayTransactionController.java
浏览文件 @
7d423c8e
package
cn
.
iocoder
.
mall
.
pay
.
application
.
controller
.
users
;
import
cn.iocoder.common.framework.util.HttpUtil
;
import
cn.iocoder.common.framework.vo.CommonResult
;
import
cn.iocoder.mall.pay.api.PayTransactionService
;
import
cn.iocoder.mall.pay.api.bo.PayTransactionSubmitBO
;
import
cn.iocoder.mall.pay.api.constant.PayChannelEnum
;
import
cn.iocoder.mall.pay.api.dto.PayTransactionSubmitDTO
;
import
com.alibaba.dubbo.config.annotation.Reference
;
import
org.springframework.http.MediaType
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestParam
;
import
org.springframework.web.bind.annotation.RestController
;
import
javax.servlet.http.HttpServletRequest
;
import
java.io.BufferedReader
;
import
java.io.IOException
;
@RestController
@RequestMapping
(
"users/transaction"
)
// TODO 芋艿,理论来说,是用户无关的。这里先酱紫先~
public
class
PayTransactionController
{
...
...
@@ -15,8 +25,35 @@ public class PayTransactionController {
private
PayTransactionService
payService
;
@PostMapping
(
"/submit"
)
// TODO api 注释
public
CommonResult
submit
()
{
// TODO 1. params 2. result
return
null
;
// TODO result 后面改下
public
CommonResult
<
PayTransactionSubmitBO
>
submit
(
HttpServletRequest
request
,
@RequestParam
(
"appId"
)
String
appId
,
@RequestParam
(
"orderId"
)
String
orderId
,
@RequestParam
(
"payChannel"
)
Integer
payChannel
)
{
PayTransactionSubmitDTO
payTransactionSubmitDTO
=
new
PayTransactionSubmitDTO
()
.
setAppId
(
appId
).
setOrderId
(
orderId
).
setPayChannel
(
payChannel
)
.
setCreateIp
(
HttpUtil
.
getIp
(
request
));
// 提交支付提交
return
payService
.
submitTransaction
(
payTransactionSubmitDTO
);
}
@PostMapping
(
value
=
"pingxx_pay_success"
,
consumes
=
MediaType
.
APPLICATION_JSON_VALUE
)
// @GetMapping(value = "pingxx_pay_success")
public
String
pingxxSuccess
(
HttpServletRequest
request
)
throws
IOException
{
// 读取 webhook
StringBuilder
sb
=
new
StringBuilder
();
try
(
BufferedReader
reader
=
request
.
getReader
())
{
String
line
;
while
((
line
=
reader
.
readLine
())
!=
null
)
{
sb
.
append
(
line
);
}
}
// JSONObject bodyObj = JSON.parseObject(sb.toString());
// bodyObj.put("webhookId", bodyObj.remove("id"));
// String body = bodyObj.toString();
payService
.
updateTransactionPaySuccess
(
PayChannelEnum
.
PINGXX
.
getId
(),
sb
.
toString
());
return
""
;
}
}
\ No newline at end of file
pay/pay-application/src/test/java/DubboGenericInvokerTest.java
0 → 100644
浏览文件 @
7d423c8e
import
com.alibaba.dubbo.config.ApplicationConfig
;
import
com.alibaba.dubbo.config.ReferenceConfig
;
import
com.alibaba.dubbo.config.RegistryConfig
;
import
com.alibaba.dubbo.rpc.service.GenericService
;
public
class
DubboGenericInvokerTest
{
public
static
void
main
(
String
[]
args
)
{
ApplicationConfig
application
=
new
ApplicationConfig
();
application
.
setName
(
"api-generic-consumer"
);
RegistryConfig
registry
=
new
RegistryConfig
();
registry
.
setAddress
(
"zookeeper://127.0.0.1:2181"
);
application
.
setRegistry
(
registry
);
ReferenceConfig
<
GenericService
>
reference
=
new
ReferenceConfig
<>();
// 弱类型接口名
reference
.
setInterface
(
"cn.iocoder.mall.pay.api.PayDemoService"
);
// 声明为泛化接口
reference
.
setGeneric
(
true
);
reference
.
setApplication
(
application
);
// 用com.alibaba.dubbo.rpc.service.GenericService可以替代所有接口引用
GenericService
genericService
=
reference
.
get
();
String
name
=
(
String
)
genericService
.
$invoke
(
"updatePaySuccess"
,
new
String
[]{
String
.
class
.
getName
()},
new
Object
[]{
"1"
});
System
.
out
.
println
(
name
);
}
}
\ No newline at end of file
pay/pay-service-api/src/main/java/cn/iocoder/mall/pay/api/PayDemoService.java
0 → 100644
浏览文件 @
7d423c8e
package
cn
.
iocoder
.
mall
.
pay
.
api
;
public
interface
PayDemoService
{
String
updatePaySuccess
(
String
orderId
);
}
\ No newline at end of file
pay/pay-service-api/src/main/java/cn/iocoder/mall/pay/api/PayTransactionService.java
浏览文件 @
7d423c8e
...
...
@@ -12,6 +12,18 @@ public interface PayTransactionService {
CommonResult
<
PayTransactionSubmitBO
>
submitTransaction
(
PayTransactionSubmitDTO
payTransactionSubmitDTO
);
/**
* 更新交易支付成功
*
* 该接口用于不同支付平台,支付成功后,回调该接口
*
* @param payChannel 支付渠道
* @param params 回调参数。
* 因为不同平台,能够提供的参数不同,所以使用 String 类型统一接收,然后在使用不同的 AbstractPaySDK 进行处理。
* @return 是否支付成功
*/
CommonResult
<
Boolean
>
updateTransactionPaySuccess
(
Integer
payChannel
,
String
params
);
CommonResult
cancelTransaction
();
// TODO 1. params 2. result
}
\ No newline at end of file
pay/pay-service-api/src/main/java/cn/iocoder/mall/pay/api/constant/PayErrorCodeEnum.java
浏览文件 @
7d423c8e
...
...
@@ -15,6 +15,8 @@ public enum PayErrorCodeEnum {
PAY_TRANSACTION_NOT_FOUND
(
100401000
,
"支付交易单不存在"
),
PAY_TRANSACTION_STATUS_IS_NOT_WAITING
(
100401001
,
"支付交易单不处于待支付"
),
PAY_TRANSACTION_EXTENSION_NOT_FOUND
(
100401002
,
"支付交易拓展单不存在"
),
PAY_TRANSACTION_EXTENSION_STATUS_IS_NOT_WAITING
(
100401003
,
"支付交易拓展单不处于待支付"
),
;
private
final
int
code
;
...
...
pay/pay-service-impl/pom.xml
浏览文件 @
7d423c8e
...
...
@@ -19,7 +19,6 @@
<dependency>
<groupId>
com.alibaba
</groupId>
<artifactId>
dubbo
</artifactId>
<scope>
compile
</scope>
</dependency>
<dependency>
<groupId>
cn.iocoder.mall
</groupId>
...
...
pay/pay-service-impl/src/main/java/cn/iocoder/mall/pay/client/AbstractPaySDK.java
浏览文件 @
7d423c8e
...
...
@@ -13,4 +13,7 @@ public abstract class AbstractPaySDK {
PayTransactionExtensionDO
transactionExtension
,
Map
<
String
,
Object
>
extra
);
// TODO 芋艿,理论来说不会出现解析失败的情况,先返回这个参数列。等后面封装支付宝和微信支付的时候,在看看。
public
abstract
CommonResult
<
TransactionPaySuccessBO
>
parseTransactionPaySuccessParams
(
String
params
);
}
\ No newline at end of file
pay/pay-service-impl/src/main/java/cn/iocoder/mall/pay/client/PingxxPaySDK.java
浏览文件 @
7d423c8e
...
...
@@ -3,11 +3,14 @@ package cn.iocoder.mall.pay.client;
import
cn.iocoder.common.framework.vo.CommonResult
;
import
cn.iocoder.mall.pay.dataobject.PayTransactionDO
;
import
cn.iocoder.mall.pay.dataobject.PayTransactionExtensionDO
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONObject
;
import
com.google.common.collect.ImmutableMap
;
import
com.pingplusplus.Pingpp
;
import
com.pingplusplus.exception.*
;
import
com.pingplusplus.model.Charge
;
import
java.util.Date
;
import
java.util.HashMap
;
import
java.util.Map
;
...
...
@@ -25,7 +28,7 @@ public class PingxxPaySDK extends AbstractPaySDK {
// 请求ping++
try
{
Charge
charge
=
Charge
.
create
(
reqObj
);
//
System.out.println(charge.toString());
System
.
out
.
println
(
charge
.
toString
());
return
CommonResult
.
success
(
charge
.
toString
());
}
catch
(
AuthenticationException
e
)
{
e
.
printStackTrace
();
...
...
@@ -43,6 +46,16 @@ public class PingxxPaySDK extends AbstractPaySDK {
return
null
;
}
@Override
public
CommonResult
<
TransactionPaySuccessBO
>
parseTransactionPaySuccessParams
(
String
params
)
{
JSONObject
paramsObj
=
JSON
.
parseObject
(
params
);
JSONObject
chargeObj
=
paramsObj
.
getJSONObject
(
"data"
).
getJSONObject
(
"object"
);
TransactionPaySuccessBO
transactionPaySuccessBO
=
new
TransactionPaySuccessBO
()
.
setTransactionCode
(
chargeObj
.
getString
(
"order_no"
))
.
setPaymentTime
(
new
Date
(
chargeObj
.
getLong
(
"time_paid"
)
*
1000
))
.
setTradeNo
(
chargeObj
.
getString
(
"transaction_no"
));
return
CommonResult
.
success
(
transactionPaySuccessBO
);
}
private
Map
<
String
,
Object
>
createChargeRequest
(
PayTransactionDO
transaction
,
PayTransactionExtensionDO
transactionExtension
,
Map
<
String
,
Object
>
extra
)
{
// 计算支付渠道和支付额外参数
...
...
pay/pay-service-impl/src/main/java/cn/iocoder/mall/pay/client/TransactionPaySuccessBO.java
0 → 100644
浏览文件 @
7d423c8e
package
cn
.
iocoder
.
mall
.
pay
.
client
;
import
java.util.Date
;
/**
* 交易支付成功结果
*/
public
class
TransactionPaySuccessBO
{
/**
* 生成传输给第三方的订单号
*
* 唯一索引
*/
private
String
transactionCode
;
/**
* 第三方的流水号
*/
private
String
tradeNo
;
/**
* 第三方支付成功的时间
*/
private
Date
paymentTime
;
public
String
getTransactionCode
()
{
return
transactionCode
;
}
public
TransactionPaySuccessBO
setTransactionCode
(
String
transactionCode
)
{
this
.
transactionCode
=
transactionCode
;
return
this
;
}
public
String
getTradeNo
()
{
return
tradeNo
;
}
public
TransactionPaySuccessBO
setTradeNo
(
String
tradeNo
)
{
this
.
tradeNo
=
tradeNo
;
return
this
;
}
public
Date
getPaymentTime
()
{
return
paymentTime
;
}
public
TransactionPaySuccessBO
setPaymentTime
(
Date
paymentTime
)
{
this
.
paymentTime
=
paymentTime
;
return
this
;
}
}
\ No newline at end of file
pay/pay-service-impl/src/main/java/cn/iocoder/mall/pay/config/ServiceExceptionConfiguration.java
浏览文件 @
7d423c8e
package
cn
.
iocoder
.
mall
.
pay
.
config
;
import
cn.iocoder.common.framework.util.ServiceExceptionUtil
;
import
cn.iocoder.mall.
admin.api.constant.Admin
ErrorCodeEnum
;
import
cn.iocoder.mall.
pay.api.constant.Pay
ErrorCodeEnum
;
import
org.springframework.boot.context.event.ApplicationReadyEvent
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.event.EventListener
;
...
...
@@ -18,7 +18,7 @@ public class ServiceExceptionConfiguration {
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
for
(
AdminErrorCodeEnum
item
:
Admin
ErrorCodeEnum
.
values
())
{
for
(
PayErrorCodeEnum
item
:
Pay
ErrorCodeEnum
.
values
())
{
ServiceExceptionUtil
.
put
(
item
.
getCode
(),
item
.
getMessage
());
}
}
...
...
pay/pay-service-impl/src/main/java/cn/iocoder/mall/pay/dao/PayTransactionExtensionMapper.java
浏览文件 @
7d423c8e
package
cn
.
iocoder
.
mall
.
pay
.
dao
;
import
cn.iocoder.mall.pay.dataobject.PayTransactionExtensionDO
;
import
org.apache.ibatis.annotations.Param
;
import
org.springframework.stereotype.Repository
;
@Repository
public
interface
PayTransactionExtensionMapper
{
void
insert
(
PayTransactionExtensionDO
payTransactionExtensionDO
);
void
insert
(
PayTransactionExtensionDO
entity
);
int
update
(
@Param
(
"entity"
)
PayTransactionExtensionDO
entity
,
@Param
(
"whereStatus"
)
Integer
whereStatus
);
PayTransactionExtensionDO
selectByTransactionCode
(
@Param
(
"transactionCode"
)
String
transactionCode
);
}
\ No newline at end of file
pay/pay-service-impl/src/main/java/cn/iocoder/mall/pay/dao/PayTransactionMapper.java
浏览文件 @
7d423c8e
...
...
@@ -9,7 +9,12 @@ public interface PayTransactionMapper {
void
insert
(
PayTransactionDO
entity
);
int
update
(
@Param
(
"entity"
)
PayTransactionDO
entity
,
@Param
(
"whereStatus"
)
Integer
whereStatus
);
PayTransactionDO
selectByAppIdAndOrderId
(
@Param
(
"appId"
)
String
appId
,
@Param
(
"orderId"
)
String
orderId
);
PayTransactionDO
selectById
(
@Param
(
"id"
)
Integer
appId
);
}
\ No newline at end of file
pay/pay-service-impl/src/main/java/cn/iocoder/mall/pay/dao/PayTransactionNotifyTaskMapper.java
0 → 100644
浏览文件 @
7d423c8e
package
cn
.
iocoder
.
mall
.
pay
.
dao
;
import
cn.iocoder.mall.pay.dataobject.PayTransactionNotifyTaskDO
;
import
org.springframework.stereotype.Repository
;
@Repository
public
interface
PayTransactionNotifyTaskMapper
{
void
insert
(
PayTransactionNotifyTaskDO
entity
);
int
update
(
PayTransactionNotifyTaskDO
entity
);
}
\ No newline at end of file
pay/pay-service-impl/src/main/java/cn/iocoder/mall/pay/dataobject/PayTransactionNotifyTaskDO.java
浏览文件 @
7d423c8e
...
...
@@ -51,9 +51,10 @@ public class PayTransactionNotifyTaskDO extends BaseDO {
* 最大可通知次数
*/
private
Integer
maxNotifyTimes
;
// TODO notify url
/**
* 通知地址
*/
private
String
notifyUrl
;
public
Integer
getTransactionId
()
{
return
transactionId
;
...
...
@@ -136,4 +137,12 @@ public class PayTransactionNotifyTaskDO extends BaseDO {
return
this
;
}
public
String
getNotifyUrl
()
{
return
notifyUrl
;
}
public
PayTransactionNotifyTaskDO
setNotifyUrl
(
String
notifyUrl
)
{
this
.
notifyUrl
=
notifyUrl
;
return
this
;
}
}
\ No newline at end of file
pay/pay-service-impl/src/main/java/cn/iocoder/mall/pay/service/PayDemoServiceImpl.java
0 → 100644
浏览文件 @
7d423c8e
package
cn
.
iocoder
.
mall
.
pay
.
service
;
import
cn.iocoder.mall.pay.api.PayDemoService
;
import
org.springframework.stereotype.Service
;
@Service
@com
.
alibaba
.
dubbo
.
config
.
annotation
.
Service
public
class
PayDemoServiceImpl
implements
PayDemoService
{
@Override
public
String
updatePaySuccess
(
String
orderId
)
{
return
"你好呀"
;
}
}
\ No newline at end of file
pay/pay-service-impl/src/main/java/cn/iocoder/mall/pay/service/PayServiceImpl.java
浏览文件 @
7d423c8e
package
cn
.
iocoder
.
mall
.
pay
.
service
;
import
cn.iocoder.common.framework.util.DateUtil
;
import
cn.iocoder.common.framework.util.MathUtil
;
import
cn.iocoder.common.framework.util.ServiceExceptionUtil
;
import
cn.iocoder.common.framework.vo.CommonResult
;
import
cn.iocoder.mall.pay.api.PayTransactionService
;
import
cn.iocoder.mall.pay.api.bo.PayTransactionBO
;
import
cn.iocoder.mall.pay.api.bo.PayTransactionSubmitBO
;
import
cn.iocoder.mall.pay.api.constant.PayErrorCodeEnum
;
import
cn.iocoder.mall.pay.api.constant.PayTransactionNotifyStatusEnum
;
import
cn.iocoder.mall.pay.api.constant.PayTransactionStatusEnum
;
import
cn.iocoder.mall.pay.api.dto.PayTransactionCreateDTO
;
import
cn.iocoder.mall.pay.api.dto.PayTransactionSubmitDTO
;
import
cn.iocoder.mall.pay.client.AbstractPaySDK
;
import
cn.iocoder.mall.pay.client.PaySDKFactory
;
import
cn.iocoder.mall.pay.client.TransactionPaySuccessBO
;
import
cn.iocoder.mall.pay.convert.PayTransactionConvert
;
import
cn.iocoder.mall.pay.dao.PayTransactionExtensionMapper
;
import
cn.iocoder.mall.pay.dao.PayTransactionMapper
;
import
cn.iocoder.mall.pay.dao.PayTransactionNotifyTaskMapper
;
import
cn.iocoder.mall.pay.dataobject.PayAppDO
;
import
cn.iocoder.mall.pay.dataobject.PayTransactionDO
;
import
cn.iocoder.mall.pay.dataobject.PayTransactionExtensionDO
;
import
cn.iocoder.mall.pay.dataobject.PayTransactionNotifyTaskDO
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
java.util.Date
;
...
...
@@ -34,6 +42,8 @@ public class PayServiceImpl implements PayTransactionService {
@Autowired
private
PayTransactionExtensionMapper
payTransactionExtensionMapper
;
@Autowired
private
PayTransactionNotifyTaskMapper
payTransactionNotifyTaskMapper
;
@Autowired
private
PayAppServiceImpl
payAppService
;
@Override
...
...
@@ -77,17 +87,18 @@ public class PayServiceImpl implements PayTransactionService {
if
(
payTransaction
==
null
)
{
// 是否存在
return
ServiceExceptionUtil
.
error
(
PayErrorCodeEnum
.
PAY_TRANSACTION_NOT_FOUND
.
getCode
());
}
if
(
PayTransactionStatusEnum
.
WAITTING
.
getValue
().
equals
(
payTransaction
.
getStatus
()))
{
// 校验状态
if
(
!
PayTransactionStatusEnum
.
WAITTING
.
getValue
().
equals
(
payTransaction
.
getStatus
()))
{
// 校验状态,必须是待支付
return
ServiceExceptionUtil
.
error
(
PayErrorCodeEnum
.
PAY_TRANSACTION_STATUS_IS_NOT_WAITING
.
getCode
());
}
// 插入 PayTransactionExtensionDO
PayTransactionExtensionDO
payTransactionExtensionDO
=
PayTransactionConvert
.
INSTANCE
.
convert
(
payTransactionSubmitDTO
)
.
setTransactionId
(
payTransaction
.
getId
())
.
setTransactionCode
(
"TODO"
)
.
setTransactionCode
(
generateTransactionCode
()
)
.
setStatus
(
PayTransactionStatusEnum
.
WAITTING
.
getValue
());
payTransactionExtensionMapper
.
insert
(
payTransactionExtensionDO
);
// 调用三方接口
CommonResult
<
String
>
invokeResult
=
PaySDKFactory
.
getSDK
(
payTransactionSubmitDTO
.
getPayChannel
()).
submitTransaction
(
payTransaction
,
payTransactionExtensionDO
,
null
);
// TODO 暂时传入 extra = null
AbstractPaySDK
paySDK
=
PaySDKFactory
.
getSDK
(
payTransactionSubmitDTO
.
getPayChannel
());
CommonResult
<
String
>
invokeResult
=
paySDK
.
submitTransaction
(
payTransaction
,
payTransactionExtensionDO
,
null
);
// TODO 暂时传入 extra = null
if
(
invokeResult
.
isError
())
{
return
CommonResult
.
error
(
invokeResult
);
}
...
...
@@ -99,8 +110,88 @@ public class PayServiceImpl implements PayTransactionService {
}
@Override
@Transactional
public
CommonResult
<
Boolean
>
updateTransactionPaySuccess
(
Integer
payChannel
,
String
params
)
{
// TODO 芋艿,记录回调日志
// 解析传入的参数,成 TransactionPaySuccessBO 对象
AbstractPaySDK
paySDK
=
PaySDKFactory
.
getSDK
(
payChannel
);
CommonResult
<
TransactionPaySuccessBO
>
paySuccessResult
=
paySDK
.
parseTransactionPaySuccessParams
(
params
);
if
(
paySuccessResult
.
isError
())
{
return
CommonResult
.
error
(
paySuccessResult
);
}
// TODO 芋艿,先最严格的校验。即使调用方重复调用,实际哪个订单已经被重复回调的支付,也返回 false 。也没问题,因为实际已经回调成功了。
// 1.1 查询 PayTransactionExtensionDO
PayTransactionExtensionDO
payTransactionExtension
=
payTransactionExtensionMapper
.
selectByTransactionCode
(
paySuccessResult
.
getData
().
getTransactionCode
());
if
(
payTransactionExtension
==
null
)
{
return
ServiceExceptionUtil
.
error
(
PayErrorCodeEnum
.
PAY_TRANSACTION_EXTENSION_NOT_FOUND
.
getCode
());
}
if
(!
PayTransactionStatusEnum
.
WAITTING
.
getValue
().
equals
(
payTransactionExtension
.
getStatus
()))
{
// 校验状态,必须是待支付
return
ServiceExceptionUtil
.
error
(
PayErrorCodeEnum
.
PAY_TRANSACTION_EXTENSION_STATUS_IS_NOT_WAITING
.
getCode
());
}
// 1.2 更新 PayTransactionExtensionDO
PayTransactionExtensionDO
updatePayTransactionExtension
=
new
PayTransactionExtensionDO
()
.
setId
(
payTransactionExtension
.
getId
())
.
setStatus
(
PayTransactionStatusEnum
.
SUCCESS
.
getValue
())
.
setExtensionData
(
params
);
int
updateCounts
=
payTransactionExtensionMapper
.
update
(
updatePayTransactionExtension
,
PayTransactionStatusEnum
.
WAITTING
.
getValue
());
if
(
updateCounts
==
0
)
{
// 校验状态,必须是待支付
throw
ServiceExceptionUtil
.
exception
(
PayErrorCodeEnum
.
PAY_TRANSACTION_EXTENSION_STATUS_IS_NOT_WAITING
.
getCode
());
}
// 2.1
PayTransactionDO
payTransactionDO
=
payTransactionMapper
.
selectById
(
payTransactionExtension
.
getTransactionId
());
if
(
payTransactionDO
==
null
)
{
return
ServiceExceptionUtil
.
error
(
PayErrorCodeEnum
.
PAY_TRANSACTION_NOT_FOUND
.
getCode
());
}
if
(!
PayTransactionStatusEnum
.
WAITTING
.
getValue
().
equals
(
payTransactionDO
.
getStatus
()))
{
// 校验状态,必须是待支付
throw
ServiceExceptionUtil
.
exception
(
PayErrorCodeEnum
.
PAY_TRANSACTION_STATUS_IS_NOT_WAITING
.
getCode
());
}
// 2.2 更新 PayTransactionDO
PayTransactionDO
updatePayTransaction
=
new
PayTransactionDO
()
.
setId
(
payTransactionDO
.
getId
())
.
setStatus
(
PayTransactionStatusEnum
.
SUCCESS
.
getValue
())
.
setExtensionId
(
payTransactionExtension
.
getId
())
.
setPayChannel
(
payChannel
)
.
setPaymentTime
(
paySuccessResult
.
getData
().
getPaymentTime
())
.
setNotifyTime
(
new
Date
())
.
setTradeNo
(
paySuccessResult
.
getData
().
getTradeNo
());
updateCounts
=
payTransactionMapper
.
update
(
updatePayTransaction
,
PayTransactionStatusEnum
.
WAITTING
.
getValue
());
if
(
updateCounts
==
0
)
{
// 校验状态,必须是待支付 TODO 这种类型,需要思考下。需要返回错误,但是又要保证事务回滚
throw
ServiceExceptionUtil
.
exception
(
PayErrorCodeEnum
.
PAY_TRANSACTION_STATUS_IS_NOT_WAITING
.
getCode
());
}
// 3. 插入
PayTransactionNotifyTaskDO
payTransactionNotifyTask
=
new
PayTransactionNotifyTaskDO
()
.
setTransactionId
(
payTransactionExtension
.
getTransactionId
()).
setTransactionExtensionId
(
payTransactionExtension
.
getId
())
.
setAppId
(
payTransactionDO
.
getAppId
()).
setOrderId
(
payTransactionDO
.
getOrderId
())
.
setStatus
(
PayTransactionNotifyStatusEnum
.
WAITING
.
getValue
())
.
setNotifyTimes
(
0
).
setMaxNotifyTimes
(
5
)
.
setNotifyUrl
(
payTransactionDO
.
getNotifyUrl
());
payTransactionNotifyTaskMapper
.
insert
(
payTransactionNotifyTask
);
// 返回结果
return
CommonResult
.
success
(
true
);
}
@Override
// TODO 芋艿,后面去实现
public
CommonResult
cancelTransaction
()
{
return
null
;
}
private
String
generateTransactionCode
()
{
// wx
// 2014
// 10
// 27
// 20
// 09
// 39
// 5522657
// a690389285100
// 目前的算法
// 时间序列,年月日时分秒 14 位
// 纯随机,6 位 TODO 此处估计是会有问题的,后续在调整
return
DateUtil
.
format
(
new
Date
(),
"yyyyMMddHHmmss"
)
+
// 时间序列
MathUtil
.
random
(
100000
,
999999
)
// 随机。为什么是这个范围,因为偷懒
;
}
}
\ No newline at end of file
pay/pay-service-impl/src/main/resources/mapper/PayAppMapper.xml
浏览文件 @
7d423c8e
...
...
@@ -3,7 +3,7 @@
<mapper
namespace=
"cn.iocoder.mall.pay.dao.PayAppMapper"
>
<sql
id=
"FIELDS"
>
id, name, status, create_time
id, name,
notify_url,
status, create_time
</sql>
<!--<insert id="insert" parameterType="RoleDO" useGeneratedKeys="true" keyColumn="id" keyProperty="id">-->
...
...
@@ -27,7 +27,7 @@
<!--WHERE id = #{id}-->
<!--</update>-->
<select
id=
"selectById"
parameterType=
"
Integer
"
resultType=
"PayAppDO"
>
<select
id=
"selectById"
parameterType=
"
String
"
resultType=
"PayAppDO"
>
SELECT
<include
refid=
"FIELDS"
/>
FROM app
...
...
pay/pay-service-impl/src/main/resources/mapper/PayTransactionExtensionMapper.xml
0 → 100644
浏览文件 @
7d423c8e
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"cn.iocoder.mall.pay.dao.PayTransactionExtensionMapper"
>
<sql
id=
"FIELDS"
>
id, transaction_id, pay_channel, transaction_code, extension_data,
create_ip, status, create_time
</sql>
<insert
id=
"insert"
parameterType=
"PayTransactionExtensionDO"
useGeneratedKeys=
"true"
keyColumn=
"id"
keyProperty=
"id"
>
INSERT INTO transaction_extension (
transaction_id, pay_channel, transaction_code, extension_data,
create_ip, status
) VALUES (
#{transactionId}, #{payChannel}, #{transactionCode}, #{extensionData},
#{createIp}, #{status}
)
</insert>
<update
id=
"update"
>
UPDATE transaction_extension
<set>
<if
test=
"entity.extensionData != null"
>
, extension_data = #{entity.extensionData}
</if>
<if
test=
"entity.status != null"
>
, status = #{entity.status}
</if>
</set>
WHERE id = #{entity.id}
<if
test=
"whereStatus != null"
>
AND status = #{whereStatus}
</if>
</update>
<select
id=
"selectByTransactionCode"
parameterType=
"String"
resultType=
"PayTransactionExtensionDO"
>
SELECT
<include
refid=
"FIELDS"
/>
FROM transaction_extension
WHERE transaction_code = #{transactionCode}
LIMIT 1
</select>
</mapper>
\ No newline at end of file
pay/pay-service-impl/src/main/resources/mapper/PayTransactionMapper.xml
0 → 100644
浏览文件 @
7d423c8e
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"cn.iocoder.mall.pay.dao.PayTransactionMapper"
>
<sql
id=
"FIELDS"
>
id, app_id, create_ip, order_id, order_subject,
order_description, order_memo, price, status, expire_time,
finish_time, notify_url, extension_id, pay_channel, payment_time,
notify_time, trade_no, create_time
</sql>
<insert
id=
"insert"
parameterType=
"PayTransactionDO"
useGeneratedKeys=
"true"
keyColumn=
"id"
keyProperty=
"id"
>
INSERT INTO transaction (
app_id, create_ip, order_id, order_subject,
order_description, order_memo, price, status, expire_time,
finish_time, notify_url, extension_id, pay_channel, payment_time,
notify_time, trade_no, create_time
) VALUES (
#{appId}, #{createIp}, #{orderId}, #{orderSubject},
#{orderDescription}, #{orderMemo}, #{price}, #{status}, #{expireTime},
#{finishTime}, #{notifyUrl}, #{extensionId}, #{payChannel}, #{paymentTime},
#{notifyTime}, #{tradeNo}, #{createTime}
)
</insert>
<update
id=
"update"
>
UPDATE transaction
<set>
<if
test=
"entity.status != null"
>
, status = #{entity.status}
</if>
<if
test=
"entity.extensionId != null"
>
, extension_id = #{entity.extensionId}
</if>
<if
test=
"entity.payChannel != null"
>
, pay_channel = #{entity.payChannel}
</if>
<if
test=
"entity.paymentTime != null"
>
, payment_time = #{entity.paymentTime}
</if>
<if
test=
"entity.notifyTime != null"
>
, notify_time = #{entity.notifyTime}
</if>
<if
test=
"entity.tradeNo != null"
>
, trade_no = #{entity.tradeNo}
</if>
</set>
WHERE id = #{entity.id}
<if
test=
"whereStatus != null"
>
AND status = #{whereStatus}
</if>
</update>
<select
id=
"selectByAppIdAndOrderId"
resultType=
"PayTransactionDO"
>
SELECT
<include
refid=
"FIELDS"
/>
FROM transaction
WHERE app_id = #{appId}
AND order_id = #{orderId}
</select>
<select
id=
"selectById"
parameterType=
"Integer"
resultType=
"PayTransactionDO"
>
SELECT
<include
refid=
"FIELDS"
/>
FROM transaction
WHERE id = #{id}
</select>
</mapper>
\ No newline at end of file
pay/pay-service-impl/src/main/resources/mapper/PayTransactionNotifyTaskMapper.xml
0 → 100644
浏览文件 @
7d423c8e
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"cn.iocoder.mall.pay.dao.PayTransactionNotifyTaskMapper"
>
<sql
id=
"FIELDS"
>
id, transaction_id, transaction_extension_id, app_id, order_id,
status, last_Notify_time, notify_times, max_notify_times, create_time
</sql>
<insert
id=
"insert"
parameterType=
"PayTransactionNotifyTaskDO"
useGeneratedKeys=
"true"
keyColumn=
"id"
keyProperty=
"id"
>
INSERT INTO transaction_notify_task (
transaction_id, transaction_extension_id, app_id, order_id,
status, last_notify_time, notify_times, max_notify_times
) VALUES (
#{transactionId}, #{transactionExtensionId}, #{appId}, #{orderId},
#{status}, #{lastNotifyTime}, #{notifyTimes}, #{maxNotifyTimes}
)
</insert>
<update
id=
"update"
parameterType=
"PayTransactionNotifyTaskDO"
>
UPDATE transaction_notify_task
<set>
<if
test=
"status != null"
>
, status = #{status}
</if>
<if
test=
"lastNotifyTime != null"
>
, last_notify_time = #{lastNotifyTime}
</if>
<if
test=
"notifyTimes != null"
>
, notify_times = #{notifyTimes}
</if>
</set>
WHERE id = #{id}
</update>
<!--<select id="selectByTransactionCode" parameterType="String" resultType="PayTransactionExtensionDO">-->
<!--SELECT-->
<!--<include refid="FIELDS"/>-->
<!--FROM transaction_extension-->
<!--WHERE transaction_code = #{transactionCode}-->
<!--LIMIT 1-->
<!--</select>-->
</mapper>
\ No newline at end of file
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论