TG settlement service

This commit is contained in:
Stephan D
2026-01-02 14:54:18 +01:00
parent ea1c69f14a
commit 743f683d92
82 changed files with 4693 additions and 503 deletions

View File

@@ -1,38 +1,42 @@
package model
import (
"time"
import paymenttypes "github.com/tech/sendico/pkg/payments/types"
"github.com/tech/sendico/pkg/db/storable"
"github.com/tech/sendico/pkg/mservice"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type ConfirmationTarget string
type ConfirmationStatus string
const (
ConfirmationTargetLogin ConfirmationTarget = "login"
ConfirmationTargetPayout ConfirmationTarget = "payout"
ConfirmationStatusConfirmed ConfirmationStatus = "CONFIRMED"
ConfirmationStatusClarified ConfirmationStatus = "CLARIFIED"
ConfirmationStatusTimeout ConfirmationStatus = "TIMEOUT"
ConfirmationStatusRejected ConfirmationStatus = "REJECTED"
)
// ConfirmationCode stores verification codes for operations like login or payouts.
type ConfirmationCode struct {
storable.Base `bson:",inline" json:",inline"`
AccountRef primitive.ObjectID `bson:"accountRef" json:"accountRef"`
Destination string `bson:"destination" json:"destination"`
Target ConfirmationTarget `bson:"target" json:"target"`
CodeHash []byte `bson:"codeHash" json:"-"`
Salt []byte `bson:"salt" json:"-"`
ExpiresAt time.Time `bson:"expiresAt" json:"expiresAt"`
Attempts int `bson:"attempts" json:"attempts"`
MaxAttempts int `bson:"maxAttempts" json:"maxAttempts"`
ResendCount int `bson:"resendCount" json:"resendCount"`
ResendLimit int `bson:"resendLimit" json:"resendLimit"`
CooldownUntil time.Time `bson:"cooldownUntil" json:"cooldownUntil"`
Used bool `bson:"used" json:"used"`
type ConfirmationRequest struct {
RequestID string `bson:"requestId,omitempty" json:"request_id,omitempty"`
TargetChatID string `bson:"targetChatId,omitempty" json:"target_chat_id,omitempty"`
RequestedMoney *paymenttypes.Money `bson:"requestedMoney,omitempty" json:"requested_money,omitempty"`
PaymentIntentID string `bson:"paymentIntentId,omitempty" json:"payment_intent_id,omitempty"`
QuoteRef string `bson:"quoteRef,omitempty" json:"quote_ref,omitempty"`
AcceptedUserIDs []string `bson:"acceptedUserIds,omitempty" json:"accepted_user_ids,omitempty"`
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"`
}
func (c *ConfirmationCode) Collection() string {
return mservice.Confirmations
type ConfirmationResult struct {
RequestID string `bson:"requestId,omitempty" json:"request_id,omitempty"`
Money *paymenttypes.Money `bson:"money,omitempty" json:"money,omitempty"`
RawReply *TelegramMessage `bson:"rawReply,omitempty" json:"raw_reply,omitempty"`
Status ConfirmationStatus `bson:"status,omitempty" json:"status,omitempty"`
ParseError string `bson:"parseError,omitempty" json:"parse_error,omitempty"`
}
type TelegramMessage struct {
ChatID string `bson:"chatId,omitempty" json:"chat_id,omitempty"`
MessageID string `bson:"messageId,omitempty" json:"message_id,omitempty"`
ReplyToMessageID string `bson:"replyToMessageId,omitempty" json:"reply_to_message_id,omitempty"`
FromUserID string `bson:"fromUserId,omitempty" json:"from_user_id,omitempty"`
FromUsername string `bson:"fromUsername,omitempty" json:"from_username,omitempty"`
Text string `bson:"text,omitempty" json:"text,omitempty"`
SentAt int64 `bson:"sentAt,omitempty" json:"sent_at,omitempty"`
}

View File

@@ -0,0 +1,36 @@
package model
import (
"time"
"github.com/tech/sendico/pkg/db/storable"
"github.com/tech/sendico/pkg/mservice"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type ConfirmationTarget string
const (
ConfirmationTargetLogin ConfirmationTarget = "login"
ConfirmationTargetPayout ConfirmationTarget = "payout"
)
type ConfirmationCode struct {
storable.Base `bson:",inline" json:",inline"`
AccountRef primitive.ObjectID `bson:"accountRef" json:"accountRef"`
Destination string `bson:"destination" json:"destination"`
Target ConfirmationTarget `bson:"target" json:"target"`
CodeHash []byte `bson:"codeHash" json:"codeHash,omitempty"`
Salt []byte `bson:"salt" json:"salt,omitempty"`
ExpiresAt time.Time `bson:"expiresAt" json:"expiresAt"`
MaxAttempts int `bson:"maxAttempts" json:"maxAttempts"`
ResendLimit int `bson:"resendLimit" json:"resendLimit"`
CooldownUntil time.Time `bson:"cooldownUntil" json:"cooldownUntil"`
Used bool `bson:"used" json:"used"`
Attempts int `bson:"attempts" json:"attempts"`
ResendCount int `bson:"resendCount" json:"resendCount"`
}
func (*ConfirmationCode) Collection() string {
return mservice.Confirmations
}

View File

@@ -12,6 +12,10 @@ const (
NASent NotificationAction = "sent"
NAPasswordReset NotificationAction = "password_reset"
NAConfirmationRequest NotificationAction = "confirmation.request"
NAPaymentGatewayIntent NotificationAction = "intent.request"
NAPaymentGatewayExecution NotificationAction = "execution.result"
NADiscoveryServiceAnnounce NotificationAction = "service.announce"
NADiscoveryGatewayAnnounce NotificationAction = "gateway.announce"
NADiscoveryHeartbeat NotificationAction = "service.heartbeat"

View File

@@ -81,6 +81,9 @@ func StringToNotificationAction(s string) (nm.NotificationAction, error) {
nm.NADeleted,
nm.NAAssigned,
nm.NAPasswordReset,
nm.NAConfirmationRequest,
nm.NAPaymentGatewayIntent,
nm.NAPaymentGatewayExecution,
nm.NADiscoveryServiceAnnounce,
nm.NADiscoveryGatewayAnnounce,
nm.NADiscoveryHeartbeat,
@@ -99,8 +102,15 @@ func StringToNotificationEvent(eventType, eventAction string) (NotificationEvent
return nil, err
}
ea, err := StringToNotificationAction(eventAction)
if err != nil {
return nil, err
if err == nil {
return NewNotification(et, ea), nil
}
return NewNotification(et, ea), nil
if et == mservice.Confirmations {
action := strings.TrimSpace(eventAction)
if action == "" {
return nil, err
}
return &NotificationEventImp{nType: et, nAction: nm.NotificationAction(action)}, nil
}
return nil, err
}

View File

@@ -0,0 +1,22 @@
package model
import paymenttypes "github.com/tech/sendico/pkg/payments/types"
type PaymentGatewayIntent struct {
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"`
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"`
}