Compare commits
8 Commits
bf1bc4b1a2
...
3061987dae
Author | SHA1 | Date |
---|---|---|
|
3061987dae | |
|
3d5e33fed0 | |
|
f85d6cc410 | |
|
d169ca7366 | |
|
0834171ea3 | |
|
514104a391 | |
|
c79e316233 | |
|
e261a39cf5 |
|
@ -6,14 +6,13 @@ import (
|
||||||
"PaymentCenter/app/http/entities"
|
"PaymentCenter/app/http/entities"
|
||||||
"PaymentCenter/app/http/entities/backend"
|
"PaymentCenter/app/http/entities/backend"
|
||||||
"PaymentCenter/app/models/ordersmodel"
|
"PaymentCenter/app/models/ordersmodel"
|
||||||
"PaymentCenter/app/models/orderthirdpaylogmodel"
|
"PaymentCenter/app/services/thirdpay/notify"
|
||||||
"PaymentCenter/app/third/paymentService"
|
"PaymentCenter/app/third/paymentService"
|
||||||
"PaymentCenter/app/third/paymentService/payCommon"
|
"PaymentCenter/app/third/paymentService/payCommon"
|
||||||
"PaymentCenter/app/utils"
|
"PaymentCenter/app/utils"
|
||||||
"PaymentCenter/config"
|
"PaymentCenter/config"
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"github.com/qit-team/snow-core/command"
|
"github.com/qit-team/snow-core/command"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -83,7 +82,7 @@ func closeOrder() {
|
||||||
if response.Code == payCommon.PAY_SUCCESS_CODE {
|
if response.Code == payCommon.PAY_SUCCESS_CODE {
|
||||||
orderIds = append(orderIds, orderInfo.Id)
|
orderIds = append(orderIds, orderInfo.Id)
|
||||||
} else {
|
} else {
|
||||||
utils.Log(nil, "关闭订单,上游支付失败", response)
|
utils.Log(nil, "关闭订单,上游失败", response)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 修改订单状态为关闭
|
// 修改订单状态为关闭
|
||||||
|
@ -172,64 +171,115 @@ func queryOrder() {
|
||||||
// 成功
|
// 成功
|
||||||
status = common.ORDER_STATUS_PAYED
|
status = common.ORDER_STATUS_PAYED
|
||||||
case "REFUND":
|
case "REFUND":
|
||||||
// 退款
|
// 退款 订单支付完成才能退款,所以支付单的状态是支付完成
|
||||||
status = common.ORDER_STATUS_REFUND
|
status = common.ORDER_STATUS_PAYED
|
||||||
|
|
||||||
case "NOTPAY":
|
case "NOTPAY":
|
||||||
// 未支付
|
// 未支付
|
||||||
return
|
return
|
||||||
case "CLOSED":
|
case "CLOSED":
|
||||||
// 关闭
|
// 关闭
|
||||||
status = common.ORDER_STATUS_CLOSE
|
status = common.ORDER_STATUS_CLOSE
|
||||||
|
|
||||||
}
|
}
|
||||||
// 回调通知下游 todo
|
// 回调通知下游 todo
|
||||||
|
notifyResult := notify.NewOrderNotifyWithHandle(orderInfo.Id, status, int(result.Result.PayerTotal), "")
|
||||||
|
utils.Log(nil, "主动查询订单支付状态,回调下游", notifyResult)
|
||||||
|
}
|
||||||
|
}(orderInfo)
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 更新订单状态 todo
|
// 主动查询退款订单状态
|
||||||
orderUpdate := ordersmodel.Orders{
|
func queryRefundOrder() {
|
||||||
Id: orderInfo.Id,
|
var now = time.Now().Format(time.DateTime)
|
||||||
Status: status,
|
utils.Log(nil, "主动查询退款订单状态", now)
|
||||||
PayerTotal: int(result.Result.PayerTotal),
|
ctx := context.Background()
|
||||||
|
// 查询退款中的订单
|
||||||
|
repo := data.NewOrderRepo(ordersmodel.GetInstance().GetDb())
|
||||||
|
// 拼接条件
|
||||||
|
cond := builder.NewCond()
|
||||||
|
cond = cond.And(builder.Eq{"status": common.ORDER_STATUS_PAYING}, builder.Gt{"orders.create_time": time.Now().Add(-time.Second * time.Duration(config.GetConf().CronConfig.QueryOrderTime))})
|
||||||
|
cond = cond.And(builder.Eq{"order_type": common.ORDER_TYPE_REFUND})
|
||||||
|
order := make([]ordersmodel.OrdersLeftPayChannelList, 0)
|
||||||
|
err := repo.OrdersLeftPayChannelList(cond, entities.PageRequest{}, &order)
|
||||||
|
if err != nil {
|
||||||
|
utils.Log(nil, "主动查询退款订单状态,查询退款中订单失败", err)
|
||||||
|
return
|
||||||
|
} else if len(order) > 0 {
|
||||||
|
ch := make(chan struct{}, config.GetConf().CronConfig.ConcurrentNumber)
|
||||||
|
wg := sync.WaitGroup{}
|
||||||
|
|
||||||
|
for index := range order {
|
||||||
|
ch <- struct{}{}
|
||||||
|
wg.Add(1)
|
||||||
|
orderInfo := order[index]
|
||||||
|
|
||||||
|
// 发起查询上游
|
||||||
|
go func(orderInfo ordersmodel.OrdersLeftPayChannelList) {
|
||||||
|
defer func() {
|
||||||
|
<-ch
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
|
||||||
|
query := paymentService.OrderRefundQueryRequest{
|
||||||
|
RefundOrderId: orderInfo.Id,
|
||||||
|
OrderId: orderInfo.RefundOrderId,
|
||||||
|
}
|
||||||
|
switch utils.PayType(orderInfo.ChannelType) {
|
||||||
|
case common.PAY_CHANNLE_TYPE_WECHAT:
|
||||||
|
wx := backend.WechatPayChannel{}
|
||||||
|
_ = json.Unmarshal([]byte(orderInfo.ExtJson), &wx)
|
||||||
|
query.PayChannel = payCommon.PAY_CHANNLE_TYPE_WECHAT
|
||||||
|
query.Wx = paymentService.WxPay{
|
||||||
|
AppId: orderInfo.AppId,
|
||||||
|
MchId: wx.MchId,
|
||||||
|
SerialNo: wx.SerialNo,
|
||||||
|
ApiV3Key: wx.ApiV3Key,
|
||||||
|
PrivateKey: wx.PrivateKey,
|
||||||
}
|
}
|
||||||
|
case common.PAY_CHANNLE_TYPE_ZFB:
|
||||||
|
ali := backend.AliPayChannel{}
|
||||||
|
query.PayChannel = payCommon.PAY_CHANNLE_TYPE_ZFB
|
||||||
|
_ = json.Unmarshal([]byte(orderInfo.ExtJson), &ali)
|
||||||
|
query.Ali = paymentService.AliPay{
|
||||||
|
AppId: orderInfo.AppId,
|
||||||
|
PrivateKey: ali.PrivateKey,
|
||||||
|
AppPublicCert: ali.AppPublicCert,
|
||||||
|
AlipayRootCert: ali.AlipayRootCert,
|
||||||
|
AlipayPublicCert: ali.AlipayPublicCert,
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
utils.Log(nil, "查询订单,支付渠道不支持", orderInfo.ChannelType)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
session := ordersmodel.GetInstance().GetDb().NewSession()
|
// 发起查询
|
||||||
if err = session.Begin(); err != nil {
|
result := paymentService.OrderRefundQuery(ctx, query)
|
||||||
utils.Log(nil, "主动查询订单支付状态,更新订单状态失败", err)
|
utils.Log(nil, "主动查询退款订单状态,上游返回数据", result)
|
||||||
|
// 查询成功,校验状态
|
||||||
|
var status int
|
||||||
|
if result.Code == payCommon.PAY_SUCCESS_CODE {
|
||||||
|
// 退款状态 0:未申请,1:退款中,2:退款成功,3:退款失败
|
||||||
|
switch result.Result.RefundStatus {
|
||||||
|
case 0:
|
||||||
|
// 未申请
|
||||||
|
utils.Log(nil, "主动查询退款订单状态,未申请", status)
|
||||||
return
|
return
|
||||||
}
|
case 1:
|
||||||
defer func() {
|
// 退款中
|
||||||
if err != nil {
|
status = common.ORDER_STATUS_PAYING
|
||||||
session.Rollback()
|
|
||||||
} else {
|
|
||||||
err = session.Commit()
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
orderLogRepo := data.NewOrderThirdPayLogRepo(session)
|
|
||||||
orderRepo := data.NewOrderRepo(session)
|
|
||||||
|
|
||||||
conn := builder.NewCond()
|
|
||||||
conn = conn.And(builder.Eq{"id": orderInfo.Id})
|
|
||||||
_, err = orderRepo.OrderUpdate(&orderUpdate, conn)
|
|
||||||
if err != nil {
|
|
||||||
utils.Log(nil, "主动查询订单支付状态,更新订单状态失败", err)
|
|
||||||
return
|
return
|
||||||
|
case 2:
|
||||||
|
// 退款成功
|
||||||
|
status = common.ORDER_STATUS_PAYED
|
||||||
|
case 3:
|
||||||
|
// 退款失败
|
||||||
|
status = common.ORDER_STATUS_FAILED
|
||||||
}
|
}
|
||||||
|
// 回调通知下游 todo
|
||||||
// 写入日志
|
notifyResult := notify.NewOrderNotifyWithHandle(orderInfo.Id, status, int(result.Result.RefundFee), "")
|
||||||
body, _ := json.Marshal(result)
|
utils.Log(nil, "主动查询退款订单状态,回调下游", notifyResult)
|
||||||
log := orderthirdpaylogmodel.OrderThirdPayLog{
|
|
||||||
OrderId: orderInfo.Id,
|
|
||||||
PayCallback: string(body),
|
|
||||||
Status: 0,
|
|
||||||
PayParam: fmt.Sprintf(`{"pay_channel_id":%d}`, orderInfo.PayChannelId),
|
|
||||||
Type: common.THIRD_ORDER_TYPE_ORDER_QUERY,
|
|
||||||
MerchantCallback: "{}",
|
|
||||||
}
|
|
||||||
_, err = orderLogRepo.OrderThirdPayLogInsertOne(&log)
|
|
||||||
if err != nil {
|
|
||||||
utils.Log(nil, "主动查询订单支付状态,写入支付日志失败", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}(orderInfo)
|
}(orderInfo)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,4 +17,5 @@ func RegisterSchedule(c *cron.Cron) {
|
||||||
//c.AddFunc("@every 10s", test)
|
//c.AddFunc("@every 10s", test)
|
||||||
c.AddFunc("@every 60s", closeOrder)
|
c.AddFunc("@every 60s", closeOrder)
|
||||||
c.AddFunc("@every 10s", queryOrder)
|
c.AddFunc("@every 10s", queryOrder)
|
||||||
|
c.AddFunc("@every 60s", queryRefundOrder)
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,13 +22,12 @@ const (
|
||||||
ADMIN_USER_NAME = "User-Name"
|
ADMIN_USER_NAME = "User-Name"
|
||||||
ADMIN_USER_INCLUDEUSERS = "Include-Users"
|
ADMIN_USER_INCLUDEUSERS = "Include-Users"
|
||||||
|
|
||||||
// '订单状态: 1待支付、2支付中、3支付成功、4支付失败、5订单关闭 6支付完成后退款,
|
// '订单状态: 1待支付、2支付中、3支付成功、4支付失败、5订单关闭
|
||||||
ORDER_STATUS_WAITPAY = 1
|
ORDER_STATUS_WAITPAY = 1
|
||||||
ORDER_STATUS_PAYING = 2
|
ORDER_STATUS_PAYING = 2
|
||||||
ORDER_STATUS_PAYED = 3
|
ORDER_STATUS_PAYED = 3
|
||||||
ORDER_STATUS_FAILED = 4
|
ORDER_STATUS_FAILED = 4
|
||||||
ORDER_STATUS_CLOSE = 5
|
ORDER_STATUS_CLOSE = 5
|
||||||
ORDER_STATUS_REFUND = 6
|
|
||||||
|
|
||||||
// 订单类型,1支付,2退款
|
// 订单类型,1支付,2退款
|
||||||
ORDER_TYPE_PAY = 1
|
ORDER_TYPE_PAY = 1
|
||||||
|
@ -63,3 +62,10 @@ var OrderTypeList = map[int]string{
|
||||||
ORDER_TYPE_PAY: "付款",
|
ORDER_TYPE_PAY: "付款",
|
||||||
ORDER_TYPE_REFUND: "退款",
|
ORDER_TYPE_REFUND: "退款",
|
||||||
}
|
}
|
||||||
|
var OrderStatusMap = map[int]string{
|
||||||
|
ORDER_STATUS_WAITPAY: "等待执行",
|
||||||
|
ORDER_STATUS_PAYING: "执行中",
|
||||||
|
ORDER_STATUS_PAYED: "执行成功",
|
||||||
|
ORDER_STATUS_FAILED: "执行失败",
|
||||||
|
ORDER_STATUS_CLOSE: "订单关闭",
|
||||||
|
}
|
||||||
|
|
|
@ -47,8 +47,9 @@ const (
|
||||||
AppSM4DecryptFail = 1231
|
AppSM4DecryptFail = 1231
|
||||||
AppSM4EncryptKeyNotFound = 1232
|
AppSM4EncryptKeyNotFound = 1232
|
||||||
AppSM4EncryptFail = 1233
|
AppSM4EncryptFail = 1233
|
||||||
|
AppAesEncryptFail = 1234
|
||||||
// 加密方式不存在
|
// 加密方式不存在
|
||||||
EncryptTypeNotFound = 1240
|
EncryptTypeNotFound = 1241
|
||||||
|
|
||||||
//渠道
|
//渠道
|
||||||
PayChannelNotFound = 1300
|
PayChannelNotFound = 1300
|
||||||
|
@ -69,6 +70,9 @@ const (
|
||||||
|
|
||||||
//回调
|
//回调
|
||||||
NotifySendFail = 1600
|
NotifySendFail = 1600
|
||||||
|
|
||||||
|
//预支付
|
||||||
|
PrePayFail = 1701
|
||||||
)
|
)
|
||||||
|
|
||||||
var MsgEN = map[int]string{
|
var MsgEN = map[int]string{
|
||||||
|
@ -110,6 +114,8 @@ var MsgZH = map[int]string{
|
||||||
AppSM4EncryptKeyNotFound: "密匙缺失,无法进行sm4加密",
|
AppSM4EncryptKeyNotFound: "密匙缺失,无法进行sm4加密",
|
||||||
AppSM4EncryptFail: "sm4加密失败",
|
AppSM4EncryptFail: "sm4加密失败",
|
||||||
|
|
||||||
|
AppAesEncryptFail: "aes 加密失败",
|
||||||
|
|
||||||
EncryptTypeNotFound: "加密方式不存在",
|
EncryptTypeNotFound: "加密方式不存在",
|
||||||
|
|
||||||
PayChannelNotFound: "支付方式不存在",
|
PayChannelNotFound: "支付方式不存在",
|
||||||
|
@ -127,6 +133,8 @@ var MsgZH = map[int]string{
|
||||||
OrderStatusErr: "订单状态错误",
|
OrderStatusErr: "订单状态错误",
|
||||||
|
|
||||||
NotifySendFail: "回调发送失败",
|
NotifySendFail: "回调发送失败",
|
||||||
|
|
||||||
|
PrePayFail: "预支付失败",
|
||||||
}
|
}
|
||||||
var MsgMap map[string]map[int]string = map[string]map[int]string{"en": MsgZH}
|
var MsgMap map[string]map[int]string = map[string]map[int]string{"en": MsgZH}
|
||||||
|
|
||||||
|
|
|
@ -7,35 +7,47 @@ import (
|
||||||
"PaymentCenter/app/models/ordersmodel"
|
"PaymentCenter/app/models/ordersmodel"
|
||||||
"PaymentCenter/app/services"
|
"PaymentCenter/app/services"
|
||||||
"PaymentCenter/app/services/thirdpay"
|
"PaymentCenter/app/services/thirdpay"
|
||||||
|
"PaymentCenter/app/services/thirdpay/api"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"xorm.io/builder"
|
"xorm.io/builder"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Pay(c *gin.Context) {
|
func PayUrl(c *gin.Context) {
|
||||||
|
var res front.PayUrlResp
|
||||||
req := controllers.GetRequest(c).(*front.PayReqs)
|
req := controllers.GetRequest(c).(*front.PayReqs)
|
||||||
appCheckInfo := controllers.GetAppCheckInfo(c).(*services.AppCheck)
|
appCheckInfo := controllers.GetAppCheckInfo(c).(*services.AppCheck)
|
||||||
check := thirdpay.ThirdPayCheck(c.Request.Context(), req, appCheckInfo, c.ClientIP())
|
check := thirdpay.ThirdPayInfoCheck(c.Request.Context(), req, appCheckInfo, c.ClientIP())
|
||||||
if check.CheckCode != errorcode.Success {
|
if check.CheckCode != errorcode.Success {
|
||||||
if check.CheckCode == errorcode.OrdersExist {
|
|
||||||
//订单已存在,直接返回订单信息
|
|
||||||
controllers.ApiRes(c, thirdpay.PayCallBack(check.OldOrder, false), errorcode.Success)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
controllers.ApiRes(c, nil, check.CheckCode)
|
controllers.ApiRes(c, nil, check.CheckCode)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
payInfo := thirdpay.ThirdPayWeb(check)
|
check.CheckOrder()
|
||||||
if payInfo.PayCode != errorcode.Success {
|
if check.CheckCode != errorcode.Success {
|
||||||
controllers.ApiRes(c, nil, payInfo.PayCode)
|
controllers.ApiRes(c, nil, check.CheckCode)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
controllers.ApiRes(c, thirdpay.PayCallBack(payInfo.Order, true), errorcode.Success)
|
pay := thirdpay.ThirdPayWeb(check)
|
||||||
|
if pay.PayCode != errorcode.Success {
|
||||||
|
controllers.ApiRes(c, nil, pay.PayCode)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data := api.NewOrdersResp(pay.Order)
|
||||||
|
encryptData, errCode := api.EnCrypt(appCheckInfo.App, data)
|
||||||
|
|
||||||
|
if errCode != errorcode.Success {
|
||||||
|
controllers.ApiRes(c, nil, pay.PayCode)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res.Order = string(encryptData)
|
||||||
|
res.Url = pay.Url
|
||||||
|
controllers.ApiRes(c, res, pay.PayCode)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询订单
|
// 查询订单
|
||||||
func QueryOrder(c *gin.Context) {
|
func QueryOrder(c *gin.Context) {
|
||||||
req := controllers.GetRequest(c).(*front.QueryReqs)
|
req := controllers.GetRequest(c).(*front.QueryReqs)
|
||||||
|
|
||||||
appCheckInfo := controllers.GetAppCheckInfo(c).(*services.AppCheck)
|
appCheckInfo := controllers.GetAppCheckInfo(c).(*services.AppCheck)
|
||||||
// 查询订单表
|
// 查询订单表
|
||||||
order := ordersmodel.Orders{
|
order := ordersmodel.Orders{
|
||||||
|
@ -47,10 +59,14 @@ func QueryOrder(c *gin.Context) {
|
||||||
cond = cond.And(builder.Eq{"out_tread_no": order.OutTreadNo}, builder.Eq{"app_id": order.AppId})
|
cond = cond.And(builder.Eq{"out_tread_no": order.OutTreadNo}, builder.Eq{"app_id": order.AppId})
|
||||||
_, code := services.OrderFindOne(&order, cond)
|
_, code := services.OrderFindOne(&order, cond)
|
||||||
if code != errorcode.OrdersExist {
|
if code != errorcode.OrdersExist {
|
||||||
controllers.ApiRes(c, order, code)
|
controllers.ApiRes(c, nil, code)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
data := front.OrdersResponse{}
|
data := api.NewOrdersResp(&order)
|
||||||
data.ResponseFromDb(order)
|
encryptData, errCode := api.EnCrypt(appCheckInfo.App, data)
|
||||||
controllers.ApiRes(c, data, errorcode.Success)
|
if errCode != errorcode.Success {
|
||||||
|
controllers.ApiRes(c, nil, errCode)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
controllers.ApiRes(c, encryptData, errorcode.Success)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package front
|
package front
|
||||||
|
|
||||||
import "PaymentCenter/app/models/ordersmodel"
|
|
||||||
|
|
||||||
type ApiCommonBody struct {
|
type ApiCommonBody struct {
|
||||||
AppId int64 `json:"app_id" validate:"required"`
|
AppId int64 `json:"app_id" validate:"required"`
|
||||||
Timestamp int64 `json:"timestamp" validate:"required"`
|
Timestamp int64 `json:"timestamp" validate:"required"`
|
||||||
|
@ -11,6 +9,7 @@ type RequestBody struct {
|
||||||
AppId int64 `json:"app_id" validate:"required"`
|
AppId int64 `json:"app_id" validate:"required"`
|
||||||
Timestamp int64 `json:"timestamp" validate:"required"`
|
Timestamp int64 `json:"timestamp" validate:"required"`
|
||||||
Data string `json:"data" validate:"required"`
|
Data string `json:"data" validate:"required"`
|
||||||
|
Key string `json:"key" validate:"max=32"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type PayReqs struct {
|
type PayReqs struct {
|
||||||
|
@ -23,37 +22,12 @@ type PayReqs struct {
|
||||||
Desc string `json:"desc" validate:"max=100" label:"商品描述"`
|
Desc string `json:"desc" validate:"max=100" label:"商品描述"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type OrderApiResp struct {
|
type PayUrlResp struct {
|
||||||
Code int
|
Order string `json:"order"`
|
||||||
Msg string
|
Url string `json:"url"`
|
||||||
Data interface{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type QueryReqs struct {
|
type QueryReqs struct {
|
||||||
ApiCommonBody
|
ApiCommonBody
|
||||||
OutTradeNo string `json:"out_trade_no" validate:"required" label:"外侧商户订单号"`
|
OutTradeNo string `json:"out_trade_no" validate:"required" label:"外侧商户订单号"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type OrdersResponse struct {
|
|
||||||
Id int64 `json:"id"`
|
|
||||||
PayChannelId int64 `json:"pay_channel_id"`
|
|
||||||
AppId int64 `json:"app_id"`
|
|
||||||
OutTreadNo string `json:"out_tread_no"`
|
|
||||||
Status int `json:"status"`
|
|
||||||
OrderType int `json:"order_type"`
|
|
||||||
Amount int `json:"amount"`
|
|
||||||
PayerTotal int `json:"payer_total"`
|
|
||||||
CreateTime string `json:"create_time"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *OrdersResponse) ResponseFromDb(db ordersmodel.Orders) {
|
|
||||||
o.Id = db.Id
|
|
||||||
o.PayChannelId = db.PayChannelId
|
|
||||||
o.AppId = db.AppId
|
|
||||||
o.OutTreadNo = db.OutTreadNo
|
|
||||||
o.Status = db.Status
|
|
||||||
o.OrderType = db.OrderType
|
|
||||||
o.Amount = db.Amount
|
|
||||||
o.PayerTotal = db.PayerTotal
|
|
||||||
o.CreateTime = db.CreateTime.Format("2006-01-02 15:04:05")
|
|
||||||
}
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"PaymentCenter/app/http/entities/front"
|
"PaymentCenter/app/http/entities/front"
|
||||||
"PaymentCenter/app/http/requestmapping"
|
"PaymentCenter/app/http/requestmapping"
|
||||||
"PaymentCenter/app/services"
|
"PaymentCenter/app/services"
|
||||||
"PaymentCenter/app/services/apicrypt"
|
"PaymentCenter/app/services/thirdpay/api"
|
||||||
"PaymentCenter/app/utils"
|
"PaymentCenter/app/utils"
|
||||||
"PaymentCenter/config"
|
"PaymentCenter/config"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
@ -155,12 +155,8 @@ func ValidatePayRequest() gin.HandlerFunc {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//解密
|
//解密
|
||||||
cryptFunc := appCheck.Crypt()
|
dataByte, errCode := api.DeCrypt(appCheck.App, requestDataStruct.Data, requestDataStruct.Key)
|
||||||
if cryptFunc == nil {
|
if errCode != errorcode.Success {
|
||||||
controllers.ApiRes(c, nil, appCheck.GetCode())
|
|
||||||
}
|
|
||||||
dataByte, errCode := cryptFunc(appCheck.App).Decrypt(requestDataStruct.Data)
|
|
||||||
if errCode != apicrypt.CryptNotError {
|
|
||||||
controllers.ApiRes(c, nil, errCode)
|
controllers.ApiRes(c, nil, errCode)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var FrontRequestMap = map[string]func() interface{}{
|
var FrontRequestMap = map[string]func() interface{}{
|
||||||
common.FRONT_V1 + "/pay/do": func() interface{} { return new(front.PayReqs) },
|
common.FRONT_V1 + "/pay/url": func() interface{} { return new(front.PayReqs) },
|
||||||
}
|
}
|
||||||
|
|
||||||
var FrontRequestMapBeforeDecrypt = map[string]func() interface{}{
|
var FrontRequestMapBeforeDecrypt = map[string]func() interface{}{
|
||||||
common.FRONT_V1 + "/pay/do": func() interface{} { return new(front.RequestBody) },
|
common.FRONT_V1 + "/pay/url": func() interface{} { return new(front.RequestBody) },
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ func RegisterRoute(router *gin.Engine) {
|
||||||
|
|
||||||
pay := v1.Group("/pay", middlewares.ValidateRequest(), middlewares.ValidatePayRequest())
|
pay := v1.Group("/pay", middlewares.ValidateRequest(), middlewares.ValidatePayRequest())
|
||||||
{
|
{
|
||||||
pay.POST("/do", front.Pay)
|
pay.POST("/url", front.PayUrl)
|
||||||
pay.POST("/query", front.QueryOrder) //查询订单
|
pay.POST("/query", front.QueryOrder) //查询订单
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ var (
|
||||||
type OrderRequestLog struct {
|
type OrderRequestLog struct {
|
||||||
Id int64
|
Id int64
|
||||||
IpAddress string `xorm:"'ip_address' varchar(16)"`
|
IpAddress string `xorm:"'ip_address' varchar(16)"`
|
||||||
URL string `xorm:"'url' varchar(20)"`
|
URL string `xorm:"'url' varchar(100)"`
|
||||||
MerchantRequest string `xorm:"'merchant_request' JSON"`
|
MerchantRequest string `xorm:"'merchant_request' JSON"`
|
||||||
MerchantResponse string `xorm:"'merchant_response' JSON"`
|
MerchantResponse string `xorm:"'merchant_response' JSON"`
|
||||||
CreateTime time.Time `xorm:"'create_time' datetime created"`
|
CreateTime time.Time `xorm:"'create_time' datetime created"`
|
||||||
|
|
|
@ -13,20 +13,21 @@ var (
|
||||||
|
|
||||||
// 实体
|
// 实体
|
||||||
type Orders struct {
|
type Orders struct {
|
||||||
Id int64
|
Id int64
|
||||||
MerchantId int64 `xorm:"'merchant_id' bigint(20)"`
|
MerchantId int64 `xorm:"'merchant_id' bigint(20)"`
|
||||||
PayChannelId int64 `xorm:"'pay_channel_id' bigint(20)"`
|
PayChannelId int64 `xorm:"'pay_channel_id' bigint(20)"`
|
||||||
AppId int64 `xorm:"'app_id' bigint(20)"`
|
AppId int64 `xorm:"'app_id' bigint(20)"`
|
||||||
OutTreadNo string `xorm:"'out_tread_no' varchar(50)"`
|
OutTreadNo string `xorm:"'out_tread_no' varchar(50)"`
|
||||||
OrderType int `xorm:"'order_type' TINYINT"`
|
OrderType int `xorm:"'order_type' TINYINT"`
|
||||||
Amount int `xorm:"'amount' int(11)"`
|
RefundOrderId int64 `xorm:"'refund_order_id' bigint(20)"`
|
||||||
PayerTotal int `xorm:"'payer_total' int(11)"`
|
Amount int `xorm:"'amount' int(11)"`
|
||||||
ExtJson string `xorm:"'ext_json' varchar(1024)"`
|
PayerTotal int `xorm:"'payer_total' int(11)"`
|
||||||
Desc string `xorm:"'desc' varchar(100)"`
|
ExtJson string `xorm:"'ext_json' varchar(1024)"`
|
||||||
CreateTime time.Time `xorm:"'create_time' datetime created"`
|
Desc string `xorm:"'desc' varchar(100)"`
|
||||||
UpdateTime time.Time `xorm:"'update_time' timestamp updated"`
|
CreateTime time.Time `xorm:"'create_time' datetime created"`
|
||||||
Status int `xorm:"'status' TINYINT"`
|
UpdateTime time.Time `xorm:"'update_time' timestamp updated"`
|
||||||
DeleteTime time.Time `xorm:"'delete_time' timestamp deleted"`
|
Status int `xorm:"'status' TINYINT"`
|
||||||
|
DeleteTime time.Time `xorm:"'delete_time' timestamp deleted"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type OrdersBackendList struct {
|
type OrdersBackendList struct {
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"PaymentCenter/app/constants/errorcode"
|
"PaymentCenter/app/constants/errorcode"
|
||||||
"PaymentCenter/app/models/appmodel"
|
"PaymentCenter/app/models/appmodel"
|
||||||
"PaymentCenter/app/utils/encrypt/rsa"
|
"PaymentCenter/app/utils/encrypt/rsa"
|
||||||
|
"encoding/base64"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewRsa(app *appmodel.App) ApiCrypt {
|
func NewRsa(app *appmodel.App) ApiCrypt {
|
||||||
|
@ -12,23 +13,23 @@ func NewRsa(app *appmodel.App) ApiCrypt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Rsa) Encrypt(decryptData string) (encryptData []byte, errCode int) {
|
func (r *Rsa) Encrypt(data []byte) (encryptData []byte, errCode int) {
|
||||||
if r.App.PublicKey == "" {
|
if r.App.PublicKey == "" {
|
||||||
return nil, errorcode.AppRsaEncryptKeyNotFound
|
return nil, errorcode.AppRsaEncryptKeyNotFound
|
||||||
}
|
}
|
||||||
publicKeyPEM := `-----BEGIN PUBLIC KEY-----
|
publicKeyPEM := `-----BEGIN PUBLIC KEY-----
|
||||||
` + r.App.PublicKey + `
|
` + r.App.PublicKey + `
|
||||||
-----END PUBLIC KEY-----`
|
-----END PUBLIC KEY-----`
|
||||||
encryptData, err := rsa.Encrypt(publicKeyPEM, []byte(decryptData))
|
encryptByte, err := rsa.Encrypt(publicKeyPEM, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errorcode.AppRsaEncryptFail
|
return nil, errorcode.AppRsaEncryptFail
|
||||||
}
|
}
|
||||||
|
encryptData = []byte(base64.StdEncoding.EncodeToString(encryptByte))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Rsa) Decrypt(encryptData string) (decryptData []byte, errCode int) {
|
func (r *Rsa) Decrypt(encryptData string) (decryptData []byte, errCode int) {
|
||||||
|
|
||||||
if r.App.PrivateKey == "" {
|
if r.App.PrivateKey == "" {
|
||||||
return nil, errorcode.AppRsaDecryptKeyNotFound
|
return nil, errorcode.AppRsaDecryptKeyNotFound
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,12 +12,13 @@ func NewSm2(app *appmodel.App) ApiCrypt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *SM2) Encrypt(decryptData string) (encryptData []byte, errCode int) {
|
func (r *SM2) Encrypt(data []byte) (encryptData []byte, errCode int) {
|
||||||
|
|
||||||
if r.App.MerchantPublicKey == "" {
|
if r.App.MerchantPublicKey == "" {
|
||||||
return nil, errorcode.AppSM2EncryptKeyNotFound
|
return nil, errorcode.AppSM2EncryptKeyNotFound
|
||||||
}
|
}
|
||||||
//
|
|
||||||
encryptDataString, err := sm2.SM2Encrypt(decryptData, r.App.PrivateKey)
|
encryptDataString, err := sm2.SM2Encrypt(string(data), r.App.PrivateKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errorcode.AppSM2EncryptFail
|
return nil, errorcode.AppSM2EncryptFail
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,12 +13,11 @@ func NewSm4(app *appmodel.App) ApiCrypt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *SM4) Encrypt(decryptData string) (encryptData []byte, errCode int) {
|
func (r *SM4) Encrypt(data []byte) (encryptData []byte, errCode int) {
|
||||||
if r.App.MerchantPublicKey == "" || r.App.PrivateKey == "" {
|
if r.App.MerchantPublicKey == "" || r.App.PrivateKey == "" {
|
||||||
return nil, errorcode.AppSM4DecryptKeyNotFound
|
return nil, errorcode.AppSM4DecryptKeyNotFound
|
||||||
}
|
}
|
||||||
|
encryptDataString, err := sm4.Sm4Encrypt(strconv.FormatInt(r.App.Id, 10), r.App.PrivateKey, r.App.MerchantPublicKey, string(data), "", true)
|
||||||
encryptDataString, err := sm4.Sm4Encrypt(strconv.FormatInt(r.App.Id, 10), r.App.PrivateKey, r.App.MerchantPublicKey, decryptData, "", true)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errorcode.AppSM4EncryptFail
|
return nil, errorcode.AppSM4EncryptFail
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
|
|
||||||
type (
|
type (
|
||||||
ApiCrypt interface {
|
ApiCrypt interface {
|
||||||
Encrypt(decryptData string) (encryptData []byte, errCode int)
|
Encrypt(data []byte) (encryptData []byte, errCode int)
|
||||||
Decrypt(encryptData string) (decryptData []byte, errCode int)
|
Decrypt(encryptData string) (decryptData []byte, errCode int)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"PaymentCenter/app/constants/errorcode"
|
"PaymentCenter/app/constants/errorcode"
|
||||||
|
"PaymentCenter/app/models/appmodel"
|
||||||
"PaymentCenter/app/utils"
|
"PaymentCenter/app/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -13,3 +14,7 @@ func handErr(err error) int {
|
||||||
return errorcode.Success
|
return errorcode.Success
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func EnCryptData(app *appmodel.App) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"PaymentCenter/app/models/ordersmodel"
|
||||||
|
)
|
||||||
|
|
||||||
|
type OrdersResp struct {
|
||||||
|
OrderNo int64 `json:"order_no"`
|
||||||
|
OrderType int `json:"order_type"`
|
||||||
|
OutTreadNo string `json:"out_tread_no"`
|
||||||
|
Amount int `json:"amount"`
|
||||||
|
Desc string `json:"desc"`
|
||||||
|
|
||||||
|
Status int `json:"status"`
|
||||||
|
CreateTime string `json:"create_time"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type OrdersWithUrl struct {
|
||||||
|
Order *OrdersResp
|
||||||
|
Url string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewOrdersResp(db *ordersmodel.Orders) *OrdersResp {
|
||||||
|
return &OrdersResp{
|
||||||
|
OrderNo: db.Id,
|
||||||
|
OutTreadNo: db.OutTreadNo,
|
||||||
|
Status: db.Status,
|
||||||
|
OrderType: db.OrderType,
|
||||||
|
Amount: db.Amount,
|
||||||
|
Desc: db.Desc,
|
||||||
|
CreateTime: db.CreateTime.Format("2006-01-02 15:04:05"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *OrdersResp) WithUrl(url string) *OrdersWithUrl {
|
||||||
|
return &OrdersWithUrl{
|
||||||
|
Order: o,
|
||||||
|
Url: url,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *OrdersResp) WithAes(url string) *OrdersWithUrl {
|
||||||
|
return &OrdersWithUrl{
|
||||||
|
Order: o,
|
||||||
|
Url: url,
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"PaymentCenter/app/constants/errorcode"
|
||||||
|
"PaymentCenter/app/models/appmodel"
|
||||||
|
"PaymentCenter/app/services"
|
||||||
|
"PaymentCenter/app/services/apicrypt"
|
||||||
|
"encoding/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
func EnCrypt(app *appmodel.App, data interface{}) ([]byte, int) {
|
||||||
|
appCheck := services.NewAppCheck(app)
|
||||||
|
cryptFunc := appCheck.Crypt()
|
||||||
|
if cryptFunc == nil {
|
||||||
|
return nil, appCheck.Code
|
||||||
|
}
|
||||||
|
dataByte, err := json.Marshal(data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errorcode.AppAesEncryptFail
|
||||||
|
}
|
||||||
|
//aesKey, err := aes.GenerateRandomStringCrypto(16)
|
||||||
|
//if err != nil {
|
||||||
|
// return "", errorcode.AppAesEncryptFail
|
||||||
|
//}
|
||||||
|
//aesData, err := aes.Encrypt(dataByte, []byte(aesKey))
|
||||||
|
//if err != nil {
|
||||||
|
// return "", errorcode.AppAesEncryptFail
|
||||||
|
//}
|
||||||
|
encryptData, errCode := cryptFunc(appCheck.App).Encrypt(dataByte)
|
||||||
|
if errCode != apicrypt.CryptNotError {
|
||||||
|
return nil, errCode
|
||||||
|
}
|
||||||
|
return encryptData, errorcode.Success
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeCrypt(app *appmodel.App, data string, aesKey string) ([]byte, int) {
|
||||||
|
appCheck := services.NewAppCheck(app)
|
||||||
|
cryptFunc := appCheck.Crypt()
|
||||||
|
if cryptFunc == nil {
|
||||||
|
return nil, appCheck.Code
|
||||||
|
}
|
||||||
|
dataByte, errCode := cryptFunc(app).Decrypt(data)
|
||||||
|
if errCode != apicrypt.CryptNotError {
|
||||||
|
return nil, errCode
|
||||||
|
}
|
||||||
|
//aesData, err := aes.Decrypt(dataByte, []byte(aesKey))
|
||||||
|
//if err != nil {
|
||||||
|
// return nil, errorcode.AppAesEncryptFail
|
||||||
|
//}
|
||||||
|
|
||||||
|
return dataByte, errorcode.Success
|
||||||
|
}
|
|
@ -3,7 +3,9 @@ package do
|
||||||
import (
|
import (
|
||||||
"PaymentCenter/app/constants/common"
|
"PaymentCenter/app/constants/common"
|
||||||
"PaymentCenter/app/constants/errorcode"
|
"PaymentCenter/app/constants/errorcode"
|
||||||
|
"PaymentCenter/app/models/paychannelmodel"
|
||||||
"PaymentCenter/app/services"
|
"PaymentCenter/app/services"
|
||||||
|
"PaymentCenter/app/third/paymentService/payCommon"
|
||||||
|
|
||||||
"PaymentCenter/app/models/ordersmodel"
|
"PaymentCenter/app/models/ordersmodel"
|
||||||
"PaymentCenter/app/third/paymentService"
|
"PaymentCenter/app/third/paymentService"
|
||||||
|
@ -13,6 +15,7 @@ type Pay struct {
|
||||||
paycheck *PayCheck
|
paycheck *PayCheck
|
||||||
Order *ordersmodel.Orders
|
Order *ordersmodel.Orders
|
||||||
PayCode int
|
PayCode int
|
||||||
|
Url string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPay(paycheck *PayCheck) *Pay {
|
func NewPay(paycheck *PayCheck) *Pay {
|
||||||
|
@ -37,9 +40,9 @@ func (w *Pay) CreateOrder() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Pay) Pay() {
|
func (w *Pay) PayUrl() (url string) {
|
||||||
var (
|
var (
|
||||||
payFunc func(commonPayInfo *paymentService.PayOrderRequest, ExtJson string) error
|
payFunc func(commonPayInfo *paymentService.PayOrderRequest, channel *paychannelmodel.PayChannel) error
|
||||||
ok bool
|
ok bool
|
||||||
)
|
)
|
||||||
thirdPay := &paymentService.PayOrderRequest{
|
thirdPay := &paymentService.PayOrderRequest{
|
||||||
|
@ -54,13 +57,23 @@ func (w *Pay) Pay() {
|
||||||
w.PayCode = errorcode.PayChannelNotBuild
|
w.PayCode = errorcode.PayChannelNotBuild
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err := payFunc(thirdPay, w.paycheck.Channel.ExtJson)
|
err := payFunc(thirdPay, w.paycheck.Channel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.PayCode = errorcode.PayChannelExtJsonError
|
w.PayCode = errorcode.PayChannelExtJsonError
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
res := paymentService.PaymentService(*w.paycheck.ctx, *thirdPay)
|
res := paymentService.PaymentService(*w.paycheck.ctx, *thirdPay)
|
||||||
// payCommon.PAY_SUCCESS_CODE
|
|
||||||
w.PayCode = res.Code
|
if res.Code == payCommon.PAY_SUCCESS_CODE {
|
||||||
|
w.Order.Status = common.ORDER_STATUS_PAYING
|
||||||
|
code := services.OrderUpdate(w.Order, "status")
|
||||||
|
if code != errorcode.Success {
|
||||||
|
w.PayCode = code
|
||||||
|
}
|
||||||
|
w.Url = res.Result
|
||||||
|
} else {
|
||||||
|
w.PayCode = errorcode.PrePayFail
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,9 +61,9 @@ func (w *PayCheck) CheckOrder() {
|
||||||
cond := builder.NewCond()
|
cond := builder.NewCond()
|
||||||
cond = cond.And(builder.Eq{"out_tread_no": w.WebPayReqs.OutTradeNo}, builder.Eq{"app_id": w.AppCheck.AppId}, builder.Neq{"status": common.ORDER_STATUS_CLOSE})
|
cond = cond.And(builder.Eq{"out_tread_no": w.WebPayReqs.OutTradeNo}, builder.Eq{"app_id": w.AppCheck.AppId}, builder.Neq{"status": common.ORDER_STATUS_CLOSE})
|
||||||
order, code := services.OrderFindOne(&ordersmodel.Orders{}, cond)
|
order, code := services.OrderFindOne(&ordersmodel.Orders{}, cond)
|
||||||
if code == errorcode.OrdersExist {
|
if code == errorcode.SystemError {
|
||||||
w.OldOrder = order
|
|
||||||
w.CheckCode = code
|
w.CheckCode = code
|
||||||
}
|
}
|
||||||
|
w.OldOrder = order
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,27 +2,30 @@ package do
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"PaymentCenter/app/constants/common"
|
"PaymentCenter/app/constants/common"
|
||||||
|
"PaymentCenter/app/models/paychannelmodel"
|
||||||
"PaymentCenter/app/third/paymentService"
|
"PaymentCenter/app/third/paymentService"
|
||||||
"github.com/bytedance/sonic"
|
"github.com/bytedance/sonic"
|
||||||
)
|
)
|
||||||
|
|
||||||
var PayWayList = map[int]func(commonPayInfo *paymentService.PayOrderRequest, ExtJson string) error{
|
var PayWayList = map[int]func(commonPayInfo *paymentService.PayOrderRequest, channel *paychannelmodel.PayChannel) error{
|
||||||
common.PAY_CHANNEL_WECHAT_H5: WechatH5,
|
common.PAY_CHANNEL_WECHAT_H5: WechatH5,
|
||||||
common.PAY_CHANNEL_ALIPAY_WEB: AlipayWeb,
|
common.PAY_CHANNEL_ALIPAY_WEB: AlipayWeb,
|
||||||
}
|
}
|
||||||
|
|
||||||
func WechatH5(commonPayInfo *paymentService.PayOrderRequest, ExtJson string) error {
|
func WechatH5(commonPayInfo *paymentService.PayOrderRequest, channel *paychannelmodel.PayChannel) error {
|
||||||
err := sonic.Unmarshal([]byte(ExtJson), &commonPayInfo.Wx)
|
err := sonic.Unmarshal([]byte(channel.ExtJson), &commonPayInfo.Wx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
commonPayInfo.Wx.AppId = channel.AppId
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func AlipayWeb(commonPayInfo *paymentService.PayOrderRequest, ExtJson string) error {
|
func AlipayWeb(commonPayInfo *paymentService.PayOrderRequest, channel *paychannelmodel.PayChannel) error {
|
||||||
err := sonic.Unmarshal([]byte(ExtJson), &commonPayInfo.Ali)
|
err := sonic.Unmarshal([]byte(channel.ExtJson), &commonPayInfo.Ali)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
commonPayInfo.Ali.AppId = channel.AppId
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ type OrderNotifySendContent struct {
|
||||||
OrderId int64 `json:"order_id"`
|
OrderId int64 `json:"order_id"`
|
||||||
OutTreadNo string `json:"out_tread_no"`
|
OutTreadNo string `json:"out_tread_no"`
|
||||||
CompleteTime time.Time `json:"complete_time"`
|
CompleteTime time.Time `json:"complete_time"`
|
||||||
|
OrderType int `json:"order-type"`
|
||||||
Status int `json:"status"`
|
Status int `json:"status"`
|
||||||
Msg string `json:"msg"`
|
Msg string `json:"msg"`
|
||||||
ErrCode int `json:"err_code"`
|
ErrCode int `json:"err_code"`
|
||||||
|
@ -93,7 +94,6 @@ func (o *OrderNotify) handle() (res *OrderNotifyResp) {
|
||||||
func (o *OrderNotify) sendNotify(body *OrderNotifySendContent) {
|
func (o *OrderNotify) sendNotify(body *OrderNotifySendContent) {
|
||||||
|
|
||||||
bodyByte, _ := sonic.Marshal(&body)
|
bodyByte, _ := sonic.Marshal(&body)
|
||||||
|
|
||||||
headers := make(map[string]string, 1)
|
headers := make(map[string]string, 1)
|
||||||
headers["Content-Type"] = "application/json"
|
headers["Content-Type"] = "application/json"
|
||||||
resByte, err := httpclient.FastHttpPost(o.app.NotifyUrl, headers, bodyByte, 0)
|
resByte, err := httpclient.FastHttpPost(o.app.NotifyUrl, headers, bodyByte, 0)
|
||||||
|
@ -109,8 +109,9 @@ func (o *OrderNotify) setBody() *OrderNotifySendContent {
|
||||||
OutTreadNo: o.order.OutTreadNo,
|
OutTreadNo: o.order.OutTreadNo,
|
||||||
CompleteTime: o.CompleteTime,
|
CompleteTime: o.CompleteTime,
|
||||||
Status: o.order.Status,
|
Status: o.order.Status,
|
||||||
|
OrderType: o.order.OrderType,
|
||||||
Msg: o.Msg,
|
Msg: o.Msg,
|
||||||
ErrCode: o.code,
|
ErrCode: o.Status,
|
||||||
AppId: o.order.AppId,
|
AppId: o.order.AppId,
|
||||||
ChannelId: o.order.PayChannelId,
|
ChannelId: o.order.PayChannelId,
|
||||||
MerchantId: o.order.MerchantId,
|
MerchantId: o.order.MerchantId,
|
||||||
|
@ -118,11 +119,11 @@ func (o *OrderNotify) setBody() *OrderNotifySendContent {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OrderNotify) updateOrder() {
|
func (o *OrderNotify) updateOrder() {
|
||||||
if o.code != errorcode.Success {
|
if _, ok := common.OrderStatusMap[o.Status]; !ok {
|
||||||
o.order.Status = common.ORDER_STATUS_FAILED
|
o.code = errorcode.OrderStatusErr
|
||||||
} else {
|
return
|
||||||
o.order.Status = common.ORDER_STATUS_PAYED
|
|
||||||
}
|
}
|
||||||
|
o.order.Status = o.Status
|
||||||
o.code = services.OrderUpdate(o.order, "status")
|
o.code = services.OrderUpdate(o.order, "status")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,37 +3,35 @@ package thirdpay
|
||||||
import (
|
import (
|
||||||
"PaymentCenter/app/constants/errorcode"
|
"PaymentCenter/app/constants/errorcode"
|
||||||
"PaymentCenter/app/http/entities/front"
|
"PaymentCenter/app/http/entities/front"
|
||||||
"PaymentCenter/app/models/ordersmodel"
|
|
||||||
"PaymentCenter/app/services"
|
"PaymentCenter/app/services"
|
||||||
thirdpay "PaymentCenter/app/services/thirdpay/do"
|
thirdpay "PaymentCenter/app/services/thirdpay/do"
|
||||||
"PaymentCenter/app/services/thirdpay/types"
|
|
||||||
"context"
|
"context"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ThirdPayWeb(check *thirdpay.PayCheck) *thirdpay.Pay {
|
func ThirdPayWeb(check *thirdpay.PayCheck) *thirdpay.Pay {
|
||||||
pay := thirdpay.NewPay(check)
|
pay := thirdpay.NewPay(check)
|
||||||
// 创建订单
|
// 创建订单
|
||||||
pay.CreateOrder()
|
if &check.OldOrder != nil {
|
||||||
if pay.PayCode != errorcode.Success {
|
pay.CreateOrder()
|
||||||
return pay
|
if pay.PayCode != errorcode.Success {
|
||||||
|
return pay
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pay.Order = check.OldOrder
|
||||||
}
|
}
|
||||||
// 支付
|
// 支付
|
||||||
pay.Pay()
|
pay.PayUrl()
|
||||||
return pay
|
return pay
|
||||||
}
|
}
|
||||||
|
|
||||||
func ThirdPayCheck(ctx context.Context, req *front.PayReqs, appCheck *services.AppCheck, ip string) (check *thirdpay.PayCheck) {
|
func ThirdPayInfoCheck(ctx context.Context, req *front.PayReqs, appCheck *services.AppCheck, ip string) (check *thirdpay.PayCheck) {
|
||||||
check = thirdpay.NewPayCheck(&ctx, req, appCheck, ip)
|
check = thirdpay.NewPayCheck(&ctx, req, appCheck, ip)
|
||||||
// 校验表单
|
// 校验表单
|
||||||
check.CheckForm()
|
check.CheckForm()
|
||||||
if check.CheckCode != errorcode.Success {
|
if check.CheckCode != errorcode.Success {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 校验订单
|
|
||||||
check.CheckOrder()
|
|
||||||
if check.CheckCode != errorcode.Success {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// 校验商户
|
// 校验商户
|
||||||
check.CheckMerchant()
|
check.CheckMerchant()
|
||||||
if check.CheckCode != errorcode.Success {
|
if check.CheckCode != errorcode.Success {
|
||||||
|
@ -47,16 +45,3 @@ func ThirdPayCheck(ctx context.Context, req *front.PayReqs, appCheck *services.A
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func PayCallBack(order *ordersmodel.Orders, isNew bool) *types.PayResp {
|
|
||||||
res := &types.PayResp{
|
|
||||||
OrderNo: order.Id,
|
|
||||||
OrderType: order.OrderType,
|
|
||||||
Amount: order.Amount,
|
|
||||||
Desc: order.Desc,
|
|
||||||
IsNewCreate: isNew,
|
|
||||||
Status: order.Status,
|
|
||||||
}
|
|
||||||
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
package aes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/aes"
|
||||||
|
"crypto/cipher"
|
||||||
|
"crypto/rand"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"math/big"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
TestKey = "ROK0nAaxcsI0KRCy8VJgLlnlfjWYAOHk"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 加密函数
|
||||||
|
func Encrypt(plaintext, key []byte) ([]byte, error) {
|
||||||
|
block, err := aes.NewCipher(key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ciphertext := make([]byte, aes.BlockSize+len(plaintext))
|
||||||
|
iv := ciphertext[:aes.BlockSize]
|
||||||
|
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
mode := cipher.NewCBCEncrypter(block, iv)
|
||||||
|
mode.CryptBlocks(ciphertext[aes.BlockSize:], plaintext)
|
||||||
|
|
||||||
|
return iv, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解密函数
|
||||||
|
func Decrypt(ciphertext, key []byte) ([]byte, error) {
|
||||||
|
block, err := aes.NewCipher(key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ciphertext) < aes.BlockSize {
|
||||||
|
return nil, fmt.Errorf("ciphertext too short")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提取iv
|
||||||
|
iv := ciphertext[:aes.BlockSize]
|
||||||
|
ciphertext = ciphertext[aes.BlockSize:]
|
||||||
|
|
||||||
|
// 创建一个cipher.BlockMode
|
||||||
|
mode := cipher.NewCBCDecrypter(block, iv)
|
||||||
|
|
||||||
|
// 解密
|
||||||
|
mode.CryptBlocks(ciphertext, ciphertext)
|
||||||
|
|
||||||
|
// 去除PKCS#7填充
|
||||||
|
plaintext, err := pkcs7Unpadding(ciphertext, block.BlockSize())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return plaintext, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PKCS#7填充
|
||||||
|
func pkcs7Padding(ciphertext []byte, blockSize int) []byte {
|
||||||
|
padding := blockSize - len(ciphertext)%blockSize
|
||||||
|
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
|
||||||
|
return append(ciphertext, padtext...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 去除PKCS#7填充
|
||||||
|
func pkcs7Unpadding(ciphertext []byte, blockSize int) ([]byte, error) {
|
||||||
|
length := len(ciphertext)
|
||||||
|
unpadding := int(ciphertext[length-1])
|
||||||
|
if unpadding > blockSize || unpadding == 0 {
|
||||||
|
return nil, fmt.Errorf("invalid padding")
|
||||||
|
}
|
||||||
|
return ciphertext[:(length - unpadding)], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GenerateRandomStringCrypto(length int) (string, error) {
|
||||||
|
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||||
|
var bytes = make([]byte, length)
|
||||||
|
for i := range bytes {
|
||||||
|
num, err := rand.Int(rand.Reader, big.NewInt(int64(len(charset))))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
bytes[i] = charset[num.Int64()]
|
||||||
|
}
|
||||||
|
return string(bytes), nil
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package aes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCreateKey(t *testing.T) {
|
||||||
|
key, _ := GenerateRandomStringCrypto(32)
|
||||||
|
fmt.Printf(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAesEncrypt(t *testing.T) {
|
||||||
|
|
||||||
|
fmt.Printf("%s\n", encrypt())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAesDecrypt(t *testing.T) {
|
||||||
|
data := "dk9trGQn2kZyE0rmfYglxwNmr7gc0DGFWvnPDVpLHfzwPiaWKkr+ZffKu0wj9/DQurIgjrQZIW8uV5/e+jxzBE6+5YZuKcT9+5xZSv6ieiXB7WUrKKnjxX/bHEaWgfoa0eDqEBhGth+mgql7qWFZLmuXpoKuAc0FPhdHTiynAttqjNMU4rMeXq52yJLuXrKHGlavhd9DETNDrhPFzyIAw7XjoMfGtBIFkXyDK5X+AKGkRvMJ8KfXR3lk9sSzTyGKRK/S"
|
||||||
|
|
||||||
|
res, err := Decrypt([]byte(data), []byte(TestKey))
|
||||||
|
fmt.Println(string(res), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func encrypt() string {
|
||||||
|
data := "{\"pay_channel_id\":8935141660703064070,\"out_trade_no\":\"asdadasdas\",\"order_type\":1,\"amount\":1,\"desc\":\"abc\",\"ext_json\":\"\",\"app_id\":5476377146882523138,\"timestamp\":53612533412643}{\"pay_channel_id\":8935141660703064070,\"out_trade_no\":\"asdadasdas\",\"order_type\":1,\"amount\":1,\"desc\":\"abc\",\"ext_json\":\"\",\"app_id\":5476377146882523138,\"timestamp\":53612533412643}{\"pay_channel_id\":8935141660703064070,\"out_trade_no\":\"asdadasdas\",\"order_type\":1,\"amount\":1,\"desc\":\"abc\",\"ext_json\":\"\",\"app_id\":5476377146882523138,\"timestamp\":53612533412643}{\"pay_channel_id\":8935141660703064070,\"out_trade_no\":\"asdadasdas\",\"order_type\":1,\"amount\":1,\"desc\":\"abc\",\"ext_json\":\"\",\"app_id\":5476377146882523138,\"timestamp\":53612533412643}{\"pay_channel_id\":8935141660703064070,\"out_trade_no\":\"asdadasdas\",\"order_type\":1,\"amount\":1,\"desc\":\"abc\",\"ext_json\":\"\",\"app_id\":5476377146882523138,\"timestamp\":53612533412643}{\"pay_channel_id\":8935141660703064070,\"out_trade_no\":\"asdadasdas\",\"order_type\":1,\"amount\":1,\"desc\":\"abc\",\"ext_json\":\"\",\"app_id\":5476377146882523138,\"timestamp\":53612533412643}{\"pay_channel_id\":8935141660703064070,\"out_trade_no\":\"asdadasdas\",\"order_type\":1,\"amount\":1,\"desc\":\"abc\",\"ext_json\":\"\",\"app_id\":5476377146882523138,\"timestamp\":53612533412643}{\"pay_channel_id\":8935141660703064070,\"out_trade_no\":\"asdadasdas\",\"order_type\":1,\"amount\":1,\"desc\":\"abc\",\"ext_json\":\"\",\"app_id\":5476377146882523138,\"timestamp\":53612533412643}"
|
||||||
|
|
||||||
|
en, err := Encrypt([]byte(data), []byte(TestKey))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(en)
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
package rsa
|
package rsa
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"PaymentCenter/app/utils/encrypt/aes"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -13,7 +14,6 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRsaEncrypt(t *testing.T) {
|
func TestRsaEncrypt(t *testing.T) {
|
||||||
|
|
||||||
fmt.Printf("%s\n", encrypt())
|
fmt.Printf("%s\n", encrypt())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,37 @@ func TestRsaDecrypt(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func encrypt() string {
|
func encrypt() string {
|
||||||
|
data := "{\"order_no\":4323455642275676219,\"order_type\":1,\"out_tread_no\":\"asdadasdas\",\"amount\":1,\"desc\":\"abc\",\"status\":2,\"create_time\":\"2024-08-07 18:36:43\"}"
|
||||||
|
fmt.Println(len(data))
|
||||||
|
dataJson := []byte(data)
|
||||||
|
pub := `-----BEGIN PUBLIC KEY-----
|
||||||
|
` + PUB + `
|
||||||
|
-----END PUBLIC KEY-----`
|
||||||
|
en, err := Encrypt(pub, dataJson)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return base64.StdEncoding.EncodeToString(en)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRsaEncryptWithAes(t *testing.T) {
|
||||||
|
|
||||||
|
fmt.Printf("%s\n", encryptWithAes())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRsaDecryptWithAes(t *testing.T) {
|
||||||
|
data := "cGuoR6Bmmm9fZr/OAnM54eM6Z7M4ysnRr7TV64rIK6mAkGDzJROwSOY443e7UJmLpwIEn8G5jNk6j8K1scxvIMMdSJZ0QOJREjgzbZfNfuXV0LO1lVNu3uhwVQXN/zMZxBHGIcYQnPWSaOHhNy6yMRPLFNRuIb5FuTx7E6VI5UVZpHk9VLv63QX+6+hQMOiqoif/YyXkAqi2xG+unq4MVq9w5aYMOVzHX1eyMiTeRFRB4iKhf6bCJmVvLMmvjHYKQl3/225R4uXaI8nv7y4IHnK8KVYAnuJE6SvEPeJAjpINrY2CRoNqTYkt7DRS2uz5l7aE+KX8GShV2XlDoM8KZA=="
|
||||||
|
privateKeyPEM := `-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
` + PRI + `
|
||||||
|
-----END RSA PRIVATE KEY-----`
|
||||||
|
res, err := Decrypt(privateKeyPEM, data)
|
||||||
|
fmt.Println(string(res), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func encryptWithAes() string {
|
||||||
data := "{\"pay_channel_id\":8935141660703064070,\"out_trade_no\":\"asdadasdas\",\"order_type\":1,\"amount\":1,\"desc\":\"abc\",\"ext_json\":\"\",\"app_id\":5476377146882523138,\"timestamp\":53612533412643}"
|
data := "{\"pay_channel_id\":8935141660703064070,\"out_trade_no\":\"asdadasdas\",\"order_type\":1,\"amount\":1,\"desc\":\"abc\",\"ext_json\":\"\",\"app_id\":5476377146882523138,\"timestamp\":53612533412643}"
|
||||||
|
aes.Encrypt([]byte(data), []byte(aes.TestKey))
|
||||||
dataJson := []byte(data)
|
dataJson := []byte(data)
|
||||||
pub := `-----BEGIN PUBLIC KEY-----
|
pub := `-----BEGIN PUBLIC KEY-----
|
||||||
` + PUB + `
|
` + PUB + `
|
||||||
|
|
Loading…
Reference in New Issue