refactor: subscribe module

This commit is contained in:
zchengo
2023-01-27 11:05:24 +08:00
parent a7d7ddb1bc
commit 9f944a34f6
7 changed files with 163 additions and 180 deletions
+8 -15
View File
@@ -1,6 +1,7 @@
package api
import (
"crm/common"
"crm/models"
"crm/response"
"crm/service"
@@ -25,8 +26,8 @@ func NewSubscribeApi() *SubscribeApi {
func (s *SubscribeApi) Pay(context *gin.Context) {
var param models.SubscribePayParam
uid, _ := strconv.Atoi(context.Request.Header.Get("uid"))
err := context.ShouldBind(&param);
if int64(uid) <= 0 || err != nil {
err := context.ShouldBind(&param)
if int64(uid) <= 0 || err != nil {
response.Result(response.ErrCodeParamInvalid, nil, context)
return
}
@@ -36,18 +37,10 @@ func (s *SubscribeApi) Pay(context *gin.Context) {
}
// 支付成功回调
func (s *SubscribeApi) Callback(context *gin.Context) {
context.Request.ParseForm()
var outTradeNo = context.Request.Form.Get("out_trade_no")
paySuccessURL, _ := s.subscribeService.Callback(outTradeNo)
context.Redirect(http.StatusMovedPermanently, paySuccessURL)
}
// 支付通知
func (s *SubscribeApi) Notify(context *gin.Context) {
context.Request.ParseForm()
var outTradeNo = context.Request.Form.Get("out_trade_no")
errCode := s.subscribeService.Notify(context.Request.Form, outTradeNo)
func (s *SubscribeApi) PayBack(context *gin.Context) {
notifyReq := common.GetAlipay().VerifySign(context.Request)
errCode := s.subscribeService.PayBack(notifyReq.GetString("out_trade_no"))
context.String(http.StatusOK, "%s", "success")
response.Result(errCode, nil, context)
}
@@ -60,4 +53,4 @@ func (s *SubscribeApi) GetInfo(context *gin.Context) {
}
subscribeInfo, errCode := s.subscribeService.GetInfo(int64(uid))
response.Result(errCode, subscribeInfo, context)
}
}
+2 -2
View File
@@ -56,8 +56,8 @@ func (s *SubscribeDao) SetOrder(tradeNo string, param *models.SubscribePayOrder)
return global.Rdb.Set(ctx, tradeNo, string(order), time.Minute*30).Err()
}
func (s *SubscribeDao) GetOrder(orderNo string) (string, error) {
orderJson, err := global.Rdb.Get(ctx, orderNo).Result()
func (s *SubscribeDao) GetOrder(tradeNo string) (string, error) {
orderJson, err := global.Rdb.Get(ctx, tradeNo).Result()
if err != nil {
return StringNull, err
}
+1 -1
View File
@@ -3,8 +3,8 @@ package global
import (
"crm/config"
"github.com/go-pay/gopay/alipay"
"github.com/go-redis/redis/v9"
"github.com/smartwalle/alipay/v3"
"gorm.io/gorm"
)
+1 -2
View File
@@ -25,7 +25,7 @@ func Router() {
route.POST("/user/register", api.NewUserApi().Register)
route.POST("/user/pass", api.NewUserApi().ForgotPass)
route.DELETE("/user/delete", api.NewUserApi().Delete)
route.GET("/subscribe/callback", api.NewSubscribeApi().Callback)
route.POST("/subscribe/payback", api.NewSubscribeApi().PayBack)
// 初始化数据
route.POST("/init/data", api.InitData)
@@ -73,7 +73,6 @@ func Router() {
// 订阅模块
route.GET("/subscribe/info", api.NewSubscribeApi().GetInfo)
route.POST("/subscribe/pay", api.NewSubscribeApi().Pay)
route.POST("/subscribe/notify", api.NewSubscribeApi().Notify)
// 通知模块
route.GET("/notice/list", api.NewNoticeApi().GetList)
+5 -4
View File
@@ -23,13 +23,14 @@ type SubscribeUpdateParam struct {
}
type SubscribePayParam struct {
Uid int64 `json:"uid" binding:"-"`
Version int `json:"version" binding:"required,oneof=2 3"`
Uid int64 `json:"uid" binding:"-"`
Duration int64 `json:"duration" binding:"required,oneof=30 90 180 365 730"`
}
type SubscribePayOrder struct {
Uid int64 `json:"uid"`
Version int `json:"version"`
Uid int64 `json:"uid"`
TradeNo string `json:"tradeNo"`
Duration int64 `json:"duration"`
}
type SubscribePayUrl struct {
+24 -100
View File
@@ -1,23 +1,12 @@
package service
import (
"crm/common"
"crm/dao"
"crm/global"
"crm/models"
"crm/response"
"encoding/json"
"fmt"
"log"
"net/url"
"time"
"github.com/smartwalle/alipay/v3"
"github.com/smartwalle/xid"
)
const (
Paying = 1 // 支付中
Payed = 2 // 已支付
)
type SubscribeService struct {
@@ -37,134 +26,69 @@ func NewSubscribeService() *SubscribeService {
func (s *SubscribeService) Pay(param models.SubscribePayParam) (*models.SubscribePayUrl, int) {
// 构建订单支付信息
tradeNo := fmt.Sprintf("%d", xid.Next())
var p = alipay.TradePagePay{}
p.NotifyURL = global.Config.Alipay.NotifyURL
p.ReturnURL = global.Config.Alipay.ReturnURL
p.Subject = "支付测试:" + tradeNo
p.OutTradeNo = tradeNo
p.ProductCode = "FAST_INSTANT_TRADE_PAY"
switch param.Version {
case 2:
p.TotalAmount = "18.00"
case 3:
p.TotalAmount = "198.00"
}
// 缓存订单信息
order := &models.SubscribePayOrder{
Uid: param.Uid,
Version: param.Version,
}
if err := s.subscribeDao.SetOrder(tradeNo, order); err != nil {
return nil, response.ErrCodeFailed
}
// 返回支付链接
payUrl, err := global.Alipay.TradePagePay(p)
tradeNo := common.GetAlipay().GenTradeNo()
totalAmount := float64(param.Duration) * 0.6
payUrl, err := common.GetAlipay().PagePay(tradeNo, totalAmount)
if err != nil {
return nil, response.ErrCodeFailed
}
order := models.SubscribePayOrder{
Uid: param.Uid,
TradeNo: tradeNo,
Duration: param.Duration,
}
if err := s.subscribeDao.SetOrder(tradeNo, &order); err != nil {
return nil, response.ErrCodeFailed
}
subscribePayUrl := models.SubscribePayUrl{
PayUrl: payUrl.String(),
PayUrl: payUrl,
}
return &subscribePayUrl, response.ErrCodeSuccess
}
// 支付成功回调
func (s *SubscribeService) Callback(outTradeNo string) (string, int) {
// 验证订单信息
var p = alipay.TradeQuery{}
p.OutTradeNo = outTradeNo
rsp, err := global.Alipay.TradeQuery(p)
if err != nil {
log.Printf("验证订单 %s 信息发生错误: %s", outTradeNo, err.Error())
return StringNull, response.ErrCodeFailed
}
if !rsp.IsSuccess() {
log.Printf("验证订单 %s 信息发生错误: %s-%s", outTradeNo, rsp.Content.Msg, rsp.Content.SubMsg)
return StringNull, response.ErrCodeFailed
}
func (s *SubscribeService) PayBack(outTradeNo string) int {
// 获取订单信息
var order models.SubscribePayOrder
orderJson, err := s.subscribeDao.GetOrder(outTradeNo)
if err != nil {
return StringNull, response.ErrCodeFailed
return response.ErrCodeFailed
}
if err := json.Unmarshal([]byte(orderJson), &order); err != nil {
return StringNull, response.ErrCodeFailed
return response.ErrCodeFailed
}
// 创建订阅信息
var expired int64
var content string
switch order.Version {
case 2:
expired = time.Now().Unix() + int64(2592000)
content = SUBSCRIBE_NOTICE_TEMPLATE1
case 3:
expired = time.Now().Unix() + int64(31104000)
content = SUBSCRIBE_NOTICE_TEMPLATE2
}
expired := order.Duration * 24 * 60 * 60
if !s.subscribeDao.IsExists(order.Uid) {
subscribe := models.SubscribeCreateParam{
Uid: order.Uid,
Version: order.Version,
Version: 2,
Expired: expired,
}
if err := s.subscribeDao.Create(&subscribe); err != nil {
return StringNull, response.ErrCodeFailed
return response.ErrCodeFailed
}
} else {
subscribe := models.SubscribeUpdateParam{
Uid: order.Uid,
Version: order.Version,
Expired: expired,
}
if err := s.subscribeDao.Update(&subscribe); err != nil {
return StringNull, response.ErrCodeFailed
return response.ErrCodeFailed
}
}
// 订阅通知
s.noticeDao.Create(&models.NoticeCreateParam{
Content: content,
Content: SUBSCRIBE_NOTICE_TEMPLATE1,
Creator: order.Uid,
})
return global.Config.Alipay.PaySuccessURL, response.ErrCodeSuccess
}
// 异步验签
func (s *SubscribeService) Notify(data url.Values, outTradeNo string) int {
ok, err := global.Alipay.VerifySign(data)
if err != nil {
log.Println("异步通知验证签名发生错误", err)
return response.ErrCodeFailed
}
if !ok {
log.Println("异步通知验证签名未通过")
return response.ErrCodeFailed
}
log.Println("异步通知验证签名通过")
var p = alipay.TradeQuery{}
p.OutTradeNo = outTradeNo
rsp, err := global.Alipay.TradeQuery(p)
if err != nil {
log.Printf("异步通知验证订单 %s 信息发生错误: %s \n", outTradeNo, err.Error())
return response.ErrCodeFailed
}
if !rsp.IsSuccess() {
log.Printf("异步通知验证订单 %s 信息发生错误: %s-%s \n", outTradeNo, rsp.Content.Msg, rsp.Content.SubMsg)
return response.ErrCodeFailed
}
log.Printf("订单 %s 支付成功 \n", outTradeNo)
return response.ErrCodeSuccess
}