mcpField
S
sumsub-create-transaction

sumsub-create-transaction

github.com/sumsub其他71.2k 次安装4 周前更新
代码仓库

关于 sumsub-create-transaction

此 Skill 根据精简规格生成并提交 Sumsub KYT 交易数据,校验必填字段,并报告响应标识与风险结果,面向处理沙盒交易监控的 Agent。

主要功能

  1. 01从精简规格构建 KytTxnData
  2. 02校验必填字段和枚举值
  3. 03适配现有或新申请人的请求路由
  4. 04向 Sumsub KYT 提交交易
  5. 05报告评分及仪表板链接

适用场景

  1. 01提交支付交易进行 KYT 监控
  2. 02记录旅行规则交易或平台事件
  3. 03查看风险评分和审核结果

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/sumsub/agent-skills --skill sumsub-create-transaction

安装后在 Claude Code 中输入/sumsub-create-transaction确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

examples/
crypto-in.json
fiat-out.json
login-event.json
new-applicant.json
travel-rule.json
references/
transaction-schema.md
scripts/
build_transaction.py
post_transaction.sh

详细介绍

Sumsub — 创建交易(KYT)

根据精简规格构建 KytTxnData JSON 负载,将其 POST 到 Sumsub KYT 端点,并报告返回的 txnId / score / reviewAnswer。

端点

有两个变体,由 post 脚本自动选择:

情况方法 + 路径
申请人已存在POST https://api.sumsub.com/resources/applicants/{applicantId}/kyt/txns/-/data
申请人不存在(Sumsub 根据 applicant.externalUserId 创建申请人)POST https://api.sumsub.com/resources/applicants/-/kyt/txns/-/data?levelName=<levelName>

请求正文:KytTxnData。返回附有监控评分的持久化 KytTxn。

这两个端点都已标记为弃用,但仍是官方文档中的规范“提交交易”入口。目前没有 v2/v3 替代方案。

身份验证 — App Token + 密钥(仅限沙盒)

此技能会调用 Sumsub 公共 API,并根据身份验证参考为每个请求签名。完整的工作原理说明见 sumsub-api-auth 技能——如果遇到 401 Invalid signature,请阅读该说明。

⚠️ 仅限沙盒令牌。 请勿在此接受或使用生产环境 App Token——交易监控会处理真实申请人数据,并可能触发真实的 KYT 警报。如果用户提供生产环境令牌,请拒绝并让其前往 https://cockpit.sumsub.com/checkus/home?sbx=true 生成一组沙盒凭据(Connect Sumsub to your AI agent -> Build & configure -> Generate token)。令牌和密钥只会显示一次——关闭对话框前请复制两者。辅助脚本会强制执行此要求——不接受未以 sbx: 开头的令牌。

变量示例
SUMSUB_APP_TOKENsbx:... — 控制面板中的沙盒 App Token。
SUMSUB_SECRET_KEY创建令牌时仅显示一次的配对密钥。
SUMSUB_BASE可选。默认为 https://api.sumsub.com。
为解析后的路径签名

这是唯一需要注意的路由细节——必须对包含查询字符串的路径签名。post 脚本会处理此事:它会读取构建器生成的旁路路由文件,选择 URI(/resources/applicants/{id}/… 或 /resources/applicants/-/…?levelName=…),对动态片段进行 URL 编码,并对发送的相同字节进行签名。如果绕过该脚本,请记住:

  • 对实际发送的路径签名——使用编码后的形式,并包含查询字符串。
  • 签名所用的请求正文字节必须与发送的字节一致(不得重新排布空白字符)。

如果用户已在对话中提供凭据,请重复使用;否则,请在运行前询问一次。绝不要回显密钥。

