Files
kami_shop/internal/service/pay.go
danial 1a75269a61 feat(payment):重构微信支付页面并优化支付流程
- 重新设计支付页面UI,采用毛玻璃效果和动态背景- 更新支付接口调用方式,从表单提交改为JSON请求
-优化支付签名验证逻辑,统一错误处理方式
- 修改京东支付接口参数和返回结构体
- 移除OpenTelemetry追踪相关代码
- 添加支付倒计时功能和本地存储支持
- 优化支付按钮加载状态和交互反馈
- 调整HTML结构和CSS样式,提升用户体验
2025-10-11 21:56:09 +08:00

129 lines
3.3 KiB
Go

package service
import (
"context"
"encoding/json"
"errors"
"shop/internal/models"
"shop/internal/traceRouter"
"shop/internal/utils/client"
"strings"
"time"
"go.uber.org/zap"
)
// VerifyPaySign 判断sign是否正确
func VerifyPaySign(ctx context.Context, sign string) (*models.OrderParams, error) {
m := models.OrderParams{}
if err := m.Decrypt(ctx, sign); err != nil {
return nil, err
}
traceRouter.Logger.WithContext(ctx).Info("订单参数", zap.Any("订单参数", m))
if time.Since(time.Unix(m.GeneratedTime, 0)).Hours() > float64(m.Duration) {
return nil, errors.New("订单超时")
}
if m.PayKey == "" {
return nil, errors.New("支付秘钥错误")
}
if m.NotifyUrl == "" {
return nil, errors.New("通知地址为空")
}
if m.OrderNo == "" {
return nil, errors.New("订单号为空")
}
return &m, nil
}
// Pay 抽离支付接口
func Pay(ctx context.Context, m *models.OriginalJdParams, order *models.OrderParams, ip string) (bool, error) {
marshal, err := json.Marshal(map[string]string{
"recoveryType": m.RecoveryType,
"data": m.Chard,
"cardNo": m.CardNo,
})
if err != nil {
return false, err
}
scanShop := new(ScanShopController)
scanShop.Params = map[string]string{
"orderPeriod": "24",
"notifyUrl": m.NotifyUrl,
"orderPrice": m.FactMMValue,
"orderNo": m.OrderId,
"productCode": m.ProductCode,
"exValue": string(marshal),
"ip": ip,
"deviceId": m.DeviceId,
}
res := scanShop.Shop(ctx, order.PayKey)
if res.Code == 200 {
return true, nil
}
if strings.Contains(res.Msg, "当前订单已存在") {
return true, nil
}
return false, errors.New(res.Msg)
}
// PayWithJd 京东原生支付
func PayWithJd(ctx context.Context, orderId, category string, orderAmount float64) (string, error) {
ctx, span := traceRouter.CreateSpan(ctx, "PayWithJd", "PayWithJd")
defer span.End()
orderResp, err := client.Post(ctx, "http://kami_backend:12401/api/jd-cookie/order/create",
nil, map[string]any{
"orderId": orderId,
"amount": orderAmount,
"category": category,
},
)
traceRouter.Logger.WithContext(ctx).Info("发送请求", zap.String("请求地址",
"http://kami_backend:12401/api/jd-cookie/order/create"), zap.Any("请求参数", map[string]any{
"merchantOrderId": orderId,
"orderAmount": orderAmount,
}))
if err != nil {
traceRouter.Logger.WithContext(ctx).Error("请求失败", zap.Error(err))
return "", err
}
traceRouter.Logger.WithContext(ctx).Info("请求结果", zap.String("response", orderResp))
type V1CardRedeemCookieOrder struct {
WxPayUrl string `json:"wxPayUrl" dc:"微信支付链接"`
ExpireTime string `json:"expireTime" dc:"链接过期时间"`
JdOrderId string `json:"jdOrderId" dc:"京东订单号"`
}
type Response struct {
Code int `json:"code"`
Message string `json:"message"`
Data V1CardRedeemCookieOrder `json:"data"`
}
var res Response
err = json.Unmarshal([]byte(orderResp), &res)
if err != nil {
traceRouter.Logger.WithContext(ctx).Error("解析失败", zap.Error(err))
return "", err
}
traceRouter.Logger.WithContext(ctx).Info("订单拉单失败", zap.Any("订单状态", res.Data),
zap.String("订单号", res.Data.JdOrderId),
)
return res.Data.WxPayUrl, nil
}