产品文档 > 智能风控 > 实时风险决策

实时风险决策产品概述

一、产品简介


顶象实时风险决策是一款基于设备指纹、规则引擎、指标策略、风险数据、机器学习等多项技术的业务风险防控产品, 支持快速私有化部署,帮助客户快速建立自有的业务安全体系,解决仿冒、盗用、欺诈、作弊、垃圾、爬虫等各类风险。

二、产品特点


  • 实时决策,利用策略和实时计算,同步识别风险,直接阻断恶意风险

  • 近线分析,t+分钟级的近线计算,计算各种特征,为实时决策提供指标参数

  • 离线挖掘,通过各种离线的挖掘和模型技术的应用,为实时决策和离线处置提供依据和能力,如:特征挖掘、模型平台训练、用户风险画像、设备风险画像等

  • 快速私有化部署,支持平滑扩容和在线升级

三、产品示例


  1. 盗号防控示例

  2. 垃圾注册防控示例

四、新手指南

4.1 业务流程


  1. 前端SDK收集设备相关信息,上报至顶象风控后台;
  2. 顶象风控后台通过上报的的设备信息,生成token,下发给用户前端;
  3. 用户前端的业务逻辑附带token发送至用户后端;
  4. 用户后端把本次请求的token,连同AppId以及相关参数,经加密和加签,发送至顶象风控后端;
  5. 顶象风控后端把风险识别结果返回给用户后端;
  6. 用户后端的业务逻辑处理,并把处理结果返回至用户前端;

4.2 名词解释


名称释义
AppId应用公钥,唯一标识。开通服务后可在实时风险决策的二级菜单“应用管理”中获取
AppSecret应用私钥,开通服务后可在实时风险决策的二级菜单“应用管理”中获取,请妥善保管,勿泄漏给他人
ConstID设备指纹ID,通过采集设备的硬件信息生成的设备唯一标识。结合顶象风控系统,能够在各个业务环节进行风险过滤和实时决策,为企业提供提供强力业务安全保障
用户前端Web端或集成SDK的Android端、iOS端、微信小程序
用户后端指企业的后台服务器
风控后台指部署在公有云或者私有云顶象的风控系统

五、开发前必读

5.1 技术接入流程


接入实时风险决策,只需四步:

     第一步:获取AppId、AppSecret,开通服务后可在实时风险决策的二级菜单“应用管理”中获取,
            在接入前请与顶象技术人员沟通,以根据您的业务特点配置不同的风险策略;
     第二步:前端接入,即设备指纹埋点,支持Web、Android、iOS、微信小程序接入,
            接入方法及相关SDK下载,请见前端接入章节;
     第三步:后端集成SDK,接入方法及SDK下载,请见后端接入章节;
     第四步:调试完毕,部署上线,可在实时风险决策的二级菜单“风险监控”中查看风险数据详情。

六、前端接入

  • 支持Web接入,支持IE8+、Chrome、Firefox、360浏览器、QQ浏览器等主流浏览器及Android、iOS上的内嵌Webview。如何引用JS请见Web接入章节

  • 支持Android接入,如何获取SDK并接入,请见Android接入章节

  • 支持iOS接入,如何获取SDK并接入,请见iOS接入章节

    提示:设备指纹token具有时效性,超过一定时间会过期,请勿自行缓存

6.1 Web接入

6.1.1 环境要求

兼容IE8+,Chrome,Firefox,360浏览器,QQ浏览器等主流浏览器。

6.1.2 引入JS

在页面 HTML 中引入const-id.js,代码如下:

<script src="https://cdn.dingxiang-inc.com/ctu-group/constid-js/index.js"></script>

6.1.3 生成token

页面加载后,初始使用,需要在 JavaScript 中调用_dx.ConstID(options, callback)方法,生成token,代码形如:

var options = {
    appId: '【这里填写 AppId】', // 唯一标识,必填
    server: 'https://constid.dingxiang-inc.com/udid/c1', // ConstId 服务接口,可选
    userId: '【这里填写 userID】' // 用户标识,可选
};
_dx.ConstID(options, function (e, id) {
if (e) {
    // console.log('error: ' + e);
    return;
}
// console.log('token is ' + id);
// console.log(_dx.constID === id); // true
});

执行成功后,页面中将会有一个全局变量_dx,可以通过_dx.constID访问这个值。也可以继续调用上面的初始化方法,同一个浏览器多次初始化返回的值相同。

