PAYATHON 2026

支付即积分方案如何判定有效交易并防范场外交易风险?

支付老李

明确结论

“支付即积分”不能简单理解为”只要发生支付就发积分”,也不宜仅凭位置信息判断交易是否有效。

一般来说,交易需要符合业务规则才能获得积分,包括商户在活动范围内、使用指定支付渠道、订单真实有效且没有退款等。这里的”圈内交易”可能是指指定商户、指定用户群、指定区域或指定支付渠道,具体含义需要在方案规则中写清楚。

位置信息可以辅助风控,但不能作为唯一判断依据。场外交易、虚假交易、自买自卖和商户套现都可能被用来套取积分,因此还要结合交易闭环、限额、关联关系识别、异常行为检测和积分延迟结算等机制。

有效交易应如何判定

有效交易可以定义为同时满足以下条件:

  1. 支付通过平台认可的渠道完成,并且能够取得可信的支付流水号。
  2. 收款商户已经加入积分活动,交易发生时资格仍然有效。
  3. 订单金额、支付金额和结算金额可以相互核对。
  4. 支付状态为成功,交易没有被撤销、退款或拒付。
  5. 交易类型在积分适用范围内。充值、转账、提现等非消费行为通常需要排除。
  6. 用户、商户和设备均未命中高风险规则。
  7. 交易没有超过单笔、每日、每月或整个活动周期的积分上限。

因此,“只有圈内交易才能获得积分”是否成立,要看”圈内”如何定义。如果它指签约商户,可以通过 merchant_id 或商户活动资格来判断;如果它指地理商圈,则需要交叉核验门店、订单和位置等信息。

位置信息应该怎样使用

位置判断更适合用来发现异常,不宜直接决定是否发放积分。

在线下到店消费场景中,可以比较用户支付位置与门店位置的距离:

[ d = 2R\arcsin\left(\sqrt{\sin^2\left(\frac{\Delta\varphi}{2}\right)+\cos(\varphi_1)\cos(\varphi_2)\sin^2\left(\frac{\Delta\lambda}{2}\right)}\right) ]

其中,(R) 为地球半径,(d) 为用户与门店之间的估算距离。

距离超过阈值不一定说明交易虚假。用户可能关闭了定位,也可能使用代理付款;商场内还可能出现定位漂移,订单也可能属于外卖、预约或代付。因此,更稳妥的处理方式是:

  • 距离正常时,增加交易可信度。
  • 距离异常时,提高风险分,但不要立即拒绝。
  • 用户没有授权定位时,结合支付流水、设备和历史行为判断。
  • 线上订单、外卖或代付交易不应套用线下到店距离规则。

客户端上传的经纬度可能被篡改。在高风险场景中,可以结合定位时间、定位精度、设备完整性、IP 地址、门店终端和支付受理环境进行校验。

场外交易有哪些常见风险

场外交易风险并不只是”人在商圈外完成支付”。更常见的情况是交易没有真实的消费背景,却通过形式上的支付套取积分,例如:

  • 用户与商户协商虚构消费,积分到账后再私下退款。
  • 用户通过自己控制的商户账户自买自卖。
  • 多个账号集中向同一商户支付小额订单。
  • 同一设备批量登录多个账号并重复支付。
  • 高频生成整数金额或固定金额的订单。
  • 支付后频繁退款,或通过现金、转账等方式在场外返还资金。
  • 商户拆分订单,绕过单笔积分上限。
  • 用户、商户、收款账户、设备或网络环境之间存在隐蔽关联。

只限制地理位置无法识别这些问题。即使用户和商户都在同一门店内,虚假交易仍然可能发生。

推荐的识别与防范步骤

1. 建立可信的交易闭环

积分系统应以支付服务端的成功通知和主动查询结果为准,不能信任客户端提交的”支付成功”状态。

至少要保存以下关联关系:

order_id -> payment_id -> merchant_id -> user_id -> refund_id

同一个 payment_id 只能计算一次积分,避免支付回调重放或重复发放。

2. 采用”基础资格 + 风险评分”模型

先检查交易是否具备积分资格,再判断风险:

有效交易
= 支付成功
∩ 商户符合活动规则
∩ 交易类型合规
∩ 未重复计分
∩ 未退款或撤销
∩ 风险评分低于阈值

积分可以按以下方式计算:

[ points=\min(\lfloor eligibleAmount \times rate \rfloor,\ limit) ]

其中:

  • eligibleAmount 是允许计分的实际支付金额;
  • rate 是积分倍率;
  • limit 是对应周期的积分上限。

具体倍率、取整方式和限额应以实际业务规则为准。

3. 识别用户、商户和设备之间的关联

可以分析以下关系:

  • 用户是否为商户经营者、员工或关联人员。
  • 支付账户与商户结算账户之间是否存在关联。
  • 多个用户是否长期共用设备、IP 地址或支付工具。
  • 新注册账号是否集中向少数商户交易。
  • 商户的交易金额、交易时间和退款模式是否明显偏离同类商户。

这些关联只能作为风险信号。共用网络等弱证据不足以直接认定作弊。

4. 设置限额和冷却机制

