mirror of
				https://github.com/linux-do/new-api.git
				synced 2025-11-04 21:33:41 +08:00 
			
		
		
		
	feat: 可自定义支付回调地址及最低购买数量
This commit is contained in:
		@@ -9,14 +9,19 @@ import (
 | 
			
		||||
	"github.com/google/uuid"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Pay Settings
 | 
			
		||||
 | 
			
		||||
var PayAddress = ""
 | 
			
		||||
var CustomCallbackAddress = ""
 | 
			
		||||
var EpayId = ""
 | 
			
		||||
var EpayKey = ""
 | 
			
		||||
var Price = 7.3
 | 
			
		||||
var MinTopUp = 1
 | 
			
		||||
 | 
			
		||||
var StartTime = time.Now().Unix() // unit: second
 | 
			
		||||
var Version = "v0.0.0"            // this hard coding will be replaced automatically when building, no need to manually change
 | 
			
		||||
var SystemName = "New API"
 | 
			
		||||
var ServerAddress = "http://localhost:3000"
 | 
			
		||||
var PayAddress = ""
 | 
			
		||||
var EpayId = ""
 | 
			
		||||
var EpayKey = ""
 | 
			
		||||
var Price = 7.3
 | 
			
		||||
var Footer = ""
 | 
			
		||||
var Logo = ""
 | 
			
		||||
var TopUpLink = ""
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,7 @@ func GetStatus(c *gin.Context) {
 | 
			
		||||
			"wechat_login":             common.WeChatAuthEnabled,
 | 
			
		||||
			"server_address":           common.ServerAddress,
 | 
			
		||||
			"price":                    common.Price,
 | 
			
		||||
			"min_topup":                common.MinTopUp,
 | 
			
		||||
			"turnstile_check":          common.TurnstileCheckEnabled,
 | 
			
		||||
			"turnstile_site_key":       common.TurnstileSiteKey,
 | 
			
		||||
			"top_up_link":              common.TopUpLink,
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,7 @@ import (
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"one-api/common"
 | 
			
		||||
	"one-api/model"
 | 
			
		||||
	"one-api/service"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
@@ -55,14 +56,14 @@ func RequestEpay(c *gin.Context) {
 | 
			
		||||
		c.JSON(200, gin.H{"message": err.Error(), "data": 10})
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if req.Amount < 1 {
 | 
			
		||||
		c.JSON(200, gin.H{"message": "充值金额不能小于1", "data": 10})
 | 
			
		||||
	if req.Amount < common.MinTopUp {
 | 
			
		||||
		c.JSON(200, gin.H{"message": fmt.Sprintf("充值数量不能小于 %d", common.MinTopUp), "data": 10})
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	id := c.GetInt("id")
 | 
			
		||||
	user, _ := model.GetUserById(id, false)
 | 
			
		||||
	amount := GetAmount(float64(req.Amount), *user)
 | 
			
		||||
	payMoney := GetAmount(float64(req.Amount), *user)
 | 
			
		||||
 | 
			
		||||
	var payType epay.PurchaseType
 | 
			
		||||
	if req.PaymentMethod == "zfb" {
 | 
			
		||||
@@ -72,11 +73,10 @@ func RequestEpay(c *gin.Context) {
 | 
			
		||||
		req.PaymentMethod = "wxpay"
 | 
			
		||||
		payType = epay.WechatPay
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	callBackAddress := service.GetCallbackAddress()
 | 
			
		||||
	returnUrl, _ := url.Parse(common.ServerAddress + "/log")
 | 
			
		||||
	notifyUrl, _ := url.Parse(common.ServerAddress + "/api/user/epay/notify")
 | 
			
		||||
	notifyUrl, _ := url.Parse(callBackAddress + "/api/user/epay/notify")
 | 
			
		||||
	tradeNo := strconv.FormatInt(time.Now().Unix(), 10)
 | 
			
		||||
	payMoney := amount
 | 
			
		||||
	client := GetEpayClient()
 | 
			
		||||
	if client == nil {
 | 
			
		||||
		c.JSON(200, gin.H{"message": "error", "data": "当前管理员未配置支付信息"})
 | 
			
		||||
@@ -169,8 +169,8 @@ func RequestAmount(c *gin.Context) {
 | 
			
		||||
		c.JSON(200, gin.H{"message": "error", "data": "参数错误"})
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if req.Amount < 1 {
 | 
			
		||||
		c.JSON(200, gin.H{"message": "error", "data": "充值金额不能小于1"})
 | 
			
		||||
	if req.Amount < common.MinTopUp {
 | 
			
		||||
		c.JSON(200, gin.H{"message": "error", "data": fmt.Sprintf("充值数量不能小于 %d", common.MinTopUp)})
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	id := c.GetInt("id")
 | 
			
		||||
 
 | 
			
		||||
@@ -56,9 +56,11 @@ func InitOptionMap() {
 | 
			
		||||
	common.OptionMap["Logo"] = common.Logo
 | 
			
		||||
	common.OptionMap["ServerAddress"] = ""
 | 
			
		||||
	common.OptionMap["PayAddress"] = ""
 | 
			
		||||
	common.OptionMap["CustomCallbackAddress"] = ""
 | 
			
		||||
	common.OptionMap["EpayId"] = ""
 | 
			
		||||
	common.OptionMap["EpayKey"] = ""
 | 
			
		||||
	common.OptionMap["Price"] = strconv.FormatFloat(common.Price, 'f', -1, 64)
 | 
			
		||||
	common.OptionMap["MinTopUp"] = strconv.Itoa(common.MinTopUp)
 | 
			
		||||
	common.OptionMap["TopupGroupRatio"] = common.TopupGroupRatio2JSONString()
 | 
			
		||||
	common.OptionMap["GitHubClientId"] = ""
 | 
			
		||||
	common.OptionMap["GitHubClientSecret"] = ""
 | 
			
		||||
@@ -194,12 +196,16 @@ func updateOptionMap(key string, value string) (err error) {
 | 
			
		||||
		common.ServerAddress = value
 | 
			
		||||
	case "PayAddress":
 | 
			
		||||
		common.PayAddress = value
 | 
			
		||||
	case "CustomCallbackAddress":
 | 
			
		||||
		common.CustomCallbackAddress = value
 | 
			
		||||
	case "EpayId":
 | 
			
		||||
		common.EpayId = value
 | 
			
		||||
	case "EpayKey":
 | 
			
		||||
		common.EpayKey = value
 | 
			
		||||
	case "Price":
 | 
			
		||||
		common.Price, _ = strconv.ParseFloat(value, 64)
 | 
			
		||||
	case "MinTopUp":
 | 
			
		||||
		common.MinTopUp, _ = strconv.Atoi(value)
 | 
			
		||||
	case "TopupGroupRatio":
 | 
			
		||||
		err = common.UpdateTopupGroupRatioByJSONString(value)
 | 
			
		||||
	case "GitHubClientId":
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								service/epay.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								service/epay.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
package service
 | 
			
		||||
 | 
			
		||||
import "one-api/common"
 | 
			
		||||
 | 
			
		||||
func GetCallbackAddress() string {
 | 
			
		||||
	if common.CustomCallbackAddress == "" {
 | 
			
		||||
		return common.ServerAddress
 | 
			
		||||
	}
 | 
			
		||||
	return common.CustomCallbackAddress
 | 
			
		||||
}
 | 
			
		||||
@@ -20,8 +20,10 @@ const SystemSetting = () => {
 | 
			
		||||
        EpayId: '',
 | 
			
		||||
        EpayKey: '',
 | 
			
		||||
        Price: 7.3,
 | 
			
		||||
        MinTopUp: 1,
 | 
			
		||||
        TopupGroupRatio: '',
 | 
			
		||||
        PayAddress: '',
 | 
			
		||||
        CustomCallbackAddress: '',
 | 
			
		||||
        Footer: '',
 | 
			
		||||
        WeChatAuthEnabled: '',
 | 
			
		||||
        WeChatServerAddress: '',
 | 
			
		||||
@@ -280,7 +282,7 @@ const SystemSetting = () => {
 | 
			
		||||
                        更新服务器地址
 | 
			
		||||
                    </Form.Button>
 | 
			
		||||
                    <Divider/>
 | 
			
		||||
                    <Header as='h3'>支付设置(当前仅支持易支付接口,使用上方服务器地址作为回调地址!)</Header>
 | 
			
		||||
                    <Header as='h3'>支付设置(当前仅支持易支付接口,默认使用上方服务器地址作为回调地址!)</Header>
 | 
			
		||||
                    <Form.Group widths='equal'>
 | 
			
		||||
                        <Form.Input
 | 
			
		||||
                            label='支付地址,不填写则不启用在线支付'
 | 
			
		||||
@@ -303,14 +305,31 @@ const SystemSetting = () => {
 | 
			
		||||
                            name='EpayKey'
 | 
			
		||||
                            onChange={handleInputChange}
 | 
			
		||||
                        />
 | 
			
		||||
                        <Form.Input
 | 
			
		||||
                            label='充值价格(x元/美金)'
 | 
			
		||||
                            placeholder='例如:7,就是7元/美金'
 | 
			
		||||
                            value={inputs.Price}
 | 
			
		||||
                            name='Price'
 | 
			
		||||
 | 
			
		||||
                            min={0}
 | 
			
		||||
                            onChange={handleInputChange}
 | 
			
		||||
                    </Form.Group>
 | 
			
		||||
                    <Form.Group widths='equal'>
 | 
			
		||||
                        <Form.Input
 | 
			
		||||
                          label='回调地址,不填写则使用上方服务器地址作为回调地址'
 | 
			
		||||
                          placeholder='例如:https://yourdomain.com'
 | 
			
		||||
                          value={inputs.CustomCallbackAddress}
 | 
			
		||||
                          name='CustomCallbackAddress'
 | 
			
		||||
                          onChange={handleInputChange}
 | 
			
		||||
                        />
 | 
			
		||||
                        <Form.Input
 | 
			
		||||
                          label='充值价格(x元/美金)'
 | 
			
		||||
                          placeholder='例如:7,就是7元/美金'
 | 
			
		||||
                          value={inputs.Price}
 | 
			
		||||
                          name='Price'
 | 
			
		||||
                          min={0}
 | 
			
		||||
                          onChange={handleInputChange}
 | 
			
		||||
                        />
 | 
			
		||||
                        <Form.Input
 | 
			
		||||
                          label='最低充值数量'
 | 
			
		||||
                          placeholder='例如:2,就是最低充值2$'
 | 
			
		||||
                          value={inputs.MinTopUp}
 | 
			
		||||
                          name='MinTopUp'
 | 
			
		||||
                          min={1}
 | 
			
		||||
                          onChange={handleInputChange}
 | 
			
		||||
                        />
 | 
			
		||||
                    </Form.Group>
 | 
			
		||||
                    <Form.Group widths='equal'>
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,7 @@ const TopUp = () => {
 | 
			
		||||
    const [topUpCount, setTopUpCount] = useState(10);
 | 
			
		||||
    const [minTopupCount, setMinTopUpCount] = useState(1);
 | 
			
		||||
    const [amount, setAmount] = useState(0.0);
 | 
			
		||||
    const [minTopUp, setMinTopUp] = useState(1);
 | 
			
		||||
    const [topUpLink, setTopUpLink] = useState('');
 | 
			
		||||
    const [enableOnlineTopUp, setEnableOnlineTopUp] = useState(false);
 | 
			
		||||
    const [userQuota, setUserQuota] = useState(0);
 | 
			
		||||
@@ -61,6 +62,10 @@ const TopUp = () => {
 | 
			
		||||
        if (amount === 0) {
 | 
			
		||||
            await getAmount();
 | 
			
		||||
        }
 | 
			
		||||
        if (topUpCount < minTopUp) {
 | 
			
		||||
            showInfo('充值数量不能小于' + minTopUp);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        setPayWay(payment)
 | 
			
		||||
        setOpen(true);
 | 
			
		||||
    }
 | 
			
		||||
@@ -69,6 +74,10 @@ const TopUp = () => {
 | 
			
		||||
        if (amount === 0) {
 | 
			
		||||
            await getAmount();
 | 
			
		||||
        }
 | 
			
		||||
        if (topUpCount < minTopUp) {
 | 
			
		||||
            showInfo('充值数量不能小于' + minTopUp);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        setOpen(false);
 | 
			
		||||
        try {
 | 
			
		||||
            const res = await API.post('/api/user/pay', {
 | 
			
		||||
@@ -132,6 +141,9 @@ const TopUp = () => {
 | 
			
		||||
            if (status.top_up_link) {
 | 
			
		||||
                setTopUpLink(status.top_up_link);
 | 
			
		||||
            }
 | 
			
		||||
            if (status.min_topup) {
 | 
			
		||||
                setMinTopUp(status.min_topup);
 | 
			
		||||
            }
 | 
			
		||||
            if (status.enable_online_topup) {
 | 
			
		||||
                setEnableOnlineTopUp(status.enable_online_topup);
 | 
			
		||||
            }
 | 
			
		||||
@@ -239,12 +251,13 @@ const TopUp = () => {
 | 
			
		||||
                                        disabled={!enableOnlineTopUp}
 | 
			
		||||
                                        field={'redemptionCount'}
 | 
			
		||||
                                        label={'实付金额:' + renderAmount()}
 | 
			
		||||
                                        placeholder='充值数量'
 | 
			
		||||
                                        placeholder={'充值数量,最低' + minTopUp + '$'}
 | 
			
		||||
                                        name='redemptionCount'
 | 
			
		||||
                                        type={'number'}
 | 
			
		||||
                                        value={topUpCount}
 | 
			
		||||
                                        suffix={'$'}
 | 
			
		||||
                                        min={1}
 | 
			
		||||
                                        min={minTopUp}
 | 
			
		||||
                                        defaultValue={minTopUp}
 | 
			
		||||
                                        max={100000}
 | 
			
		||||
                                        onChange={async (value) => {
 | 
			
		||||
                                            if (value < 1) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user