options 字段说明 {#options-字段说明}

字段类型是否必填说明
AppIdString当前应用的标识,请联系您在顶象的商务经理获取
serverString服务接口,可选,如不填,则默认会用云服务接口
sceneString场景标识,例如loginsurvey
userIdString业务方的用户唯一标识,例如用户名、用户ID、手机号、Email等

6.2 Android接入

6.2.1 环境要求

条目说明
开发目标Android 4.0+
开发环境Android Studio 3.0.1 或者 Eclipse + ADT
CPU架构ARM 或者 x86
SDK三方依赖

6.2.2 法规要求

根据《工业和信息化部 337号令》的规定,重点对以下四个方面开展规范整治工作。
(一)违规收集用户个人信息方面
(二)违规使用用户个人信息方面
(三)不合理索取用户权限方面
(四)为用户账号注销设置障碍方面
法规地址:http://miit.gov.cn/n1146295/n1652858/n1652930/n3757020/c7506353/content.html

其中SDK涉及到第一条:收集个人信息(包括唯一设备识别码、网络设备硬件地址等信息)。
法规规定,所采集的数据项目需在隐私政策中明确声明,在客户不同意隐私政策的情况下,不允许进行采集。且申请授权需与场景相关,请根据实际情况做出合理调整。

解决方式

需要客户在集成了SDK的app中增加《隐私政策声明》,来规避风险。并在客户同意隐私政策后,进行sdk的调用。

隐私政策(拟,可根据实际情况进行修改)

为了识别设备/账号异常状态,我们将会接受并记录您所使用的设备相关信息(包括设备型号、操作系统、设备设置、唯一设备标识符(IMEI码)、网络设备硬件地址(MAC)、设备环境等软硬件特征信息,设备所在位置相关信息(包括您授权的GPS位置以及WLAN接入点、蓝牙和基站等信息)

6.2.3 集成SDK

6.2.3.1 下载SDK

点击下载SDK

点击下载demo(仅做代码配置演示使用,其中appId请在顶象后台申请,SDK需要替换为链接中下载的SDK)

6.2.3.2 Android Studio 集成

SDK包集成内容:

  • libs文件夹下的jar和so
  • assets文件夹下的配置文件
libsjarso库放到相应模块的libs目录下,assets下的文件放置到项目assets

在该Module的build.gradle中如下配置:
android{
    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
            assets.srcDirs = ['assets']
        }
    }

    packagingOptions {
        doNotStrip "**/libDX*.so"
    }
}

repositories{
    flatDir{
        dirs 'libs'
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation files('libs/dx-risk-x.x.x.jar')
}
6.2.3.3 添加SDK所需权限
<!-- 必选-默认申请 -->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>

<!-- 可选-6.0或以上需动态申请 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
6.2.3.4 Proguard混淆配置
-dontwarn com.dx.mobile.**
-dontwarn *.com.dx.mobile.**
-dontwarn *.com.mobile.strenc.**
-keep class com.dx.mobile.risk.**{*;}
-keep class com.security.inner.**{*;}
-keep class *.com.dx.mobile.**{*;}
-keep class *.com.mobile.strenc.**{*;}
6.2.3.5 API 6.0或以上动态权限申请说明

需要动态申请权限如下:

android.permission.WRITE_EXTERNAL_STORAGE
android.permission.READ_EXTERNAL_STORAGE
android.permission.READ_PHONE_STATE
android.permission.ACCESS_COARSE_LOCATION
android.permission.ACCESS_FINE_LOCATION

动态申请代码实例(Activity下):

protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_demo);

   // API 23或以上的动态申请权限
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
       String[] permissionArray = {
               "android.permission.ACCESS_COARSE_LOCATION",
               "android.permission.ACCESS_FINE_LOCATION",
               "android.permission.WRITE_EXTERNAL_STORAGE",
               "android.permission.READ_EXTERNAL_STORAGE",
               "android.permission.READ_PHONE_STATE",
       };
       this.requestPermissions(permissionArray, 1);
   }

}


@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
   super.onRequestPermissionsResult(requestCode, permissions, grantResults);
   // start getToken
   new Thread(new Runnable() {
       @Override
       public void run() {
           HashMap<String, String> params = new HashMap<String, String>();
           String token = DXRisk.getToken("appid", params);
       }
   }).start();

}

6.2.4 接口使用说明

6.2.4.1 方法和参数说明
功能描述

采集端的设备指纹信息,上传至风控后台,再由风控后台返回token。 该API为耗时操作,因此必须在非主线程上调用,否则会抛异常。

