separated quotation and payments

This commit is contained in:
Stephan D
2026-02-10 18:29:47 +01:00
parent 6745bc0f6f
commit 296cc7b86a
163 changed files with 13516 additions and 191 deletions

View File

@@ -14,7 +14,7 @@ import (
"google.golang.org/grpc/credentials/insecure"
)
// Client exposes typed helpers around the payment orchestrator gRPC API.
// Client exposes typed helpers around the payment orchestration and quotation gRPC APIs.
type Client interface {
QuotePayment(ctx context.Context, req *orchestratorv1.QuotePaymentRequest) (*orchestratorv1.QuotePaymentResponse, error)
QuotePayments(ctx context.Context, req *orchestratorv1.QuotePaymentsRequest) (*orchestratorv1.QuotePaymentsResponse, error)
@@ -30,8 +30,6 @@ type Client interface {
}
type grpcOrchestratorClient interface {
QuotePayment(ctx context.Context, in *orchestratorv1.QuotePaymentRequest, opts ...grpc.CallOption) (*orchestratorv1.QuotePaymentResponse, error)
QuotePayments(ctx context.Context, in *orchestratorv1.QuotePaymentsRequest, opts ...grpc.CallOption) (*orchestratorv1.QuotePaymentsResponse, error)
InitiatePayments(ctx context.Context, in *orchestratorv1.InitiatePaymentsRequest, opts ...grpc.CallOption) (*orchestratorv1.InitiatePaymentsResponse, error)
InitiatePayment(ctx context.Context, in *orchestratorv1.InitiatePaymentRequest, opts ...grpc.CallOption) (*orchestratorv1.InitiatePaymentResponse, error)
CancelPayment(ctx context.Context, in *orchestratorv1.CancelPaymentRequest, opts ...grpc.CallOption) (*orchestratorv1.CancelPaymentResponse, error)
@@ -42,10 +40,17 @@ type grpcOrchestratorClient interface {
ProcessDepositObserved(ctx context.Context, in *orchestratorv1.ProcessDepositObservedRequest, opts ...grpc.CallOption) (*orchestratorv1.ProcessDepositObservedResponse, error)
}
type grpcQuotationClient interface {
QuotePayment(ctx context.Context, in *orchestratorv1.QuotePaymentRequest, opts ...grpc.CallOption) (*orchestratorv1.QuotePaymentResponse, error)
QuotePayments(ctx context.Context, in *orchestratorv1.QuotePaymentsRequest, opts ...grpc.CallOption) (*orchestratorv1.QuotePaymentsResponse, error)
}
type orchestratorClient struct {
cfg Config
conn *grpc.ClientConn
client grpcOrchestratorClient
cfg Config
conn *grpc.ClientConn
quoteConn *grpc.ClientConn
client grpcOrchestratorClient
quoteClient grpcQuotationClient
}
// New dials the payment orchestrator endpoint and returns a ready client.
@@ -54,10 +59,36 @@ func New(ctx context.Context, cfg Config, opts ...grpc.DialOption) (Client, erro
if strings.TrimSpace(cfg.Address) == "" {
return nil, merrors.InvalidArgument("payment-orchestrator: address is required")
}
if strings.TrimSpace(cfg.QuoteAddress) == "" {
cfg.QuoteAddress = cfg.Address
}
conn, err := dial(ctx, cfg, cfg.Address, opts...)
if err != nil {
return nil, err
}
quoteConn := conn
if cfg.QuoteAddress != cfg.Address {
quoteConn, err = dial(ctx, cfg, cfg.QuoteAddress, opts...)
if err != nil {
_ = conn.Close()
return nil, err
}
}
return &orchestratorClient{
cfg: cfg,
conn: conn,
quoteConn: quoteConn,
client: orchestratorv1.NewPaymentOrchestratorClient(conn),
quoteClient: orchestratorv1.NewPaymentQuotationClient(quoteConn),
}, nil
}
func dial(ctx context.Context, cfg Config, address string, opts ...grpc.DialOption) (*grpc.ClientConn, error) {
dialCtx, cancel := context.WithTimeout(ctx, cfg.DialTimeout)
defer cancel()
dialOpts := make([]grpc.DialOption, 0, len(opts)+1)
dialOpts = append(dialOpts, opts...)
@@ -67,44 +98,64 @@ func New(ctx context.Context, cfg Config, opts ...grpc.DialOption) (Client, erro
dialOpts = append(dialOpts, grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})))
}
conn, err := grpc.DialContext(dialCtx, cfg.Address, dialOpts...)
conn, err := grpc.DialContext(dialCtx, address, dialOpts...)
if err != nil {
return nil, merrors.InternalWrap(err, fmt.Sprintf("payment-orchestrator: dial %s", cfg.Address))
return nil, merrors.InternalWrap(err, fmt.Sprintf("payment-orchestrator: dial %s", address))
}
return &orchestratorClient{
cfg: cfg,
conn: conn,
client: orchestratorv1.NewPaymentOrchestratorClient(conn),
}, nil
return conn, nil
}
// NewWithClient injects a pre-built orchestrator client (useful for tests).
func NewWithClient(cfg Config, oc grpcOrchestratorClient) Client {
return NewWithClients(cfg, oc, nil)
}
// NewWithClients injects pre-built orchestrator and quotation clients (useful for tests).
func NewWithClients(cfg Config, oc grpcOrchestratorClient, qc grpcQuotationClient) Client {
cfg.setDefaults()
if qc == nil {
if q, ok := any(oc).(grpcQuotationClient); ok {
qc = q
}
}
return &orchestratorClient{
cfg: cfg,
client: oc,
cfg: cfg,
client: oc,
quoteClient: qc,
}
}
func (c *orchestratorClient) Close() error {
if c.conn != nil {
return c.conn.Close()
var firstErr error
if c.quoteConn != nil && c.quoteConn != c.conn {
if err := c.quoteConn.Close(); err != nil && firstErr == nil {
firstErr = err
}
}
return nil
if c.conn != nil {
if err := c.conn.Close(); err != nil && firstErr == nil {
firstErr = err
}
}
return firstErr
}
func (c *orchestratorClient) QuotePayment(ctx context.Context, req *orchestratorv1.QuotePaymentRequest) (*orchestratorv1.QuotePaymentResponse, error) {
if c.quoteClient == nil {
return nil, merrors.InvalidArgument("payment-orchestrator: quotation client is not configured")
}
ctx, cancel := c.callContext(ctx)
defer cancel()
return c.client.QuotePayment(ctx, req)
return c.quoteClient.QuotePayment(ctx, req)
}
func (c *orchestratorClient) QuotePayments(ctx context.Context, req *orchestratorv1.QuotePaymentsRequest) (*orchestratorv1.QuotePaymentsResponse, error) {
if c.quoteClient == nil {
return nil, merrors.InvalidArgument("payment-orchestrator: quotation client is not configured")
}
ctx, cancel := c.callContext(ctx)
defer cancel()
return c.client.QuotePayments(ctx, req)
return c.quoteClient.QuotePayments(ctx, req)
}
func (c *orchestratorClient) InitiatePayments(ctx context.Context, req *orchestratorv1.InitiatePaymentsRequest) (*orchestratorv1.InitiatePaymentsResponse, error) {

View File

@@ -4,10 +4,11 @@ import "time"
// Config captures connection settings for the payment orchestrator gRPC service.
type Config struct {
Address string
DialTimeout time.Duration
CallTimeout time.Duration
Insecure bool
Address string
QuoteAddress string
DialTimeout time.Duration
CallTimeout time.Duration
Insecure bool
}
func (c *Config) setDefaults() {