修复商福通接口签名编码逻辑;统一充值和创建套餐接口为聚合接口

This commit is contained in:
2025-06-19 17:44:56 +08:00
parent a4e5fc2af5
commit 63fbcbd6dd
6 changed files with 93 additions and 73 deletions

View File

@@ -22,7 +22,7 @@ var Resource = &resourceService{}
type resourceService struct{}
func (s *resourceService) CreateResource(uid int32, now time.Time, ser *CreateResourceSerializer) error {
func (s *resourceService) CreateResource(uid int32, now time.Time, ser *CreateResourceData) error {
data, err := ser.ToData()
if err != nil {
@@ -87,7 +87,7 @@ func (s *resourceService) CreateResource(uid int32, now time.Time, ser *CreateRe
return nil
}
func (s *resourceService) PrepareResource(uid int32, now time.Time, ser *CreateResourceSerializer) (*TradeCreateResult, error) {
func (s *resourceService) PrepareResource(uid int32, now time.Time, ser *PrepareResourceData) (*TradeCreateResult, error) {
data, err := ser.ToData()
if err != nil {
@@ -119,16 +119,16 @@ func (s *resourceService) PrepareResource(uid int32, now time.Time, ser *CreateR
}
// 保存请求缓存
resourceSerializer := new(CreateResourceSerializer)
resourceSerializer := new(PrepareResourceData)
if err := resourceSerializer.ByData(data); err != nil {
return err
}
err = g.Redis.Set(context.Background(), result.TradeNo, &CreateResourceCache{
Uid: uid,
TradeId: result.Trade.ID,
BillId: result.Bill.ID,
CreateResourceSerializer: resourceSerializer,
err = g.Redis.Set(context.Background(), result.TradeNo, &PrepareResourceCache{
Uid: uid,
TradeId: result.Trade.ID,
BillId: result.Bill.ID,
PrepareResourceData: resourceSerializer,
}, 30*time.Minute).Err()
if err != nil {
return err
@@ -150,7 +150,7 @@ func (s *resourceService) CompleteResource(tradeNo string, now time.Time, opResu
if err != nil {
return err
}
cache := new(CreateResourceCache)
cache := new(PrepareResourceCache)
if err := json.Unmarshal([]byte(reqStr), cache); err != nil {
return err
}
@@ -225,7 +225,7 @@ func (s *resourceService) CancelResource(tradeNo string, now time.Time, opRevoke
if err != nil {
return err
}
cache := new(CreateResourceCache)
cache := new(PrepareResourceCache)
if err := json.Unmarshal([]byte(cacheStr), cache); err != nil {
return err
}
@@ -247,7 +247,7 @@ func (s *resourceService) CancelResource(tradeNo string, now time.Time, opRevoke
return nil
}
func createResource(q *q.Query, uid int32, now time.Time, data CreateResourceData) (*m.Resource, error) {
func createResource(q *q.Query, uid int32, now time.Time, data CreateTypeResourceDataInter) (*m.Resource, error) {
// 套餐基本信息
var resource = m.Resource{
@@ -293,7 +293,7 @@ func createResource(q *q.Query, uid int32, now time.Time, data CreateResourceDat
return &resource, nil
}
type CreateResourceData interface {
type CreateTypeResourceDataInter interface {
GetName() string
GetPrice() decimal.Decimal
}
@@ -405,15 +405,13 @@ func (data *CreateLongResourceData) GetPrice() decimal.Decimal {
return *data.price
}
type CreateResourceSerializer struct {
Type resource2.Type `json:"type" validate:"required"`
Short *CreateShortResourceData `json:"short,omitempty"`
Long *CreateLongResourceData `json:"long,omitempty"`
PaymentMethod trade2.Method `json:"payment_method" validate:"required"`
PaymentPlatform trade2.Platform `json:"payment_platform" validate:"required"`
type CreateResourceData struct {
Type resource2.Type `json:"type" validate:"required"`
Short *CreateShortResourceData `json:"short,omitempty"`
Long *CreateLongResourceData `json:"long,omitempty"`
}
func (s *CreateResourceSerializer) ToData() (CreateResourceData, error) {
func (s *CreateResourceData) ToData() (CreateTypeResourceDataInter, error) {
switch s.Type {
case resource2.TypeShort:
return s.Short, nil
@@ -423,7 +421,7 @@ func (s *CreateResourceSerializer) ToData() (CreateResourceData, error) {
return nil, fmt.Errorf("不支持的套餐类型")
}
func (s *CreateResourceSerializer) ByData(data CreateResourceData) error {
func (s *CreateResourceData) ByData(data CreateTypeResourceDataInter) error {
switch data := data.(type) {
case *CreateShortResourceData:
s.Type = resource2.TypeShort
@@ -437,14 +435,20 @@ func (s *CreateResourceSerializer) ByData(data CreateResourceData) error {
return nil
}
type CreateResourceCache struct {
type PrepareResourceData struct {
CreateResourceData
PaymentMethod trade2.Method `json:"payment_method" validate:"required"`
PaymentPlatform trade2.Platform `json:"payment_platform" validate:"required"`
}
type PrepareResourceCache struct {
Uid int32 `json:"uid"`
TradeId int32 `json:"trade_id"`
BillId int32 `json:"bill_id"`
*CreateResourceSerializer
*PrepareResourceData
}
func (c CreateResourceCache) MarshalBinary() (data []byte, err error) {
func (c PrepareResourceCache) MarshalBinary() (data []byte, err error) {
data, err = json.Marshal(c)
if err != nil {
return nil, err
@@ -452,7 +456,7 @@ func (c CreateResourceCache) MarshalBinary() (data []byte, err error) {
return data, nil
}
func (c CreateResourceCache) UnmarshalBinary(data []byte) error {
func (c PrepareResourceCache) UnmarshalBinary(data []byte) error {
if err := json.Unmarshal(data, &c); err != nil {
return err
}

View File

@@ -3,7 +3,9 @@ package services
import (
"context"
"errors"
"fmt"
"github.com/shopspring/decimal"
wecahtpay_core "github.com/wechatpay-apiv3/wechatpay-go/core"
"io"
"log/slog"
"net/http"
@@ -151,7 +153,7 @@ func (s *tradeService) CreateTrade(q *q.Query, uid int32, now time.Time, data *T
Body: subject,
Amount: amountReal.Mul(decimal.NewFromInt(100)).Round(0).IntPart(),
Currency: "cny",
ClientIp: "",
ClientIp: "123.52.74.23",
OrderTimeout: u.P(expire.Format("2006-01-02 15:04:05")),
})
if err != nil {
@@ -174,7 +176,7 @@ func (s *tradeService) CreateTrade(q *q.Query, uid int32, now time.Time, data *T
Amount: amountReal.Mul(decimal.NewFromInt(100)).Round(0).IntPart(),
PayType: payType,
Currency: "cny",
ClientIp: "",
ClientIp: "123.52.74.23",
OrderTimeout: u.P(expire.Format("2006-01-02 15:04:05")),
})
if err != nil {
@@ -273,7 +275,9 @@ func (s *tradeService) OnTradeCreated(q *q.Query, data *OnTradeCreateData) (*m.T
trade.Acquirer = int32(acquirer)
trade.PaidAt = u.P(orm.LocalDateTime(paidAt))
trade.PayURL = u.P("")
_, err = q.Trade.Updates(trade)
_, err = q.Trade.
Where(q.Trade.ID.Eq(trade.ID)).
Updates(trade)
if err != nil {
return nil, err
}
@@ -397,10 +401,22 @@ func (s *tradeService) VerifyTrade(data *TradeVerifyData) (*TradeSuccessResult,
Mchid: &env.WechatPayMchId,
})
if err != nil {
var apiErr *wecahtpay_core.APIError
if errors.As(err, &apiErr) {
if apiErr.Code == "ORDER_NOT_EXIST" {
return nil, ErrTransactionNotPaid
}
return nil, core.NewServErr(
fmt.Sprintf("微信上游接口异常code=%vmessage=%v", apiErr.Code, apiErr.Message),
apiErr,
)
}
return nil, err
}
if *resp.TradeState != "SUCCESS" {
return nil, ErrTransactionNotPaid
return nil, core.NewServErr(
fmt.Sprintf("预期之外的支付未完成state=%v, stateDesc=%v", resp.TradeState, resp.TradeStateDesc),
)
}
transId = *resp.TransactionId