流程

  1. 将用户意图映射到以下精简规范。绝大多数交易都是 type: finance(付款)——对于这类交易,用户实际提供的是金额 + 币种 + 方向 + 申请人 + 交易对手方。

  2. 验证:txnId 非空,applicant.externalUserId 非空,并按 type 验证:

    • finance / travelRule → 必须提供 info.amount、info.currencyCode、info.direction(OpenAPI 将这三项标记为 KytTxnInfo 的必填字段)。
    • userPlatformEvent → 必须提供 userPlatformEvent.type。
    • 枚举(direction、currencyType、applicant.type、nameType 等)需提前检查,验证失败时列出所有允许值。
  3. 使用 ${CLAUDE_SKILL_DIR}/scripts/build_transaction.py 生成完整载荷(通过标准输入传入精简规范 → 通过标准输出获取完整的 KytTxnData 载荷)。

  4. 通过 ${CLAUDE_SKILL_DIR}/scripts/post_transaction.sh POST — 根据规范中是否设置了 _applicantId,自动路由到现有申请人或非现有申请人的 URL(而不是根据载荷中的设置判断——见下文)。

  5. 构建仪表板链接。 从响应正文中读取 id(服务器分配的标识符,不是你提供的 txnId)和 clientId,并按以下格式生成:

    https://cockpit.sumsub.com/checkus/kyt/txns/<id>?clientId=<clientId>&sbx=true
    

    规范中用户提供的 txnId(例如 finance-2026-05-21-0001)不会放入 URL — Sumsub 在持久化时会分配单独的标识符。sbx=true 查询参数指向 Sandbox 工作区 — 这是所有技能共用的规范 Sandbox 链接参数。

  6. 报告:txnId(你提供的)、服务器 id、申请人的 externalUserId、方向 + 金额 + 币种、交易对手方(如果有),响应中的 score / reviewAnswer / riskLabels(如果存在),以及作为可点击 Markdown 链接的仪表板链接。

精简规范格式(通过标准输入传入 JSON 或 YAML)

# Top-level
txnId: "finance-2026-05-21-0001"     # REQUIRED, unique alphanumeric in your system
txnDate: "2026-05-21 14:30:00+0000"  # optional; format: yyyy-MM-dd HH:mm:ss+XXXX
zoneId:  "UTC+01:00"                 # optional, time zone string
type:    finance                     # finance | travelRule | kyc | userPlatformEvent | iGamingSession (default: finance)

# Routing — pick ONE
_applicantId: "67abc..."             # post to existing applicant (path id, NOT a payload field)
# - OR -
_levelName: "Default"                # post to non-existing-applicant URL with ?levelName=...
                                     # (Sumsub creates the applicant from applicant.externalUserId)

# Finance / Travel Rule info (required for those types)
amount:       1500.50
currency:     USD                    # ISO-4217 fiat or crypto ticker (BTC, ETH, …)
currencyType: fiat                   # fiat | crypto  (default: fiat)
direction:    out                    # in | out
amountInDefaultCurrency: 1500.50     # optional, converted to client default
defaultCurrencyCode:     USD
paymentDetails: "Invoice #INV-2026-001"
mcc:    5411                         # optional, 4-digit Merchant Category Code

# Crypto-only block (used when currencyType=crypto)
crypto:
  chain:        ETH                  # ETH | BTC | TRX | … (mandatory for tokens; empty for native)
  contract:     "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
  paymentTxnId: "0x1234abcd..."      # on-chain hash
  fingerprint:  "0x1234abcd..."      # alternative blockchain identifier
  attemptId:    "attempt-01"         # optional, when retrying
  outputIndex:  0                    # for UTXO chains

# Applicant (REQUIRED) — the person/entity acting on your platform
applicant:
  externalUserId: "user-001"         # REQUIRED — your stable user id
  type: individual                   # individual | company (default: individual)
  fullName: "John Smith"             # required for company; recommended for non-existing-applicant flow
  dob: "1990-05-01"
  email: "[email protected]"
  phone: "+1234567890"
  placeOfBirth: "London"
  address:
    country: USA
    town: "New York"
    street: "5th Avenue"
    formatted: "5th Avenue, New York, USA"
  paymentMethod:
    type: bankCard                   # bankCard | bankAccount | crypto | cryptoWallet |
                                     # eWallet | unhostedWallet | card | other
    accountId: "4111********1111"    # IBAN, last4-hash, wallet address, etc.
    issuingCountry: USA
    "3dsUsed": true
    "2faUsed": false
    memo: "optional memo"
  idDoc:
    number: "A12345678"
    country: USA
    idDocType: PASSPORT
  device:
    fingerprint: "abc123"
    userAgent: "Mozilla/5.0 ..."
    ipInfo: { ip: "1.2.3.4" }

