feat(waffo): Waffo payment gateway integration with configurable methods

- Add Waffo payment SDK integration (waffo-go v1.3.1)
- Backend: webhook handler, pay endpoint, order lock race-condition fix
- Settings: full Waffo config (API keys, sandbox/prod, currency, pay methods)
- Frontend: Waffo payment buttons in topup page, admin settings panel
- i18n: Waffo-related translations for en/fr/ja/ru/vi/zh-TW

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
zhongyuan.zhao
2026-03-17 18:04:58 +08:00
parent 620e066b39
commit 202a433f86
24 changed files with 1472 additions and 89 deletions
+50
View File
@@ -89,6 +89,22 @@ func InitOptionMap() {
common.OptionMap["CreemProducts"] = setting.CreemProducts
common.OptionMap["CreemTestMode"] = strconv.FormatBool(setting.CreemTestMode)
common.OptionMap["CreemWebhookSecret"] = setting.CreemWebhookSecret
common.OptionMap["WaffoEnabled"] = strconv.FormatBool(setting.WaffoEnabled)
common.OptionMap["WaffoApiKey"] = setting.WaffoApiKey
common.OptionMap["WaffoPrivateKey"] = setting.WaffoPrivateKey
common.OptionMap["WaffoPublicCert"] = setting.WaffoPublicCert
common.OptionMap["WaffoSandboxPublicCert"] = setting.WaffoSandboxPublicCert
common.OptionMap["WaffoSandboxApiKey"] = setting.WaffoSandboxApiKey
common.OptionMap["WaffoSandboxPrivateKey"] = setting.WaffoSandboxPrivateKey
common.OptionMap["WaffoSandbox"] = strconv.FormatBool(setting.WaffoSandbox)
common.OptionMap["WaffoMerchantId"] = setting.WaffoMerchantId
common.OptionMap["WaffoNotifyUrl"] = setting.WaffoNotifyUrl
common.OptionMap["WaffoReturnUrl"] = setting.WaffoReturnUrl
common.OptionMap["WaffoSubscriptionReturnUrl"] = setting.WaffoSubscriptionReturnUrl
common.OptionMap["WaffoCurrency"] = setting.WaffoCurrency
common.OptionMap["WaffoUnitPrice"] = strconv.FormatFloat(setting.WaffoUnitPrice, 'f', -1, 64)
common.OptionMap["WaffoMinTopUp"] = strconv.Itoa(setting.WaffoMinTopUp)
common.OptionMap["WaffoPayMethods"] = setting.WaffoPayMethods2JsonString()
common.OptionMap["TopupGroupRatio"] = common.TopupGroupRatio2JSONString()
common.OptionMap["Chats"] = setting.Chats2JsonString()
common.OptionMap["AutoGroups"] = setting.AutoGroups2JsonString()
@@ -358,6 +374,36 @@ func updateOptionMap(key string, value string) (err error) {
setting.CreemTestMode = value == "true"
case "CreemWebhookSecret":
setting.CreemWebhookSecret = value
case "WaffoEnabled":
setting.WaffoEnabled = value == "true"
case "WaffoApiKey":
setting.WaffoApiKey = value
case "WaffoPrivateKey":
setting.WaffoPrivateKey = value
case "WaffoPublicCert":
setting.WaffoPublicCert = value
case "WaffoSandboxPublicCert":
setting.WaffoSandboxPublicCert = value
case "WaffoSandboxApiKey":
setting.WaffoSandboxApiKey = value
case "WaffoSandboxPrivateKey":
setting.WaffoSandboxPrivateKey = value
case "WaffoSandbox":
setting.WaffoSandbox = value == "true"
case "WaffoMerchantId":
setting.WaffoMerchantId = value
case "WaffoNotifyUrl":
setting.WaffoNotifyUrl = value
case "WaffoReturnUrl":
setting.WaffoReturnUrl = value
case "WaffoSubscriptionReturnUrl":
setting.WaffoSubscriptionReturnUrl = value
case "WaffoCurrency":
setting.WaffoCurrency = value
case "WaffoUnitPrice":
setting.WaffoUnitPrice, _ = strconv.ParseFloat(value, 64)
case "WaffoMinTopUp":
setting.WaffoMinTopUp, _ = strconv.Atoi(value)
case "TopupGroupRatio":
err = common.UpdateTopupGroupRatioByJSONString(value)
case "GitHubClientId":
@@ -458,6 +504,10 @@ func updateOptionMap(key string, value string) (err error) {
setting.StreamCacheQueueLength, _ = strconv.Atoi(value)
case "PayMethods":
err = operation_setting.UpdatePayMethodsByJsonString(value)
case "WaffoPayMethods":
// WaffoPayMethods is read directly from OptionMap via setting.GetWaffoPayMethods().
// The value is already stored in OptionMap at the top of this function (line: common.OptionMap[key] = value).
// No additional in-memory variable to update.
}
return err
}