方法说明

DXRisk.java 该类是DxRisk SDK的风控组件接口,负责采集本地信息并返回用户前端token。

初始化setup

SDK使用前必须调用先setupsetup主要用于数据/环境初始化,一般在ApplicationonCreate下调用:

/**
* 初始化参数,环境
* @param context
* @return
*/
public static boolean setup(Context context)

PS:下列两种方式获取token在网络通畅的情况下没有任何的不同。

常规Token
/**
 * @return token 通常返回长度为40的字符串。在网络卡顿或不通的情况下,返回4-5k的字符串。
 * @throws DXRiskErrorException 如在主线程调用本API,或者appId为空等等,则会抛出该异常
 */
public static String getToken(String appId, HashMap<String, String> paramsMap) throws DXRiskErrorException
精简Token

获取轻量级Token可获取的设备信息信息远少于getToken(),可能会造成在判断设备是否有风险时出现较大误差,请谨慎使用。

/**
 `* @return token 通常返回长度为40的字符串。在网络卡顿或不通的情况下,返回1k的字符串。
 `* @throws DXRiskErrorException 如在主线程调用本API,或者appId为空等等,则会抛出该异常
 */
public static String getLightToken(String appId, HashMap<String, String> paramsMap) throws DXRiskErrorException
6.2.4.2 使用示例
(1) 初始化setup

建议Application.onCreate下调用

@Override
public void onCreate() {
  super.onCreate();    
  // 环境初始化
  DXRisk.setup(this);
}
(2) 获取token

整个过程由于是耗时操作,必须要在非主线程上执行,否则会crash

new Thread(){

    @Override
    public void run() {
      /* 私有化配置 */
      HashMap<String, String> params = new HashMap<String, String>();
      // 私有化部署服务端url
      params.put(DXRisk.KEY_URL, "https://constid.dingxiang-inc.com");
      // 开启线上数据备份 
      params.put(DXRisk.KEY_BACKUP, DXRisk.VALUE_ENABLE_BACKUP);
      // 设置请求token超时时长ms,不设置默认为500ms
      parsms.put(DXRisk.KEY_DELAY_MS_TIME, "2000");

      // 开通服务后可在实时风险决策的菜单获取
      String appId = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
       // 获取设备指纹token
      final String token = DXRisk.getToken(appId, paramsMap);

      // TODO 把token通过Post请求,传到用户后端
  }
}.start();
6.2.4.3 异常说明

在获取token过程中,如果因为网络超时或者加解密失败,该接口有可能会返回为null,同时会输出tag为DXRISK的错误信息,具体描述如下:

DXRISK_REQUEST_NETWORK_ERR            -1001
DXRISK_REQUEST_DECRYPT_ERR            -1002
DXRISK_REQUEST_UNCOMPRESS_ERR         -1003
DXRISK_REQUEST_RESPONSE_EMPTY_ERR     -1004
DXRISK_REQUEST_DATA_PARSE_ERR         -1005
DXRISK_REQUEST_DIRTY_DATA_ERR         -1006
DXRISK_CONST_ID_EMPTY                 -1007

如果出现上述错误信息,请联系顶象技术人员。

6.3 iOS接入

Apple Store上架请特别注意(2.2.3 节)

6.3.1环境需求

条目说明
兼容平台iOS 8.0+
开发环境XCode 4.0 +
CPU架构armv7, arm64, i386, x86_64
SDK依赖libz, libresolv, libc++ , SystemConfiguration.framework , CoreLocation.framework , CoreTelephony.framework

6.3.2集成SDK

6.3.2.1 下载SDK

点击下载SDK,SDK的目录结构如下:

点击下载集成demo

  • dx-risk-iOS-x.x.x-xxxxxxx目录 DXRisk sdk
    • DXRisk.framework 不带idfa获取逻辑的Dynamic Library Framework
    • DXRiskWithIDFA.framework 带idfa获取逻辑的Dynamic Library Framework
    • DXRiskStatic.framework 不带idfa获取逻辑的Static Library Framework
    • DXRiskStaticWithIDFA.framework 带idfa获取逻辑的Static Library Framework
6.3.2.2 将SDK接入XCode
(1) 导入Framework

