refactored payment orchestration
This commit is contained in:
@@ -92,6 +92,6 @@ require (
|
||||
golang.org/x/sys v0.40.0 // indirect
|
||||
golang.org/x/text v0.33.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260202165425-ce8ad4cf556b // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
@@ -271,8 +271,8 @@ gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251029180050-ab9386a59fda h1:+2XxjfsAu6vqFxwGBRcHiMaDCuZiqXGDUDVWVtrFAnE=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251029180050-ab9386a59fda/go.mod h1:fDMmzKV90WSg1NbozdqrE64fkuTv6mlq2zxo9ad+3yo=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 h1:H86B94AW+VfJWDqFeEbBPhEtHzJwJfTbgE2lZa54ZAQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260202165425-ce8ad4cf556b h1:GZxXGdFaHX27ZSMHudWc4FokdD+xl8BC2UJm1OVIEzs=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260202165425-ce8ad4cf556b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
|
||||
google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc=
|
||||
google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U=
|
||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package model
|
||||
package account_role
|
||||
|
||||
import (
|
||||
"strings"
|
||||
@@ -86,8 +86,9 @@ func (n ChainNetwork) IsEVM() bool {
|
||||
func (n ChainNetwork) IsTestnet() bool {
|
||||
switch n {
|
||||
case ChainNetworkTronNile:
|
||||
case ChainNetworkArbitrumSepolia:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@ type ConfirmationRequest struct {
|
||||
TimeoutSeconds int32 `bson:"timeoutSeconds,omitempty" json:"timeout_seconds,omitempty"`
|
||||
SourceService string `bson:"sourceService,omitempty" json:"source_service,omitempty"`
|
||||
Rail string `bson:"rail,omitempty" json:"rail,omitempty"`
|
||||
OperationRef string `bson:"operationRef,omitempty" json:"operation_ref,omitempty"`
|
||||
IntentRef string `bson:"intentRef,omitempty" json:"intent_ref,omitempty"`
|
||||
}
|
||||
|
||||
type ConfirmationResult struct {
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/tech/sendico/pkg/db/storable"
|
||||
"github.com/tech/sendico/pkg/merrors"
|
||||
"github.com/tech/sendico/pkg/model/account_role"
|
||||
"github.com/tech/sendico/pkg/mservice"
|
||||
"go.mongodb.org/mongo-driver/v2/bson"
|
||||
)
|
||||
@@ -63,7 +64,7 @@ type LedgerAccount struct {
|
||||
// Role defines the functional purpose of the account within an organization
|
||||
// (e.g., pending, operating, settlement, hold, etc.).
|
||||
// Must be set for organization accounts and omitted for system accounts.
|
||||
Role AccountRole `bson:"role,omitempty" json:"role,omitempty"`
|
||||
Role account_role.AccountRole `bson:"role,omitempty" json:"role,omitempty"`
|
||||
|
||||
// AccountCode is a logical classification code of the account
|
||||
// (e.g., "asset:cash:usd") used for reporting and grouping.
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
package model
|
||||
|
||||
type Money struct {
|
||||
Currency string `bson:"currency" json:"currency"`
|
||||
Amount string `bson:"amount" json:"amount"`
|
||||
}
|
||||
@@ -144,3 +144,24 @@ func (m *PaymentMethod) UnmarshalJSON(data []byte) error {
|
||||
m.Data = raw
|
||||
return nil
|
||||
}
|
||||
|
||||
type PaymentStatus string
|
||||
|
||||
const (
|
||||
PaymentStatusUnspecified PaymentStatus = "unspecified"
|
||||
|
||||
// Intent exists, no funds touched yet.
|
||||
PaymentStatusCreated PaymentStatus = "created"
|
||||
|
||||
// Internal Sendico operations: holds, ledger, FX, fee calc.
|
||||
PaymentStatusAuthorizing PaymentStatus = "authorizing"
|
||||
|
||||
// Funds are outside Sendico (rail/gateway/blockchain/provider).
|
||||
// Observe lives ONLY in this state.
|
||||
PaymentStatusExecuting PaymentStatus = "executing"
|
||||
|
||||
// Final states.
|
||||
PaymentStatusSucceeded PaymentStatus = "success"
|
||||
PaymentStatusFailed PaymentStatus = "failed"
|
||||
PaymentStatusCancelled PaymentStatus = "cancelled"
|
||||
)
|
||||
|
||||
@@ -1,22 +1,28 @@
|
||||
package model
|
||||
|
||||
import paymenttypes "github.com/tech/sendico/pkg/payments/types"
|
||||
import (
|
||||
"github.com/tech/sendico/pkg/payments/rail"
|
||||
paymenttypes "github.com/tech/sendico/pkg/payments/types"
|
||||
)
|
||||
|
||||
type PaymentGatewayIntent struct {
|
||||
PaymentRef string `bson:"paymentRef,omitempty" json:"payment_ref,omitempty"`
|
||||
PaymentIntentID string `bson:"paymentIntentId,omitempty" json:"payment_intent_id,omitempty"`
|
||||
IdempotencyKey string `bson:"idempotencyKey,omitempty" json:"idempotency_key,omitempty"`
|
||||
OutgoingLeg string `bson:"outgoingLeg,omitempty" json:"outgoing_leg,omitempty"`
|
||||
QuoteRef string `bson:"quoteRef,omitempty" json:"quote_ref,omitempty"`
|
||||
IntentRef string `bson:"intentRef,omitempty" json:"intent_ref,omitempty"`
|
||||
OperationRef string `bson:"operationRef,omitempty" json:"operation_ref,omitempty"`
|
||||
RequestedMoney *paymenttypes.Money `bson:"requestedMoney,omitempty" json:"requested_money,omitempty"`
|
||||
TargetChatID string `bson:"targetChatId,omitempty" json:"target_chat_id,omitempty"`
|
||||
}
|
||||
|
||||
type PaymentGatewayExecution struct {
|
||||
PaymentIntentID string `bson:"paymentIntentId,omitempty" json:"payment_intent_id,omitempty"`
|
||||
IdempotencyKey string `bson:"idempotencyKey,omitempty" json:"idempotency_key,omitempty"`
|
||||
QuoteRef string `bson:"quoteRef,omitempty" json:"quote_ref,omitempty"`
|
||||
ExecutedMoney *paymenttypes.Money `bson:"executedMoney,omitempty" json:"executed_money,omitempty"`
|
||||
Status ConfirmationStatus `bson:"status,omitempty" json:"status,omitempty"`
|
||||
RequestID string `bson:"requestId,omitempty" json:"request_id,omitempty"`
|
||||
RawReply *TelegramMessage `bson:"rawReply,omitempty" json:"raw_reply,omitempty"`
|
||||
PaymentIntentID string `bson:"paymentIntentId,omitempty" json:"payment_intent_id,omitempty"`
|
||||
PaymentRef string `bson:"paymentRef,omitempty" json:"payment_ref,omitempty"`
|
||||
IdempotencyKey string `bson:"idempotencyKey,omitempty" json:"idempotency_key,omitempty"`
|
||||
ExecutedMoney *paymenttypes.Money `bson:"executedMoney,omitempty" json:"executed_money,omitempty"`
|
||||
Status rail.OperationResult `bson:"status,omitempty" json:"status,omitempty"`
|
||||
OperationRef string `bson:"operationRef,omitempty" json:"operation_ref,omitempty"`
|
||||
TransferRef string `bson:"transferRef,omitempty" json:"transfer_ref,omitempty"`
|
||||
Error string `bson:"error,omitempty" json:"error,omitempty"`
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ const (
|
||||
RefreshTokens Type = "refresh_tokens" // Represents refresh tokens for authentication
|
||||
Roles Type = "roles" // Represents roles in access control
|
||||
Storage Type = "storage" // Represents statuses of tasks or projects
|
||||
TgSettle Type = "tgsettle_gateway" // Represents tg settlement gateway
|
||||
Tenants Type = "tenants" // Represents tenants managed in the system
|
||||
Wallets Type = "wallets" // Represents workflows for tasks or projects
|
||||
Workflows Type = "workflows" // Represents workflows for tasks or projects
|
||||
|
||||
@@ -3,19 +3,32 @@ package rail
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tech/sendico/pkg/model"
|
||||
"github.com/tech/sendico/pkg/model/account_role"
|
||||
paymenttypes "github.com/tech/sendico/pkg/payments/types"
|
||||
)
|
||||
|
||||
// Money represents a currency amount using decimal-safe strings.
|
||||
type Money = paymenttypes.Money
|
||||
|
||||
type TransferStatus string
|
||||
|
||||
const (
|
||||
TransferStatusUnspecified = "UNSPECIFIED"
|
||||
TransferStatusSuccess = "SUCCESS"
|
||||
TransferStatusFailed = "FAILED"
|
||||
TransferStatusRejected = "REJECTED"
|
||||
TransferStatusPending = "PENDING"
|
||||
TransferStatusUnspecified TransferStatus = "unspecified"
|
||||
TransferStatusCreated TransferStatus = "created"
|
||||
TransferStatusSuccess TransferStatus = "success"
|
||||
TransferStatusFailed TransferStatus = "failed"
|
||||
TransferStatusWaiting TransferStatus = "waiting"
|
||||
TransferStatusProcessing TransferStatus = "processing"
|
||||
TransferStatusCancelled TransferStatus = "cancelled"
|
||||
)
|
||||
|
||||
// OperationResult represents the outcome status of an operation in a gateway
|
||||
type OperationResult string
|
||||
|
||||
const (
|
||||
OperationResultSuccess OperationResult = "success"
|
||||
OperationResultFailed OperationResult = "failed"
|
||||
OperationResultCancelled OperationResult = "cancelled"
|
||||
)
|
||||
|
||||
// RailCapabilities are declared per gateway instance.
|
||||
@@ -39,6 +52,9 @@ type FeeBreakdown struct {
|
||||
// TransferRequest defines the inputs for sending value through a rail gateway.
|
||||
type TransferRequest struct {
|
||||
OrganizationRef string
|
||||
IntentRef string
|
||||
OperationRef string
|
||||
PaymentRef string
|
||||
FromAccountID string
|
||||
ToAccountID string
|
||||
Currency string
|
||||
@@ -48,10 +64,9 @@ type TransferRequest struct {
|
||||
Fees []FeeBreakdown
|
||||
IdempotencyKey string
|
||||
Metadata map[string]string
|
||||
ClientReference string
|
||||
DestinationMemo string
|
||||
FromRole model.AccountRole
|
||||
ToRole model.AccountRole
|
||||
FromRole account_role.AccountRole
|
||||
ToRole account_role.AccountRole
|
||||
}
|
||||
|
||||
// BlockRequest defines the inputs for reserving value through a rail gateway.
|
||||
@@ -62,35 +77,35 @@ type BlockRequest struct {
|
||||
Amount string
|
||||
IdempotencyKey string
|
||||
Metadata map[string]string
|
||||
ClientReference string
|
||||
PaymentRef string
|
||||
}
|
||||
|
||||
// ReleaseRequest defines the inputs for releasing a prior block.
|
||||
type ReleaseRequest struct {
|
||||
ReferenceID string
|
||||
IdempotencyKey string
|
||||
Metadata map[string]string
|
||||
ClientReference string
|
||||
ReferenceID string
|
||||
IdempotencyKey string
|
||||
Metadata map[string]string
|
||||
PaymentRef string
|
||||
}
|
||||
|
||||
// RailResult reports the outcome of a rail gateway operation.
|
||||
type RailResult struct {
|
||||
ReferenceID string
|
||||
Status string
|
||||
Status TransferStatus
|
||||
FinalAmount *Money
|
||||
Error *RailError
|
||||
Error *Error
|
||||
}
|
||||
|
||||
// ObserveResult reports the outcome of a confirmation observation.
|
||||
type ObserveResult struct {
|
||||
ReferenceID string
|
||||
Status string
|
||||
Status TransferStatus
|
||||
FinalAmount *Money
|
||||
Error *RailError
|
||||
Error *Error
|
||||
}
|
||||
|
||||
// RailError captures structured failure details from a gateway.
|
||||
type RailError struct {
|
||||
// Error captures structured failure details from a gateway.
|
||||
type Error struct {
|
||||
Code string
|
||||
Message string
|
||||
CanRetry bool
|
||||
|
||||
Reference in New Issue
Block a user