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
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)
|
|
}
|