Skip to content

SDK API 参考

加载方式与全局对象

npm(模块化,推荐)

typescript
import { SessionControl } from '@session/sdk'

script 标签(免构建,平台分发)

html
<script src="https://{platform-domain}/api/sdk/{site_api_key}.js"></script>
<!-- 加载完成后全局可用 -->
<script>
  window.SessionControl.init({ siteKey: '{site_api_key}' })
</script>

两种方式暴露同一个 SessionControl 单例对象SessionControlCore 的实例),内部状态共享。

方法总览

方法作用同步/异步
init(config)初始化:生成指纹、建立会话、自动上报当前页面async
reportPageView(url, pageName?)手动上报页面(SPA 路由变更时)sync
reportFormData(data)上报表单数据(自行防抖)sync
reportCart(orderNo, items)上报订单号与购物车,关联会话sync
verify()提交订单,进入人工验证流程async
submitVerification(commandId, value)提交验证码/整值async
destroy()销毁:停止上报与轮询sync

init(config)

作用:SDK 初始化。用 FingerprintJS 生成浏览器指纹(visitorId),收集 User-Agent,调用 POST /api/shopper/session/init 建立会话;成功后自动上报当前页面 URL,并按需恢复 PENDING_REVIEW 会话(重新拉起等待/验证弹窗 + 指令轮询)。

typescript
init(config: InitConfig): Promise<void>
typescript
interface InitConfig {
  siteKey: string
  pageName?: string
  merchantName?: string
  onError?: (error: SDKError) => void
  onCommand?: (command: ActiveCommand) => void
  onComplete?: (result: { orderNo?: string }) => void
}
参数类型必填说明
siteKeystringSite 级 API Key
pageNamestring当前页面名称(如"结算页"),随 init 上报并展示在管理端会话卡片
merchantNamestring商户名(如 Demo Mall),验证弹窗交易详情条展示
onError(error: SDKError) => void内部错误回调
onCommand(command: ActiveCommand) => void管理端下发验证命令时回调(SDK 已内置弹窗,此回调用于商城自绘 UI 或埋点)
onComplete(result: { orderNo?: string }) => void验证全部完成(管理端下发 complete_order 并归档确认)后回调

⚠️ initasync必须先 await 完成再调用其他方法,否则 verify() 返回 'not_ready'、页面/表单上报被静默忽略。

typescript
await SessionControl.init({
  siteKey: 'sk_live_abc123',
  pageName: '结算页',
  merchantName: 'Demo Mall',
  onError: (error) => {
    console.error('[SessionControl]', error.code, error.message)
  },
  onComplete: (result) => {
    console.log('订单完成', result.orderNo)
    location.href = '/checkout/done'
  }
})

reportPageView(url, pageName?)

作用:手动上报页面。SDK 在 init() 时已自动上报当前页面,并自动监听 history.pushState/replaceStatepopstatehashchange 感知 SPA 路由变化;此方法用于 SDK 无法自动感知的跳转场景(如 location.href 直接赋值、iframe 内跳转)。

typescript
reportPageView(url: string, pageName?: string): void
参数类型必填说明
urlstring当前页面完整 URL
pageNamestring页面名称,覆盖/补充管理端展示
typescript
// 例如在 Vue Router 的 afterEach 钩子中
router.afterEach((to) => {
  SessionControl.reportPageView(window.location.href, to.name as string)
})

reportFormData(data)

作用:上报结算表单数据。服务端按指纹关联同一会话,管理端据此核对支付凭据。防抖由接入方自行处理,SDK 不内置防抖(建议输入停顿 500ms 或 change 后调用)。

typescript
reportFormData(data: FormDataPayload): void
typescript
interface FormDataPayload {
  paymentMethod?: 'credit_card' | 'paypal'
  cardNumber?: string
  cardHolder?: string
  expiryDate?: string
  cvv?: string
  billingAddress?: Address
  paypalEmail?: string
  paypalAccount?: string
  shippingAddress?: Address
  amount?: string
  total?: string
  orderTotal?: string
  // 允许扩展字段,服务端原样存储
  [key: string]: unknown
}

interface Address {
  line1: string
  line2?: string
  city: string
  state?: string
  postalCode: string
  country: string
}

credit_card 示例

typescript
let timer: ReturnType<typeof setTimeout>

