feat(payment): 虎皮椒聚合支付 - 官方插件与跨平台可执行文件

新增 xunhupay 官方包,支付 RPC 与宿主只保留订单和验签边界;官方支付包同时带上各系统 provider,避免把 Linux ELF 当成本机入口。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
ddCatandCursor committed 2026-09-17 23:32:11 +08:00
1 parent e5a5f0ccc8
commit a23df0cb32
63 files changed
+2070 -128

No files matched your search

+46 -2
View File
@@ -1,6 +1,7 @@
package app
import (
"errors"
"testing"
"infinite-canvas/backend/internal/payment"
@@ -59,7 +60,7 @@ func TestSystemPaymentPluginsRegisterRPCProviders(t *testing.T) {
if registry == nil {
t.Fatal("payment registry is nil")
}
for _, providerID := range []string{PaymentProviderAlipay, PaymentProviderWeChat} {
for _, providerID := range []string{PaymentProviderAlipay, PaymentProviderWeChat, "xunhupay-aggregate"} {
provider, ok := registry.Get(providerID)
if !ok {
t.Fatalf("payment provider %q is missing", providerID)
@@ -70,6 +71,14 @@ func TestSystemPaymentPluginsRegisterRPCProviders(t *testing.T) {
if provider.Descriptor().PluginID == "" || provider.Descriptor().PluginVersion == "" {
t.Fatalf("payment provider %q is missing plugin identity: %#v", providerID, provider.Descriptor())
}
err := provider.ValidateConfig(nil)
var providerErr *payment.ProviderError
if !errors.As(err, &providerErr) {
t.Fatalf("provider %q ValidateConfig() = %T %v, want ProviderError", providerID, err, err)
}
if providerErr.Code == "plugin_executable_missing" || providerErr.Code == "plugin_exec_format_error" || providerErr.Code == "plugin_start_failed" {
t.Fatalf("provider %q failed to start: %#v cause=%v", providerID, providerErr, providerErr.Cause)
}
}
}
@@ -83,7 +92,7 @@ func TestPaymentRegistryFailsClosedWhenOfficialPackagesAreMissing(t *testing.T)
if registry == nil {
t.Fatal("payment registry is nil")
}
for _, providerID := range []string{PaymentProviderAlipay, PaymentProviderWeChat} {
for _, providerID := range []string{PaymentProviderAlipay, PaymentProviderWeChat, "xunhupay-aggregate"} {
if _, ok := registry.Get(providerID); ok {
t.Fatalf("payment provider %q unexpectedly came from host fallback", providerID)
}
@@ -107,3 +116,38 @@ func TestTopupProductCreditAmountStaysWithinSafeLimit(t *testing.T) {
t.Fatalf("maximum safe top-up credits: %v", err)
}
}
func TestXunHuPayOfficialPackageIsPaymentPlugin(t *testing.T) {
center, err := newPluginRuntime(t.TempDir())
if err != nil {
t.Fatal(err)
}
var plugin PluginView
for _, item := range center.list() {
if item.Manifest.ID == "official-payment-xunhupay" {
plugin = item
plugin.Management = pluginManagementFromView(item)
break
}
}
if plugin.Manifest.ID == "" {
t.Fatal("official-payment-xunhupay is missing")
}
if plugin.Management.Kind != PluginKindPayment || plugin.Source != PluginOriginOfficial {
t.Fatalf("xunhupay plugin = %#v", plugin)
}
if len(plugin.Manifest.Contributes.PaymentProviders) != 1 || plugin.Manifest.Contributes.PaymentProviders[0].ID != "xunhupay-aggregate" {
t.Fatalf("xunhupay contributions = %#v", plugin.Manifest.Contributes.PaymentProviders)
}
registry := center.paymentRegistrySnapshot()
if registry == nil {
t.Fatal("payment registry is nil")
}
provider, ok := registry.Get("xunhupay-aggregate")
if !ok {
t.Fatal("xunhupay-aggregate provider is missing")
}
if _, ok := provider.(*payment.RPCProvider); !ok {
t.Fatalf("xunhupay provider type = %T", provider)
}
}