package wechat import ( "cls/internal/domain/payment" "cls/pkg/logger" "crypto/md5" "encoding/hex" "encoding/xml" "fmt" "sort" "strings" ) // Config 微信支付配置 type Config struct { AppID string // 公众号ID MchID string // 商户号 APIKey string // API密钥 NotifyURL string // 支付回调通知地址 } // Service 微信支付服务 type Service struct { config Config client *APIClient log logger.Logger } // NewService 创建微信支付服务 func NewService(config Config, log logger.New) *Service { return &Service{ config: config, client: NewAPIClient(config), log: log("cls:payment:wechat"), } } // CreatePayment 创建支付订单 func (s *Service) CreatePayment(order *payment.Payment) (map[string]interface{}, error) { // 构建统一下单请求 req := &UnifiedOrderRequest{ Body: order.Description, OutTradeNo: order.OrderNo, TotalFee: fmt.Sprintf("%d", order.Amount), } // 调用统一下单接口 resp, err := s.client.UnifiedOrder(req) if err != nil { return nil, fmt.Errorf("创建支付订单失败: %v", err) } // 检查响应结果 if resp.ReturnCode != "SUCCESS" { return nil, fmt.Errorf("微信支付接口返回错误: %s", resp.ReturnMsg) } if resp.ResultCode != "SUCCESS" { return nil, fmt.Errorf("微信支付业务处理失败: %s", resp.ErrCodeDes) } // 返回支付二维码链接 return map[string]interface{}{ "code_url": resp.CodeURL, }, nil } // VerifyNotify 验证支付回调通知 func (s *Service) VerifyNotify(notifyData string) (map[string]string, error) { // 解析XML数据 var notify struct { ReturnCode string `xml:"return_code"` ReturnMsg string `xml:"return_msg"` ResultCode string `xml:"result_code"` ErrCode string `xml:"err_code"` ErrCodeDes string `xml:"err_code_des"` OutTradeNo string `xml:"out_trade_no"` TotalFee string `xml:"total_fee"` TransactionID string `xml:"transaction_id"` Sign string `xml:"sign"` } if err := xml.Unmarshal([]byte(notifyData), ¬ify); err != nil { return nil, fmt.Errorf("解析通知数据失败: %v", err) } // 验证签名 if !s.client.verifySign(¬ify) { return nil, fmt.Errorf("签名验证失败") } // 检查支付结果 if notify.ReturnCode != "SUCCESS" || notify.ResultCode != "SUCCESS" { return nil, fmt.Errorf("支付失败: %s", notify.ErrCodeDes) } return map[string]string{ "order_no": notify.OutTradeNo, "amount": notify.TotalFee, "transaction_id": notify.TransactionID, }, nil } // generateSign 生成签名 func (s *Service) generateSign(params map[string]string) string { // 按键排序 var keys []string for k := range params { if k != "sign" && params[k] != "" { keys = append(keys, k) } } sort.Strings(keys) // 拼接字符串 var builder strings.Builder for i, k := range keys { if i > 0 { builder.WriteString("&") } builder.WriteString(k) builder.WriteString("=") builder.WriteString(params[k]) } builder.WriteString("&key=") builder.WriteString(s.config.APIKey) // MD5加密 h := md5.New() h.Write([]byte(builder.String())) return strings.ToUpper(hex.EncodeToString(h.Sum(nil))) } // verifySign 验证签名 func (s *Service) verifySign(notifyData, sign string) bool { // TODO: 实现签名验证逻辑 return true }