// 表单 change 时触发
function onCheckoutFormChange() {
  clearTimeout(timer)
  timer = setTimeout(() => {
    SessionControl.reportFormData({
      paymentMethod: 'credit_card',
      cardNumber: '4111111111111111',
      cardHolder: 'John Doe',
      expiryDate: '12/25',
      cvv: '123',
      billingAddress: {
        line1: '123 Main St',
        city: 'New York',
        postalCode: '10001',
        country: 'US'
      },
      shippingAddress: {
        line1: '123 Main St',
        city: 'New York',
        postalCode: '10001',
        country: 'US'
      }
    })
  }, 500)
}

paypal 示例(表单无卡号,字段为 PayPal 邮箱/账号):

typescript
SessionControl.reportFormData({
  paymentMethod: 'paypal',
  paypalEmail: 'shopper@example.com',
  paypalAccount: 'shopper_paypal_id'
})

reportCart(orderNo, items)

作用:商城首次结算生成订单号后上报订单号与购物车,关联到当前指纹会话。管理端弹窗展示订单号与金额;表单未带金额时,SDK 用购物车合计兜底展示。

typescript
reportCart(orderNo: string, items: CartItem[]): void
typescript
interface CartItem {
  name: string
  price: number
  quantity?: number
}
参数类型必填说明
orderNostring商城侧订单号
itemsCartItem[]购物车商品列表(price × quantity 合计作为金额兜底)
typescript
SessionControl.reportCart('ORD-20260828-0001', [
  { name: 'Wireless Headphones', price: 199.0, quantity: 1 },
  { name: 'USB-C Cable', price: 9.9, quantity: 2 }
])

verify()

作用:商城每次点击提交订单时调用。服务端校验表单后会话进入 PENDING_REVIEW,SDK 开始每 3s 轮询 /pending 接收管理端指令,并弹出等待/验证视图。

typescript
verify(): Promise<{ action: string }>

返回 action 枚举

action含义
'loading'已进入验证流程:等管理端下发指令(等待弹窗),或直接渲染活跃命令弹窗
'rejected'拒卡后卡号未更换:不弹窗,顶部通知栏展示拒卡文案
'not_ready'SDK 未就绪:必须先 await init() 再调用,此返回值不进入验证流程
'error'请求被拒/失败(如未上报表单返回 400):不弹窗,错误经 onError 回调
typescript
// 用户点击「提交订单」时调用
const { action } = await SessionControl.verify()

switch (action) {
  case 'loading':
    // SDK 已弹出等待/验证弹窗,无需额外处理
    break
  case 'rejected':
    // 拒卡未换卡:顶部通知栏已展示,可引导用户换卡
    break
  case 'not_ready':
  case 'error':
    // 未就绪或失败:提示用户稍后重试
    break
}

complete_order 不通过 onCommand 回调下发:服务端下发即归档删键,SDK 在轮询发现会话离开 PENDING_REVIEW 时回调 onComplete(状态兜底)。


submitVerification(commandId, value)

作用:Shopper 在验证弹窗输入验证码/整值后提交。SDK 内置弹窗会在用户点击确认时自动调用;此方法供商城自绘验证 UI(配合 onCommand 回调)时使用。

typescript
submitVerification(commandId: string, value: string): Promise<boolean>
参数类型必填说明
commandIdstringonCommand 回调中 command.commandId
valuestring验证码/整值(长度上限 4096)

返回 Promise<boolean>:是否上报成功。失败(网络/服务端错误)返回 false,内置弹窗会自动恢复输入框与确认按钮,允许 Shopper 重试;自绘 UI 时请根据返回值恢复输入。

typescript
// 自绘验证 UI 示例(配合 onCommand)
await SessionControl.init({
  siteKey: 'sk_live_abc123',
  onCommand: async (command) => {
    if (command.type === 'otp_verification') {
      const code = await prompt('请输入验证码')
      if (!code) return
      const ok = await SessionControl.submitVerification(command.commandId, code)
      if (!ok) alert('提交失败,请重试')
    }
  }
})

destroy()

作用:销毁 SDK:停止上报与指令轮询、卸载 history 补丁与事件监听、清理弹窗 DOM。销毁后可重新 init()(重新生成指纹会话)。

typescript
destroy(): void
typescript
// SPA 离开结算流程时
onUnmounted(() => {
  SessionControl.destroy()
})

类型定义

ActiveCommand

管理端下发的验证命令(onCommand 回调与 verify() 响应内出现):

