Fully separated payment quotation and orchestration flows
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
package plan
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/tech/sendico/payments/storage/model"
|
||||
"github.com/tech/sendico/pkg/merrors"
|
||||
)
|
||||
|
||||
func resolveRouteNetwork(attrs map[string]string, sourceNetwork, destNetwork string) (string, error) {
|
||||
src := strings.ToUpper(strings.TrimSpace(sourceNetwork))
|
||||
dst := strings.ToUpper(strings.TrimSpace(destNetwork))
|
||||
if src != "" && dst != "" && !strings.EqualFold(src, dst) {
|
||||
return "", merrors.InvalidArgument("plan builder: source and destination networks mismatch")
|
||||
}
|
||||
|
||||
override := strings.ToUpper(strings.TrimSpace(attributeLookup(attrs,
|
||||
"network",
|
||||
"route_network",
|
||||
"routeNetwork",
|
||||
"source_network",
|
||||
"sourceNetwork",
|
||||
"destination_network",
|
||||
"destinationNetwork",
|
||||
)))
|
||||
if override != "" {
|
||||
if src != "" && !strings.EqualFold(src, override) {
|
||||
return "", merrors.InvalidArgument("plan builder: source network does not match override")
|
||||
}
|
||||
if dst != "" && !strings.EqualFold(dst, override) {
|
||||
return "", merrors.InvalidArgument("plan builder: destination network does not match override")
|
||||
}
|
||||
return override, nil
|
||||
}
|
||||
if src != "" {
|
||||
return src, nil
|
||||
}
|
||||
if dst != "" {
|
||||
return dst, nil
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func selectRoute(ctx context.Context, routes RouteStore, sourceRail, destRail model.Rail, network string) (*model.PaymentRoute, error) {
|
||||
if routes == nil {
|
||||
return nil, merrors.InvalidArgument("plan builder: routes store is required")
|
||||
}
|
||||
enabled := true
|
||||
result, err := routes.List(ctx, &model.PaymentRouteFilter{
|
||||
FromRail: sourceRail,
|
||||
ToRail: destRail,
|
||||
Network: "",
|
||||
IsEnabled: &enabled,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if result == nil || len(result.Items) == 0 {
|
||||
return nil, merrors.InvalidArgument("plan builder: route not allowed")
|
||||
}
|
||||
candidates := make([]*model.PaymentRoute, 0, len(result.Items))
|
||||
for _, route := range result.Items {
|
||||
if route == nil || !route.IsEnabled {
|
||||
continue
|
||||
}
|
||||
if route.FromRail != sourceRail || route.ToRail != destRail {
|
||||
continue
|
||||
}
|
||||
if !routeMatchesNetwork(route, network) {
|
||||
continue
|
||||
}
|
||||
candidates = append(candidates, route)
|
||||
}
|
||||
if len(candidates) == 0 {
|
||||
return nil, merrors.InvalidArgument("plan builder: route not allowed")
|
||||
}
|
||||
sort.Slice(candidates, func(i, j int) bool {
|
||||
pi := routePriority(candidates[i], network)
|
||||
pj := routePriority(candidates[j], network)
|
||||
if pi != pj {
|
||||
return pi < pj
|
||||
}
|
||||
if candidates[i].Network != candidates[j].Network {
|
||||
return candidates[i].Network < candidates[j].Network
|
||||
}
|
||||
return candidates[i].ID.Hex() < candidates[j].ID.Hex()
|
||||
})
|
||||
return candidates[0], nil
|
||||
}
|
||||
|
||||
func routeMatchesNetwork(route *model.PaymentRoute, network string) bool {
|
||||
if route == nil {
|
||||
return false
|
||||
}
|
||||
routeNetwork := strings.ToUpper(strings.TrimSpace(route.Network))
|
||||
net := strings.ToUpper(strings.TrimSpace(network))
|
||||
if routeNetwork == "" {
|
||||
return true
|
||||
}
|
||||
if net == "" {
|
||||
return false
|
||||
}
|
||||
return strings.EqualFold(routeNetwork, net)
|
||||
}
|
||||
|
||||
func routePriority(route *model.PaymentRoute, network string) int {
|
||||
if route == nil {
|
||||
return 2
|
||||
}
|
||||
routeNetwork := strings.ToUpper(strings.TrimSpace(route.Network))
|
||||
net := strings.ToUpper(strings.TrimSpace(network))
|
||||
if net != "" && strings.EqualFold(routeNetwork, net) {
|
||||
return 0
|
||||
}
|
||||
if routeNetwork == "" {
|
||||
return 1
|
||||
}
|
||||
return 2
|
||||
}
|
||||
Reference in New Issue
Block a user