DXRisk.framework,DXRiskWithIDFA.framework,DXRiskStatic.framework,DXRiskStaticWithIDFA.framework`其中之一直接拖入工程目录中,或者右击总文件夹添加文件。

  • 如果App中包含广告相关的功能,则选择DXRiskWithIDFA.framework 或者 DXRiskStaticWithIDFA.framework,该版本可以提供更精准的token
  • 如果没有广告,获取idfa可能导致拒绝上架,此时请选择DXRisk.framework 或者 DXRiskStatic.framework
(2) 添加FrameWork到工程

若在项目中添加DXRisk.framework或者DXRiskWithIDFA.framework其中之一,选择Target -> General,在Frameworks,Libraries,and Embedded Content中,将DXRisk.framework或者DXRiskWithIDFA.framework 对应的 Embed 切换到Embed & Sign。如下图:

若在项目中添加DXRiskStatic.framework或者DXRiskStaticWithIDFA.framework其中之一,需要在Build Settings -> Other Linker Flags 设置 -ObjC 如下图:

4A23453213E696EC12C2AE2A1070EA0C.jpg

(3) 配置打包脚本

以下的操作仅限导入DXRisk.framework ,DXRiskWithIDFA.framework动态库

此步骤主要是解决上传Store架构不符合的问题,如项目中已配置过Carthage或有其他相关的打包Framework调整脚本,可略过此步自行调整 选择Target -> Build Phases,点击+按钮,添加如下脚本:


APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"

# This script loops through the frameworks embedded in the application and
# removes unused architectures.
find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
do
FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"

EXTRACTED_ARCHS=()

for ARCH in $ARCHS
do
echo "Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME"
lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH"
EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH")
done

echo "Merging extracted architectures: ${ARCHS}"
lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[@]}"
rm "${EXTRACTED_ARCHS[@]}"

echo "Replacing original executable with thinned version"
rm "$FRAMEWORK_EXECUTABLE_PATH"
mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"

done

6.3.3 接口使用说明

6.3.3.1方法和参数说明
// 风控组件:DXRiskManager类
@interface DXRiskManager : NSObject

// 字符串常量
extern NSString* const DXRiskManagerKeyUserId;
extern NSString* const DXRiskManagerKeyEmail;
extern NSString* const DXRiskManagerKeyPhone;
extern NSString* const DXRiskManagerKeyUserExtend1;
extern NSString* const DXRiskManagerKeyUserExtend2;
extern NSString* const DXRiskManagerKeyURL;//私有化服务器地址
extern NSString* const DXRiskManagerKeyBackup;//私有化下使用,将数据备份到顶象服务器(开启为DXRiskManagerKeyBackupEnable 值)
extern NSString* const DXRiskManagerKeyBackupAppId; // 私有化下使用,指定数据备份到顶象服务器的AppId 

extern NSString* const DXRiskManagerKeyDegradeNotify;//数据降级通知,若打开,服务端会有响应的降级统计
extern NSString* const DXRiskManagerKeyCountry;//国家地区设置,默认中国

extern NSString* const DXRiskManagerKeyDelayMsTime; //可填设置请求超时毫秒时间(默认值为 500 ,范围是:【100 : 3000】)
// NoticeDegrade参数
/* The NoticeDegrade Value. This value only be used pair with key:DXRiskManagerKeyDegradeNotify to notify token degrade. */
extern NSString* const DXRiskManagerKeyDegradeNotifyEnable;
// Backup参数
/* The Backup Value. This value only be used pair with key:DXRiskManagerKeyBackup to set data backup. */
extern NSString* const DXRiskManagerKeyBackupEnable;
// Country参数
/* The Country Value. This value only be used pair with key:DXRiskManagerKeyCountry to set country. */
extern NSString* const DXRiskManagerCountryChina;
/* The Country Value. This value only be used pair with key:DXRiskManagerKeyCountry to set country. */
extern NSString* const DXRiskManagerCountryIndonesia;

/**
 采集端的设备指纹信息,上传至风控后台,再由风控后台返回token。
 该API为耗时操作,因此必须在非主线程上调用。

 @param appId appId   开通服务后可在实时风险决策的二级菜单“应用管理”中获取
 @param extendsParams 业务方用户唯一标识,用户名,用户ID,Email等等,常用Key值可参考DXRiskManagerKeyUserId, DXRiskManagerKeyEmail等等
 @return token
 */
+ (NSString *)getToken:(NSString *)appId extendParams:(NSDictionary *)extendsParams;

/** 
 DXRiskManager -- 初始化方法
 */
+ (BOOL)setup;  
@end
6.3.3.2使用示例
示例一:Native
// 整个过程由于是耗时操作,必须要在非主线程上执行,否则会阻塞UI。如果本身已经在非UI线程上执行,则不需要另开线程
    dispatch_queue_t dxrisk_queue = dispatch_queue_create("com.dingxiang.dxrisk", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(dxrisk_queue, ^{
        // 根据业务逻辑,填充自定义字段
        NSDictionary *dic = @{DXRiskManagerKeyUserId: @"123456"};
        // 如需自定义服务端URL,填充DXRiskManagerKeyURL字段,如需备份私有化数据填充DXRiskManagerKeyBackup字段,如下注释
        // NSDictionary *dic = @{DXRiskManagerKeyUserId: @"123456",DXRiskManagerKeyURL:@"http://xxxxxxx",DXRiskManagerKeyBackup:DXRiskManagerKeyBackupEnable};
        // 如需统计设备降级率,填充DXRiskManagerKeyDegradeNotify字段,如下注释
        // NSDictionary *dic = @{DXRiskManagerKeyUserId: @"123456",DXRiskManagerKeyDegradeNotify:DXRiskManagerKeyDegradeNotifyEnable};
        // 获取token
        // 注意:token最好不要保存在某个局部变量或者字段,每次使用时,都通过API获取。
         //初始化
        BOOL isSuccess = [DXRiskManager setup];
        NSLog(@"setup success: %@" , isSuccess ? @"YES":@"NO");
        // 获取token
        // 注意:token最好不要保存在某个局部变量或者字段,每次使用时,都通过API获取。
        NSString *constID = [DXRiskManager getToken:@"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" extendsParams:dic];                    NSLog(@"token: %@", token);
        // TODO 把token通过Post请求,传到业务后台。
        // 下面是模拟频繁调用的过程
        while(TRUE) {
             NSLog(@"constID: %@", [DXRiskManager getToken:@"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" extendsParams:dic]);
            [NSThread sleepForTimeInterval:.5];
        }
    });
示例二:JavaScript

将相关变量导入JSContext

    JSContext *jsContext = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    jsContext[@"DXRiskManager"] = [DXRiskManager class];
    jsContext[@"DXRiskManagerKeyUserId"] = DXRiskManagerKeyUserId;
    jsContext[@"DXRiskManagerKeyBackup"] = DXRiskManagerKeyBackup;
    jsContext[@"DXRiskManagerKeyURL"] = DXRiskManagerKeyURL;
    jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
        context.exception = exceptionValue;
        NSLog(@"异常信息:%@", exceptionValue);
    };

使用

    // 根据业务逻辑,填充自定义字段(同Native使用示例)
  var isSuccess = DXRiskManager.setup()
  var token = DXRiskManager.getToken('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' , {[DXRiskManagerKeyUserId]: '123456'})

私有化部属的用户,使用4.8.0以上版本的SDK, DXRiskManagerKeyURL填写规则为ip+port(http://ip:port)或者域名(http://domain.com),注意后面不要拼"/"

6.3.3.3 异常说明

在获取token过程中,如果因为网络超时或者加解密失败,该接口有可能会返回为null,同时会输出tag为DXRISK的错误信息,具体描述如下:

DXRISK_REQUEST_NETWORK_ERR            -1001
DXRISK_REQUEST_DECRYPT_ERR            -1002
DXRISK_REQUEST_UNCOMPRESS_ERR         -1003
DXRISK_REQUEST_RESPONSE_EMPTY_ERR     -1004
DXRISK_REQUEST_DATA_PARSE_ERR         -1005
DXRISK_REQUEST_DIRTY_DATA_ERR         -1006
DXRISK_CONST_ID_EMPTY                 -1007

如果出现上述错误信息,请联系顶象技术人员。

6.4 微信小程序接入

js接入

一、下载设备指纹js

私有化版本下载

SaaS版本下载

二、获取密钥

未注册用户可在顶象官网进行账号注册,创建应用获取应用密钥AppID和AppSecret。

三、使用

  1. 代码接入
    const ConstId = require('本地设备指纹js存放路径')
    Page({
     onLoad: function () {
       new ConstId({
         appId: '【这里填写在顶象官网申请到的 AppID】', // 唯一标识,必填
         server: '' // constId 私有化服务接口,选填
       }, (e, id) => {
         if (e) {
           console.log(e)
           return
         }
         console.log('constId:', id)
       })
     }
    })
  2. SaaS用户在小程序后台配置业务域名https://constid.dingxiang-inc.com,私有化用户配置部署域名,测试阶段可以开启微信开发者工具右上角详情->本地设置->“不校验域名”。

七、后端接入

7.1 第一步 申请AppId


  • 开通服务后可在实时风险决策的二级菜单“应用管理”中获取到AppId、AppSecret。

7.2 第二步 下载SDK并接入


  • 非maven项目

    JAVA6版本SDK下载点击下载, JAVA7、8版本SDK下载点击下载, 如需其他版本SDK请联系在线客服。

  • maven项目引入依赖(Java7及以上版本)

    <dependency>
      <groupId>com.dingxiang-inc</groupId>
      <artifactId>ctu-client-sdk</artifactId>
      <version>2.0</version>
    </dependency>
  • PHP版本SDK下载:点击下载

  • C#版本SDK下载 支持.net framework 4.0:点击下载

  • Python版本SDK下载: 点击下载

  • NodeJS版本SDK参考下方示例,直接从npm安装

  • Go版本SDK

  • 接入事件的event_code和事件需要的参数,请咨询顶象技术人员或官网在线客服

7.3 返回参数说明

CtuRequest: 风控引擎的请求类,包含一次请求的所有业务数据

字段名称类型是否必须说明
eventCodeString事件的唯一编码,由顶象提供
flagString请求标记,客户端可以标记该次请求
dataMap<String, object>Map结构,包含该次请求的业务数据

CtuResponse:风控引擎返回的结果类,包含引擎返回的识别结果

字段名称类型说明
uuidString服务端返回的请求标识码,供服务端排查问题
statusString服务端返回的状态
resultCtuResult服务端返回的识别结果类

CtuResponse status状态说明

状态code描述出现的场景
SUCCESS成功调用成功无误
INVALID_REQUEST_PARAMS请求不合法,缺少必须参数1. 请求url中缺少sign参数
2. 缺少AppId
3. 缺少eventCode
4. 缺少执行策略过程中的某些字段指标, 在这种情况下会额外返回错误描述信息在CtuResult中extraInfo的ruleeval_error和errorpolicy, 标识发生在哪条策略, 哪条规则
INVALID_REQUEST_BODY请求不合法,请求body为空请求中没有传CtuRequest对象
INVALID_REQUEST_NO_EVENT_DATA请求不合法,请求事件的数据为空请求中没有传业务数据, CtuRequest.data`
INVALID_REQUEST_SIGN请求签名错误请求签名校验失败
INVALID_APP_KEY不合法的AppId找不到传入的AppId
INVALID_EVENT_CODE不合法的事件传入的事件Code有误
INVALID_APP_EVENT_RELATION应用和事件的绑定关系错误传入的 AppId和事件Code没有关联关系
EVENT_GRAY_SCALE事件有灰度控制,非灰度请求事件设置了灰度值, 本次请求非灰度请求
POLICY_HAS_ERROR防控策略配置有错误执行策略过程中发生异常
NOT_SUPPORTED_POLICY_OPERATOR不支持防控策略里的操作符某个策略中使用的操作符不存在
SERVICE_INTERNAL_ERROR服务器内部错误执行过程中产生了异常, 在这种情况下会额外返回错误描述信息在CtuResult中extraInfo的exceptionmsg
QPS_EXCEEDING_MAXIMUM_THRESHOLD并发超过限制流量过大时,服务端会进行限流,超出部分流量返回ACCEPT

