From 8855683f2fd443759cf7738956494103e37fcf7a Mon Sep 17 00:00:00 2001 From: dengqichen Date: Wed, 19 Nov 2025 23:22:56 +0800 Subject: [PATCH] aaaaa --- .env | 3 +- src/shared/libs/card-generator/config.js | 23 ++++++-- src/shared/libs/card-generator/generator.js | 31 ++++++---- .../configs/sites/windsurf.yaml | 59 +++++++++++++++++-- .../core/config-validator.js | 2 +- 5 files changed, 95 insertions(+), 23 deletions(-) diff --git a/.env b/.env index 54b5ea2..02d8d47 100644 --- a/.env +++ b/.env @@ -1,7 +1,8 @@ # AdsPower 指纹浏览器配置 ADSPOWER_USER_ID=k1728p8l ADSPOWER_API_KEY=35de43696f6241f3df895f2f48777a99 -# ADSPOWER_API=http://local.adspower.net:50325 +# 使用 127.0.0.1 而不是 local.adspower.net,避免 TUN VPN 路由冲突 +ADSPOWER_API=http://127.0.0.1:50325 # MySQL 数据库配置 MYSQL_HOST=172.22.222.111 diff --git a/src/shared/libs/card-generator/config.js b/src/shared/libs/card-generator/config.js index 10ebfa8..6c85e1c 100644 --- a/src/shared/libs/card-generator/config.js +++ b/src/shared/libs/card-generator/config.js @@ -6,8 +6,21 @@ const CARD_TYPES = { unionpay: { name: '中国银联 (UnionPay)', - // 固定前缀(用户提供的成功案例都是这个前缀) - prefix: '622836754', // 固定BIN前缀 + // 多个 9 位银联卡 BIN 前缀(基于真实成功案例和同系列扩展) + // 策略:优先使用已验证成功的 622836754 和其同系列变体 + prefixes: [ + '622836754', // ✅ 原始成功案例(最高优先级) + '622836755', '622836756', '622836757', // 同系列变体 + '622836758', '622836759', '622836750', // 继续同系列 + '622836751', '622836752', '622836753', // 更多同系列 + ], + // 备用:如果同系列都失败,尝试其他真实 BIN + // 暂时注释掉未验证的 BIN,减少失败率 + // prefixes_backup: [ + // '622206000', '622210000', // 工商银行 + // '622620000', // 民生银行 + // '622588000', // 招商银行 + // ], length: 16, cvvLength: 3, useLuhn: true, @@ -29,10 +42,10 @@ const CARD_TYPES = { '5956423', '7237848', '0385107', '4252006', '7562054' ], - // 生成策略配置 + // 生成策略配置(优化后) generation: { - mutationRate: 0.5, // 50% 使用变异策略 - randomRate: 0.5, // 50% 使用纯随机 + mutationRate: 0.7, // 70% 使用变异策略(基于真实成功案例) + randomRate: 0.3, // 30% 使用纯随机 mutationDigits: [1, 2] // 变异时改变1-2个数字 } }, diff --git a/src/shared/libs/card-generator/generator.js b/src/shared/libs/card-generator/generator.js index 5682d55..30c219d 100644 --- a/src/shared/libs/card-generator/generator.js +++ b/src/shared/libs/card-generator/generator.js @@ -83,29 +83,36 @@ class CardGenerator { * @returns {string} */ _generateCardNumberInternal(type, config) { - const { prefix, length, useLuhn, successfulPatterns, generation } = config; + const { prefix, prefixes, length, useLuhn, successfulPatterns, generation } = config; - // 如果有成功案例和生成策略配置,使用三策略混合 + // 支持单个 prefix 或多个 prefixes + let selectedPrefix = prefix; + if (prefixes && Array.isArray(prefixes) && prefixes.length > 0) { + // 从 prefixes 数组中随机选择一个 + selectedPrefix = prefixes[randomInt(0, prefixes.length - 1)]; + } + + // 如果有成功案例和生成策略配置,使用三策略混合(优化版) if (successfulPatterns && generation) { const rand = Math.random(); - // 策略1(30%):加权生成(基于统计分布) - if (rand < 0.3) { - return this.generateByWeights(prefix, length); + // 策略1(20%):加权生成(基于统计分布) + if (rand < 0.2) { + return this.generateByWeights(selectedPrefix, length); } - // 策略2(40%):变异真实案例 - else if (rand < 0.7) { - return this.generateByMutation(prefix, successfulPatterns, generation.mutationDigits); + // 策略2(60%):变异真实案例(提高到60%,因为这是最可靠的) + else if (rand < 0.8) { + return this.generateByMutation(selectedPrefix, successfulPatterns, generation.mutationDigits); } - // 策略3(30%):完全随机 + // 策略3(20%):完全随机(降低到20%) } // 策略3:纯随机生成(默认或回退) if (useLuhn) { - return generateLuhnNumber(prefix, length); + return generateLuhnNumber(selectedPrefix, length); } else { - const remainingLength = length - prefix.length; - return prefix + randomDigits(remainingLength); + const remainingLength = length - selectedPrefix.length; + return selectedPrefix + randomDigits(remainingLength); } } diff --git a/src/tools/automation-framework/configs/sites/windsurf.yaml b/src/tools/automation-framework/configs/sites/windsurf.yaml index 2de3a67..7ef6ea7 100644 --- a/src/tools/automation-framework/configs/sites/windsurf.yaml +++ b/src/tools/automation-framework/configs/sites/windsurf.yaml @@ -151,8 +151,11 @@ workflow: type: "select" addressLine1: find: + - css: '#billingAddressLine1' # 使用 id 选择器,兼容所有语言 + - css: 'input[name="billingAddressLine1"]' - css: 'input[placeholder*="地址"]' - css: 'input[placeholder*="Address"]' + - css: 'input[placeholder*="Alamat"]' # 印尼语 value: "kowloon" # 滚动到页面底部(确保订阅按钮可见) @@ -164,8 +167,10 @@ workflow: - action: click name: "点击提交支付" selector: - - css: 'button[data-testid="hosted-payment-submit-button"]' - - css: 'button[type="submit"]' + - css: 'button[data-testid="hosted-payment-submit-button"]' # Stripe 官方 testid + - css: 'button.SubmitButton' # Stripe 按钮类名 + - css: 'button[type="submit"]' # 通用 submit 按钮 + - css: 'button:has(.SubmitButton-IconContainer)' # 包含 icon 容器的按钮 timeout: 30000 # 给足够时间等待按钮从 disabled 变为可点击 waitForEnabled: true # 循环等待按钮激活(不是等待出现,而是等待可点击) @@ -187,13 +192,30 @@ workflow: - urlNotContains: "stripe.com" - urlNotContains: "checkout.stripe.com" failure: + # 英文 - textContains: "card was declined" - textContains: "Your card was declined" - textContains: "declined" + - textContains: "We are unable to authenticate your payment method" + # 中文 - textContains: "卡片被拒绝" - textContains: "我们无法验证您的支付方式" - textContains: "我们未能验证您的支付方式" - textContains: "请选择另一支付方式并重试" + # 马来语 + - textContains: "Kad anda telah ditolak" # 您的卡已被拒绝 + - textContains: "Kami tidak dapat mensahihkan kaedah pembayaran" + - textContains: "Sila pilih kaedah pembayaran yang berbeza" + # 印尼语 + - textContains: "Kami tidak dapat memverifikasi metode pembayaran" + - textContains: "Silakan pilih metode pembayaran" + - textContains: "kartu ditolak" + # 泰语 + - textContains: "บัตรของคุณถูกปฏิเสธ" # 您的卡被拒绝 + - textContains: "ไม่สามารถยืนยัน" # 无法验证 + - textContains: "เราตรวจสอบสิทธิ์วิธีการชำระเงินของคุณไม่ได้" # 我们无法验证您的支付方式 + - textContains: "โปรดเลือกวิธีการชำระเงินอื่น" # 请选择另一个支付方式 + # 通用错误元素 - elementExists: ".error-message" timeout: 15000 pollInterval: 500 @@ -240,13 +262,42 @@ workflow: optional: true # ==================== 步骤 9: 退出登录 ==================== + # 9.1 滚动到页面底部 + - action: scroll + name: "滚动到页面底部" + direction: "bottom" + + # 9.2 等待滚动完成 + - action: wait + name: "等待滚动完成" + duration: 1000 + + # 9.3 点击退出登录 - action: click name: "点击退出登录" selector: + - css: "div.body3.cursor-pointer" + text: "Log out" - text: "Log out" options: - exact: true - caseInsensitive: false + exact: false + caseInsensitive: true + timeout: 15000 + waitForNavigation: false + + # 9.4 等待退出完成 + - action: wait + name: "等待退出完成" + duration: 3000 + + # 9.5 验证是否跳转到登录页 + - action: verify + name: "验证跳转到登录页" + conditions: + success: + - urlContains: "/account/login" + timeout: 10000 + onFailure: "throw" # 错误处理配置 errorHandling: diff --git a/src/tools/automation-framework/core/config-validator.js b/src/tools/automation-framework/core/config-validator.js index 6d8ff35..80c70e8 100644 --- a/src/tools/automation-framework/core/config-validator.js +++ b/src/tools/automation-framework/core/config-validator.js @@ -42,7 +42,7 @@ class ConfigValidator { }, scroll: { required: [], - optional: ['name', 'type', 'selector', 'x', 'y', 'behavior'] + optional: ['name', 'type', 'selector', 'x', 'y', 'behavior', 'direction'] }, custom: { required: ['handler'],