开发接入文档

Funnel 接入

Funnel 已配置完成。使用标准 SDK 获取决策,校验结果后用于现有业务即可。

01调用 Funnel

安装 SDK,再将我们提供的 API 地址、服务端 Key、App ID 和 Funnel ID 配到后端。先在 Sandbox 联调。

安装 · Node.js 22+
npm install @tinkerlandai/indiana-sdk@0.3.1

npm 包页面 · 下载 npm 包(.tgz)

Node.js · 仅服务端
import { createFunnelCampaignClient } from "@tinkerlandai/indiana-sdk/server";

const funnel = createFunnelCampaignClient({
  baseUrl: process.env.INDIANA_API_URL,
  apiKey: process.env.INDIANA_API_KEY,
  scope: {
    projectId: process.env.INDIANA_PROJECT_ID,
    environment: "sandbox",
  },
  funnelId: process.env.INDIANA_FUNNEL_ID,
});

export async function getOffer(input) {
  const decision = await funnel.decide({
    requestId: input.requestId,
    customer: {
      type: "externalUserId",
      value: input.userId,
    },
    attributes: {
      is_new_paying_user: input.isNewPayingUser,
      channel: input.channel,
      country: input.country,
    },
  });
  return decision;
}

用户与归因信息从你们后端读取。发送前保存 UUID 格式的 requestId 与完整输入;重试时原样复用。

02读取结果

入口按用户稳定分流:10% 进入优惠规则,90% 沿用常规策略。优惠组仍须满足从未付费且来自 MetaAds 或 GoogleAds;对照组不返回新客月付优惠,年付政策保持不变。

读取 decision.value,按 plan_id 匹配套餐,将结果用于现有界面与支付流程。

decision.value · 示例节选
{
  "discount_offers": [
    {
      "plan_id": "plus_first_month",
      "discount_rate": 15
    },
    {
      "plan_id": "pro_first_month",
      "discount_rate": 20
    },
    {
      "plan_id": "wonder_first_month",
      "discount_rate": 25
    }
  ]
}

discount_rate 为 20 表示减免 20%。标准 campaign 入口会复用该用户在此 Funnel 中已接受的活动决策。

03使用前做好校验

用户身份
以登录态识别用户,从可信付费历史判断新客;付过后退款仍算历史付费。服务端 Key 不下发到前端。
决策结果
核对返回用户、结果结构、套餐白名单及约定的折扣范围。无适用优惠或请求失败时使用常规价格。
支付金额
后端再次核验资格、商品和优惠有效性。核对实际首期金额与续费价格,年付优惠不重复叠加。
支付状态
以权威服务端记录确认支付与权益。页面回跳或 Funnel 完成不等于支付成功;切换账号后重新获取结果。

接入真实流量前检查优惠组、对照组、不符合条件的用户和历史付费用户,再核对分组稳定性、超时重试与真实报价。