aaaaa
This commit is contained in:
parent
2cc8139924
commit
8855683f2f
3
.env
3
.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
|
||||
|
||||
@ -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个数字
|
||||
}
|
||||
},
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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'],
|
||||
|
||||
Loading…
Reference in New Issue
Block a user