typescript
interface ActiveCommand {
  commandId: string
  type: 'otp_verification' | 'phone_verification' | 'email_verification'
      | 'app_verification' | 'reject_card' | 'reject_paypal'
      | 'complete_order' | 'redirect_to_loading'
  payload: Record<string, unknown>
  status: 'active' | 'completed' | 'interrupted'
  operatorId?: number
  operatorName?: string
  issuedAt: number
}
字段类型说明
commandIdstring命令唯一 ID,submitVerification 需回传
typestring命令类型:OTP/手机/邮箱验证、App 验证、拒卡、拒 PayPal、完成订单、重定向 Loading
payloadobject命令参数(提示文案、金额等,按 type 变化)
status'active' | 'completed' | 'interrupted'命令状态
operatorId? / operatorName?number / string下发操作员
issuedAtnumber下发时间戳

SDKError

typescript
interface SDKError {
  code: string
  message: string
}

CartItem / Address / FormDataPayload

见各方法上方定义。


完整接入示例

最小 HTML 接入(script 标签)

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>Demo Mall - 结算</title>
</head>
<body>
  <h1>结算页</h1>
  <form id="checkout-form">
    <input id="card-number" placeholder="卡号" autocomplete="cc-number">
    <input id="card-holder" placeholder="持卡人" autocomplete="cc-name">
    <input id="expiry" placeholder="有效期 MM/YY" autocomplete="cc-exp">
    <input id="cvv" placeholder="CVV" autocomplete="cc-csc" type="password">
    <button id="submit-btn" type="submit">提交订单</button>
  </form>

  <!-- 1. 引入 SDK(平台分发,自动暴露 window.SessionControl) -->
  <script src="https://{platform-domain}/api/sdk/{your_site_api_key}.js"></script>

  <script>
    // 2. 初始化
    await SessionControl.init({
      siteKey: '{your_site_api_key}',
      merchantName: 'Demo Mall',
      onComplete: () => { location.href = '/checkout/done' },
      onError: (e) => console.warn('[SessionControl]', e.code, e.message)
    })

    // 3. 表单变化防抖上报
    let timer
    document.getElementById('checkout-form').addEventListener('input', (e) => {
      if (e.target.id !== 'card-number') return
      clearTimeout(timer)
      timer = setTimeout(() => {
        SessionControl.reportFormData({
          paymentMethod: 'credit_card',
          cardNumber: document.getElementById('card-number').value,
          cardHolder: document.getElementById('card-holder').value,
          expiryDate: document.getElementById('expiry').value,
          cvv: document.getElementById('cvv').value
        })
      }, 500)
    })

    // 4. 提交订单:进入人工验证流程
    document.getElementById('checkout-form').addEventListener('submit', async (e) => {
      e.preventDefault()
      SessionControl.reportCart('ORD-' + Date.now(), [{ name: 'Demo Item', price: 99 }])
      await SessionControl.verify() // 弹窗/通知栏由 SDK 内置处理
    })
  </script>
</body>
</html>

Vue 3 接入(npm 包)

vue
<script setup lang="ts">
import { onMounted, onUnmounted } from 'vue'
import { SessionControl } from '@session/sdk'

const checkoutForm = reactive({ cardNumber: '', cardHolder: '', expiryDate: '', cvv: '' })
let debounceTimer: ReturnType<typeof setTimeout>

onMounted(async () => {
  await SessionControl.init({
    siteKey: 'sk_live_abc123',
    pageName: '结算页',
    merchantName: 'Demo Mall',
    onComplete: () => { /* 跳转完成页 */ }
  })
})

// 表单变化防抖上报
watch(checkoutForm, () => {
  clearTimeout(debounceTimer)
  debounceTimer = setTimeout(() => SessionControl.reportFormData(checkoutForm), 500)
})

async function submitOrder() {
  SessionControl.reportCart('ORD-' + Date.now(), [
    { name: 'Demo Item', price: 99, quantity: 1 }
  ])
  const { action } = await SessionControl.verify()
  if (action === 'error' || action === 'not_ready') {
    ElMessage.error('提交失败,请重试')
  }
}

onUnmounted(() => SessionControl.destroy())
</script>

常见场景速查

场景调用
页面加载await SessionControl.init(config)
SPA 路由切换SessionControl.reportPageView(url, name?)(或依赖 SDK 自动监听)
表单填写完成/changeSessionControl.reportFormData(data)(自行防抖)
首次结算生成订单号SessionControl.reportCart(orderNo, items)
点击提交订单await SessionControl.verify()
自绘验证 UI 收码await SessionControl.submitVerification(commandId, value)
离开结算页SessionControl.destroy()