refactored payment orchestration

This commit is contained in:
Stephan D
2026-02-03 00:40:46 +01:00
parent 05d998e0f7
commit 5e87e2f2f9
184 changed files with 3920 additions and 2219 deletions

View File

@@ -9,7 +9,7 @@ import (
chainasset "github.com/tech/sendico/pkg/chain"
"github.com/tech/sendico/pkg/merrors"
pmodel "github.com/tech/sendico/pkg/model"
"github.com/tech/sendico/pkg/model/account_role"
describablev1 "github.com/tech/sendico/pkg/proto/common/describable/v1"
moneyv1 "github.com/tech/sendico/pkg/proto/common/money/v1"
paginationv1 "github.com/tech/sendico/pkg/proto/common/pagination/v1"
@@ -426,7 +426,7 @@ func operationFromTransfer(req *chainv1.SubmitTransferRequest) (*connectorv1.Ope
params := map[string]interface{}{
"organization_ref": strings.TrimSpace(req.GetOrganizationRef()),
"client_reference": strings.TrimSpace(req.GetClientReference()),
"payment_ref": strings.TrimSpace(req.GetPaymentRef()),
}
if memo := strings.TrimSpace(req.GetDestination().GetMemo()); memo != "" {
params["destination_memo"] = memo
@@ -444,6 +444,8 @@ func operationFromTransfer(req *chainv1.SubmitTransferRequest) (*connectorv1.Ope
From: &connectorv1.OperationParty{Ref: &connectorv1.OperationParty_Account{Account: &connectorv1.AccountRef{ConnectorId: chainConnectorID, AccountId: strings.TrimSpace(req.GetSourceWalletRef())}}},
Money: req.GetAmount(),
Params: structFromMap(params),
IntentRef: strings.TrimSpace(req.GetIntentRef()),
OperationRef: strings.TrimSpace(req.GetOperationRef()),
}
to, err := destinationToParty(req.GetDestination())
if err != nil {
@@ -472,14 +474,14 @@ func setOperationRolesFromMetadata(op *connectorv1.Operation, metadata map[strin
if op == nil || len(metadata) == 0 {
return
}
if raw := strings.TrimSpace(metadata[pmodel.MetadataKeyFromRole]); raw != "" {
if role, ok := pmodel.Parse(raw); ok && role != "" {
op.FromRole = pmodel.ToProto(role)
if raw := strings.TrimSpace(metadata[account_role.MetadataKeyFromRole]); raw != "" {
if role, ok := account_role.Parse(raw); ok && role != "" {
op.FromRole = account_role.ToProto(role)
}
}
if raw := strings.TrimSpace(metadata[pmodel.MetadataKeyToRole]); raw != "" {
if role, ok := pmodel.Parse(raw); ok && role != "" {
op.ToRole = pmodel.ToProto(role)
if raw := strings.TrimSpace(metadata[account_role.MetadataKeyToRole]); raw != "" {
if role, ok := account_role.Parse(raw); ok && role != "" {
op.ToRole = account_role.ToProto(role)
}
}
}
@@ -619,7 +621,7 @@ func gasTopUpEnsureOperation(req *chainv1.EnsureGasTopUpRequest) (*connectorv1.O
"mode": "ensure",
"organization_ref": strings.TrimSpace(req.GetOrganizationRef()),
"target_wallet_ref": strings.TrimSpace(req.GetTargetWalletRef()),
"client_reference": strings.TrimSpace(req.GetClientReference()),
"payment_ref": strings.TrimSpace(req.GetPaymentRef()),
"estimated_total_fee": map[string]interface{}{"amount": fee.GetAmount(), "currency": fee.GetCurrency()},
}
if len(req.GetMetadata()) > 0 {
@@ -765,28 +767,54 @@ func managedWalletStatusFromAccount(state connectorv1.AccountState) chainv1.Mana
}
}
func transferStatusFromOperation(status connectorv1.OperationStatus) chainv1.TransferStatus {
switch status {
case connectorv1.OperationStatus_CONFIRMED:
return chainv1.TransferStatus_TRANSFER_CONFIRMED
case connectorv1.OperationStatus_FAILED:
return chainv1.TransferStatus_TRANSFER_FAILED
case connectorv1.OperationStatus_CANCELED:
return chainv1.TransferStatus_TRANSFER_CANCELLED
default:
return chainv1.TransferStatus_TRANSFER_PENDING
}
}
func operationStatusFromTransfer(status chainv1.TransferStatus) connectorv1.OperationStatus {
switch status {
case chainv1.TransferStatus_TRANSFER_CONFIRMED:
return connectorv1.OperationStatus_CONFIRMED
case chainv1.TransferStatus_TRANSFER_CREATED:
return connectorv1.OperationStatus_OPERATION_CREATED
case chainv1.TransferStatus_TRANSFER_PROCESSING:
return connectorv1.OperationStatus_OPERATION_PROCESSING
case chainv1.TransferStatus_TRANSFER_WAITING:
return connectorv1.OperationStatus_OPERATION_WAITING
case chainv1.TransferStatus_TRANSFER_SUCCESS:
return connectorv1.OperationStatus_OPERATION_SUCCESS
case chainv1.TransferStatus_TRANSFER_FAILED:
return connectorv1.OperationStatus_FAILED
return connectorv1.OperationStatus_OPERATION_FAILED
case chainv1.TransferStatus_TRANSFER_CANCELLED:
return connectorv1.OperationStatus_CANCELED
return connectorv1.OperationStatus_OPERATION_CANCELLED
default:
return connectorv1.OperationStatus_OPERATION_STATUS_UNSPECIFIED
}
}
func transferStatusFromOperation(status connectorv1.OperationStatus) chainv1.TransferStatus {
switch status {
case connectorv1.OperationStatus_OPERATION_CREATED:
return chainv1.TransferStatus_TRANSFER_CREATED
case connectorv1.OperationStatus_OPERATION_PROCESSING:
return chainv1.TransferStatus_TRANSFER_PROCESSING
case connectorv1.OperationStatus_OPERATION_WAITING:
return chainv1.TransferStatus_TRANSFER_WAITING
case connectorv1.OperationStatus_OPERATION_SUCCESS:
return chainv1.TransferStatus_TRANSFER_SUCCESS
case connectorv1.OperationStatus_OPERATION_FAILED:
return chainv1.TransferStatus_TRANSFER_FAILED
case connectorv1.OperationStatus_OPERATION_CANCELLED:
return chainv1.TransferStatus_TRANSFER_CANCELLED
default:
return chainv1.TransferStatus_TRANSFER_STATUS_UNSPECIFIED
}
}

View File

@@ -5,7 +5,7 @@ import (
"strings"
"github.com/tech/sendico/pkg/merrors"
pmodel "github.com/tech/sendico/pkg/model"
"github.com/tech/sendico/pkg/model/account_role"
"github.com/tech/sendico/pkg/payments/rail"
moneyv1 "github.com/tech/sendico/pkg/proto/common/money/v1"
chainv1 "github.com/tech/sendico/pkg/proto/gateway/chain/v1"
@@ -102,13 +102,15 @@ func (g *chainRailGateway) Send(ctx context.Context, req rail.TransferRequest) (
OrganizationRef: orgRef,
SourceWalletRef: source,
Destination: dest,
IntentRef: strings.TrimSpace(req.IntentRef),
OperationRef: strings.TrimSpace(req.OperationRef),
PaymentRef: strings.TrimSpace(req.PaymentRef),
Amount: &moneyv1.Money{
Currency: currency,
Amount: amountValue,
},
Fees: fees,
Metadata: transferMetadataWithRoles(req.Metadata, req.FromRole, req.ToRole),
ClientReference: strings.TrimSpace(req.ClientReference),
Fees: fees,
Metadata: transferMetadataWithRoles(req.Metadata, req.FromRole, req.ToRole),
})
if err != nil {
return rail.RailResult{}, err
@@ -186,20 +188,29 @@ func (g *chainRailGateway) isManagedWallet(ctx context.Context, walletRef string
return true, nil
}
func statusFromTransfer(status chainv1.TransferStatus) string {
func statusFromTransfer(status chainv1.TransferStatus) rail.TransferStatus {
switch status {
case chainv1.TransferStatus_TRANSFER_CONFIRMED:
case chainv1.TransferStatus_TRANSFER_CREATED:
return rail.TransferStatusCreated
case chainv1.TransferStatus_TRANSFER_PROCESSING:
return rail.TransferStatusProcessing
case chainv1.TransferStatus_TRANSFER_WAITING:
return rail.TransferStatusProcessing
case chainv1.TransferStatus_TRANSFER_SUCCESS:
return rail.TransferStatusSuccess
case chainv1.TransferStatus_TRANSFER_FAILED:
return rail.TransferStatusFailed
case chainv1.TransferStatus_TRANSFER_CANCELLED:
return rail.TransferStatusRejected
case chainv1.TransferStatus_TRANSFER_SIGNING,
chainv1.TransferStatus_TRANSFER_PENDING,
chainv1.TransferStatus_TRANSFER_SUBMITTED:
return rail.TransferStatusPending
return rail.TransferStatusCancelled
default:
return rail.TransferStatusPending
return rail.TransferStatusUnspecified
}
}
@@ -255,19 +266,19 @@ func railMoneyFromProto(m *moneyv1.Money) *rail.Money {
}
}
func transferMetadataWithRoles(metadata map[string]string, fromRole, toRole pmodel.AccountRole) map[string]string {
func transferMetadataWithRoles(metadata map[string]string, fromRole, toRole account_role.AccountRole) map[string]string {
result := cloneMetadata(metadata)
if strings.TrimSpace(string(fromRole)) != "" {
if result == nil {
result = map[string]string{}
}
result[pmodel.MetadataKeyFromRole] = strings.TrimSpace(string(fromRole))
result[account_role.MetadataKeyFromRole] = strings.TrimSpace(string(fromRole))
}
if strings.TrimSpace(string(toRole)) != "" {
if result == nil {
result = map[string]string{}
}
result[pmodel.MetadataKeyToRole] = strings.TrimSpace(string(toRole))
result[account_role.MetadataKeyToRole] = strings.TrimSpace(string(toRole))
}
if len(result) == 0 {
return nil