mirror of
https://github.com/yangjian102621/geekai.git
synced 2026-04-21 18:44:24 +08:00
110 lines
3.0 KiB
Go
110 lines
3.0 KiB
Go
package payment
|
|
|
|
// * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// * Copyright 2023 The Geek-AI Authors. All rights reserved.
|
|
// * Use of this source code is governed by a Apache-2.0 license
|
|
// * that can be found in the LICENSE file.
|
|
// * @Author yangjian102621@163.com
|
|
// * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"geekai/core/types"
|
|
logger2 "geekai/logger"
|
|
"net/http"
|
|
"os"
|
|
|
|
"github.com/go-pay/gopay"
|
|
"github.com/go-pay/gopay/alipay"
|
|
)
|
|
|
|
type AlipayService struct {
|
|
client *alipay.Client
|
|
config *types.AlipayConfig
|
|
}
|
|
|
|
var logger = logger2.GetLogger()
|
|
|
|
func NewAlipayService(sysConfig *types.SystemConfig) (*AlipayService, error) {
|
|
config := sysConfig.Payment.Alipay
|
|
if !config.Enabled {
|
|
logger.Debug("Disabled Alipay service")
|
|
}
|
|
|
|
service := &AlipayService{config: &config}
|
|
if config.Enabled {
|
|
err := service.UpdateConfig(&config)
|
|
if err != nil {
|
|
logger.Errorf("支付宝服务初始化失败: %v", err)
|
|
}
|
|
}
|
|
|
|
return service, nil
|
|
}
|
|
|
|
func (s *AlipayService) UpdateConfig(config *types.AlipayConfig) error {
|
|
client, err := alipay.NewClient(config.AppId, config.PrivateKey, !config.SandBox)
|
|
if err != nil {
|
|
return fmt.Errorf("error with initialize alipay service: %v", err)
|
|
}
|
|
|
|
s.client = client
|
|
s.config = config
|
|
if os.Getenv("GEEKAI_DEBUG") == "true" {
|
|
logger.Info("Alipay Debug mode is enabled")
|
|
client.DebugSwitch = gopay.DebugOn
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *AlipayService) Pay(params PayRequest) (string, error) {
|
|
bm := make(gopay.BodyMap)
|
|
bm.Set("subject", params.Subject)
|
|
bm.Set("out_trade_no", params.OutTradeNo)
|
|
bm.Set("total_amount", params.TotalFee)
|
|
return s.client.TradeWapPay(context.Background(), bm)
|
|
}
|
|
|
|
func (s *AlipayService) Query(outTradeNo string) (OrderInfo, error) {
|
|
bm := make(gopay.BodyMap)
|
|
bm.Set("out_trade_no", outTradeNo)
|
|
rsp, err := s.client.TradeQuery(context.Background(), bm)
|
|
if err != nil {
|
|
return OrderInfo{}, fmt.Errorf("error with trade query: %v", err)
|
|
}
|
|
|
|
switch rsp.Response.TradeStatus {
|
|
case "TRADE_SUCCESS":
|
|
logger.Debugf("支付宝查询订单成功:%+v", rsp.Response)
|
|
return OrderInfo{
|
|
OutTradeNo: rsp.Response.OutTradeNo,
|
|
TradeId: rsp.Response.TradeNo,
|
|
Amount: rsp.Response.TotalAmount,
|
|
Status: Success,
|
|
PayTime: rsp.Response.SendPayDate,
|
|
}, nil
|
|
case "TRADE_CLOSED":
|
|
return OrderInfo{Status: Closed}, nil
|
|
default:
|
|
return OrderInfo{}, fmt.Errorf("error with trade query: %v", rsp.Response.TradeStatus)
|
|
}
|
|
}
|
|
|
|
// TradeVerify 交易验证
|
|
func (s *AlipayService) TradeVerify(request *http.Request) (OrderInfo, error) {
|
|
notifyReq, err := alipay.ParseNotifyToBodyMap(request) // c.Request 是 gin 框架的写法
|
|
if err != nil {
|
|
return OrderInfo{}, fmt.Errorf("error with parse notify request: %v", err)
|
|
}
|
|
|
|
_, err = alipay.VerifySignWithCert(s.config.AlipayPublicKey, notifyReq)
|
|
if err != nil {
|
|
return OrderInfo{}, fmt.Errorf("error with verify sign: %v", err)
|
|
}
|
|
|
|
return s.Query(request.Form.Get("out_trade_no"))
|
|
}
|
|
|
|
var _ PayService = (*AlipayService)(nil)
|