You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

148 lines
3.6 KiB
Go

package payment
import (
"cls/internal/domain/payment"
"cls/pkg/logger"
"cls/pkg/util/page"
"errors"
"fmt"
"time"
"xorm.io/builder"
)
// ServiceImpl 支付服务实现
type ServiceImpl struct {
repo payment.PaymentRepository
provider payment.PaymentProvider
log logger.Logger
}
// NewServiceImpl 创建支付服务实现
func NewServiceImpl(repo payment.PaymentRepository, provider payment.PaymentProvider, log logger.New) *ServiceImpl {
return &ServiceImpl{
repo: repo,
provider: provider,
log: log("cls:service:payment"),
}
}
// CreateOrder 创建支付订单
func (s *ServiceImpl) CreateOrder(userID, targetID uint64, paymentType payment.PaymentType, amount int64, description string) (*payment.Payment, error) {
if amount <= 0 {
return nil, ErrInvalidAmount
}
// 生成订单号
orderNo := fmt.Sprintf("%d%d%d", time.Now().UnixNano(), userID, targetID)
// 检查订单是否已存在
_, err := s.repo.FindByOrderNo(orderNo)
if err == nil {
return nil, ErrOrderExists
}
// 创建支付订单
payment := &payment.Payment{
OrderNo: orderNo,
UserID: userID,
TargetID: targetID,
Type: paymentType,
Amount: amount,
Status: payment.StatusPending,
Description: description,
}
// 保存订单
if err := s.repo.Save(payment); err != nil {
return nil, err
}
return payment, nil
}
// GetOrder 获取支付订单
func (s *ServiceImpl) GetOrder(orderNo string) (*payment.Payment, error) {
return s.repo.FindByOrderNo(orderNo)
}
// GetUserOrders 获取用户支付订单列表
func (s *ServiceImpl) GetUserOrders(userID uint64, page *page.Page) error {
return s.repo.FindByUserID(userID, page)
}
// GetOrderList 获取支付订单列表
func (s *ServiceImpl) GetOrderList(page *page.Page, conds []builder.Cond) error {
return s.repo.FindAll(page, conds)
}
// UpdateOrderStatus 更新订单状态
func (s *ServiceImpl) UpdateOrderStatus(orderNo string, status payment.PaymentStatus, transactionID string, notifyData string) error {
order, err := s.repo.FindByOrderNo(orderNo)
if err != nil {
return ErrOrderNotFound
}
// 检查订单状态
if order.Status != payment.StatusPending {
return ErrOrderPaid
}
// 更新订单状态
order.Status = status
order.TransactionID = transactionID
order.NotifyData = notifyData
return s.repo.Update(order)
}
// CancelOrder 取消支付订单
func (s *ServiceImpl) CancelOrder(orderNo string) error {
order, err := s.repo.FindByOrderNo(orderNo)
if err != nil {
return ErrOrderNotFound
}
// 检查订单状态
if order.Status != payment.StatusPending {
return ErrOrderPaid
}
// 更新订单状态为已取消
order.Status = payment.StatusCancelled
return s.repo.Update(order)
}
// DeleteOrder 删除支付订单
func (s *ServiceImpl) DeleteOrder(id uint64) error {
return s.repo.Delete(id)
}
// GetPaymentURL 获取支付链接
func (s *ServiceImpl) GetPaymentURL(order *payment.Payment) (map[string]interface{}, error) {
return s.provider.CreatePayment(order)
}
// HandleNotify 处理支付回调通知
func (s *ServiceImpl) HandleNotify(notifyData string) error {
// 验证通知数据
result, err := s.provider.VerifyNotify(notifyData)
if err != nil {
return fmt.Errorf("验证通知数据失败: %v", err)
}
// 获取订单号
orderNo := result["order_no"]
if orderNo == "" {
return errors.New("订单号不能为空")
}
// 获取订单
order, err := s.repo.FindByOrderNo(orderNo)
if err != nil {
return fmt.Errorf("获取订单失败: %v", err)
}
// 更新订单状态
return s.UpdateOrderStatus(order.OrderNo, payment.StatusSuccess, result["transaction_id"], notifyData)
}