CtuResult 字段解释

字段名称类型说明
riskLevelRiskLevel类该次请求的风险级别,枚举类型,包括 ACCEPT(无风险,建议放过),REVIEW(不确定,需要进一步审核),REJECT(有风险,建议拒绝)
riskTypeString风险类型,例如 垃圾注册,账号盗用
hitPolicyCodeString命中的策略code
hitPolicyNameString命中的策略标题
hitRulesList命中的规则列表,每个规则包括规则id和左变量
suggestPoliciesList建议的防控策略
suggestionList命中策略处置建议
flagString客户端请求带上来的标记
extraInfoMap<String, Object>附加信息

7.4 示例代码


  • JAVA版
/**
 * 风控引擎url
 **/
public static final String url = "https://sec.dingxiang-inc.com/ctu/event.do";
/**
 * 应用AppId,公钥
 **/
public static final String appId = "你的AppId";
/**
 * 应用AppSecret,私钥
 **/
public static final String appSecret = "你的AppSecret";

public static void checkRisk() throws Exception {
    /**业务请求数据**/
    Map<String, Object> data = new HashMap<>();
    data.put("const_id", "exxxxxxwbZsF1PqoflWOyhKLIhAzw9X1"); // 设备指纹token,端上获取 传入后台
    data.put("user_id", 456799324); // 用户ID
    data.put("phone_number", "13800138000"); // 手机号
    data.put("source", 2); // 登录来源
    data.put("ip", "127.0.0.1"); // 请求的ip地址

    data.put("activity_id", 1); // 活动ID
    data.put("register_date", "注册时间,时间格式2017-09-27 10:09:20"); //用户注册时间
    data.put("ext_answer_end_date","答题结束时间,时间格式2017-09-27 10:09:20"); //答题结束时间
    data.put("ext_answer_start_date", "答题开始时间,时间格式2017-09-27 10:09:20"); //答题开始时间
    data.put("ext_open_id", "xxxxxea3174dde1f"); //微信登录id
    data.put("ext_user_level", 5); //会员等级
    data.put("ext_prov_name", "北京市"); //手机所属省份

    /**创建一个请求数据实例**/
    CtuRequest request = new CtuRequest();
    /**设置事件编码**/
    request.setEventCode("activity_event");
    /**设置该次风控请求的业务数据**/
    request.setData(data);
    request.setFlag("activity_" + System.currentTimeMillis());
    /**创建一个客户端实例**/
    CtuClient client = new CtuClient(url, appId, appSecret);
   /** CtuClient client = new CtuClient(url,appKey,appSecret, connectTimeout, connectionRequestTimeout,socketTimeout)
     用户可以自定义超时设置
     connectTimeout,connectionRequestTimeout,socketTimeout 单位:毫秒
     默认超时设置均为2000毫秒     
     **/
    /**向风控引擎发送请求,获取引擎返回的结果**/
    CtuResponse response = client.checkRisk(request);
    if (RiskLevel.ACCEPT.equals(response.getResult().getRiskLevel())) {
        System.out.printf(JSON.toJSONString(response));
        //... 业务代码,当前请求没有风险
    } else if (RiskLevel.REVIEW.equals(response.getResult().getRiskLevel())) {
        System.out.printf(JSON.toJSONString(response));
        //... 业务代码,当前请求有一定风险,建议复审
    } else if (RiskLevel.REJECT.equals(response.getResult().getRiskLevel())) {
        System.out.printf(JSON.toJSONString(response));
        //... 业务代码,当前请求有风险,建议拒绝
    }
}
  • PHP版
