PAYATHON 2026

payment processor 基于 IP address 的 Fraud detection 问题

支付小周

结论

不要为客服付款请求伪造、随机生成或轮换 IP address。客服付款和客户自助付款是两种不同的交易渠道,应该交给 payment processor 按不同的风控配置处理。

建议这样做:

  1. 客户自助付款继续提交真实的客户 IP address,并保留现有 Fraud detection rules。
  2. 客服代客付款使用独立的 merchant account、子账户、API credential、payment profile 或 transaction source。
  3. 客服渠道使用适合人工代客交易的风控规则,例如 MOTO(Mail Order / Telephone Order)、客服辅助交易或 trusted backend flow。
  4. 如果 payment processor 无法按账户或渠道区分规则,应联系其技术支持调整集成方案,或者为客服渠道更换 processor。

如果 processor 只接受一个 IP 字段,并且无条件对所有交易执行同一套全局 IP 限流规则,应用端就没有真实、可靠的规避方法。

为什么不能简单更换 IP

客服代表所用电脑的 IP address 不是持卡人或付款人的 IP address。它只能表明客服操作来自哪台设备,不能代表付款人的网络位置。

以下做法都不合适:

  • 随机生成 IP address;
  • 轮换代理服务器或出口 IP;
  • 用固定服务器 IP 冒充客户 IP;
  • 无法确认来源时,填写客户声称的 IP;
  • 随意采用 X-Forwarded-For 中未经验证的值。

这些做法会污染风控数据,可能违反 processor 的接口约定,也会增加异常交易的追踪难度。部分 processor 还可能结合账户、设备、银行卡、地址及请求行为,识别这类规避操作。

推荐的渠道拆分方案

两类请求最好有明确且可审计的来源:

Customer browser
    -> Customer API
    -> Processor profile: ecommerce
    -> IP-based fraud rules enabled

Customer service workstation
    -> Internal CS API
    -> Processor profile: assisted-payment / MOTO
    -> Channel-specific fraud rules

这里的 “profile” 是泛称。具体实现取决于 payment processor,可能采用以下名称:

  • merchant account;
  • sub-merchant;
  • payment profile;
  • processing account;
  • API credential;
  • transaction source;
  • fraud rule set;
  • MOTO / card-not-present channel。

需要查看 processor 的 API 文档或联系其支持团队,确认它提供哪种隔离能力。

请求中应分别记录哪些 IP

客户自助付款时,可以从受信任的反向代理或负载均衡器获取客户 IP:

function getTrustedClientIp(req) {
  // 前提:应用只接受受信任代理转发的请求,
  // 并且代理会覆盖而不是直接透传客户端提供的该请求头。
  return req.headers["x-forwarded-for"]?.split(",")[0].trim()
    || req.socket.remoteAddress;
}

如果公网请求可以直接访问应用服务器,就不能无条件信任 X-Forwarded-For,因为攻击者可以自行构造该请求头。应在负载均衡器、CDN 和应用框架中配置可信代理范围。

客服代客付款时,应记录客服会话信息,但不要将客服工作站 IP 当作持卡人 IP:

const paymentRequest = {
  amount: 12500,
  currency: "USD",
  paymentMethodToken,
  channel: "customer_service",
  operatorId: authenticatedAgent.id,
  sessionId: customerServiceSession.id,
  operatorIp: getTrustedClientIp(req)
};

这些字段仅作示意。channel、operatorId 和 operatorIp 能否发送给 processor,以及对应的准确字段名称,都应以其 API 定义为准。应用自己的审计日志仍需保留这些信息。

调用 processor 时,应根据渠道选择不同的配置:

const processorClient =
  paymentRequest.channel === "customer_service"
    ? assistedPaymentClient
    : ecommercePaymentClient;

const result = await processorClient.createPayment({
  amount: paymentRequest.amount,
  currency: paymentRequest.currency,
  payment_method: paymentRequest.paymentMethodToken
});

assistedPaymentClient 和 ecommercePaymentClient 应使用不同的 processor credential 或 account profile,不能只在本地更换变量名。

客服渠道仍然需要风控

拆分渠道不代表关闭风控。客服付款通常需要使用另一组信号,包括:

  • 客服代表的身份与权限;
  • 单个代表的交易频率和金额;
  • 客户账户历史;
  • payment method fingerprint;
  • billing address 或 postal code 校验;
  • CVV、AVS 或 3-D Secure 的适用结果;
  • 同一卡片跨多个客户账户使用;
  • 短时间内连续失败;
  • 高金额交易的人工复核;
  • 客服账号登录位置或设备异常;
  • 客服操作和客户授权记录。

例如,可以在自己的服务中按客服和客户两个维度增加限制:

await riskEngine.assertAllowed({
  channel: "customer_service",
  agentId: authenticatedAgent.id,
  customerId,
  paymentMethodFingerprint,
  amount,
  currency
});

这样既能减少共享 IP 对正常交易的误伤,也能继续检测客服账号滥用、账户接管和异常支付行为。

与 processor 沟通时需要确认的内容

可以向 processor 说明这是 “客服辅助的 card-not-present payment”,并确认以下事项:

  1. 是否支持 MOTO 或 assisted-payment transaction type;
  2. 是否能为不同 API credential 配置不同的 Fraud detection rules;
  3. 是否支持 sub-account 或多个 merchant profile;
  4. IP 字段表示持卡人 IP、操作员 IP,还是请求服务器 IP;
  5. 客服交易没有持卡人 IP 时,该字段应该省略、设为 null,还是改用其他字段;
  6. 是否提供 trusted merchant、server-to-server 或 manual review 流程;
  7. 两个账户的清算、退款、对账和 webhook 能否统一处理。

不要自行猜测 IP 字段是否必填,或可以填写什么值。不同 processor 对字段语义和合规要求可能有不同规定。

如果 processor 不支持渠道隔离

如果 processor 只有一套全局规则,无法区分 credential、merchant account 或 transaction type,可选方案只有:

  • 为客服渠道申请另一个 processor account;
  • 将客服付款接入支持 MOTO 或渠道化风控的其他 processor;
  • 向客户发送安全的付款链接,让客户在自己的设备上完成付款;
  • 由客服创建订单,再让客户通过短信或邮件中的一次性链接确认并支付。

安全付款链接通常是最直接的替代方案。processor 可以获取客户真实的网络和设备信号,客服也不必直接处理支付凭据。

无论采用哪种方案,都不应通过伪造或轮换 IP 绕过 Fraud detection rules。问题在于交易渠道的建模方式,应通过账户、凭据或交易类型隔离来解决。

备注:内容仅供参考。