支付相关
This commit is contained in:
@@ -0,0 +1,157 @@
|
||||
package payment
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"kra/internal/biz"
|
||||
|
||||
"github.com/go-pay/gopay"
|
||||
"github.com/go-pay/gopay/douyin"
|
||||
)
|
||||
|
||||
// The adapters in this package intentionally keep GoPay request/response
|
||||
// models below the data boundary. The business layer only sees PaymentResult.
|
||||
|
||||
func callbackRequest(callback *biz.PaymentCallback) (*http.Request, error) {
|
||||
request, err := http.NewRequest(http.MethodPost, "http://payment-callback.local", bytes.NewReader(callback.Body))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for key, value := range callback.Headers {
|
||||
request.Header.Set(key, value)
|
||||
}
|
||||
return request, nil
|
||||
}
|
||||
|
||||
func mergeGoPayExtras(dst gopay.BodyMap, src map[string]any, protected ...string) {
|
||||
protectedKeys := make(map[string]struct{}, len(protected))
|
||||
for _, key := range protected {
|
||||
protectedKeys[key] = struct{}{}
|
||||
}
|
||||
for key, value := range src {
|
||||
if _, ok := protectedKeys[key]; ok {
|
||||
continue
|
||||
}
|
||||
dst[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
func mergeGoPayConfigExtras(dst gopay.BodyMap, config map[string]any, key string, protected ...string) {
|
||||
extra, ok := config[key].(map[string]any)
|
||||
if !ok || extra == nil {
|
||||
return
|
||||
}
|
||||
mergeGoPayExtras(dst, extra, protected...)
|
||||
}
|
||||
|
||||
func anyConfig(c map[string]any, keys ...string) any {
|
||||
for _, key := range keys {
|
||||
if value, ok := c[key]; ok && fmt.Sprint(value) != "" {
|
||||
return value
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func firstAnyOr(values map[string]any, fallback string, keys ...string) string {
|
||||
if value := firstAny(values, keys...); value != "" {
|
||||
return value
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
func mustJSON(value any) []byte {
|
||||
encoded, _ := json.Marshal(value)
|
||||
return encoded
|
||||
}
|
||||
|
||||
func douyinError(rsp any) error {
|
||||
return fmt.Errorf("抖音支付请求失败: %v", rsp)
|
||||
}
|
||||
|
||||
func qqOK(returnCode, resultCode string) bool {
|
||||
return strings.EqualFold(returnCode, "SUCCESS") && (resultCode == "" || strings.EqualFold(resultCode, "SUCCESS"))
|
||||
}
|
||||
|
||||
func rspMap(value any) map[string]string {
|
||||
encoded, _ := json.Marshal(value)
|
||||
var object map[string]any
|
||||
_ = json.Unmarshal(encoded, &object)
|
||||
result := make(map[string]string, len(object))
|
||||
for key, val := range object {
|
||||
result[key] = fmt.Sprint(val)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func normalizeDouyinState(state string) string {
|
||||
switch strings.ToUpper(strings.TrimSpace(state)) {
|
||||
case douyin.TradeStateSuccess:
|
||||
return "success"
|
||||
case douyin.TradeStatePayErr:
|
||||
return "failed"
|
||||
case douyin.TradeStateClosed:
|
||||
return "failed"
|
||||
default:
|
||||
return "pending"
|
||||
}
|
||||
}
|
||||
|
||||
func normalizeRefundState(state string) string {
|
||||
switch strings.ToUpper(strings.TrimSpace(state)) {
|
||||
case douyin.RefundStatusSuccess, "REFUNDED":
|
||||
return "success"
|
||||
case douyin.RefundStatusClosed, douyin.RefundStatusAbnormal, "FAILED":
|
||||
return "failed"
|
||||
default:
|
||||
return "pending"
|
||||
}
|
||||
}
|
||||
|
||||
func normalizeQQState(state string) string {
|
||||
switch strings.ToUpper(strings.TrimSpace(state)) {
|
||||
case "SUCCESS", "REFUND":
|
||||
return "success"
|
||||
case "CLOSED", "PAYERROR", "REVOKED", "NOPAY":
|
||||
return "failed"
|
||||
default:
|
||||
return "pending"
|
||||
}
|
||||
}
|
||||
|
||||
func normalizeAllinState(state string) string {
|
||||
switch strings.ToUpper(strings.TrimSpace(state)) {
|
||||
case "SUCCESS", "0000", "2000", "3040":
|
||||
return "success"
|
||||
case "FAIL", "FAILED", "3000", "3045":
|
||||
return "failed"
|
||||
default:
|
||||
return "pending"
|
||||
}
|
||||
}
|
||||
|
||||
func normalizeLakalaState(state string) string {
|
||||
switch strings.ToUpper(strings.TrimSpace(state)) {
|
||||
case "SUCCESS", "PAID", "PAY_SUCCESS", "1":
|
||||
return "success"
|
||||
case "CLOSED", "FAILED", "FAIL", "CANCELLED":
|
||||
return "failed"
|
||||
default:
|
||||
return "pending"
|
||||
}
|
||||
}
|
||||
|
||||
func normalizeSaobeiState(state string) string {
|
||||
switch strings.ToUpper(strings.TrimSpace(state)) {
|
||||
case "SUCCESS":
|
||||
return "success"
|
||||
case "CLOSED", "PAYERROR", "REVOKED", "FAILED", "NOPAY":
|
||||
return "failed"
|
||||
default:
|
||||
return "pending"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user