实时风险评分事件发送:集成指南

Charles Archibong, 联合创始人
在执行任何操作之前,请从后端调用交易端点(用于处理资金流动)和活动端点(用于处理登录和账户变更)。发送完整的参与方信息和稳定 ID,然后根据汇总结果进行路由:允许、审核或阻止。

要点
- 将资金流动发送到 /api/v1/transactions,将登录或帐户更改发送到 /api/v1/activities。
- 在发放资金之前进行通话,并根据评估结果进行路由:允许、审查或阻止。
- 缺少交易对手姓名或钱包地址会导致需要审核才能做出决定,而不是做出明确决定,因此请发送完整的交易对手信息。
- 重试时重用 externalActivityId;重放会返回现有评估结果,而不会再次评分。
为了获得实时风险决策,您的后端会调用POST /api/v1/transactions对于每一笔付款、转账、存款或取款,以及POST /api/v1/activities对于每次登录、注册、密码重置、受益人变更以及类似的账户事件,每次调用都会在同一请求中返回一个结果:allow,review或者block并给出评分、最充分的理由以及建议的下一步行动。你的代码会根据该决定来控制行动。
集成效果好坏取决于三个因素:在合适的时机调用(资金转移之前,而不是之后)、发送完整的资金发送方和接收方信息,以及使用稳定的标识符,避免重试导致重复评估。本指南将逐一介绍这些要素,并参考事件监控文档 (在新标签页中打开)中的请求格式。
可用性。这些端点属于欺诈监控领域。 Toden 风险情报功能仅对拥有访问权限的帐户开放。生产环境使用也需要已获批准的业务配置文件。如果您的帐户未启用端点,请联系我们。 Toden 在你建立起对抗他们的机制之前。
每个事件分别属于哪个端点?
发生了什么 | 端点 | 为什么 |
|---|---|---|
资金已转移或即将转移,附有汇款人和收款人的详细信息 |
| 记录交易关系、使用的账户或钱包,筛选交易对手并对交易进行评分。 |
一位客户对其账户进行了某些操作。 |
| 它根据设备、IP、位置和事件属性构建行为证据,然后对其进行评分。 |
较早的集成方式发送自由格式的事件形状 |
| 仅兼容;无法模拟完整的参与方或工具。 |
活动type这是一个封闭列表:login,signup,password_reset,beneficiary_added,profile_change,device_change,payout和withdrawal文档明确指出,包含汇款人和收款人信息的资金流动会发送到交易端点,而不是通过活动端点。payout。
通话应该安排在流程的什么位置?
从客户确认到不可逆步骤之间。以钱包应用中的一笔出账银行转账为例:
客户确认向新的收款人转账。
您的后端发送交易并等待响应。
它沿着
assessment.summary.outcome。仅在
allow它是否将付款提交给银行?
结果 | 你的后端做什么 |
|---|---|
| 继续。无需操作员干预。 |
| 暂缓执行此操作,并将其提交审核。 |
| 停止行动。保留该决定及其证据以备调查。 |
付款完成后再进行评分属于监控,虽然对调查仍有价值,但无法阻止损失。如果要限制任何操作,必须首先考虑这一点。 Toden 它返回一个决定;它不会阻止您应用程序中的帐户,因此控制权在于您的代码。
第一个请求是什么样的?
所有风险情报调用都使用来自您后端的一个密钥:sk_test_反对https://sandbox-api.toden.co/api/v1,sk_live_反对https://api.toden.co/api/v1官方 Node.js SDK 是@myazahq/trust-sdk( ESM (仅限 Node.js 20 或更高版本),并且它会从其中选择主机。environment选项。摘自《风险情报快速入门 (在新标签页中打开)》:
import { Myaza } from '@myazahq/trust-sdk';
const myaza = new Myaza({
apiKey: process.env.MYAZA_SECRET_KEY,
environment: 'sandbox',
});
const assessment = await myaza.transactions.create({
externalActivityId: 'activity_txn_10001',
subject: { type: 'individual', externalUserId: 'user_42' },
occurredAt: new Date().toISOString(),
transaction: {
externalTransactionId: 'txn_10001',
assetClass: 'fiat',
direction: 'outbound',
amount: '48000.00',
currency: 'NGN',
transactionType: 'bank_transfer',
},
}, { idempotencyKey: 'transaction-txn_10001' });
console.log(assessment.summary?.outcome, assessment.summary?.reason);注意amount是一个字符串。 API 接受最多八位小数的正十进制字符串,因此输入的金额永远不会通过浮点数进行四舍五入。
该请求有效,但并不完整,下一节将解释为什么这很重要。
为什么政党如此重要?
因为筛查取决于他们。交易direction始终要从客户的角度出发,而且 Toden 在做出决定前,先对运动的另一方进行评估:
方向和资产 | 政党筛选 | 筛选内容 |
|---|---|---|
出境法定货币 | 接受者 | 姓名和可用身份证明 |
入境法定货币 | 发件人 | 姓名和可用身份证明 |
出境加密货币 | 接受者 | 钱包地址和网络 |
入站加密货币 | 发件人 | 钱包地址和网络 |
银行账号仅作为关联证明保存,不用于筛选。如果筛选所需的姓名或钱包信息缺失,系统会做出因数据不足而导致的审核决定,而不是将交易视为已通过。
这是正确的做法,这意味着精简集成会产生繁忙的审核队列。发送parties数组。每一方都需要一个role(sender,recipient,customer或者counterparty),一个稳定的参考(externalUserId,entityId或者externalPartyId),以及外部法定筛选 adisplayName请附上各方用作支付工具的账户或钱包:
{
"role": "recipient",
"externalPartyId": "beneficiary_998877",
"type": "individual",
"displayName": "Amina Bello",
"country": "NG",
"instruments": [
{
"type": "bank_account",
"externalInstrumentId": "beneficiary_account_998877",
"identifier": "9988776655",
"institutionName": "Recipient Bank",
"country": "NG",
"currency": "NGN"
}
]
}乐器的原始状态identifier该号码已进行指纹识别,用于关系匹配,不会以原始形式存储。如果您不想发送原始号码,请提供您自己的号码。externalInstrumentId或现有的fingerprint反而。
如何发送账户活动信息?
同样的信封,没有transaction块,加上一个type登录 HTTP :
curl -X POST "https://sandbox-api.toden.co/api/v1/activities" \
-H "Authorization: Bearer $MYAZA_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"externalActivityId": "login_10001",
"subject": { "type": "individual", "externalUserId": "user_42" },
"type": "login",
"occurredAt": "2026-08-16T09:30:00.000Z",
"channel": "mobile_app",
"deviceRef": "device_7f53",
"ipAddress": "102.89.12.34",
"country": "NG",
"customAttributes": { "trustedDevice": false, "failedAttemptsBeforeSuccess": 2 }
}'其中两个字段承载了大部分价值。deviceRef这是您自己的稳定设备参考;重复使用它来构建设备历史记录,并且正是它使得新设备信号具有任何意义。ipAddress必须是最终用户的地址。 API 不会替换服务器的 IP 地址,因此如果您的后端转发调用,请传递您观察到的客户端地址,而不是您自己的地址。
请仅提交您实际收集到的证据。经纬度必须同时提供,且您提供的位置信息优先于根据 IP 地址推断出的任何位置信息。
你应该如何解读这个回复?
读assessment.summary首先,它持有outcome,title,reason,score,riskLevel,matchedRules和nextAction这足以满足正常的路由需求。同样的响应还包含详细的匹配规则、筛选证据和计费明细,以便调查人员进行核实。decisionId和alertId针对您自己的交易,以便运营商日后可以找到证据。
使用机器值(allow,review,block)按照文档建议,用代码编写你自己的面向客户的文案,而不是将评估文本传递给客户。
如何避免重复得分?
使用稳定标识符:
一
externalActivityId每个逻辑评估结果在重试过程中保持不变。重放操作返回现有评估结果。replayed: true并且不会再次评分或计费。一
externalTransactionId每笔客户交易。重复使用标识符处理不同的不可变数据会返回结果
409(idempotency_conflict或者transaction_id_conflict这是你的标识符方案中的一个错误,不需要重试。寄送原件
occurredAt时间不能超过五分钟以后,而且 Toden 记录事件发生时间和接收时间,因此即使事件发生较晚,也能保持可见性,而不会扭曲时间线。
如果没有得到任何决定,应该怎么办?
请在发布前决定这一点,因为文档中说明的行为是启动失败并自动关闭。您会遇到的错误:
地位 | 错误 | 该怎么办 |
|---|---|---|
|
| 修复有效载荷:缺少字段、金额不是精确的十进制字符串、位置信息不完整。 |
|
| 您的制作费抵扣额不足以支付评估费用。请补足差额;目前尚未做出决定。 |
|
| 此环境中不存在所引用的客户或实体。 |
|
| 标识符被重复用于不同数据。请修复,无需重试。 |
|
| 本合同无法评估标的物类型。 |
| 服务故障 | 使用相同的标识符重试并退避。 |
错误文档中 (在新标签页中打开)增加了一条值得写入操作手册的要点:当信用额度不足时,交易和活动决策将失败并关闭,而延迟记录并非授权响应。如果无法及时获得决策,您的产品需要制定一条规则,例如,在获得决策之前,阻止超过您设定限额的出站转账。务必记录下这条规则;不要让超时默认设置为“允许”。
你还需要webhook吗?
是的,运营方面需要订阅。fraud.transaction.assessed和fraud.activity.assessed接受每一项决定,并且screening.match,risk.signal.created和alert.created根据调查结果采取行动。将每个签名与原始数据进行比对,并按事件 ID 进行去重。event.flagged仅作为不允许决策的兼容性别名保留。如果您正在使用POST /api/identity/events计划迁移到 v1 端点:旧形状可以为简单的事件评分,但不能承载结构化的参与者或工具。
检查清单
密钥和风险情报主机仅托管在您的后端;
sk_test_在构建过程中与 Sandbox 主机一起使用。资金转移前会先进行交易;你的代码就是闸门。
parties每次移动的屏幕侧面都会显示姓名或钱包信息。最终用户的 IP 地址和您的稳定器
deviceRef关于活动。稳定的
externalActivityId和externalTransactionId, 原来的occurredAt。制定书面规则,规定在无法做出决定时应该采取的措施。
Webhooks 已订阅、已验证并已去重。
参考来源