可以设置以下限制:

  • 单笔可计积分金额上限。
  • 用户每日、每月积分上限。
  • 商户每日发放积分上限。
  • 同一用户与同一商户之间的交易频次限制。
  • 新用户、新商户或高风险账户的积分冷却期。

限额既能降低损失,也能为人工审核留出时间。

5. 延迟结算并处理退款

高风险业务不宜在支付成功后立即让积分进入可兑换状态。积分可以先进入 pending 状态,等退款观察期结束后再转为 available。

发生退款时,应按原订单冲回积分。如果积分已经使用,则要按照业务规则形成负积分、冻结权益或转入人工处理流程。部分退款需要按实际退款金额等比例冲回,避免按整单处理造成误差。

规则实现示例

下面的 TypeScript 示例展示了简化的资格判断和风险评分流程。示例中的阈值只用于说明结构,不能直接用作生产参数。

type Transaction = {
  orderId: string;
  paymentId: string;
  userId: string;
  merchantId: string;
  amount: number;
  paymentStatus: "SUCCESS" | "FAILED" | "CLOSED";
  transactionType: "PURCHASE" | "TRANSFER" | "TOP_UP";
  merchantEligible: boolean;
  alreadyRewarded: boolean;
  refundedAmount: number;
  distanceToStoreMeters?: number;
  locationAccuracyMeters?: number;
  transactionsWithMerchantToday: number;
  deviceAccountCount: number;
};

type Evaluation = {
  eligible: boolean;
  riskScore: number;
  action: "REJECT" | "REVIEW" | "PENDING" | "APPROVE";
  reasons: string[];
};

function evaluateTransaction(tx: Transaction): Evaluation {
  const reasons: string[] = [];

  if (tx.paymentStatus !== "SUCCESS") {
    return {
      eligible: false,
      riskScore: 0,
      action: "REJECT",
      reasons: ["PAYMENT_NOT_SUCCESSFUL"],
    };
  }

  if (!tx.merchantEligible) {
    return {
      eligible: false,
      riskScore: 0,
      action: "REJECT",
      reasons: ["MERCHANT_NOT_ELIGIBLE"],
    };
  }

  if (tx.transactionType !== "PURCHASE") {
    return {
      eligible: false,
      riskScore: 0,
      action: "REJECT",
      reasons: ["TRANSACTION_TYPE_NOT_ELIGIBLE"],
    };
  }

  if (tx.alreadyRewarded) {
    return {
      eligible: false,
      riskScore: 0,
      action: "REJECT",
      reasons: ["DUPLICATE_REWARD"],
    };
  }

  if (tx.refundedAmount >= tx.amount) {
    return {
      eligible: false,
      riskScore: 0,
      action: "REJECT",
      reasons: ["FULLY_REFUNDED"],
    };
  }

  let riskScore = 0;

  if (
    tx.distanceToStoreMeters !== undefined &&
    tx.locationAccuracyMeters !== undefined &&
    tx.locationAccuracyMeters <= 100 &&
    tx.distanceToStoreMeters > 3000
  ) {
    riskScore += 20;
    reasons.push("LOCATION_DISTANCE_ANOMALY");
  }

  if (tx.transactionsWithMerchantToday > 10) {
    riskScore += 30;
    reasons.push("HIGH_FREQUENCY_WITH_SAME_MERCHANT");
  }

  if (tx.deviceAccountCount > 5) {
    riskScore += 40;
    reasons.push("MULTIPLE_ACCOUNTS_ON_DEVICE");
  }

  if (riskScore >= 60) {
    return {
      eligible: true,
      riskScore,
      action: "REVIEW",
      reasons,
    };
  }

  if (riskScore >= 20) {
    return {
      eligible: true,
      riskScore,
      action: "PENDING",
      reasons,
    };
  }

  return {
    eligible: true,
    riskScore,
    action: "APPROVE",
    reasons,
  };
}

生产环境还需要通过数据库唯一约束保证幂等性,例如:

CREATE UNIQUE INDEX uk_points_payment
ON points_ledger (payment_id, points_rule_id);

不能只依赖应用层的”是否已经发放”查询,因为并发回调仍可能造成积分重复发放。

注意事项

位置信息属于敏感个人信息。采集前需要说明用途、范围和保存期限,并按照适用法律和隐私政策取得授权。用户没有授予定位权限时,应提供合理的替代校验方式,不能直接将拒绝授权视为作弊。

风控规则还需要注意以下事项:

  • 不要公开完整的阈值和规则权重,以免被反向测试。
  • 不要只依赖 IP、GPS 或设备指纹等单一信号。
  • 为误判交易提供申诉和人工复核入口。
  • 保存规则版本、命中原因和处理记录,以便审计。
  • 定期分析退款率、积分成本和误报率,并据此调整阈值。
  • 高风险交易可以暂缓发放积分,但证据不足时不能直接认定用户或商户存在欺诈。

整体上,可以用商户资格和可信支付流水判断交易能否参与积分活动,再结合位置、频次、设备和关联关系识别可疑交易,最后通过延迟结算、退款冲回和人工复核控制实际损失。

备注:内容仅供参考。