142 lines
3.8 KiB
Go
142 lines
3.8 KiB
Go
package paymentkit
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/url"
|
|
"strings"
|
|
)
|
|
|
|
func NormalizeStatus(value, fallback string) string {
|
|
switch strings.ToUpper(strings.TrimSpace(value)) {
|
|
case "SUCCESS", "OK", "PAID", "FULFILLED", "TRADE_SUCCESS", "TRADE_FINISHED", "COMPLETED", "PAY_SUCCESS", "REFUND_SUCCESS", "REFUNDED":
|
|
return "success"
|
|
case "WAIT_BUYER_PAY", "USERPAYING", "NOTPAY", "PROCESSING", "PENDING", "CREATED", "CLIENT_PENDING", "ACCEPT", "ACCEPTED", "PAYING":
|
|
return "pending"
|
|
case "CLOSED", "TRADE_CLOSED", "CANCELLED", "CANCELED", "REVOKED", "FAILED", "FAIL", "REJECTED", "DENIED", "DECLINED", "ERROR", "PAYERROR":
|
|
return "failed"
|
|
default:
|
|
return fallback
|
|
}
|
|
}
|
|
|
|
func NormalizeRefundStatus(value, fallback string) string {
|
|
switch strings.ToUpper(strings.TrimSpace(value)) {
|
|
case "SUCCESS", "OK", "PAID", "REFUND_SUCCESS", "REFUNDED", "COMPLETED", "FINISHED", "TRADE_SUCCESS":
|
|
return "success"
|
|
case "WAIT_BUYER_PAY", "USERPAYING", "NOTPAY", "PROCESSING", "PENDING", "CREATED", "ACCEPT", "ACCEPTED", "PAYING":
|
|
return "pending"
|
|
case "CLOSED", "TRADE_CLOSED", "CANCELLED", "CANCELED", "REVOKED", "REFUND", "FAILED", "FAIL", "REJECTED", "DENIED", "DECLINED", "ERROR", "PAYERROR":
|
|
return "failed"
|
|
default:
|
|
return fallback
|
|
}
|
|
}
|
|
|
|
// NormalizePaymentMethod canonicalizes provider method identifiers while
|
|
// leaving provider-specific classification to the integration adapter.
|
|
func NormalizePaymentMethod(value string) string {
|
|
return strings.NewReplacer(".", "_", "-", "_", " ", "_").Replace(strings.ToLower(strings.TrimSpace(value)))
|
|
}
|
|
|
|
func ConfiguredInt64(values map[string]any, key string, fallback int64) int64 {
|
|
value, ok := values[key]
|
|
if !ok {
|
|
return fallback
|
|
}
|
|
parsed, err := ParseIntegerAmount(strings.TrimSpace(toString(value)))
|
|
if err != nil || parsed <= 0 {
|
|
return fallback
|
|
}
|
|
return parsed
|
|
}
|
|
|
|
func ConfiguredValues(values map[string]any, key string) []string {
|
|
result := []string{}
|
|
for _, item := range strings.Split(toString(values[key]), ",") {
|
|
item = strings.ToUpper(strings.TrimSpace(item))
|
|
if item != "" {
|
|
result = append(result, item)
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
func ContainsFold(values []string, value string) bool {
|
|
value = strings.ToUpper(strings.TrimSpace(value))
|
|
for _, item := range values {
|
|
if item == value {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func Text(values map[string]any, key string) string {
|
|
value, _ := values[key].(string)
|
|
return value
|
|
}
|
|
|
|
func FirstText(values map[string]any, keys ...string) string {
|
|
for _, key := range keys {
|
|
if value := Text(values, key); value != "" {
|
|
return value
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func FirstString(values map[string]string, keys ...string) string {
|
|
for _, key := range keys {
|
|
if values[key] != "" {
|
|
return values[key]
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// CallbackFields merges query parameters, form data, and top-level JSON
|
|
// strings using the same precedence for every payment boundary.
|
|
func CallbackFields(query, headers map[string]string, body []byte) map[string]string {
|
|
fields := make(map[string]string, len(query))
|
|
for key, value := range query {
|
|
fields[key] = value
|
|
}
|
|
contentType := ""
|
|
for key, value := range headers {
|
|
if strings.EqualFold(key, "Content-Type") {
|
|
contentType = strings.ToLower(value)
|
|
break
|
|
}
|
|
}
|
|
if strings.Contains(contentType, "application/x-www-form-urlencoded") {
|
|
if values, err := url.ParseQuery(string(body)); err == nil {
|
|
for key, value := range values {
|
|
if len(value) > 0 {
|
|
fields[key] = value[0]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var object map[string]any
|
|
if json.Unmarshal(body, &object) == nil {
|
|
for key, value := range object {
|
|
if text, ok := value.(string); ok {
|
|
fields[key] = text
|
|
}
|
|
}
|
|
}
|
|
return fields
|
|
}
|
|
|
|
func toString(value any) string {
|
|
if value == nil {
|
|
return ""
|
|
}
|
|
return strings.TrimSpace(strings.ReplaceAll(strings.TrimSpace(stringify(value)), "<nil>", ""))
|
|
}
|
|
|
|
func stringify(value any) string {
|
|
return fmt.Sprint(value)
|
|
}
|