| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807 |
- //go:build unit
- package service
- import (
- "context"
- "crypto/rand"
- "crypto/rsa"
- "crypto/x509"
- "encoding/pem"
- "strconv"
- "testing"
- "time"
- dbent "github.com/Wei-Shaw/sub2api/ent"
- "github.com/Wei-Shaw/sub2api/internal/payment"
- infraerrors "github.com/Wei-Shaw/sub2api/internal/pkg/errors"
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
- )
- func TestValidateProviderRequest(t *testing.T) {
- t.Parallel()
- tests := []struct {
- name string
- providerKey string
- providerName string
- supportedTypes string
- wantErr bool
- errContains string
- }{
- {
- name: "valid easypay with types",
- providerKey: "easypay",
- providerName: "MyProvider",
- supportedTypes: "alipay,wxpay",
- wantErr: false,
- },
- {
- name: "valid stripe with empty types",
- providerKey: "stripe",
- providerName: "Stripe Provider",
- supportedTypes: "",
- wantErr: false,
- },
- {
- name: "valid airwallex provider",
- providerKey: payment.TypeAirwallex,
- providerName: "Airwallex Provider",
- supportedTypes: payment.TypeAirwallex,
- wantErr: false,
- },
- {
- name: "valid alipay provider",
- providerKey: "alipay",
- providerName: "Alipay Direct",
- supportedTypes: "alipay",
- wantErr: false,
- },
- {
- name: "valid wxpay provider",
- providerKey: "wxpay",
- providerName: "WeChat Pay",
- supportedTypes: "wxpay",
- wantErr: false,
- },
- {
- name: "invalid provider key",
- providerKey: "invalid",
- providerName: "Name",
- supportedTypes: "alipay",
- wantErr: true,
- errContains: "invalid provider key",
- },
- {
- name: "empty name",
- providerKey: "easypay",
- providerName: "",
- supportedTypes: "alipay",
- wantErr: true,
- errContains: "provider name is required",
- },
- {
- name: "whitespace-only name",
- providerKey: "easypay",
- providerName: " ",
- supportedTypes: "alipay",
- wantErr: true,
- errContains: "provider name is required",
- },
- {
- name: "tab-only name",
- providerKey: "easypay",
- providerName: "\t",
- supportedTypes: "alipay",
- wantErr: true,
- errContains: "provider name is required",
- },
- }
- for _, tc := range tests {
- t.Run(tc.name, func(t *testing.T) {
- t.Parallel()
- err := validateProviderRequest(tc.providerKey, tc.providerName, tc.supportedTypes)
- if tc.wantErr {
- require.Error(t, err)
- assert.Contains(t, err.Error(), tc.errContains)
- } else {
- require.NoError(t, err)
- }
- })
- }
- }
- func TestValidateEasyPayCustomMethods(t *testing.T) {
- t.Parallel()
- tests := []struct {
- name string
- config map[string]string
- supportedTypes string
- wantErr string
- }{
- {
- name: "valid custom methods",
- config: map[string]string{"customMethods": `[{"type":"ldc","upstreamType":"epay","displayName":"LDC"}]`},
- supportedTypes: "alipay,wxpay,ldc",
- },
- {
- name: "malformed custom methods json",
- config: map[string]string{"customMethods": `not-json`},
- supportedTypes: "alipay,wxpay,ldc",
- wantErr: "customMethods must be a JSON array",
- },
- {
- name: "missing upstream type",
- config: map[string]string{"customMethods": `[{"type":"ldc","displayName":"LDC"}]`},
- supportedTypes: "alipay,wxpay,ldc",
- wantErr: "customMethods upstreamType is required",
- },
- {
- name: "duplicate custom type",
- config: map[string]string{"customMethods": `[{"type":"ldc","upstreamType":"epay"},{"type":"ldc","upstreamType":"epay2"}]`},
- supportedTypes: "alipay,wxpay,ldc",
- wantErr: "duplicate customMethods type",
- },
- {
- name: "custom type must already be lowercase",
- config: map[string]string{"customMethods": `[{"type":"LDC","upstreamType":"epay"}]`},
- supportedTypes: "alipay,wxpay,ldc",
- wantErr: "customMethods type may only contain lowercase letters",
- },
- {
- name: "upstream type must already be lowercase",
- config: map[string]string{"customMethods": `[{"type":"ldc","upstreamType":"ALIPAY"}]`},
- supportedTypes: "alipay,wxpay,ldc",
- wantErr: "customMethods upstreamType may only contain lowercase letters",
- },
- {
- name: "custom type uses alipay prefix",
- config: map[string]string{"customMethods": `[{"type":"alipay_hk","upstreamType":"hkpay"}]`},
- supportedTypes: "alipay,wxpay,alipay_hk",
- wantErr: "customMethods type cannot start with alipay or wxpay",
- },
- {
- name: "custom type uses wxpay prefix",
- config: map[string]string{"customMethods": `[{"type":"wxpay_usdt","upstreamType":"usdt"}]`},
- supportedTypes: "alipay,wxpay,wxpay_usdt",
- wantErr: "customMethods type cannot start with alipay or wxpay",
- },
- {
- name: "supported custom type missing mapping",
- config: map[string]string{"customMethods": `[{"type":"ldc","upstreamType":"epay"}]`},
- supportedTypes: "alipay,wxpay,ldc,usdt_trc20",
- wantErr: "supported EasyPay custom type usdt_trc20 has no customMethods mapping",
- },
- {
- name: "supported custom type must already be lowercase",
- config: map[string]string{"customMethods": `[{"type":"ldc","upstreamType":"epay"}]`},
- supportedTypes: "alipay,wxpay,LDC",
- wantErr: "supported EasyPay custom type LDC may only contain lowercase letters",
- },
- }
- for _, tc := range tests {
- tc := tc
- t.Run(tc.name, func(t *testing.T) {
- t.Parallel()
- err := validateEasyPayCustomMethods(tc.config, tc.supportedTypes)
- if tc.wantErr == "" {
- require.NoError(t, err)
- return
- }
- require.Error(t, err)
- require.Contains(t, err.Error(), tc.wantErr)
- })
- }
- }
- func TestIsSensitiveProviderConfigField(t *testing.T) {
- t.Parallel()
- tests := []struct {
- providerKey string
- field string
- wantSen bool
- }{
- // Stripe: publishableKey is public, only secretKey/webhookSecret are secrets
- {"stripe", "secretKey", true},
- {"stripe", "webhookSecret", true},
- {"stripe", "SecretKey", true}, // case-insensitive
- {"stripe", "publishableKey", false},
- {"stripe", "currency", false},
- {"stripe", "appId", false},
- // Alipay
- {"alipay", "privateKey", true},
- {"alipay", "publicKey", true},
- {"alipay", "alipayPublicKey", true},
- {"alipay", "appId", false},
- {"alipay", "notifyUrl", false},
- // Wxpay
- {"wxpay", "privateKey", true},
- {"wxpay", "apiV3Key", true},
- {"wxpay", "publicKey", true},
- {"wxpay", "publicKeyId", false},
- {"wxpay", "certSerial", false},
- {"wxpay", "mchId", false},
- // EasyPay
- {"easypay", "pkey", true},
- {"easypay", "pid", false},
- {"easypay", "apiBase", false},
- // Airwallex
- {payment.TypeAirwallex, "apiKey", true},
- {payment.TypeAirwallex, "webhookSecret", true},
- {payment.TypeAirwallex, "clientId", false},
- {payment.TypeAirwallex, "apiBase", false},
- {payment.TypeAirwallex, "accountId", false},
- {payment.TypeAirwallex, "currency", false},
- // Unknown provider: never sensitive
- {"unknown", "secretKey", false},
- }
- for _, tc := range tests {
- tc := tc
- t.Run(tc.providerKey+"/"+tc.field, func(t *testing.T) {
- t.Parallel()
- got := isSensitiveProviderConfigField(tc.providerKey, tc.field)
- assert.Equal(t, tc.wantSen, got, "isSensitiveProviderConfigField(%q, %q)", tc.providerKey, tc.field)
- })
- }
- }
- func TestJoinTypes(t *testing.T) {
- t.Parallel()
- tests := []struct {
- name string
- input []string
- want string
- }{
- {
- name: "multiple types",
- input: []string{"alipay", "wxpay"},
- want: "alipay,wxpay",
- },
- {
- name: "single type",
- input: []string{"stripe"},
- want: "stripe",
- },
- {
- name: "empty slice",
- input: []string{},
- want: "",
- },
- {
- name: "nil slice",
- input: nil,
- want: "",
- },
- {
- name: "three types",
- input: []string{"alipay", "wxpay", "stripe"},
- want: "alipay,wxpay,stripe",
- },
- {
- name: "types with spaces are not trimmed",
- input: []string{" alipay ", " wxpay "},
- want: " alipay , wxpay ",
- },
- }
- for _, tc := range tests {
- t.Run(tc.name, func(t *testing.T) {
- t.Parallel()
- got := joinTypes(tc.input)
- assert.Equal(t, tc.want, got)
- })
- }
- }
- func TestCreateProviderInstanceAllowsVisibleMethodProvidersFromDifferentSources(t *testing.T) {
- t.Parallel()
- ctx := context.Background()
- client := newPaymentConfigServiceTestClient(t)
- svc := &PaymentConfigService{
- entClient: client,
- encryptionKey: []byte("0123456789abcdef0123456789abcdef"),
- }
- _, err := svc.CreateProviderInstance(ctx, CreateProviderInstanceRequest{
- ProviderKey: "easypay",
- Name: "EasyPay Alipay",
- Config: map[string]string{
- "pid": "1001",
- "pkey": "pkey-1001",
- "apiBase": "https://pay.example.com",
- "notifyUrl": "https://merchant.example.com/notify",
- "returnUrl": "https://merchant.example.com/return",
- },
- SupportedTypes: []string{"alipay"},
- Enabled: true,
- })
- require.NoError(t, err)
- _, err = svc.CreateProviderInstance(ctx, CreateProviderInstanceRequest{
- ProviderKey: "alipay",
- Name: "Official Alipay",
- Config: map[string]string{"appId": "app-1", "privateKey": "private-key"},
- SupportedTypes: []string{"alipay"},
- Enabled: true,
- })
- require.NoError(t, err)
- }
- func TestUpdateProviderInstanceAllowsEnablingVisibleMethodProviderFromDifferentSource(t *testing.T) {
- t.Parallel()
- ctx := context.Background()
- client := newPaymentConfigServiceTestClient(t)
- svc := &PaymentConfigService{
- entClient: client,
- encryptionKey: []byte("0123456789abcdef0123456789abcdef"),
- }
- existing, err := svc.CreateProviderInstance(ctx, CreateProviderInstanceRequest{
- ProviderKey: "easypay",
- Name: "EasyPay WeChat",
- Config: map[string]string{
- "pid": "2001",
- "pkey": "pkey-2001",
- "apiBase": "https://pay.example.com",
- "notifyUrl": "https://merchant.example.com/notify",
- "returnUrl": "https://merchant.example.com/return",
- },
- SupportedTypes: []string{"wxpay"},
- Enabled: true,
- })
- require.NoError(t, err)
- require.NotNil(t, existing)
- candidate, err := svc.CreateProviderInstance(ctx, CreateProviderInstanceRequest{
- ProviderKey: "wxpay",
- Name: "Official WeChat",
- Config: validWxpayProviderConfig(t),
- SupportedTypes: []string{"wxpay"},
- Enabled: false,
- })
- require.NoError(t, err)
- _, err = svc.UpdateProviderInstance(ctx, candidate.ID, UpdateProviderInstanceRequest{
- Enabled: boolPtrValue(true),
- })
- require.NoError(t, err)
- }
- func TestUpdateProviderInstancePersistsEnabledAndSupportedTypes(t *testing.T) {
- t.Parallel()
- ctx := context.Background()
- client := newPaymentConfigServiceTestClient(t)
- svc := &PaymentConfigService{
- entClient: client,
- encryptionKey: []byte("0123456789abcdef0123456789abcdef"),
- }
- instance, err := svc.CreateProviderInstance(ctx, CreateProviderInstanceRequest{
- ProviderKey: "easypay",
- Name: "EasyPay",
- Config: map[string]string{
- "pid": "3001",
- "pkey": "pkey-3001",
- "apiBase": "https://pay.example.com",
- "notifyUrl": "https://merchant.example.com/notify",
- "returnUrl": "https://merchant.example.com/return",
- },
- SupportedTypes: []string{"alipay"},
- Enabled: false,
- })
- require.NoError(t, err)
- _, err = svc.UpdateProviderInstance(ctx, instance.ID, UpdateProviderInstanceRequest{
- Enabled: boolPtrValue(true),
- SupportedTypes: []string{"alipay", "wxpay"},
- })
- require.NoError(t, err)
- saved, err := client.PaymentProviderInstance.Get(ctx, instance.ID)
- require.NoError(t, err)
- require.True(t, saved.Enabled)
- require.Equal(t, "alipay,wxpay", saved.SupportedTypes)
- }
- func TestUpdateProviderInstanceRejectsProtectedConfigChangesWhilePendingOrders(t *testing.T) {
- t.Parallel()
- tests := []struct {
- name string
- providerKey string
- createConfig func(*testing.T) map[string]string
- supportedType []string
- updateConfig map[string]string
- fieldName string
- wantValue string
- }{
- {
- name: "wxpay appId",
- providerKey: payment.TypeWxpay,
- createConfig: validWxpayProviderConfig,
- supportedType: []string{payment.TypeWxpay},
- updateConfig: map[string]string{"appId": "wx-app-updated"},
- fieldName: "appId",
- wantValue: "wx-app-test",
- },
- {
- name: "wxpay mpAppId",
- providerKey: payment.TypeWxpay,
- createConfig: validWxpayProviderConfigWithJSAPIAppID,
- supportedType: []string{payment.TypeWxpay},
- updateConfig: map[string]string{"mpAppId": "wx-mp-app-updated"},
- fieldName: "mpAppId",
- wantValue: "wx-mp-app-test",
- },
- {
- name: "wxpay mchId",
- providerKey: payment.TypeWxpay,
- createConfig: validWxpayProviderConfig,
- supportedType: []string{payment.TypeWxpay},
- updateConfig: map[string]string{"mchId": "mch-updated"},
- fieldName: "mchId",
- wantValue: "mch-test",
- },
- {
- name: "wxpay publicKeyId",
- providerKey: payment.TypeWxpay,
- createConfig: validWxpayProviderConfig,
- supportedType: []string{payment.TypeWxpay},
- updateConfig: map[string]string{"publicKeyId": "public-key-id-updated"},
- fieldName: "publicKeyId",
- wantValue: "public-key-id-test",
- },
- {
- name: "wxpay certSerial",
- providerKey: payment.TypeWxpay,
- createConfig: validWxpayProviderConfig,
- supportedType: []string{payment.TypeWxpay},
- updateConfig: map[string]string{"certSerial": "cert-serial-updated"},
- fieldName: "certSerial",
- wantValue: "cert-serial-test",
- },
- {
- name: "alipay appId",
- providerKey: payment.TypeAlipay,
- createConfig: validAlipayProviderConfig,
- supportedType: []string{payment.TypeAlipay},
- updateConfig: map[string]string{"appId": "alipay-app-updated"},
- fieldName: "appId",
- wantValue: "alipay-app-test",
- },
- {
- name: "easypay pid",
- providerKey: payment.TypeEasyPay,
- createConfig: validEasyPayProviderConfig,
- supportedType: []string{payment.TypeAlipay},
- updateConfig: map[string]string{"pid": "pid-updated"},
- fieldName: "pid",
- wantValue: "pid-test",
- },
- {
- name: "stripe currency",
- providerKey: payment.TypeStripe,
- createConfig: validStripeProviderConfig,
- supportedType: []string{payment.TypeStripe},
- updateConfig: map[string]string{"currency": "HKD"},
- fieldName: "currency",
- wantValue: "CNY",
- },
- {
- name: "airwallex accountId",
- providerKey: payment.TypeAirwallex,
- createConfig: validAirwallexProviderConfig,
- supportedType: []string{payment.TypeAirwallex},
- updateConfig: map[string]string{"accountId": "acct-updated"},
- fieldName: "accountId",
- wantValue: "acct-test",
- },
- {
- name: "airwallex currency",
- providerKey: payment.TypeAirwallex,
- createConfig: validAirwallexProviderConfig,
- supportedType: []string{payment.TypeAirwallex},
- updateConfig: map[string]string{"currency": "HKD"},
- fieldName: "currency",
- wantValue: "CNY",
- },
- {
- name: "airwallex webhookSecret",
- providerKey: payment.TypeAirwallex,
- createConfig: validAirwallexProviderConfig,
- supportedType: []string{payment.TypeAirwallex},
- updateConfig: map[string]string{"webhookSecret": "whsec-updated"},
- fieldName: "webhookSecret",
- wantValue: "whsec-test",
- },
- }
- for _, tc := range tests {
- tc := tc
- t.Run(tc.name, func(t *testing.T) {
- t.Parallel()
- ctx := context.Background()
- client := newPaymentConfigServiceTestClient(t)
- svc := &PaymentConfigService{
- entClient: client,
- encryptionKey: []byte("0123456789abcdef0123456789abcdef"),
- }
- instance, err := svc.CreateProviderInstance(ctx, CreateProviderInstanceRequest{
- ProviderKey: tc.providerKey,
- Name: "protected-config-instance",
- Config: tc.createConfig(t),
- SupportedTypes: tc.supportedType,
- Enabled: true,
- })
- require.NoError(t, err)
- createPendingProviderConfigOrder(t, ctx, client, instance)
- updated, err := svc.UpdateProviderInstance(ctx, instance.ID, UpdateProviderInstanceRequest{
- Config: tc.updateConfig,
- })
- require.Nil(t, updated)
- require.Error(t, err)
- require.Equal(t, "PENDING_ORDERS", infraerrors.Reason(err))
- saved, err := client.PaymentProviderInstance.Get(ctx, instance.ID)
- require.NoError(t, err)
- cfg, err := svc.decryptConfig(saved.Config)
- require.NoError(t, err)
- require.Equal(t, tc.wantValue, cfg[tc.fieldName])
- })
- }
- }
- func TestUpdateProviderInstanceAllowsSafeConfigChangesWhilePendingOrders(t *testing.T) {
- t.Parallel()
- tests := []struct {
- name string
- providerKey string
- createConfig func(*testing.T) map[string]string
- supportedType []string
- updateConfig map[string]string
- fieldName string
- wantValue string
- }{
- {
- name: "wxpay notifyUrl",
- providerKey: payment.TypeWxpay,
- createConfig: validWxpayProviderConfig,
- supportedType: []string{payment.TypeWxpay},
- updateConfig: map[string]string{"notifyUrl": "https://merchant.example.com/wxpay/notify-v2"},
- fieldName: "notifyUrl",
- wantValue: "https://merchant.example.com/wxpay/notify-v2",
- },
- {
- name: "alipay same appId",
- providerKey: payment.TypeAlipay,
- createConfig: validAlipayProviderConfig,
- supportedType: []string{payment.TypeAlipay},
- updateConfig: map[string]string{"appId": "alipay-app-test"},
- fieldName: "appId",
- wantValue: "alipay-app-test",
- },
- }
- for _, tc := range tests {
- tc := tc
- t.Run(tc.name, func(t *testing.T) {
- t.Parallel()
- ctx := context.Background()
- client := newPaymentConfigServiceTestClient(t)
- svc := &PaymentConfigService{
- entClient: client,
- encryptionKey: []byte("0123456789abcdef0123456789abcdef"),
- }
- instance, err := svc.CreateProviderInstance(ctx, CreateProviderInstanceRequest{
- ProviderKey: tc.providerKey,
- Name: "safe-config-instance",
- Config: tc.createConfig(t),
- SupportedTypes: tc.supportedType,
- Enabled: true,
- })
- require.NoError(t, err)
- createPendingProviderConfigOrder(t, ctx, client, instance)
- updated, err := svc.UpdateProviderInstance(ctx, instance.ID, UpdateProviderInstanceRequest{
- Config: tc.updateConfig,
- })
- require.NoError(t, err)
- require.NotNil(t, updated)
- saved, err := client.PaymentProviderInstance.Get(ctx, instance.ID)
- require.NoError(t, err)
- cfg, err := svc.decryptConfig(saved.Config)
- require.NoError(t, err)
- require.Equal(t, tc.wantValue, cfg[tc.fieldName])
- })
- }
- }
- func TestUpdateProviderInstanceClearsAirwallexAccountID(t *testing.T) {
- t.Parallel()
- ctx := context.Background()
- client := newPaymentConfigServiceTestClient(t)
- svc := &PaymentConfigService{
- entClient: client,
- encryptionKey: []byte("0123456789abcdef0123456789abcdef"),
- }
- instance, err := svc.CreateProviderInstance(ctx, CreateProviderInstanceRequest{
- ProviderKey: payment.TypeAirwallex,
- Name: "airwallex-clear-account",
- Config: validAirwallexProviderConfig(t),
- SupportedTypes: []string{payment.TypeAirwallex},
- Enabled: true,
- })
- require.NoError(t, err)
- updated, err := svc.UpdateProviderInstance(ctx, instance.ID, UpdateProviderInstanceRequest{
- Config: map[string]string{"accountId": ""},
- })
- require.NoError(t, err)
- require.NotNil(t, updated)
- saved, err := client.PaymentProviderInstance.Get(ctx, instance.ID)
- require.NoError(t, err)
- cfg, err := svc.decryptConfig(saved.Config)
- require.NoError(t, err)
- require.Empty(t, cfg["accountId"])
- require.Equal(t, "client-id-test", cfg["clientId"])
- }
- func createPendingProviderConfigOrder(t *testing.T, ctx context.Context, client *dbent.Client, instance *dbent.PaymentProviderInstance) {
- t.Helper()
- user, err := client.User.Create().
- SetEmail("provider-config-pending@example.com").
- SetPasswordHash("hash").
- SetUsername("provider-config-pending-user").
- Save(ctx)
- require.NoError(t, err)
- instanceID := strconv.FormatInt(instance.ID, 10)
- _, err = client.PaymentOrder.Create().
- SetUserID(user.ID).
- SetUserEmail(user.Email).
- SetUserName(user.Username).
- SetAmount(88).
- SetPayAmount(88).
- SetFeeRate(0).
- SetRechargeCode("PENDING-PROVIDER-CONFIG-" + instanceID).
- SetOutTradeNo("sub2_pending_provider_config_" + instanceID).
- SetPaymentType(providerPendingOrderPaymentType(instance.ProviderKey)).
- SetPaymentTradeNo("").
- SetOrderType(payment.OrderTypeBalance).
- SetStatus(OrderStatusPending).
- SetExpiresAt(time.Now().Add(time.Hour)).
- SetClientIP("127.0.0.1").
- SetSrcHost("api.example.com").
- SetProviderInstanceID(instanceID).
- SetProviderKey(instance.ProviderKey).
- Save(ctx)
- require.NoError(t, err)
- }
- func providerPendingOrderPaymentType(providerKey string) string {
- switch providerKey {
- case payment.TypeWxpay:
- return payment.TypeWxpay
- case payment.TypeAlipay:
- return payment.TypeAlipay
- case payment.TypeAirwallex:
- return payment.TypeAirwallex
- case payment.TypeStripe:
- return payment.TypeStripe
- default:
- return payment.TypeAlipay
- }
- }
- func validStripeProviderConfig(t *testing.T) map[string]string {
- t.Helper()
- return map[string]string{
- "secretKey": "sk_test_123",
- "publishableKey": "pk_test_123",
- "webhookSecret": "whsec-test",
- "currency": "CNY",
- }
- }
- func boolPtrValue(v bool) *bool {
- return &v
- }
- func validAlipayProviderConfig(t *testing.T) map[string]string {
- t.Helper()
- return map[string]string{
- "appId": "alipay-app-test",
- "privateKey": "alipay-private-key-test",
- "notifyUrl": "https://merchant.example.com/alipay/notify",
- "returnUrl": "https://merchant.example.com/alipay/return",
- }
- }
- func validEasyPayProviderConfig(t *testing.T) map[string]string {
- t.Helper()
- return map[string]string{
- "pid": "pid-test",
- "pkey": "pkey-test",
- "apiBase": "https://pay.example.com",
- "notifyUrl": "https://merchant.example.com/easypay/notify",
- "returnUrl": "https://merchant.example.com/easypay/return",
- }
- }
- func validAirwallexProviderConfig(t *testing.T) map[string]string {
- t.Helper()
- return map[string]string{
- "clientId": "client-id-test",
- "apiKey": "api-key-test",
- "webhookSecret": "whsec-test",
- "apiBase": "https://api-demo.airwallex.com/api/v1",
- "accountId": "acct-test",
- "currency": "CNY",
- }
- }
- func validWxpayProviderConfig(t *testing.T) map[string]string {
- t.Helper()
- key, err := rsa.GenerateKey(rand.Reader, 2048)
- require.NoError(t, err)
- privDER, err := x509.MarshalPKCS8PrivateKey(key)
- require.NoError(t, err)
- pubDER, err := x509.MarshalPKIXPublicKey(&key.PublicKey)
- require.NoError(t, err)
- return map[string]string{
- "appId": "wx-app-test",
- "mchId": "mch-test",
- "privateKey": string(pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privDER})),
- "apiV3Key": "12345678901234567890123456789012",
- "publicKey": string(pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: pubDER})),
- "publicKeyId": "public-key-id-test",
- "certSerial": "cert-serial-test",
- }
- }
- func validWxpayProviderConfigWithJSAPIAppID(t *testing.T) map[string]string {
- t.Helper()
- cfg := validWxpayProviderConfig(t)
- cfg["mpAppId"] = "wx-mp-app-test"
- return cfg
- }
|