Bläddra i källkod

调整 优化代码细节

Little Write 5 månader sedan
förälder
incheckning
95cb7fc862
4 ändrade filer med 103 tillägg och 103 borttagningar
  1. 13 12
      controller/topup_creem.go
  2. 1 2
      model/topup.go
  3. 1 6
      web/src/components/settings/PaymentSetting.js
  4. 88 83
      web/src/pages/TopUp/index.js

+ 13 - 12
controller/topup_creem.go

@@ -36,8 +36,9 @@ func generateCreemSignature(payload string, secret string) string {
 // 验证Creem webhook签名
 func verifyCreemSignature(payload string, signature string, secret string) bool {
 	if secret == "" {
+		log.Printf("Creem webhook secret not set")
 		if setting.CreemTestMode {
-			log.Printf("Creem webhook secret未配置,测试模式下跳过签名验证")
+			log.Printf("Skip Creem webhook sign verify in test mode")
 			return true
 		}
 		return false
@@ -146,8 +147,8 @@ func RequestCreemPay(c *gin.Context) {
 	// 读取body内容用于打印,同时保留原始数据供后续使用
 	bodyBytes, err := io.ReadAll(c.Request.Body)
 	if err != nil {
-		log.Printf("读取请求body失败: %v", err)
-		c.JSON(200, gin.H{"message": "error", "data": "读取请求失败"})
+		log.Printf("read creem pay req body err: %v", err)
+		c.JSON(200, gin.H{"message": "error", "data": "read query error"})
 		return
 	}
 
@@ -158,7 +159,6 @@ func RequestCreemPay(c *gin.Context) {
 	c.Request.Body = io.NopCloser(bytes.NewReader(bodyBytes))
 
 	err = c.ShouldBindJSON(&req)
-	log.Printf(" json body is %+v", req)
 	if err != nil {
 		c.JSON(200, gin.H{"message": "error", "data": "参数错误"})
 		return
@@ -251,7 +251,9 @@ func CreemWebhook(c *gin.Context) {
 
 	// 打印关键信息(避免输出完整敏感payload)
 	log.Printf("Creem Webhook - URI: %s", c.Request.RequestURI)
-	if signature == "" && !setting.CreemTestMode {
+	if setting.CreemTestMode {
+		log.Printf("Creem Webhook - Signature: %s , Body: %s", signature, bodyBytes)
+	} else if signature == "" {
 		log.Printf("Creem Webhook缺少签名头")
 		c.AbortWithStatus(http.StatusUnauthorized)
 		return
@@ -314,12 +316,11 @@ func handleCheckoutCompleted(c *gin.Context, event *CreemWebhookEvent) {
 	}
 
 	// 记录详细的支付信息
-	log.Printf("处理Creem支付完成 - 订单号: %s, Creem订单ID: %s, 支付金额: %d %s, 客户邮箱: %s, 产品: %s",
+	log.Printf("处理Creem支付完成 - 订单号: %s, Creem订单ID: %s, 支付金额: %d %s, 客户邮箱: <redacted>, 产品: %s",
 		referenceId,
 		event.Object.Order.Id,
 		event.Object.Order.AmountPaid,
 		event.Object.Order.Currency,
-		event.Object.Customer.Email,
 		event.Object.Product.Name)
 
 	// 查询本地订单确认存在
@@ -355,8 +356,8 @@ func handleCheckoutCompleted(c *gin.Context, event *CreemWebhookEvent) {
 		return
 	}
 
-	log.Printf("Creem充值成功 - 订单号: %s, 充值额度: %d, 支付金额: %.2f, 客户邮箱: %s, 客户姓名: %s",
-		referenceId, topUp.Amount, topUp.Money, customerEmail, customerName)
+	log.Printf("Creem充值成功 - 订单号: %s, 充值额度: %d, 支付金额: %.2f",
+		referenceId, topUp.Amount, topUp.Money)
 	c.Status(http.StatusOK)
 }
 
@@ -438,11 +439,11 @@ func genCreemLink(referenceId string, product *CreemProduct, email string, usern
 		return "", fmt.Errorf("读取响应失败: %v", err)
 	}
 
-	log.Printf("Creem API响应 - 状态码: %d, 响应体: %s", resp.StatusCode, string(body))
+	log.Printf("Creem API resp - status code: %d, resp: %s", resp.StatusCode, string(body))
 
 	// 检查响应状态
 	if resp.StatusCode/100 != 2 {
-		return "", fmt.Errorf("Creem API 返回错误状态 %d: %s", resp.StatusCode, string(body))
+		return "", fmt.Errorf("Creem API http status %d ", resp.StatusCode)
 	}
 	// 解析响应
 	var checkoutResp CreemCheckoutResponse
@@ -452,7 +453,7 @@ func genCreemLink(referenceId string, product *CreemProduct, email string, usern
 	}
 
 	if checkoutResp.CheckoutUrl == "" {
-		return "", fmt.Errorf("Creem API 未返回支付链接")
+		return "", fmt.Errorf("Creem API resp no checkout url ")
 	}
 
 	log.Printf("Creem 支付链接创建成功 - 订单号: %s, 支付链接: %s", referenceId, checkoutResp.CheckoutUrl)

+ 1 - 2
model/topup.go

@@ -98,7 +98,7 @@ func Recharge(referenceId string, customerId string) (err error) {
 
 	return nil
 }
-func RechargeCreem(referenceId string, customerEmail string) (err error) {
+func RechargeCreem(referenceId string, customerEmail string, customerName string) (err error) {
 	if referenceId == "" {
 		return errors.New("未提供支付单号")
 	}
@@ -148,7 +148,6 @@ func RechargeCreem(referenceId string, customerEmail string) (err error) {
 			// 如果用户邮箱为空,则更新为支付时使用的邮箱
 			if user.Email == "" {
 				updateFields["email"] = customerEmail
-				// 避免输出敏感信息到stdout
 			}
 		}
 

+ 1 - 6
web/src/components/settings/PaymentSetting.js

@@ -50,12 +50,7 @@ const PaymentSetting = () => {
             }
             break;
           case 'CreemProducts':
-            try {
-              newInputs[item.key] = item.value;
-            } catch (error) {
-              console.error('解析CreemProducts出错:', error);
-              newInputs[item.key] = '[]';
-            }
+            newInputs[item.key] = item.value || '[]';
             break;
           case 'Price':
           case 'MinTopUp':

+ 88 - 83
web/src/pages/TopUp/index.js

@@ -315,6 +315,11 @@ const TopUp = () => {
       showError(t('请选择产品'));
       return;
     }
+    // Validate product has required fields
+    if (!selectedCreemProduct.productId) {
+      showError(t('产品配置错误,请联系管理员'));
+      return;
+    }
     setConfirmLoading(true);
     try {
       const res = await API.post('/api/user/creem/pay', {
@@ -668,14 +673,14 @@ const TopUp = () => {
       </Modal>
 
       <Modal
-          title={t('确定要充值吗')}
-          visible={stripeOpen}
-          onOk={onlineStripeTopUp}
-          onCancel={handleStripeCancel}
-          maskClosable={false}
-          size='small'
-          centered
-          confirmLoading={confirmLoading}
+        title={t('确定要充值吗')}
+        visible={stripeOpen}
+        onOk={onlineStripeTopUp}
+        onCancel={handleStripeCancel}
+        maskClosable={false}
+        size='small'
+        centered
+        confirmLoading={confirmLoading}
       >
         <p>
           {t('充值数量')}:{stripeTopUpCount}
@@ -1026,85 +1031,85 @@ const TopUp = () => {
               )}
 
               {enableStripeTopUp && (
-                  <>
-                    {/* 桌面端显示的自定义金额和支付按钮 */}
-                    <div className='hidden md:block space-y-4'>
-                      <Divider style={{ margin: '24px 0' }}>
-                        <Text className='text-sm font-medium'>
-                          {t(!enableOnlineTopUp ? '或输入自定义金额' : 'Stripe')}
-                        </Text>
-                      </Divider>
-
-                      <div>
-                        <div className='flex justify-between mb-2'>
-                          <Text strong>{t('充值数量')}</Text>
-                          {amountLoading ? (
-                              <Skeleton.Title
-                                  style={{ width: '80px', height: '16px' }}
-                              />
-                          ) : (
-                              <Text type='tertiary'>
-                                {t('实付金额:') + renderStripeAmount()}
-                              </Text>
-                          )}
-                        </div>
-                        <InputNumber
-                            disabled={!enableStripeTopUp}
-                            placeholder={
-                                t('充值数量,最低 ') + renderQuotaWithAmount(stripeMinTopUp)
-                            }
-                            value={stripeTopUpCount}
-                            min={stripeMinTopUp}
-                            max={999999999}
-                            step={1}
-                            precision={0}
-                            onChange={async (value) => {
-                              if (value && value >= 1) {
-                                setStripeTopUpCount(value);
-                                setSelectedPreset(null);
-                                await getStripeAmount(value);
-                              }
-                            }}
-                            onBlur={(e) => {
-                              const value = parseInt(e.target.value);
-                              if (!value || value < 1) {
-                                setStripeTopUpCount(1);
-                                getStripeAmount(1);
-                              }
-                            }}
-                            size='large'
-                            className='w-full'
-                            formatter={(value) => (value ? `${value}` : '')}
-                            parser={(value) =>
-                                value ? parseInt(value.replace(/[^\d]/g, '')) : 0
-                            }
-                        />
+                <>
+                  {/* 桌面端显示的自定义金额和支付按钮 */}
+                  <div className='hidden md:block space-y-4'>
+                    <Divider style={{ margin: '24px 0' }}>
+                      <Text className='text-sm font-medium'>
+                        {t(!enableOnlineTopUp ? '或输入自定义金额' : 'Stripe')}
+                      </Text>
+                    </Divider>
+
+                    <div>
+                      <div className='flex justify-between mb-2'>
+                        <Text strong>{t('充值数量')}</Text>
+                        {amountLoading ? (
+                          <Skeleton.Title
+                            style={{ width: '80px', height: '16px' }}
+                          />
+                        ) : (
+                          <Text type='tertiary'>
+                            {t('实付金额:') + renderStripeAmount()}
+                          </Text>
+                        )}
                       </div>
+                      <InputNumber
+                        disabled={!enableStripeTopUp}
+                        placeholder={
+                          t('充值数量,最低 ') + renderQuotaWithAmount(stripeMinTopUp)
+                        }
+                        value={stripeTopUpCount}
+                        min={stripeMinTopUp}
+                        max={999999999}
+                        step={1}
+                        precision={0}
+                        onChange={async (value) => {
+                          if (value && value >= 1) {
+                            setStripeTopUpCount(value);
+                            setSelectedPreset(null);
+                            await getStripeAmount(value);
+                          }
+                        }}
+                        onBlur={(e) => {
+                          const value = parseInt(e.target.value);
+                          if (!value || value < 1) {
+                            setStripeTopUpCount(1);
+                            getStripeAmount(1);
+                          }
+                        }}
+                        size='large'
+                        className='w-full'
+                        formatter={(value) => (value ? `${value}` : '')}
+                        parser={(value) =>
+                          value ? parseInt(value.replace(/[^\d]/g, '')) : 0
+                        }
+                      />
+                    </div>
 
-                      <div>
-                        <Text strong className='block mb-3'>
-                          {t('选择支付方式')}
-                        </Text>
-                          <div className='grid grid-cols-1 gap-3'>
-                            <Button
-                                key='stripe'
-                                type='primary'
-                                onClick={() => stripePreTopUp()}
-                                size='large'
-                                disabled={!enableStripeTopUp}
-                                loading={paymentLoading && payWay === 'stripe'}
-                                icon={<CreditCard size={16} />}
-                                style={{
-                                  height: '40px',
-                                  color: '#b161fe',
-                                }}
-                                className='transition-all hover:shadow-md w-full'
-                            >
-                              <span className='ml-1'>Stripe</span>
-                            </Button>
-                          </div>
+                    <div>
+                      <Text strong className='block mb-3'>
+                        {t('选择支付方式')}
+                      </Text>
+                      <div className='grid grid-cols-1 gap-3'>
+                        <Button
+                          key='stripe'
+                          type='primary'
+                          onClick={() => stripePreTopUp()}
+                          size='large'
+                          disabled={!enableStripeTopUp}
+                          loading={paymentLoading && payWay === 'stripe'}
+                          icon={<CreditCard size={16} />}
+                          style={{
+                            height: '40px',
+                            color: '#b161fe',
+                          }}
+                          className='transition-all hover:shadow-md w-full'
+                        >
+                          <span className='ml-1'>Stripe</span>
+                        </Button>
                       </div>
                     </div>
+                  </div>
 
                   {/* 移动端 Stripe 充值区域 */}
                   <div className='md:hidden space-y-4'>