diff --git a/assets/admin/src/schema/sections/payment/gateway.js b/assets/admin/src/schema/sections/payment/gateway.js
index 53fd11df..86fca069 100644
--- a/assets/admin/src/schema/sections/payment/gateway.js
+++ b/assets/admin/src/schema/sections/payment/gateway.js
@@ -282,7 +282,7 @@ export const gatewaySchema = {
},
{ key: 'paypal_client_id', label: 'Client ID', type: 'input', default: '' },
{ key: 'paypal_client_secret', label: 'Client Secret', type: 'input', default: '' },
- { key: 'paypal_currency', label: '结算货币', type: 'select', default: 'USD', options: currencyOptions },
+ { key: 'paypal_currency', label: '结算货币', type: 'select', case_insensitive: true, default: 'USD', options: currencyOptions },
{ key: 'paypal_rates', label: '货币汇率', type: 'input', default: '0.14', help: '根据你选择的货币类型与您定价货币的汇率进行填写,例如1元人民币兑换0.137美元(USD),则此处填0.137' },
{ key: 'paypal_sandbox', label: '沙盒调试模式', type: 'switch', default: false, help: '沙箱模式(Sandbox)是PayPal支付的测试环境。开启后请使用沙箱环境生成的收款账户和付款账户进行测试。' },
],
@@ -306,7 +306,7 @@ export const gatewaySchema = {
{ key: 'stripe_secret_key', label: '私钥Secret Key', type: 'input', default: '', help: 'Stripe Dashboard → Developers → API keys → Secret key' },
{ key: 'stripe_publishable_key', label: 'Publishable Key', type: 'input', default: '' },
{ key: 'stripe_webhook_secret', label: '签名密钥Webhook Secret', type: 'input', default: '', help: 'Developers → Webhooks → 端点 → Signing secret(whsec_ 开头)' },
- { key: 'stripe_currency', label: '结算货币', type: 'select', default: 'USD', options: currencyOptions },
+ { key: 'stripe_currency', label: '结算货币', type: 'select', case_insensitive: true, default: 'USD', options: currencyOptions },
{ key: 'stripe_rates', label: '货币汇率', type: 'input', default: '0.14', help: '根据你选择的货币类型与您定价货币的汇率进行填写,例如1元人民币兑换0.137美元(USD),则此处填0.137' },
{ key: 'stripe_test_mode', label: '测试模式', type: 'switch', default: false, help: '如果使用的测试开放模式,则请使用 sk_test_ 测试密钥与 Stripe 测试卡进行配置' },
],
diff --git a/src/Admin/Schema/SchemaPayment.php b/src/Admin/Schema/SchemaPayment.php
index 1e788ff7..7d1504c4 100644
--- a/src/Admin/Schema/SchemaPayment.php
+++ b/src/Admin/Schema/SchemaPayment.php
@@ -469,7 +469,7 @@ class SchemaPayment {
['key' => 'paypal_notice', 'label' => '', 'type' => 'content', 'ui_only' => true, 'content' => '
- PayPal(贝宝)是常见的海外支付接口
- 如果您的收款账户为中国大陆地区,则账户类型必须是企业,且只能收取非中国大陆区的PayPal付款
- REST 应用申请:https://developer.paypal.com/dashboard/applications
'],
['key' => 'paypal_client_id', 'label' => 'Client ID', 'type' => 'input', 'default' => ''],
['key' => 'paypal_client_secret', 'label' => 'Client Secret', 'type' => 'input', 'default' => ''],
- ['key' => 'paypal_currency', 'label' => '结算货币', 'type' => 'select', 'default' => 'USD', 'options' => self::currency_options()],
+ ['key' => 'paypal_currency', 'label' => '结算货币', 'type' => 'select', 'case_insensitive' => true, 'default' => 'USD', 'options' => self::currency_options()],
['key' => 'paypal_rates', 'label' => '货币汇率', 'type' => 'input', 'default' => '0.14', 'help' => '根据你选择的货币类型与您定价货币的汇率进行填写,例如1元人民币兑换0.137美元(USD),则此处填0.137'],
['key' => 'paypal_sandbox', 'label' => '沙盒调试模式', 'type' => 'switch', 'default' => false, 'help' => '沙箱模式(Sandbox)是PayPal支付的测试环境。开启后请使用沙箱环境生成的收款账户和付款账户进行测试。'],
]],
@@ -478,7 +478,7 @@ class SchemaPayment {
['key' => 'stripe_secret_key', 'label' => '私钥Secret Key', 'type' => 'input', 'default' => '', 'help' => 'Stripe Dashboard → Developers → API keys → Secret key'],
['key' => 'stripe_publishable_key', 'label' => 'Publishable Key', 'type' => 'input', 'default' => ''],
['key' => 'stripe_webhook_secret', 'label' => '签名密钥Webhook Secret', 'type' => 'input', 'default' => '', 'help' => 'Developers → Webhooks → 端点 → Signing secret(whsec_ 开头)'],
- ['key' => 'stripe_currency', 'label' => '结算货币', 'type' => 'select', 'default' => 'USD', 'options' => self::currency_options()],
+ ['key' => 'stripe_currency', 'label' => '结算货币', 'type' => 'select', 'case_insensitive' => true, 'default' => 'USD', 'options' => self::currency_options()],
['key' => 'stripe_rates', 'label' => '货币汇率', 'type' => 'input', 'default' => '0.14', 'help' => '根据你选择的货币类型与您定价货币的汇率进行填写,例如1元人民币兑换0.137美元(USD),则此处填0.137'],
['key' => 'stripe_test_mode', 'label' => '测试模式', 'type' => 'switch', 'default' => false, 'help' => '如果使用的测试开放模式,则请使用 sk_test_ 测试密钥与 Stripe 测试卡进行配置'],
]],
diff --git a/src/Admin/SchemaProvider.php b/src/Admin/SchemaProvider.php
index a58d8085..7bd633d7 100644
--- a/src/Admin/SchemaProvider.php
+++ b/src/Admin/SchemaProvider.php
@@ -237,12 +237,14 @@ class SchemaProvider {
// (legacy / SPA may still use type=select multiple).
if (!empty($field['multiple']) && is_array($value)) {
foreach ($value as $item) {
- if (!in_array($item, $valid_values, true)) {
+ if (!in_array($item, $valid_values, true)
+ && (empty($field['case_insensitive']) || $this->normalize_case_insensitive_option($item, (array) $field['options']) === null)) {
$errors[] = sprintf('%s has an invalid value', $field['label'] ?? $key);
break;
}
}
- } elseif (!in_array($value, $valid_values, true)) {
+ } elseif (!in_array($value, $valid_values, true)
+ && (empty($field['case_insensitive']) || $this->normalize_case_insensitive_option($value, (array) $field['options']) === null)) {
$errors[] = sprintf('%s has an invalid value', $field['label'] ?? $key);
}
}
@@ -545,6 +547,12 @@ class SchemaProvider {
if ($has_stored) {
$data[$field['key']] = $stored[$field['key']];
}
+ // 大小写不敏感字段:存储值归一化为选项规范写法;匹配不到回退默认,
+ // 避免旧自由文本值(如小写货币代码)导致枚举校验失败。
+ if (!empty($field['case_insensitive']) && in_array($field_type, ['select', 'radio'], true) && !empty($field['options'])) {
+ $normalized = $this->normalize_case_insensitive_option($data[$field['key']] ?? '', (array) $field['options']);
+ $data[$field['key']] = $normalized !== null ? $normalized : ($field['default'] ?? ($data[$field['key']] ?? ''));
+ }
if (($field['sanitize_type'] ?? '') === 'money_decimal' && array_key_exists($field['key'], $data)) {
$normalized = $this->normalize_money_decimal($data[$field['key']]);
if ($normalized !== '') {
@@ -855,6 +863,27 @@ class SchemaProvider {
}
}
+ /**
+ * 对大小写不敏感字段(case_insensitive),把值归一化为选项中的规范写法;
+ * 匹配不到返回 null。
+ *
+ * @param mixed $value
+ * @param array $options
+ */
+ private function normalize_case_insensitive_option($value, array $options): ?string {
+ if (!is_string($value) || $value === '') {
+ return null;
+ }
+ $lower = strtolower(trim($value));
+ foreach ($options as $opt) {
+ $opt_value = is_array($opt) ? ($opt['value'] ?? null) : $opt;
+ if (is_string($opt_value) && strtolower($opt_value) === $lower) {
+ return $opt_value;
+ }
+ }
+ return null;
+ }
+
private function sanitize_field_value($value, array $field) {
if (!empty($field['captcha_provider'])) {
return function_exists('aksrt_captcha_sanitize_provider_config')
@@ -874,6 +903,12 @@ class SchemaProvider {
return $this->sanitize_value($value, 'attachment_ids');
}
+ if (in_array($type, ['select', 'radio'], true) && !empty($field['case_insensitive']) && !empty($field['options'])) {
+ // 旧自由文本值(如小写货币代码)归一化为选项规范写法。
+ $normalized = $this->normalize_case_insensitive_option($value, (array) $field['options']);
+ return $normalized !== null ? $normalized : (string) ($field['default'] ?? '');
+ }
+
if (in_array($type, ['fieldset', 'accordion'], true)) {
return $this->sanitize_object_fields($value, (array) ($field['fields'] ?? []));
}