hi-server/internal/logic/public/iap/apple/attachTransactionByIdLogic.go
shanshanzhong 3c6dd5058b
All checks were successful
Build docker and publish / build (20.15.1) (push) Successful in 6m41s
feat(apple): 添加通过transaction_id附加苹果交易功能
新增通过transaction_id附加苹果交易的功能,包括:
1. 添加AttachAppleTransactionByIdRequest类型和对应路由
2. 实现AppleIAPConfig配置模型
3. 添加ServerAPI获取交易信息的实现
4. 优化JWS解析逻辑,增加cleanB64函数处理空格
5. 完善苹果通知处理逻辑的日志和注释
2025-12-15 22:35:33 -08:00

73 lines
2.5 KiB
Go

package apple
import (
"context"
"github.com/perfect-panel/server/internal/model/payment"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/constant"
iapapple "github.com/perfect-panel/server/pkg/iap/apple"
"github.com/perfect-panel/server/pkg/logger"
"github.com/perfect-panel/server/pkg/xerr"
"github.com/pkg/errors"
)
type AttachTransactionByIdLogic struct {
logger.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewAttachTransactionByIdLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AttachTransactionByIdLogic {
return &AttachTransactionByIdLogic{
Logger: logger.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *AttachTransactionByIdLogic) AttachById(req *types.AttachAppleTransactionByIdRequest) (*types.AttachAppleTransactionResponse, error) {
_, ok := l.ctx.Value(constant.CtxKeyUser).(*struct{ Id int64 })
if !ok {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidAccess), "invalid access")
}
ord, err := l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, req.OrderNo)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.OrderNotExist), "order not exist")
}
pay, err := l.svcCtx.PaymentModel.FindOne(l.ctx, ord.PaymentId)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.PaymentMethodNotFound), "payment not found")
}
var cfg payment.AppleIAPConfig
if err := cfg.Unmarshal([]byte(pay.Config)); err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "iap config error")
}
apiCfg := iapapple.ServerAPIConfig{
KeyID: cfg.KeyID,
IssuerID: cfg.IssuerID,
PrivateKey: cfg.PrivateKey,
Sandbox: cfg.Sandbox,
}
if req.Sandbox != nil {
apiCfg.Sandbox = *req.Sandbox
}
if apiCfg.KeyID == "" || apiCfg.IssuerID == "" || apiCfg.PrivateKey == "" {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "apple server api credential missing")
}
jws, err := iapapple.GetTransactionInfo(apiCfg, req.TransactionId)
if err != nil {
l.Errorw("fetch transaction info error", logger.Field("error", err.Error()))
return nil, errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "fetch transaction info error")
}
// reuse existing attach logic with JWS
attach := NewAttachTransactionLogic(l.ctx, l.svcCtx)
return attach.Attach(&types.AttachAppleTransactionRequest{
SignedTransactionJWS: jws,
SubscribeId: 0,
DurationDays: 0,
Tier: "",
OrderNo: req.OrderNo,
})
}