From f9acb47ad7af6df50196ce98429711e671cf1df8 Mon Sep 17 00:00:00 2001 From: Stephan D Date: Tue, 3 Mar 2026 12:23:07 +0100 Subject: [PATCH 1/2] mntx gateway lookup name fixed --- .../internal/server/internal/discovery_clients.go | 2 +- test.csv | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 test.csv diff --git a/api/payments/orchestrator/internal/server/internal/discovery_clients.go b/api/payments/orchestrator/internal/server/internal/discovery_clients.go index 3997445f..8c8a777c 100644 --- a/api/payments/orchestrator/internal/server/internal/discovery_clients.go +++ b/api/payments/orchestrator/internal/server/internal/discovery_clients.go @@ -31,7 +31,7 @@ var ( feesServiceNames = []string{"BILLING_FEES", string(mservice.FeePlans)} ledgerServiceNames = []string{"LEDGER", string(mservice.Ledger)} oracleServiceNames = []string{"FX_ORACLE", string(mservice.FXOracle)} - mntxServiceNames = []string{"CARD_RAIL_GATEWAY", string(mservice.MntxGateway)} + mntxServiceNames = []string{discovery.RailCardPayout, string(mservice.MntxGateway)} feesRequiredOps = []string{discovery.OperationFeeCalc} ledgerRequiredOps = discovery.LedgerServiceOperations() diff --git a/test.csv b/test.csv new file mode 100644 index 00000000..b860632e --- /dev/null +++ b/test.csv @@ -0,0 +1,5 @@ +pan;first_name;last_name;exp_month;exp_year;amount +2204310159722456;Anastasiia;Limonova;06;2028;100 +2204320167919754;Anastasiia;Limonova;10;2027;100 +2200242558874568;Anastasiia;Limonova;07;2032;100 +2203410113188371;Vladimir;Burmakin;02;2033;100 \ No newline at end of file From 83745bcd10e31d2d2dc9d5de100749083e608225 Mon Sep 17 00:00:00 2001 From: Stephan D Date: Tue, 3 Mar 2026 13:15:42 +0100 Subject: [PATCH 2/2] fixed mntx discovery --- .../internal/service/documents/service.go | 2 +- .../fees/internal/service/fees/service.go | 2 +- .../internal/server/internal/discovery.go | 2 +- api/fx/ingestor/internal/app/app.go | 3 +- .../oracle/internal/service/oracle/service.go | 2 +- .../chain/internal/service/gateway/service.go | 2 +- .../mntx/internal/service/gateway/service.go | 2 +- .../internal/service/gateway/service.go | 2 +- .../tron/internal/service/gateway/service.go | 2 +- api/ledger/internal/service/ledger/service.go | 2 +- .../server/notificationimp/notification.go | 2 +- .../internal/server/internal/discovery.go | 3 +- .../internal/server/internal/dependencies.go | 6 - .../internal/server/internal/discovery.go | 2 +- .../server/internal/discovery_clients.go | 128 ++++++--------- .../server/internal/discovery_wrappers.go | 55 ------- .../orchestrator/card_payout_executor.go | 149 +++++++++++++++++- .../orchestrator/card_payout_executor_test.go | 72 ++++++--- .../internal/service/orchestrator/options.go | 11 -- .../internal/service/orchestrator/service.go | 3 - .../service/orchestrator/service_v2.go | 6 +- .../internal/server/internal/discovery.go | 3 +- api/pkg/discovery/types.go | 4 +- api/pkg/mservice/services.go | 4 + 24 files changed, 268 insertions(+), 201 deletions(-) diff --git a/api/billing/documents/internal/service/documents/service.go b/api/billing/documents/internal/service/documents/service.go index e8a3dbdb..5d9f9e69 100644 --- a/api/billing/documents/internal/service/documents/service.go +++ b/api/billing/documents/internal/service/documents/service.go @@ -391,7 +391,7 @@ func (s *Service) startDiscoveryAnnouncer() { } announce := discovery.Announcement{ - Service: "BILLING_DOCUMENTS", + Service: mservice.BillingDocuments, Operations: []string{discovery.OperationDocumentsBatchResolve, discovery.OperationDocumentsGet}, InvokeURI: s.invokeURI, Version: appversion.Create().Short(), diff --git a/api/billing/fees/internal/service/fees/service.go b/api/billing/fees/internal/service/fees/service.go index a72f6bec..7cce39a7 100644 --- a/api/billing/fees/internal/service/fees/service.go +++ b/api/billing/fees/internal/service/fees/service.go @@ -564,7 +564,7 @@ func (s *Service) startDiscoveryAnnouncer() { } announce := discovery.Announcement{ - Service: "BILLING_FEES", + Service: mservice.BillingFees, Operations: []string{discovery.OperationFeeCalc}, InvokeURI: s.invokeURI, Version: appversion.Create().Short(), diff --git a/api/discovery/internal/server/internal/discovery.go b/api/discovery/internal/server/internal/discovery.go index 9d66bc8a..19680943 100644 --- a/api/discovery/internal/server/internal/discovery.go +++ b/api/discovery/internal/server/internal/discovery.go @@ -49,7 +49,7 @@ func (i *Imp) startDiscovery(cfg *config) error { i.registrySvc = svc announce := discovery.Announcement{ - Service: "DISCOVERY", + Service: mservice.Discovery, InstanceID: discovery.InstanceID(), Operations: []string{discovery.OperationDiscoveryLookup}, Version: appversion.Create().Short(), diff --git a/api/fx/ingestor/internal/app/app.go b/api/fx/ingestor/internal/app/app.go index dcdc3eef..cb4fc02e 100644 --- a/api/fx/ingestor/internal/app/app.go +++ b/api/fx/ingestor/internal/app/app.go @@ -17,6 +17,7 @@ import ( msg "github.com/tech/sendico/pkg/messaging" msgproducer "github.com/tech/sendico/pkg/messaging/producer" "github.com/tech/sendico/pkg/mlogger" + "github.com/tech/sendico/pkg/mservice" "go.uber.org/zap" ) @@ -85,7 +86,7 @@ func (a *App) Run(ctx context.Context) error { } else { producer := msgproducer.NewProducer(a.logger.Named("discovery_producer"), broker) announce := discovery.Announcement{ - Service: "FX_INGESTOR", + Service: mservice.FXIngestor, Operations: []string{discovery.OperationFXIngest}, Version: appversion.Create().Short(), } diff --git a/api/fx/oracle/internal/service/oracle/service.go b/api/fx/oracle/internal/service/oracle/service.go index 12c9cb63..66198641 100644 --- a/api/fx/oracle/internal/service/oracle/service.go +++ b/api/fx/oracle/internal/service/oracle/service.go @@ -105,7 +105,7 @@ func (s *Service) startDiscoveryAnnouncer() { return } announce := discovery.Announcement{ - Service: "FX_ORACLE", + Service: mservice.FXOracle, Operations: []string{discovery.OperationFXQuote}, InvokeURI: s.invokeURI, Version: appversion.Create().Short(), diff --git a/api/gateway/chain/internal/service/gateway/service.go b/api/gateway/chain/internal/service/gateway/service.go index 437bd0da..446ac324 100644 --- a/api/gateway/chain/internal/service/gateway/service.go +++ b/api/gateway/chain/internal/service/gateway/service.go @@ -224,7 +224,7 @@ func (s *Service) startDiscoveryAnnouncers() { announce := discovery.Announcement{ ID: discovery.StableCryptoRailGatewayID(string(network.Name)), InstanceID: discovery.InstanceID(), - Service: "CRYPTO_RAIL_GATEWAY", + Service: mservice.ChainWallets, Rail: discovery.RailCrypto, Operations: discovery.CryptoRailGatewayOperations(), Currencies: currencies, diff --git a/api/gateway/mntx/internal/service/gateway/service.go b/api/gateway/mntx/internal/service/gateway/service.go index 0ddaece1..7a2c158a 100644 --- a/api/gateway/mntx/internal/service/gateway/service.go +++ b/api/gateway/mntx/internal/service/gateway/service.go @@ -151,7 +151,7 @@ func (s *Service) startDiscoveryAnnouncer() { return } announce := discovery.Announcement{ - Service: "CARD", + Service: mservice.MntxGateway, Rail: discovery.RailCardPayout, Operations: discovery.CardPayoutRailGatewayOperations(), InvokeURI: s.invokeURI, diff --git a/api/gateway/tgsettle/internal/service/gateway/service.go b/api/gateway/tgsettle/internal/service/gateway/service.go index ce7971bf..636caaa9 100644 --- a/api/gateway/tgsettle/internal/service/gateway/service.go +++ b/api/gateway/tgsettle/internal/service/gateway/service.go @@ -534,7 +534,7 @@ func (s *Service) startAnnouncer() { announce := discovery.Announcement{ ID: discovery.StablePaymentGatewayID(rail), InstanceID: discovery.InstanceID(), - Service: string(mservice.PaymentGateway), + Service: mservice.TgSettle, Rail: rail, Operations: caps, InvokeURI: s.invokeURI, diff --git a/api/gateway/tron/internal/service/gateway/service.go b/api/gateway/tron/internal/service/gateway/service.go index e9d49a6b..89b1de9c 100644 --- a/api/gateway/tron/internal/service/gateway/service.go +++ b/api/gateway/tron/internal/service/gateway/service.go @@ -229,7 +229,7 @@ func (s *Service) startDiscoveryAnnouncers() { announce := discovery.Announcement{ ID: discovery.StableCryptoRailGatewayID(network.Name.String()), InstanceID: discovery.InstanceID(), - Service: "CRYPTO_RAIL_GATEWAY", + Service: mservice.TronGateway, Rail: discovery.RailCrypto, Operations: discovery.CryptoRailGatewayOperations(), Currencies: currencies, diff --git a/api/ledger/internal/service/ledger/service.go b/api/ledger/internal/service/ledger/service.go index 86fc8e36..9f195df6 100644 --- a/api/ledger/internal/service/ledger/service.go +++ b/api/ledger/internal/service/ledger/service.go @@ -409,7 +409,7 @@ func (s *Service) startDiscoveryAnnouncer() { return } announce := discovery.Announcement{ - Service: "LEDGER", + Service: mservice.Ledger, Rail: discovery.RailLedger, Operations: discovery.LedgerServiceOperations(), InvokeURI: s.invokeURI, diff --git a/api/notification/internal/server/notificationimp/notification.go b/api/notification/internal/server/notificationimp/notification.go index 7a3664bd..5e1438b0 100644 --- a/api/notification/internal/server/notificationimp/notification.go +++ b/api/notification/internal/server/notificationimp/notification.go @@ -119,7 +119,7 @@ func CreateAPI(a api.API) (*NotificationAPI, error) { } announce := discovery.Announcement{ - Service: "NOTIFICATIONS", + Service: mservice.Notifications, Operations: []string{discovery.OperationNotifySend}, Version: appversion.Create().Short(), } diff --git a/api/payments/methods/internal/server/internal/discovery.go b/api/payments/methods/internal/server/internal/discovery.go index 42931e2e..48df3267 100644 --- a/api/payments/methods/internal/server/internal/discovery.go +++ b/api/payments/methods/internal/server/internal/discovery.go @@ -6,6 +6,7 @@ import ( "github.com/tech/sendico/payments/methods/internal/appversion" "github.com/tech/sendico/pkg/discovery" msg "github.com/tech/sendico/pkg/messaging" + "github.com/tech/sendico/pkg/mservice" "go.uber.org/zap" ) @@ -51,7 +52,7 @@ func (i *Imp) startDiscoveryAnnouncer(cfg *config, producer msg.Producer) { } announce := discovery.Announcement{ - Service: "PAYMENTS_METHODS", + Service: mservice.PaymentMethods, Operations: []string{ discovery.OperationPaymentMethodsManage, discovery.OperationPaymentMethodsRead, diff --git a/api/payments/orchestrator/internal/server/internal/dependencies.go b/api/payments/orchestrator/internal/server/internal/dependencies.go index 751050af..07d4ba6c 100644 --- a/api/payments/orchestrator/internal/server/internal/dependencies.go +++ b/api/payments/orchestrator/internal/server/internal/dependencies.go @@ -1,14 +1,12 @@ package serverimp import ( - mntxclient "github.com/tech/sendico/gateway/mntx/client" ledgerclient "github.com/tech/sendico/ledger/client" "github.com/tech/sendico/payments/orchestrator/internal/service/orchestrator" ) type orchestratorDeps struct { ledgerClient ledgerclient.Client - mntxClient mntxclient.Client gatewayInvokeResolver orchestrator.GatewayInvokeResolver } @@ -23,7 +21,6 @@ func (i *Imp) initDependencies(_ *config) *orchestratorDeps { i.discoveryClients = newDiscoveryClientResolver(i.logger, i.discoveryReg) deps.ledgerClient = &discoveryLedgerClient{resolver: i.discoveryClients} - deps.mntxClient = &discoveryMntxClient{resolver: i.discoveryClients} deps.gatewayInvokeResolver = discoveryGatewayInvokeResolver{resolver: i.discoveryClients} return deps } @@ -36,9 +33,6 @@ func (i *Imp) buildServiceOptions(cfg *config, deps *orchestratorDeps) []orchest if deps.ledgerClient != nil { opts = append(opts, orchestrator.WithLedgerClient(deps.ledgerClient)) } - if deps.mntxClient != nil { - opts = append(opts, orchestrator.WithMntxGateway(deps.mntxClient)) - } if deps.gatewayInvokeResolver != nil { opts = append(opts, orchestrator.WithGatewayInvokeResolver(deps.gatewayInvokeResolver)) diff --git a/api/payments/orchestrator/internal/server/internal/discovery.go b/api/payments/orchestrator/internal/server/internal/discovery.go index 45d84462..0fc1be49 100644 --- a/api/payments/orchestrator/internal/server/internal/discovery.go +++ b/api/payments/orchestrator/internal/server/internal/discovery.go @@ -32,7 +32,7 @@ func (i *Imp) initDiscovery(cfg *config) { i.logger.Info("Discovery registry watcher started") } announce := discovery.Announcement{ - Service: "PAYMENTS_ORCHESTRATOR", + Service: mservice.PaymentOrchestrator, Operations: []string{discovery.OperationPaymentInitiate}, InvokeURI: cfg.GRPC.DiscoveryInvokeURI(), Version: appversion.Create().Short(), diff --git a/api/payments/orchestrator/internal/server/internal/discovery_clients.go b/api/payments/orchestrator/internal/server/internal/discovery_clients.go index 8c8a777c..6f9c4079 100644 --- a/api/payments/orchestrator/internal/server/internal/discovery_clients.go +++ b/api/payments/orchestrator/internal/server/internal/discovery_clients.go @@ -12,7 +12,6 @@ import ( oracleclient "github.com/tech/sendico/fx/oracle/client" chainclient "github.com/tech/sendico/gateway/chain/client" - mntxclient "github.com/tech/sendico/gateway/mntx/client" ledgerclient "github.com/tech/sendico/ledger/client" "github.com/tech/sendico/pkg/discovery" "github.com/tech/sendico/pkg/merrors" @@ -28,15 +27,9 @@ import ( const discoveryLogThrottle = 30 * time.Second var ( - feesServiceNames = []string{"BILLING_FEES", string(mservice.FeePlans)} - ledgerServiceNames = []string{"LEDGER", string(mservice.Ledger)} - oracleServiceNames = []string{"FX_ORACLE", string(mservice.FXOracle)} - mntxServiceNames = []string{discovery.RailCardPayout, string(mservice.MntxGateway)} - feesRequiredOps = []string{discovery.OperationFeeCalc} ledgerRequiredOps = discovery.LedgerServiceOperations() oracleRequiredOps = []string{discovery.OperationFXQuote} - mntxRequiredOps = discovery.CardPayoutRailGatewayOperations() ) type discoveryEndpoint struct { @@ -64,9 +57,6 @@ type discoveryClientResolver struct { oracleClient oracleclient.Client oracleEndpoint discoveryEndpoint - mntxClient mntxclient.Client - mntxEndpoint discoveryEndpoint - chainClients map[string]chainclient.Client lastSelection map[string]string @@ -101,10 +91,6 @@ func (r *discoveryClientResolver) Close() { _ = r.oracleClient.Close() r.oracleClient = nil } - if r.mntxClient != nil { - _ = r.mntxClient.Close() - r.mntxClient = nil - } for key, client := range r.chainClients { if client != nil { _ = client.Close() @@ -114,27 +100,22 @@ func (r *discoveryClientResolver) Close() { } func (r *discoveryClientResolver) FeesAvailable() bool { - _, ok := r.findEntry("fees", feesServiceNames, "", "", feesRequiredOps) + _, ok := r.findEntry(mservice.BillingFees, "", "", feesRequiredOps) return ok } func (r *discoveryClientResolver) LedgerAvailable() bool { - _, ok := r.findEntry("ledger", ledgerServiceNames, "", "", ledgerRequiredOps) + _, ok := r.findEntry(mservice.Ledger, "", "", ledgerRequiredOps) return ok } func (r *discoveryClientResolver) OracleAvailable() bool { - _, ok := r.findEntry("oracle", oracleServiceNames, "", "", oracleRequiredOps) - return ok -} - -func (r *discoveryClientResolver) MntxAvailable() bool { - _, ok := r.findEntry("mntx", mntxServiceNames, "", "", mntxRequiredOps) + _, ok := r.findEntry(mservice.FXOracle, "", "", oracleRequiredOps) return ok } func (r *discoveryClientResolver) FeesClient(ctx context.Context) (feesv1.FeeEngineClient, error) { - entry, ok := r.findEntry("fees", feesServiceNames, "", "", feesRequiredOps) + entry, ok := r.findEntry(mservice.BillingFees, "", "", feesRequiredOps) if !ok { return nil, merrors.NoData("discovery: fees service unavailable") } @@ -154,7 +135,7 @@ func (r *discoveryClientResolver) FeesClient(ctx context.Context) (feesv1.FeeEng } conn, dialErr := dialGrpc(ctx, endpoint) if dialErr != nil { - r.logMissing("fees", "failed to dial fees service", endpoint.raw, dialErr) + r.logMissing("fees", "Failed to dial fees service", endpoint.raw, dialErr) return nil, dialErr } r.feesConn = conn @@ -165,13 +146,13 @@ func (r *discoveryClientResolver) FeesClient(ctx context.Context) (feesv1.FeeEng } func (r *discoveryClientResolver) LedgerClient(ctx context.Context) (ledgerclient.Client, error) { - entry, ok := r.findEntry("ledger", ledgerServiceNames, "", "", ledgerRequiredOps) + entry, ok := r.findEntry(mservice.Ledger, "", "", ledgerRequiredOps) if !ok { return nil, merrors.NoData("discovery: ledger service unavailable") } endpoint, err := parseDiscoveryEndpoint(entry.InvokeURI) if err != nil { - r.logMissing("ledger", "invalid ledger invoke uri", entry.InvokeURI, err) + r.logMissing("ledger", "Invalid ledger invoke uri", entry.InvokeURI, err) return nil, err } @@ -188,7 +169,7 @@ func (r *discoveryClientResolver) LedgerClient(ctx context.Context) (ledgerclien Insecure: endpoint.insecure, }) if dialErr != nil { - r.logMissing("ledger", "failed to dial ledger service", endpoint.raw, dialErr) + r.logMissing("ledger", "Failed to dial ledger service", endpoint.raw, dialErr) return nil, dialErr } r.ledgerClient = client @@ -199,13 +180,13 @@ func (r *discoveryClientResolver) LedgerClient(ctx context.Context) (ledgerclien } func (r *discoveryClientResolver) OracleClient(ctx context.Context) (oracleclient.Client, error) { - entry, ok := r.findEntry("oracle", oracleServiceNames, "", "", oracleRequiredOps) + entry, ok := r.findEntry(mservice.FXOracle, "", "", oracleRequiredOps) if !ok { return nil, merrors.NoData("discovery: oracle service unavailable") } endpoint, err := parseDiscoveryEndpoint(entry.InvokeURI) if err != nil { - r.logMissing("oracle", "invalid oracle invoke uri", entry.InvokeURI, err) + r.logMissing("oracle", "Invalid oracle invoke uri", entry.InvokeURI, err) return nil, err } @@ -222,7 +203,7 @@ func (r *discoveryClientResolver) OracleClient(ctx context.Context) (oracleclien Insecure: endpoint.insecure, }) if dialErr != nil { - r.logMissing("oracle", "failed to dial oracle service", endpoint.raw, dialErr) + r.logMissing("oracle", "Failed to dial oracle service", endpoint.raw, dialErr) return nil, dialErr } r.oracleClient = client @@ -232,47 +213,10 @@ func (r *discoveryClientResolver) OracleClient(ctx context.Context) (oracleclien return r.oracleClient, nil } -func (r *discoveryClientResolver) MntxClient(ctx context.Context) (mntxclient.Client, error) { - entry, ok := r.findEntry("mntx", mntxServiceNames, "", "", mntxRequiredOps) - if !ok { - return nil, merrors.NoData("discovery: mntx service unavailable") - } - endpoint, err := parseDiscoveryEndpoint(entry.InvokeURI) - if err != nil { - r.logMissing("mntx", "invalid mntx invoke uri", entry.InvokeURI, err) - return nil, err - } - - r.mu.Lock() - defer r.mu.Unlock() - - if r.mntxClient == nil || r.mntxEndpoint.key() != endpoint.key() || r.mntxEndpoint.address != endpoint.address { - if r.mntxClient != nil { - _ = r.mntxClient.Close() - r.mntxClient = nil - } - if !endpoint.insecure && r.logger != nil { - r.logger.Warn("Mntx gateway does not support TLS, falling back to insecure transport", - zap.String("invoke_uri", endpoint.raw)) - } - client, dialErr := mntxclient.New(ctx, mntxclient.Config{ - Address: endpoint.address, - }) - if dialErr != nil { - r.logMissing("mntx", "failed to dial mntx service", endpoint.raw, dialErr) - return nil, dialErr - } - r.mntxClient = client - r.mntxEndpoint = endpoint - } - - return r.mntxClient, nil -} - func (r *discoveryClientResolver) ChainClient(ctx context.Context, invokeURI string) (chainclient.Client, error) { endpoint, err := parseDiscoveryEndpoint(invokeURI) if err != nil { - r.logMissing("chain", "invalid chain gateway invoke uri", invokeURI, err) + r.logMissing("chain", "Invalid chain gateway invoke uri", invokeURI, err) return nil, err } @@ -288,7 +232,7 @@ func (r *discoveryClientResolver) ChainClient(ctx context.Context, invokeURI str Insecure: endpoint.insecure, }) if dialErr != nil { - r.logMissing("chain", "failed to dial chain gateway", endpoint.raw, dialErr) + r.logMissing("chain", "Failed to dial chain gateway", endpoint.raw, dialErr) return nil, dialErr } r.chainClients[endpoint.key()] = client @@ -298,7 +242,7 @@ func (r *discoveryClientResolver) ChainClient(ctx context.Context, invokeURI str func (r *discoveryClientResolver) PaymentGatewayClient(ctx context.Context, invokeURI string) (chainclient.Client, error) { endpoint, err := parseDiscoveryEndpoint(invokeURI) if err != nil { - r.logMissing("payment_gateway", "invalid payment gateway invoke uri", invokeURI, err) + r.logMissing("payment_gateway", "Invalid payment gateway invoke uri", invokeURI, err) return nil, err } @@ -314,16 +258,18 @@ func (r *discoveryClientResolver) PaymentGatewayClient(ctx context.Context, invo Insecure: endpoint.insecure, }) if dialErr != nil { - r.logMissing("payment_gateway", "failed to dial payment gateway", endpoint.raw, dialErr) + r.logMissing("payment_gateway", "Failed to dial payment gateway", endpoint.raw, dialErr) return nil, dialErr } r.chainClients[endpoint.key()] = client return client, nil } -func (r *discoveryClientResolver) findEntry(key string, services []string, rail string, network string, requiredOps []string) (*discovery.RegistryEntry, bool) { +func (r *discoveryClientResolver) findEntry(service mservice.Type, rail string, network string, requiredOps []string) (*discovery.RegistryEntry, bool) { + key := discoverySelectionKey(service, rail, network) + if r == nil || r.registry == nil { - r.logMissing(key, "discovery registry unavailable", "", nil) + r.logMissing(key, "Discovery registry unavailable", "", nil) return nil, false } @@ -335,7 +281,7 @@ func (r *discoveryClientResolver) findEntry(key string, services []string, rail entries := r.registry.List(time.Now(), true) matches := make([]discoveryMatch, 0) for _, entry := range entries { - if !matchesService(entry.Service, services) { + if service != "" && !matchesService(entry.Service, service) { continue } if rail != "" && !strings.EqualFold(strings.TrimSpace(entry.Rail), rail) { @@ -351,7 +297,7 @@ func (r *discoveryClientResolver) findEntry(key string, services []string, rail } if len(matches) == 0 { - r.logMissing(key, "discovery entry missing", "", nil) + r.logMissing(key, "Discovery entry missing", "", nil) return nil, false } @@ -374,6 +320,27 @@ func (r *discoveryClientResolver) findEntry(key string, services []string, rail return &entry, true } +func discoverySelectionKey(service mservice.Type, rail, network string) string { + serviceName := strings.TrimSpace(string(service)) + railName := strings.ToUpper(strings.TrimSpace(rail)) + networkName := strings.ToUpper(strings.TrimSpace(network)) + + switch { + case serviceName != "" && railName != "" && networkName != "": + return fmt.Sprintf("%s|%s|%s", serviceName, railName, networkName) + case serviceName != "" && railName != "": + return fmt.Sprintf("%s|%s", serviceName, railName) + case serviceName != "": + return serviceName + case railName != "" && networkName != "": + return fmt.Sprintf("rail:%s|%s", railName, networkName) + case railName != "": + return "rail:" + railName + default: + return "discovery" + } +} + func (r *discoveryClientResolver) logSelection(key, entryKey string, entry discovery.RegistryEntry) { r.mu.Lock() last := r.lastSelection[key] @@ -423,17 +390,12 @@ func discoveryEntryKey(entry discovery.RegistryEntry) string { strings.TrimSpace(entry.InvokeURI)) } -func matchesService(service string, candidates []string) bool { +func matchesService(service string, candidate mservice.Type) bool { service = strings.TrimSpace(service) - if service == "" || len(candidates) == 0 { + if service == "" || strings.TrimSpace(string(candidate)) == "" { return false } - for _, candidate := range candidates { - if strings.EqualFold(service, strings.TrimSpace(candidate)) { - return true - } - } - return false + return strings.EqualFold(service, strings.TrimSpace(string(candidate))) } func parseDiscoveryEndpoint(raw string) (discoveryEndpoint, error) { diff --git a/api/payments/orchestrator/internal/server/internal/discovery_wrappers.go b/api/payments/orchestrator/internal/server/internal/discovery_wrappers.go index d7816328..c80c5406 100644 --- a/api/payments/orchestrator/internal/server/internal/discovery_wrappers.go +++ b/api/payments/orchestrator/internal/server/internal/discovery_wrappers.go @@ -11,7 +11,6 @@ import ( moneyv1 "github.com/tech/sendico/pkg/proto/common/money/v1" connectorv1 "github.com/tech/sendico/pkg/proto/connector/v1" chainv1 "github.com/tech/sendico/pkg/proto/gateway/chain/v1" - mntxv1 "github.com/tech/sendico/pkg/proto/gateway/mntx/v1" ledgerv1 "github.com/tech/sendico/pkg/proto/ledger/v1" "google.golang.org/grpc" ) @@ -247,60 +246,6 @@ func (c *discoveryOracleClient) Close() error { return client.Close() } -type discoveryMntxClient struct { - resolver *discoveryClientResolver -} - -func (c *discoveryMntxClient) Available() bool { - if c == nil || c.resolver == nil { - return false - } - return c.resolver.MntxAvailable() -} - -func (c *discoveryMntxClient) CreateCardPayout(ctx context.Context, req *mntxv1.CardPayoutRequest) (*mntxv1.CardPayoutResponse, error) { - client, err := c.resolver.MntxClient(ctx) - if err != nil { - return nil, err - } - return client.CreateCardPayout(ctx, req) -} - -func (c *discoveryMntxClient) CreateCardTokenPayout(ctx context.Context, req *mntxv1.CardTokenPayoutRequest) (*mntxv1.CardTokenPayoutResponse, error) { - client, err := c.resolver.MntxClient(ctx) - if err != nil { - return nil, err - } - return client.CreateCardTokenPayout(ctx, req) -} - -func (c *discoveryMntxClient) GetCardPayoutStatus(ctx context.Context, req *mntxv1.GetCardPayoutStatusRequest) (*mntxv1.GetCardPayoutStatusResponse, error) { - client, err := c.resolver.MntxClient(ctx) - if err != nil { - return nil, err - } - return client.GetCardPayoutStatus(ctx, req) -} - -func (c *discoveryMntxClient) ListGatewayInstances(ctx context.Context, req *mntxv1.ListGatewayInstancesRequest) (*mntxv1.ListGatewayInstancesResponse, error) { - client, err := c.resolver.MntxClient(ctx) - if err != nil { - return nil, err - } - return client.ListGatewayInstances(ctx, req) -} - -func (c *discoveryMntxClient) Close() error { - if c == nil || c.resolver == nil { - return nil - } - client, err := c.resolver.MntxClient(context.Background()) - if err != nil { - return nil - } - return client.Close() -} - type discoveryChainClient struct { resolver *discoveryClientResolver invokeURI string diff --git a/api/payments/orchestrator/internal/service/orchestrator/card_payout_executor.go b/api/payments/orchestrator/internal/service/orchestrator/card_payout_executor.go index 2b2fe5ec..85639ca5 100644 --- a/api/payments/orchestrator/internal/service/orchestrator/card_payout_executor.go +++ b/api/payments/orchestrator/internal/service/orchestrator/card_payout_executor.go @@ -3,8 +3,11 @@ package orchestrator import ( "context" "github.com/tech/sendico/pkg/discovery" + "net" + "net/url" "strconv" "strings" + "sync" "github.com/shopspring/decimal" mntxclient "github.com/tech/sendico/gateway/mntx/client" @@ -20,7 +23,12 @@ import ( ) type gatewayCardPayoutExecutor struct { - mntxClient mntxclient.Client + gatewayRegistry GatewayRegistry + + mu sync.Mutex + clients map[string]mntxclient.Client + + dialClient func(ctx context.Context, address string) (mntxclient.Client, error) } type cardPayoutCustomer struct { @@ -40,12 +48,20 @@ func (e *gatewayCardPayoutExecutor) ExecuteCardPayout(ctx context.Context, req s if req.Payment == nil { return nil, merrors.InvalidArgument("card payout send: payment is required") } - if e == nil || e.mntxClient == nil { - return nil, merrors.InvalidArgument("card payout send: mntx client is required") + if e == nil || e.gatewayRegistry == nil { + return nil, merrors.InvalidArgument("card payout send: gateway registry is required") } if model.ParseRailOperation(string(req.Step.Action)) != discovery.RailOperationSend { return nil, merrors.InvalidArgument("card payout send: unsupported action") } + gateway, err := e.resolveGateway(ctx, req.Step) + if err != nil { + return nil, err + } + client, err := e.client(ctx, strings.TrimSpace(gateway.InvokeURI)) + if err != nil { + return nil, err + } card, err := payoutDestinationCard(req.Payment, req.Step.Metadata) if err != nil { @@ -68,7 +84,7 @@ func (e *gatewayCardPayoutExecutor) ExecuteCardPayout(ctx context.Context, req s var responsePayout *mntxv1.CardPayoutState if token := strings.TrimSpace(card.Token); token != "" { - resp, createErr := e.mntxClient.CreateCardTokenPayout(ctx, &mntxv1.CardTokenPayoutRequest{ + resp, createErr := client.CreateCardTokenPayout(ctx, &mntxv1.CardTokenPayoutRequest{ PayoutId: payoutRef, ProjectId: projectID, CustomerId: customer.id, @@ -106,7 +122,7 @@ func (e *gatewayCardPayoutExecutor) ExecuteCardPayout(ctx context.Context, req s if card.ExpMonth == 0 || card.ExpYear == 0 { return nil, merrors.InvalidArgument("card payout send: card expiry is required") } - resp, createErr := e.mntxClient.CreateCardPayout(ctx, &mntxv1.CardPayoutRequest{ + resp, createErr := client.CreateCardPayout(ctx, &mntxv1.CardPayoutRequest{ PayoutId: payoutRef, ProjectId: projectID, CustomerId: customer.id, @@ -141,7 +157,12 @@ func (e *gatewayCardPayoutExecutor) ExecuteCardPayout(ctx context.Context, req s resolvedPayoutRef := firstNonEmpty(strings.TrimSpace(responsePayout.GetPayoutId()), payoutRef) resolvedOperationRef := firstNonEmpty(strings.TrimSpace(responsePayout.GetOperationRef()), operationRef) - gatewayInstanceID := firstNonEmpty(strings.TrimSpace(req.Step.InstanceID), strings.TrimSpace(req.Step.Gateway)) + gatewayInstanceID := firstNonEmpty( + strings.TrimSpace(req.Step.InstanceID), + strings.TrimSpace(gateway.InstanceID), + strings.TrimSpace(req.Step.Gateway), + strings.TrimSpace(gateway.ID), + ) externalRefs, refsErr := cardPayoutExternalRefs(resolvedPayoutRef, resolvedOperationRef, gatewayInstanceID) if refsErr != nil { return nil, refsErr @@ -155,6 +176,122 @@ func (e *gatewayCardPayoutExecutor) ExecuteCardPayout(ctx context.Context, req s return &sexec.ExecuteOutput{StepExecution: step}, nil } +func (e *gatewayCardPayoutExecutor) resolveGateway(ctx context.Context, step xplan.Step) (*model.GatewayInstanceDescriptor, error) { + if e.gatewayRegistry == nil { + return nil, merrors.InvalidArgument("card payout send: gateway registry is required") + } + items, err := e.gatewayRegistry.List(ctx) + if err != nil { + return nil, err + } + + stepGateway := strings.TrimSpace(step.Gateway) + stepInstance := strings.TrimSpace(step.InstanceID) + + var byInstance *model.GatewayInstanceDescriptor + var byGateway *model.GatewayInstanceDescriptor + var single *model.GatewayInstanceDescriptor + cardCount := 0 + for i := range items { + item := items[i] + if item == nil || model.ParseRail(string(item.Rail)) != discovery.RailCardPayout || !item.IsEnabled { + continue + } + cardCount++ + single = item + if stepInstance != "" && (strings.EqualFold(strings.TrimSpace(item.InstanceID), stepInstance) || strings.EqualFold(strings.TrimSpace(item.ID), stepInstance)) { + byInstance = item + break + } + if stepGateway != "" && (strings.EqualFold(strings.TrimSpace(item.ID), stepGateway) || strings.EqualFold(strings.TrimSpace(item.InstanceID), stepGateway)) { + byGateway = item + } + } + + switch { + case byInstance != nil: + if strings.TrimSpace(byInstance.InvokeURI) == "" { + return nil, merrors.InvalidArgument("card payout send: gateway invoke uri is missing") + } + return byInstance, nil + case byGateway != nil: + if strings.TrimSpace(byGateway.InvokeURI) == "" { + return nil, merrors.InvalidArgument("card payout send: gateway invoke uri is missing") + } + return byGateway, nil + case stepGateway == "" && stepInstance == "" && cardCount == 1: + if strings.TrimSpace(single.InvokeURI) == "" { + return nil, merrors.InvalidArgument("card payout send: gateway invoke uri is missing") + } + return single, nil + default: + return nil, merrors.InvalidArgument("card payout send: gateway instance not found") + } +} + +func (e *gatewayCardPayoutExecutor) client(ctx context.Context, invokeURI string) (mntxclient.Client, error) { + address, err := parseGatewayAddress(invokeURI) + if err != nil { + return nil, err + } + + e.mu.Lock() + defer e.mu.Unlock() + + if e.clients == nil { + e.clients = map[string]mntxclient.Client{} + } + if c := e.clients[address]; c != nil { + return c, nil + } + + dial := e.dialClient + if dial == nil { + dial = func(ctx context.Context, address string) (mntxclient.Client, error) { + return mntxclient.New(ctx, mntxclient.Config{Address: address}) + } + } + + client, dialErr := dial(ctx, address) + if dialErr != nil { + return nil, dialErr + } + e.clients[address] = client + return client, nil +} + +func parseGatewayAddress(raw string) (string, error) { + raw = strings.TrimSpace(raw) + if raw == "" { + return "", merrors.InvalidArgument("card payout send: gateway invoke uri is required") + } + + if !strings.Contains(raw, "://") { + if _, _, splitErr := net.SplitHostPort(raw); splitErr != nil { + return "", merrors.InvalidArgument("card payout send: gateway invoke uri must include host:port") + } + return raw, nil + } + + parsed, err := url.Parse(raw) + if err != nil || parsed.Scheme == "" { + return "", merrors.InvalidArgument("card payout send: gateway invoke uri must include host:port") + } + + switch strings.ToLower(strings.TrimSpace(parsed.Scheme)) { + case "grpc", "grpcs": + address := strings.TrimSpace(parsed.Host) + if _, _, splitErr := net.SplitHostPort(address); splitErr != nil { + return "", merrors.InvalidArgument("card payout send: gateway invoke uri must include host:port") + } + return address, nil + case "dns", "passthrough": + return raw, nil + default: + return "", merrors.InvalidArgument("card payout send: unsupported gateway invoke uri scheme") + } +} + func payoutDestinationCard(payment *agg.Payment, metadata map[string]string) (*model.CardEndpoint, error) { if card, ok := batchmeta.CardFromMetadata(metadata); ok && card != nil { return card, nil diff --git a/api/payments/orchestrator/internal/service/orchestrator/card_payout_executor_test.go b/api/payments/orchestrator/internal/service/orchestrator/card_payout_executor_test.go index a834ee56..bcaecfd6 100644 --- a/api/payments/orchestrator/internal/service/orchestrator/card_payout_executor_test.go +++ b/api/payments/orchestrator/internal/service/orchestrator/card_payout_executor_test.go @@ -23,17 +23,32 @@ func TestGatewayCardPayoutExecutor_ExecuteCardPayout_SubmitsCardPayout(t *testin orgID := bson.NewObjectID() var payoutReq *mntxv1.CardPayoutRequest + var dialAddress string executor := &gatewayCardPayoutExecutor{ - mntxClient: &mntxclient.Fake{ - CreateCardPayoutFn: func(_ context.Context, req *mntxv1.CardPayoutRequest) (*mntxv1.CardPayoutResponse, error) { - payoutReq = req - return &mntxv1.CardPayoutResponse{ - Payout: &mntxv1.CardPayoutState{ - PayoutId: "payout-remote-1", - }, - }, nil + gatewayRegistry: &fakeGatewayRegistry{ + items: []*model.GatewayInstanceDescriptor{ + { + ID: paymenttypes.DefaultCardsGatewayID, + InstanceID: paymenttypes.DefaultCardsGatewayID, + Rail: discovery.RailCardPayout, + InvokeURI: "grpc://mntx-gateway:50051", + IsEnabled: true, + }, }, }, + dialClient: func(_ context.Context, address string) (mntxclient.Client, error) { + dialAddress = address + return &mntxclient.Fake{ + CreateCardPayoutFn: func(_ context.Context, req *mntxv1.CardPayoutRequest) (*mntxv1.CardPayoutResponse, error) { + payoutReq = req + return &mntxv1.CardPayoutResponse{ + Payout: &mntxv1.CardPayoutState{ + PayoutId: "payout-remote-1", + }, + }, nil + }, + }, nil + }, } req := sexec.StepRequest{ @@ -104,6 +119,9 @@ func TestGatewayCardPayoutExecutor_ExecuteCardPayout_SubmitsCardPayout(t *testin if payoutReq == nil { t.Fatal("expected payout request to be submitted") } + if got, want := dialAddress, "mntx-gateway:50051"; got != want { + t.Fatalf("dial address mismatch: got=%q want=%q", got, want) + } if got, want := payoutReq.GetPayoutId(), "payment-1"; got != want { t.Fatalf("payout_id mismatch: got=%q want=%q", got, want) } @@ -146,17 +164,32 @@ func TestGatewayCardPayoutExecutor_ExecuteCardPayout_UsesStepMetadataOverrides(t orgID := bson.NewObjectID() var payoutReq *mntxv1.CardPayoutRequest + var dialAddress string executor := &gatewayCardPayoutExecutor{ - mntxClient: &mntxclient.Fake{ - CreateCardPayoutFn: func(_ context.Context, req *mntxv1.CardPayoutRequest) (*mntxv1.CardPayoutResponse, error) { - payoutReq = req - return &mntxv1.CardPayoutResponse{ - Payout: &mntxv1.CardPayoutState{ - PayoutId: "payout-remote-2", - }, - }, nil + gatewayRegistry: &fakeGatewayRegistry{ + items: []*model.GatewayInstanceDescriptor{ + { + ID: paymenttypes.DefaultCardsGatewayID, + InstanceID: paymenttypes.DefaultCardsGatewayID, + Rail: discovery.RailCardPayout, + InvokeURI: "grpc://mntx-gateway:50051", + IsEnabled: true, + }, }, }, + dialClient: func(_ context.Context, address string) (mntxclient.Client, error) { + dialAddress = address + return &mntxclient.Fake{ + CreateCardPayoutFn: func(_ context.Context, req *mntxv1.CardPayoutRequest) (*mntxv1.CardPayoutResponse, error) { + payoutReq = req + return &mntxv1.CardPayoutResponse{ + Payout: &mntxv1.CardPayoutState{ + PayoutId: "payout-remote-2", + }, + }, nil + }, + }, nil + }, } req := sexec.StepRequest{ @@ -221,6 +254,9 @@ func TestGatewayCardPayoutExecutor_ExecuteCardPayout_UsesStepMetadataOverrides(t if payoutReq == nil { t.Fatal("expected payout request to be submitted") } + if got, want := dialAddress, "mntx-gateway:50051"; got != want { + t.Fatalf("dial address mismatch: got=%q want=%q", got, want) + } if got, want := payoutReq.GetAmountMinor(), int64(15000); got != want { t.Fatalf("amount_minor mismatch: got=%d want=%d", got, want) } @@ -235,7 +271,7 @@ func TestGatewayCardPayoutExecutor_ExecuteCardPayout_UsesStepMetadataOverrides(t } } -func TestGatewayCardPayoutExecutor_ExecuteCardPayout_RequiresMntxClient(t *testing.T) { +func TestGatewayCardPayoutExecutor_ExecuteCardPayout_RequiresGatewayRegistry(t *testing.T) { orgID := bson.NewObjectID() executor := &gatewayCardPayoutExecutor{} @@ -270,7 +306,7 @@ func TestGatewayCardPayoutExecutor_ExecuteCardPayout_RequiresMntxClient(t *testi if err == nil { t.Fatal("expected error") } - if !strings.Contains(err.Error(), "mntx client is required") { + if !strings.Contains(err.Error(), "gateway registry is required") { t.Fatalf("unexpected error: %v", err) } } diff --git a/api/payments/orchestrator/internal/service/orchestrator/options.go b/api/payments/orchestrator/internal/service/orchestrator/options.go index c44ba466..b9eec828 100644 --- a/api/payments/orchestrator/internal/service/orchestrator/options.go +++ b/api/payments/orchestrator/internal/service/orchestrator/options.go @@ -6,7 +6,6 @@ import ( "time" chainclient "github.com/tech/sendico/gateway/chain/client" - mntxclient "github.com/tech/sendico/gateway/mntx/client" ledgerclient "github.com/tech/sendico/ledger/client" "github.com/tech/sendico/payments/storage/model" clockpkg "github.com/tech/sendico/pkg/clock" @@ -54,16 +53,6 @@ func WithLedgerClient(client ledgerclient.Client) Option { } } -// WithMntxGateway configures card payout execution for card-bound steps. -func WithMntxGateway(client mntxclient.Client) Option { - return func(s *Service) { - if s == nil { - return - } - s.mntxClient = client - } -} - // WithPaymentGatewayBroker wires broker subscription for payment gateway execution events. func WithPaymentGatewayBroker(broker mb.Broker) Option { return func(s *Service) { diff --git a/api/payments/orchestrator/internal/service/orchestrator/service.go b/api/payments/orchestrator/internal/service/orchestrator/service.go index 634f7554..10116f2b 100644 --- a/api/payments/orchestrator/internal/service/orchestrator/service.go +++ b/api/payments/orchestrator/internal/service/orchestrator/service.go @@ -3,7 +3,6 @@ package orchestrator import ( "context" - mntxclient "github.com/tech/sendico/gateway/mntx/client" ledgerclient "github.com/tech/sendico/ledger/client" "github.com/tech/sendico/payments/orchestrator/internal/service/orchestrationv2/prepo" "github.com/tech/sendico/payments/orchestrator/internal/service/orchestrationv2/psvc" @@ -26,7 +25,6 @@ type Service struct { producer msg.Producer ledgerClient ledgerclient.Client - mntxClient mntxclient.Client gatewayInvokeResolver GatewayInvokeResolver gatewayRegistry GatewayRegistry cardGatewayRoutes map[string]CardGatewayRoute @@ -56,7 +54,6 @@ func NewService(logger mlogger.Logger, repo storage.Repository, producer msg.Pro var err error svc.v2, svc.paymentRepo, err = newOrchestrationV2Service(svc.logger, repo, v2RuntimeDeps{ LedgerClient: svc.ledgerClient, - MntxClient: svc.mntxClient, GatewayInvokeResolver: svc.gatewayInvokeResolver, GatewayRegistry: svc.gatewayRegistry, CardGatewayRoutes: svc.cardGatewayRoutes, diff --git a/api/payments/orchestrator/internal/service/orchestrator/service_v2.go b/api/payments/orchestrator/internal/service/orchestrator/service_v2.go index 96aa7912..95233f1e 100644 --- a/api/payments/orchestrator/internal/service/orchestrator/service_v2.go +++ b/api/payments/orchestrator/internal/service/orchestrator/service_v2.go @@ -3,7 +3,6 @@ package orchestrator import ( "context" - mntxclient "github.com/tech/sendico/gateway/mntx/client" ledgerclient "github.com/tech/sendico/ledger/client" "github.com/tech/sendico/payments/orchestrator/internal/service/orchestrationv2/oobs" "github.com/tech/sendico/payments/orchestrator/internal/service/orchestrationv2/pquery" @@ -27,7 +26,6 @@ type v2MongoDBProvider interface { type v2RuntimeDeps struct { LedgerClient ledgerclient.Client - MntxClient mntxclient.Client GatewayInvokeResolver GatewayInvokeResolver GatewayRegistry GatewayRegistry CardGatewayRoutes map[string]CardGatewayRoute @@ -114,9 +112,9 @@ func buildOrchestrationV2Executors(logger mlogger.Logger, runtimeDeps v2RuntimeD ledgerClient: runtimeDeps.LedgerClient, } var cardPayoutExecutor sexec.CardPayoutExecutor - if runtimeDeps.MntxClient != nil { + if runtimeDeps.GatewayRegistry != nil { cardPayoutExecutor = &gatewayCardPayoutExecutor{ - mntxClient: runtimeDeps.MntxClient, + gatewayRegistry: runtimeDeps.GatewayRegistry, } } return psvc.NewDefaultExecutors(execLogger, sexec.Dependencies{ diff --git a/api/payments/quotation/internal/server/internal/discovery.go b/api/payments/quotation/internal/server/internal/discovery.go index ad80b257..4944ce15 100644 --- a/api/payments/quotation/internal/server/internal/discovery.go +++ b/api/payments/quotation/internal/server/internal/discovery.go @@ -6,6 +6,7 @@ import ( "github.com/tech/sendico/payments/quotation/internal/appversion" "github.com/tech/sendico/pkg/discovery" msg "github.com/tech/sendico/pkg/messaging" + "github.com/tech/sendico/pkg/mservice" "go.uber.org/zap" ) @@ -51,7 +52,7 @@ func (i *Imp) startDiscoveryAnnouncer(cfg *config, producer msg.Producer) { } announce := discovery.Announcement{ - Service: "PAYMENTS_QUOTATION", + Service: mservice.PaymentQuotation, Operations: []string{discovery.OperationPaymentQuote, discovery.OperationPaymentMultiQuote}, InvokeURI: invokeURI, Version: appversion.Create().Short(), diff --git a/api/pkg/discovery/types.go b/api/pkg/discovery/types.go index 76f9a91b..95bd87f9 100644 --- a/api/pkg/discovery/types.go +++ b/api/pkg/discovery/types.go @@ -1,5 +1,7 @@ package discovery +import "github.com/tech/sendico/pkg/mservice" + type HealthParams struct { IntervalSec int `json:"intervalSec"` TimeoutSec int `json:"timeoutSec"` @@ -103,7 +105,7 @@ type CurrencyAnnouncement struct { type Announcement struct { ID string `json:"id"` InstanceID string `bson:"instanceId" json:"instanceId"` - Service string `json:"service"` + Service mservice.Type `json:"service"` Rail string `json:"rail,omitempty"` Operations []string `json:"operations,omitempty"` Currencies []CurrencyAnnouncement `json:"currencies,omitempty"` diff --git a/api/pkg/mservice/services.go b/api/pkg/mservice/services.go index 04349df9..8e54fef7 100644 --- a/api/pkg/mservice/services.go +++ b/api/pkg/mservice/services.go @@ -16,8 +16,10 @@ const ( MntxGateway Type = "mntx_gateway" // Represents Monetix gateway microservice PaymentGateway Type = "payment_gateway" // Represents payment gateway microservice FXOracle Type = "fx_oracle" // Represents FX oracle microservice + FXIngestor Type = "fx_ingestor" // Represents FX ingestor microservice FeePlans Type = "fee_plans" // Represents fee plans microservice BillingDocuments Type = "billing_documents" // Represents billing documents microservice + BillingFees Type = "billing_fees" // Represents billing fees microservice FilterProjects Type = "filter_projects" // Represents comments on tasks or other resources Invitations Type = "invitations" // Represents invitations sent to users Invoices Type = "invoices" // Represents invoices @@ -30,6 +32,7 @@ const ( LedgerParties Type = "ledger_parties" // Represents ledger account owner parties microservice LedgerPlines Type = "ledger_posting_lines" // Represents ledger journal posting lines microservice PaymentOrchestrator Type = "payment_orchestrator" // Represents payment orchestration microservice + PaymentQuotation Type = "payment_quotation" // Represents payment quotation microservice ChainAssets Type = "chain_assets" // Represents managed chain assets ChainWallets Type = "chain_wallets" // Represents managed chain wallets ChainWalletBalances Type = "chain_wallet_balances" // Represents managed chain wallet balances @@ -49,6 +52,7 @@ const ( 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 + TronGateway Type = "tron_gateway" // Represents tron gateway microservice Tenants Type = "tenants" // Represents tenants managed in the system VerificationTokens Type = "verification_tokens" //Represents verification tokens managed in the system Wallets Type = "wallets" // Represents workflows for tasks or projects