payments orchestrator refactoring

This commit is contained in:
Stephan D
2026-01-30 16:03:08 +01:00
parent 51f5b0804a
commit 73fadc9eb2
36 changed files with 1371 additions and 368 deletions

View File

@@ -6,6 +6,7 @@ import (
"github.com/tech/sendico/pkg/db/storable"
"github.com/tech/sendico/pkg/model"
pmodel "github.com/tech/sendico/pkg/model"
"github.com/tech/sendico/pkg/mservice"
paymenttypes "github.com/tech/sendico/pkg/payments/types"
)
@@ -33,9 +34,11 @@ const (
type CommitPolicy string
const (
CommitPolicyUnspecified CommitPolicy = "UNSPECIFIED"
CommitPolicyImmediate CommitPolicy = "IMMEDIATE"
CommitPolicyAfterSuccess CommitPolicy = "AFTER_SUCCESS"
CommitPolicyUnspecified CommitPolicy = "UNSPECIFIED"
CommitPolicyImmediate CommitPolicy = "IMMEDIATE"
CommitPolicyAfterSuccess CommitPolicy = "AFTER_SUCCESS"
CommitPolicyAfterFailure CommitPolicy = "AFTER_FAILURE"
CommitPolicyAfterCanceled CommitPolicy = "AFTER_TERMINAL"
)
// PaymentState enumerates lifecycle phases.
@@ -83,6 +86,9 @@ const (
RailOperationUnspecified RailOperation = "UNSPECIFIED"
RailOperationDebit RailOperation = "DEBIT"
RailOperationCredit RailOperation = "CREDIT"
RailOperationExternalDebit RailOperation = "EXTERNAL_DEBIT"
RailOperationExternalCredit RailOperation = "EXTERNAL_CREDIT"
RailOperationMove RailOperation = "MOVE"
RailOperationSend RailOperation = "SEND"
RailOperationFee RailOperation = "FEE"
RailOperationObserveConfirm RailOperation = "OBSERVE_CONFIRM"
@@ -265,26 +271,28 @@ type ExecutionRefs struct {
// PaymentStep is an explicit action within a payment plan.
type PaymentStep struct {
StepID string `bson:"stepId,omitempty" json:"stepId,omitempty"`
Rail Rail `bson:"rail" json:"rail"`
GatewayID string `bson:"gatewayId,omitempty" json:"gatewayId,omitempty"`
InstanceID string `bson:"instanceId,omitempty" json:"instanceId,omitempty"`
Action RailOperation `bson:"action" json:"action"`
DependsOn []string `bson:"dependsOn,omitempty" json:"dependsOn,omitempty"`
CommitPolicy CommitPolicy `bson:"commitPolicy,omitempty" json:"commitPolicy,omitempty"`
CommitAfter []string `bson:"commitAfter,omitempty" json:"commitAfter,omitempty"`
StepID string `bson:"stepId,omitempty" json:"stepId,omitempty"`
Rail Rail `bson:"rail" json:"rail"`
GatewayID string `bson:"gatewayId,omitempty" json:"gatewayId,omitempty"`
InstanceID string `bson:"instanceId,omitempty" json:"instanceId,omitempty"`
Action RailOperation `bson:"action" json:"action"`
DependsOn []string `bson:"dependsOn,omitempty" json:"dependsOn,omitempty"`
CommitPolicy CommitPolicy `bson:"commitPolicy,omitempty" json:"commitPolicy,omitempty"`
CommitAfter []string `bson:"commitAfter,omitempty" json:"commitAfter,omitempty"`
Amount *paymenttypes.Money `bson:"amount,omitempty" json:"amount,omitempty"`
Ref string `bson:"ref,omitempty" json:"ref,omitempty"`
Ref string `bson:"ref,omitempty" json:"ref,omitempty"`
FromRole *pmodel.AccountRole `bson:"fromRole,omitempty" json:"fromRole,omitempty"`
ToRole *pmodel.AccountRole `bson:"toRole,omitempty" json:"toRole,omitempty"`
}
// PaymentPlan captures the ordered list of steps to execute a payment.
type PaymentPlan struct {
ID string `bson:"id,omitempty" json:"id,omitempty"`
FXQuote *paymenttypes.FXQuote `bson:"fxQuote,omitempty" json:"fxQuote,omitempty"`
ID string `bson:"id,omitempty" json:"id,omitempty"`
FXQuote *paymenttypes.FXQuote `bson:"fxQuote,omitempty" json:"fxQuote,omitempty"`
Fees []*paymenttypes.FeeLine `bson:"fees,omitempty" json:"fees,omitempty"`
Steps []*PaymentStep `bson:"steps,omitempty" json:"steps,omitempty"`
IdempotencyKey string `bson:"idempotencyKey,omitempty" json:"idempotencyKey,omitempty"`
CreatedAt time.Time `bson:"createdAt,omitempty" json:"createdAt,omitempty"`
Steps []*PaymentStep `bson:"steps,omitempty" json:"steps,omitempty"`
IdempotencyKey string `bson:"idempotencyKey,omitempty" json:"idempotencyKey,omitempty"`
CreatedAt time.Time `bson:"createdAt,omitempty" json:"createdAt,omitempty"`
}
// ExecutionStep describes a planned or executed payment step for reporting.
@@ -467,7 +475,7 @@ func normalizeEndpoint(ep *PaymentEndpoint) {
func normalizeCommitPolicy(policy CommitPolicy) CommitPolicy {
val := strings.ToUpper(strings.TrimSpace(string(policy)))
switch CommitPolicy(val) {
case CommitPolicyImmediate, CommitPolicyAfterSuccess:
case CommitPolicyImmediate, CommitPolicyAfterSuccess, CommitPolicyAfterFailure, CommitPolicyAfterCanceled:
return CommitPolicy(val)
default:
if val == "" {