# Counterparty (typical for finance + travelRule; same shape as applicant + a few extras)
counterparty:
  externalUserId: "merchant-XYZ"
  type: company
  fullName: "Acme Inc."
  registrationNumber: "12345678"
  leiCode: "529900XXXX0000XXXX00"
  residenceCountry: QAT
  address: { country: QAT }
  institution:                       # → institutionInfo
    code: "ACME-CODE"
    name: "Acme Bank"
    internalId: "<VASP id from directory>"
  ceo:                               # only for company counterparties (Travel Rule)
    firstName: "Jane"
    lastName: "Roe"

# user-platform-event only (when type=userPlatformEvent)
userPlatformEvent:
  type: login                        # login | failedLogin | signup | passwordReset | twoFaReset | general
  twoFaUsed: true
  passwordHash: "..."

# Optional escape hatches
sourceKey: "<segregation key>"
props:                               # custom string-string map
  customField: "value"
  dailyOutLimit: "10000"
枚举(提前验证)
字段允许值
type(顶层)finance、travelRule、kyc、auditTrailEvent、userPlatformEvent、scheduledEvent、iGamingSession
directionin、out
currencyTypecrypto、fiat
applicant.type / counterparty.typeindividual、company
applicant.nameTypealiasName、birthName、maidenName、legalName、shortName、tradingName、other
userPlatformEvent.typelogin、failedLogin、signup、passwordReset、twoFaReset、general

有意不对 paymentMethod.type 执行枚举验证 — OpenAPI 列出了 KytTxnPaymentMethodType(仅含 smartContract、bankCard、bankAccount),但文档和实时数据接受更多类型(如 crypto、eWallet、unhostedWallet 等)。构建器会原样转发调用方提供的值。

输出

成功时,报告以下所有内容:

  • txnId(你提供的)以及 id(服务器分配,用于仪表板链接)。
  • 申请人的 externalUserId。
  • direction amount currency、交易对手方(如果有)。
  • 响应返回的 score / reviewAnswer / riskLabels。
  • 仪表板链接:https://cockpit.sumsub.com/checkus/kyt/txns/<id>?clientId=<clientId>&sbx=true。将其呈现为可点击的 Markdown 链接。<id> 是服务器分配的标识符(不是你发送的 txnId);这两个值都在 POST 响应正文中;sbx=true 指向 Sandbox 工作区。

失败时:报告 HTTP 状态码以及 Sumsub 的 description/errorName。最可能遇到的 4xx 情况:

  • 409 Entity already exists — txnId 冲突(请使用新的 id,或使用批量导入方法进行更新)。
  • 400 — 缺少必填字段(常见字段:info.amount、info.currencyCode、info.direction 或 applicant.externalUserId)。
  • 400 — levelName 未知(使用非现有申请人流程时)。

示例

  • examples/fiat-out.json — 向境外交易对手支付欧元银行卡款项(文档中的标准示例)。
  • examples/crypto-in.json — 接收 ETH 存款,包含 cryptoParams.cryptoChain=ETH、合约地址和链上 paymentTxnId。
  • examples/travel-rule.json — 使用 type: travelRule 进行加密货币出账,交易对手的 institution.internalId(VASP ID)。
  • examples/login-event.json — 用户通过双重身份验证成功登录时的 type: userPlatformEvent。
  • examples/new-applicant.json — 新申请人流程:设置 _levelName,使 POST 请求发送到 /-/kyt/txns/-/data,并附带 ?levelName=...。

另请参阅

评论

支持 Markdown