mock.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. package channel
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "sync"
  7. )
  8. // MockChannel 联调用模拟渠道:订单创建即返回二维码内容,
  9. // 通过 MarkMockPaid 模拟"车主已付款",QueryOrder 才会返回已支付。
  10. type MockChannel struct {
  11. mu sync.Mutex
  12. paid map[string]string // orderNo -> mock transaction id
  13. }
  14. func NewMockChannel() *MockChannel {
  15. return &MockChannel{paid: map[string]string{}}
  16. }
  17. func (m *MockChannel) Code() string { return ChannelMock }
  18. func (m *MockChannel) CreateOrder(ctx context.Context, req CreateOrderRequest) (CreateOrderResult, error) {
  19. // 二维码内容对 mock 无真实意义,保证同一订单稳定即可。
  20. return CreateOrderResult{CodeURL: fmt.Sprintf("mockpay:order:%s:%.2f", req.OrderNo, req.Amount)}, nil
  21. }
  22. func (m *MockChannel) QueryOrder(ctx context.Context, orderNo string) (QueryOrderResult, error) {
  23. m.mu.Lock()
  24. defer m.mu.Unlock()
  25. if txn, ok := m.paid[orderNo]; ok {
  26. return QueryOrderResult{Status: QueryPaid, TransactionID: txn}, nil
  27. }
  28. return QueryOrderResult{Status: QueryPending}, nil
  29. }
  30. // MarkMockPaid 模拟渠道侧支付成功(调试端点调用)。
  31. func (m *MockChannel) MarkMockPaid(orderNo string) {
  32. m.mu.Lock()
  33. defer m.mu.Unlock()
  34. m.paid[orderNo] = "MOCK" + orderNo
  35. }
  36. // MarkMockPaid 从注册表取 mock 渠道并模拟支付成功。
  37. func MarkMockPaid(orderNo string) error {
  38. ch, err := Get(ChannelMock)
  39. if err != nil {
  40. return err
  41. }
  42. mock, ok := ch.(*MockChannel)
  43. if !ok {
  44. return errors.New("mock 渠道不可用")
  45. }
  46. mock.MarkMockPaid(orderNo)
  47. return nil
  48. }