174 lines
4.8 KiB
Go
174 lines
4.8 KiB
Go
package discovery
|
|
|
|
import "strings"
|
|
|
|
const (
|
|
RailCrypto = "CRYPTO"
|
|
RailProviderSettlement = "SETTLEMENT"
|
|
RailLedger = "LEDGER"
|
|
RailCardPayout = "CARD"
|
|
RailFiatOnRamp = "ONRAMP"
|
|
)
|
|
|
|
const (
|
|
RailOperationDebit = "DEBIT"
|
|
RailOperationCredit = "CREDIT"
|
|
RailOperationExternalDebit = "EXTERNAL_DEBIT"
|
|
RailOperationExternalCredit = "EXTERNAL_CREDIT"
|
|
RailOperationMove = "MOVE"
|
|
RailOperationSend = "SEND"
|
|
RailOperationFee = "FEE"
|
|
RailOperationObserveConfirm = "OBSERVE_CONFIRM"
|
|
RailOperationFXConvert = "FX_CONVERT"
|
|
RailOperationBlock = "BLOCK"
|
|
RailOperationRelease = "RELEASE"
|
|
)
|
|
|
|
var knownRails = map[string]struct{}{
|
|
RailCrypto: {},
|
|
RailProviderSettlement: {},
|
|
RailLedger: {},
|
|
RailCardPayout: {},
|
|
RailFiatOnRamp: {},
|
|
}
|
|
|
|
var knownRailOperations = map[string]struct{}{
|
|
RailOperationDebit: {},
|
|
RailOperationCredit: {},
|
|
RailOperationExternalDebit: {},
|
|
RailOperationExternalCredit: {},
|
|
RailOperationMove: {},
|
|
RailOperationSend: {},
|
|
RailOperationFee: {},
|
|
RailOperationObserveConfirm: {},
|
|
RailOperationFXConvert: {},
|
|
RailOperationBlock: {},
|
|
RailOperationRelease: {},
|
|
}
|
|
|
|
// NormalizeRail canonicalizes a rail token.
|
|
func NormalizeRail(value string) string {
|
|
clean := strings.ToUpper(strings.TrimSpace(value))
|
|
if clean == "" {
|
|
return ""
|
|
}
|
|
clean = strings.ReplaceAll(clean, "-", "_")
|
|
clean = strings.ReplaceAll(clean, " ", "_")
|
|
for strings.Contains(clean, "__") {
|
|
clean = strings.ReplaceAll(clean, "__", "_")
|
|
}
|
|
|
|
switch clean {
|
|
case RailCrypto, "RAIL_CRYPTO":
|
|
return RailCrypto
|
|
case RailProviderSettlement, "PROVIDER_SETTLEMENT", "RAIL_SETTLEMENT", "RAIL_PROVIDER_SETTLEMENT":
|
|
return RailProviderSettlement
|
|
case RailLedger, "RAIL_LEDGER":
|
|
return RailLedger
|
|
case RailCardPayout, "CARD_PAYOUT", "RAIL_CARD", "RAIL_CARD_PAYOUT":
|
|
return RailCardPayout
|
|
case RailFiatOnRamp, "FIAT_ONRAMP", "RAIL_ONRAMP", "RAIL_FIAT_ONRAMP":
|
|
return RailFiatOnRamp
|
|
default:
|
|
return clean
|
|
}
|
|
}
|
|
|
|
// IsKnownRail reports whether the value is a recognized payment rail.
|
|
func IsKnownRail(value string) bool {
|
|
_, ok := knownRails[NormalizeRail(value)]
|
|
return ok
|
|
}
|
|
|
|
// NormalizeRailOperation canonicalizes a rail operation token.
|
|
func NormalizeRailOperation(value string) string {
|
|
clean := strings.ToUpper(strings.TrimSpace(value))
|
|
if after, ok := strings.CutPrefix(clean, "RAIL_OPERATION_"); ok {
|
|
clean = after
|
|
}
|
|
return clean
|
|
}
|
|
|
|
// IsKnownRailOperation reports whether the value is a recognized rail operation.
|
|
func IsKnownRailOperation(value string) bool {
|
|
_, ok := knownRailOperations[NormalizeRailOperation(value)]
|
|
return ok
|
|
}
|
|
|
|
// ExpandRailOperation maps canonical and legacy names to normalized rail operations.
|
|
func ExpandRailOperation(value string) []string {
|
|
if op := NormalizeRailOperation(value); op != "" {
|
|
if IsKnownRailOperation(op) {
|
|
return []string{op}
|
|
}
|
|
}
|
|
|
|
switch strings.ToLower(strings.TrimSpace(value)) {
|
|
case "payin", "payin.crypto", "payin.fiat", "payin.card":
|
|
return []string{RailOperationExternalDebit}
|
|
case "payout", "payout.crypto", "payout.fiat", "payout.card":
|
|
return []string{RailOperationExternalCredit, RailOperationSend}
|
|
case "fee.send", "fees.send":
|
|
return []string{RailOperationFee}
|
|
case "observe.confirm", "observe_confirm":
|
|
return []string{RailOperationObserveConfirm}
|
|
case "funds.block", "hold.balance", "block":
|
|
return []string{RailOperationBlock}
|
|
case "funds.release", "release", "unblock":
|
|
return []string{RailOperationRelease}
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// NormalizeRailOperations canonicalizes and deduplicates rail operation values.
|
|
func NormalizeRailOperations(values []string) []string {
|
|
if len(values) == 0 {
|
|
return nil
|
|
}
|
|
|
|
result := make([]string, 0, len(values))
|
|
seen := map[string]bool{}
|
|
for _, value := range values {
|
|
for _, op := range ExpandRailOperation(value) {
|
|
if op == "" || seen[op] {
|
|
continue
|
|
}
|
|
seen[op] = true
|
|
result = append(result, op)
|
|
}
|
|
}
|
|
if len(result) == 0 {
|
|
return nil
|
|
}
|
|
return result
|
|
}
|
|
|
|
// CryptoRailGatewayOperations returns canonical operations for crypto rail gateways.
|
|
func CryptoRailGatewayOperations() []string {
|
|
return []string{
|
|
RailOperationSend,
|
|
RailOperationExternalDebit,
|
|
RailOperationExternalCredit,
|
|
RailOperationFee,
|
|
RailOperationObserveConfirm,
|
|
}
|
|
}
|
|
|
|
// CardPayoutRailGatewayOperations returns canonical operations for card payout gateways.
|
|
func CardPayoutRailGatewayOperations() []string {
|
|
return []string{
|
|
RailOperationSend,
|
|
RailOperationExternalCredit,
|
|
RailOperationObserveConfirm,
|
|
}
|
|
}
|
|
|
|
// ProviderSettlementRailGatewayOperations returns canonical operations for settlement gateways.
|
|
func ProviderSettlementRailGatewayOperations() []string {
|
|
return []string{
|
|
RailOperationFXConvert,
|
|
RailOperationObserveConfirm,
|
|
}
|
|
}
|