70 lines
2.4 KiB
Go
70 lines
2.4 KiB
Go
package order
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
)
|
|
|
|
// Authorization is the result of authorizing a payment with a provider.
|
|
type Authorization struct {
|
|
Provider string
|
|
Reference string
|
|
Amount int64
|
|
}
|
|
|
|
// Capture is the result of capturing an authorization.
|
|
type Capture struct {
|
|
Provider string
|
|
Reference string
|
|
Amount int64
|
|
}
|
|
|
|
// RefundResult is the result of refunding a captured payment.
|
|
type RefundResult struct {
|
|
Provider string
|
|
Reference string
|
|
Amount int64
|
|
}
|
|
|
|
// PaymentProvider abstracts a payment processor. It mirrors the ShippingProvider
|
|
// seam in go-shipping: one interface, interchangeable implementations. The order
|
|
// flow actions (pkg/order/actions.go) call this; the grain only records facts.
|
|
type PaymentProvider interface {
|
|
Name() string
|
|
Authorize(ctx context.Context, orderRef string, amount int64, currency string) (Authorization, error)
|
|
Capture(ctx context.Context, authRef string, amount int64) (Capture, error)
|
|
Refund(ctx context.Context, captureRef string, amount int64) (RefundResult, error)
|
|
Void(ctx context.Context, authRef string) error
|
|
}
|
|
|
|
// MockProvider is a deterministic, always-succeeding payment provider. It lets
|
|
// an order be placed and paid end-to-end with no external dependency — the
|
|
// simplest path to a captured order for local dev, demos and tests.
|
|
type MockProvider struct{}
|
|
|
|
func NewMockProvider() *MockProvider { return &MockProvider{} }
|
|
|
|
var _ PaymentProvider = (*MockProvider)(nil)
|
|
|
|
func (m *MockProvider) Name() string { return "mock" }
|
|
|
|
func (m *MockProvider) Authorize(_ context.Context, orderRef string, amount int64, _ string) (Authorization, error) {
|
|
return Authorization{Provider: m.Name(), Reference: "mock-auth-" + orderRef, Amount: amount}, nil
|
|
}
|
|
|
|
func (m *MockProvider) Capture(_ context.Context, authRef string, amount int64) (Capture, error) {
|
|
if authRef == "" {
|
|
return Capture{}, fmt.Errorf("mock: capture requires an authorization reference")
|
|
}
|
|
return Capture{Provider: m.Name(), Reference: "mock-capture-" + authRef, Amount: amount}, nil
|
|
}
|
|
|
|
func (m *MockProvider) Refund(_ context.Context, captureRef string, amount int64) (RefundResult, error) {
|
|
if captureRef == "" {
|
|
return RefundResult{}, fmt.Errorf("mock: refund requires a capture reference")
|
|
}
|
|
return RefundResult{Provider: m.Name(), Reference: "mock-refund-" + captureRef, Amount: amount}, nil
|
|
}
|
|
|
|
func (m *MockProvider) Void(_ context.Context, _ string) error { return nil }
|