include "./CtuClient.php";

$url = "https://sec.dingxiang-inc.com/ctu/event.do";
$appId = "你的AppId";
$appSecret = "你的AppSecret";

// 时区
ini_set('date.timezone','Asia/Shanghai');

// 构造请求参数
$request = new CtuClient($url, $appId, $appSecret);
$reqJsonString =  json_encode($request, JSON_UNESCAPED_UNICODE);
$ctuRequest = new CtuRequest();

// $data 具体的业务参数,根据业务实际情况传入
$data = array (
  "const_id" => "exxxxxxKgiPKBMmcwbZsF1PqoflWOyhKLIhAzw9X1",  // 设备指纹token,端上获取 传入后台
  "user_id" => "438888824",
  "phone_number" => "13800138000", 
  "source" => 2, 
  "activity_id" => 1, 
  "ext_prov_name" => "北京市",
  "register_date" => date('Y-m-d H:i:s'), 
  "ext_answer_end_date" => date('Y-m-d H:i:s'),
  "ext_answer_start_date" => date('Y-m-d H:i:s'),
  "ext_user_level" => 5,
  "ext_open_id" => "58888888174dde1f", 
  "ip" => "127.0.0.1"
);

// $eventCode 事件code
$ctuRequest -> eventCode = "activity_event";
$ctuRequest -> flag = "activity_" . time();
$ctuRequest -> data = $data;

