优化结构
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
package paymentutil
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
const (
|
||||
ProviderAlipay = "alipay"
|
||||
ProviderAlipayV3 = "alipay-v3"
|
||||
ProviderWechatV2 = "wechat-v2"
|
||||
ProviderWechatV3 = "wechat-v3"
|
||||
ProviderApple = "apple-iap"
|
||||
)
|
||||
|
||||
// CallbackAck is the provider-facing HTTP acknowledgement returned after a
|
||||
// payment notification is processed.
|
||||
type CallbackAck struct {
|
||||
StatusCode int
|
||||
ContentType string
|
||||
Body []byte
|
||||
}
|
||||
|
||||
// CallbackError carries a safe provider acknowledgement alongside the cause
|
||||
// that should be logged or returned to the application layer.
|
||||
type CallbackError struct {
|
||||
Cause error
|
||||
Ack CallbackAck
|
||||
}
|
||||
|
||||
func (e *CallbackError) Error() string {
|
||||
if e == nil || e.Cause == nil {
|
||||
return "支付回调处理失败"
|
||||
}
|
||||
return e.Cause.Error()
|
||||
}
|
||||
|
||||
func (e *CallbackError) Unwrap() error {
|
||||
if e == nil {
|
||||
return nil
|
||||
}
|
||||
return e.Cause
|
||||
}
|
||||
|
||||
func CallbackFailure(err error, fallback CallbackAck) CallbackAck {
|
||||
var callbackErr *CallbackError
|
||||
if errors.As(err, &callbackErr) && callbackErr.Ack.StatusCode != 0 {
|
||||
return callbackErr.Ack
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
// DefaultCallbackAck returns the conventional acknowledgement for providers
|
||||
// whose callback wire formats are stable across modules.
|
||||
func DefaultCallbackAck(provider string, success bool) CallbackAck {
|
||||
status := 200
|
||||
if !success {
|
||||
status = 500
|
||||
}
|
||||
switch provider {
|
||||
case ProviderAlipay, ProviderAlipayV3:
|
||||
body := "success"
|
||||
if !success {
|
||||
body = "failure"
|
||||
}
|
||||
return CallbackAck{StatusCode: status, ContentType: "text/plain; charset=utf-8", Body: []byte(body)}
|
||||
case ProviderWechatV2:
|
||||
code, message := "SUCCESS", "OK"
|
||||
if !success {
|
||||
code, message = "FAIL", "FAIL"
|
||||
}
|
||||
body := fmt.Sprintf("<xml><return_code><![CDATA[%s]]></return_code><return_msg><![CDATA[%s]]></return_msg></xml>", code, message)
|
||||
return CallbackAck{StatusCode: status, ContentType: "application/xml; charset=utf-8", Body: []byte(body)}
|
||||
case ProviderWechatV3:
|
||||
code, message := "SUCCESS", "成功"
|
||||
if !success {
|
||||
code, message = "FAIL", "失败"
|
||||
}
|
||||
body, _ := json.Marshal(map[string]string{"code": code, "message": message})
|
||||
return CallbackAck{StatusCode: status, ContentType: "application/json; charset=utf-8", Body: body}
|
||||
case ProviderApple:
|
||||
return CallbackAck{StatusCode: status}
|
||||
default:
|
||||
body := "success"
|
||||
if !success {
|
||||
body = "failure"
|
||||
}
|
||||
return CallbackAck{StatusCode: status, ContentType: "text/plain; charset=utf-8", Body: []byte(body)}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user