优化结构
This commit is contained in:
@@ -1,13 +1,28 @@
|
||||
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", "TRADE_SUCCESS", "TRADE_FINISHED", "COMPLETED", "PAY_SUCCESS", "REFUND_SUCCESS", "REFUNDED":
|
||||
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", "REFUND", "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":
|
||||
return "success"
|
||||
case "WAIT_BUYER_PAY", "USERPAYING", "NOTPAY", "PROCESSING", "PENDING", "CREATED", "ACCEPT", "ACCEPTED", "PAYING":
|
||||
return "pending"
|
||||
@@ -65,6 +80,49 @@ func FirstText(values map[string]any, keys ...string) string {
|
||||
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 ""
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package paymentkit
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestNormalizeStatusCoversCanonicalPaymentStates(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
input, want string
|
||||
}{
|
||||
{input: "fulfilled", want: "success"},
|
||||
{input: "client_pending", want: "pending"},
|
||||
{input: "trade_closed", want: "failed"},
|
||||
} {
|
||||
if got := NormalizeStatus(test.input, "unknown"); got != test.want {
|
||||
t.Fatalf("NormalizeStatus(%q) = %q, want %q", test.input, got, test.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNormalizeStatusSeparatesRefundStates(t *testing.T) {
|
||||
if got := NormalizeStatus("REFUND_SUCCESS", "unknown"); got != "success" {
|
||||
t.Fatalf("payment status for completed payment = %q, want success", got)
|
||||
}
|
||||
if got := NormalizeRefundStatus("REFUND_SUCCESS", "unknown"); got != "success" {
|
||||
t.Fatalf("refund status = %q, want success", got)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user