// 请求超时时间,单位秒
$timeout = 1;
//调用风控引擎
$responseData = $request -> checkRisk($ctuRequest, $timeout);
echo "风险引擎返回结果:" . $responseData. "\n";
$jsonResult = json_decode($responseData, true);
$result = $jsonResult['result']["riskLevel"];

// ... 根据不同风险做出相关处理
if ($result == "ACCEPT") {
    // 无风险,建议放过
    echo "风险结果:无风险,建议放过" . "\n";
} else if ($result == "REVIEW") {
    // 不确定,需要进一步审核
    echo "风险结果:不确定,需要进一步审核" . "\n";
} else if ($result == "REJECT") {
    // 有风险,建议拒绝
    echo "风险结果:有风险,建议拒绝" . "\n";
}
  • C#版
String appId = "560074aad5xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
 /**应用AppId,公钥**/

String appSecret = "ea2662cxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
/**应用AppSecret,私钥**/

String url = "https://sec.dingxiang-inc.com/ctu/event.do"; 
/** 风控引擎url**/
CtuClient ctuClient = new CtuClient(url, appId, appSecret);

Dictionary<string, string> data = new Dictionary<string, string>();
/**业务请求数据,根据实际情况传入**/
data.Add("const_id", "exxxxxxKgiPKBMmcwbZsF1PqoflWOyhKLIhAzw9X1");// 设备指纹token,端上获取 传入后台
data.Add("user_id", "438888824");
data.Add("ext_referer", "ext_refererext_referer");
data.Add("phone_number", "1801002000");
data.Add("ip", "123.21.21.12");
data.Add("time", "2016-10-15 20:12:12"); //时间格式 
CtuRequest ctuRequest = new CtuRequest();
ctuRequest.data = data;
ctuRequest.eventCode = "your event code";
ctuRequest.flag = "自定义标记,可以用uuid";
CtuResponse response = ctuClient.CheckRisk(ctuRequest);

/**向风控引擎发送请求,获取引擎返回的结果**/
if (String.Equals(response.result.RiskLevel, "ACCEPT"))
{
     //... 业务代码,当前请求没有风险
}
else if (String.Equals(response.result.RiskLevel, "REVIEW"))
{
    //... 业务代码,当前请求有一定风险,建议复审
}
else if (String.Equals(response.result.RiskLevel, "REJECT"))
{
    //... 业务代码,当前请求有风险,建议拒绝
}
  • Python 版
# coding=utf-8
import json
from CtuRequest import CtuRequest
from CtuClient import CtuClient
from RiskLevel import RiskLevel

class Demo:
    URL = "https://sec.dingxiang-inc.com/ctu/event.do"
    #风控引擎url
    APP_ID = 'appId'
    #应用AppId,公钥
    APP_SECERT = 'appSecret'
    #应用AppSecret,私钥
    if __name__ == '__main__':
        event_code = 'event_code'
        flag = 'test1'
        data = { #业务请求数据,根据实际情况传入
            'const_id': 'constId', #设备指纹token,端上获取 传入后台
            'user_id': '123',
            'phone_number': '15700000000',
            'ip': '127.0.0.1'
        }
        ctuRequest = CtuRequest(event_code, flag, data)
        client = CtuClient(URL, APP_ID, APP_SECERT)
        #client.timeout = 2
        #设置超时时间 默认两秒
        ctuResponse = client.checkRisk(ctuRequest)
        #向风控引擎发送请求,获取引擎返回的结果
        print ctuResponse
        if ctuResponse["result"]["riskLevel"] == RiskLevel.ACCEPT:
            print "当前请求没有风险"
            pass
        elif ctuResponse["result"]["riskLevel"] == RiskLevel.REVIEW:
            print "当前请求有一定风险,建议复审"
            pass
        elif ctuResponse["result"]["riskLevel"] == RiskLevel.REJECT:
            print "当前请求有风险,建议拒绝"
            pass
  • NodeJS版本
npm install dx-ctu-client-sdk --save
const ClientSDK = require('dx-ctu-client-sdk')

const sdk = new ClientSDK('服务url', '您的appId', '您的appSecret')

sdk.checkRisk({
  "data": {
    "phone_number": "17800000000",
    "user_id": "12345326232",
    "ip": "125.121.232.219",
    "const_id": "N4RG6TtsY6ILK5ePY6HVtjj12pu5Yi5wnjnbaUI41" // 设备指纹token,端上获取 传入后台
  },
  "eventCode": "test_event_1",
  "flag": "test1"
}).then((resp) => {
  const level = resp.result.riskLevel

  if (level === 'ACCEPT') {
    // 业务代码,当前请求没有风险
  } else if (level === 'REVIEW') {
    // 业务代码,当前请求有一定风险,建议复审
  } else if (level === 'REJECT') {
    // 业务代码,当前请求有风险,建议拒绝
  }
})

// 设置超时时间
// checkRisk第二个参数为超时时间,默认为2000(2秒)
400-8786-123
QQ在线咨询
在线咨询
betway88