--- url: >- https://acquirer-api-docs-v4-en.pingpongx.com/notes/zh/risk/riskDefense/index.md description: >- riskDefense组件用于集成3DS验证及风控功能,适用于提升支付安全性。初始化时需加载JS并配置环境参数如env、accId等。通过获取generatedData来准备必要的风控信息,并在下单支付时传递browserInfo以完成交易安全检查。 --- # 3DS riskDefense组件集成指南 ## 初始化 ### load JS ::: code-tabs @tab URL ``` https://pay-cdn.pingpongx.com/production-fra/static/riskDefense/pingpongRiskDefense.min.js ``` ::: ### initialize JS ::: danger 沙箱联调请填入`env`=`SANDBOX`, 生产环境请填入`env`=`PRODUCTION`。 ::: ::: code-tabs @tab JavaScript ```js const pp = new PingPongRiskDefense({ env: 'SANDBOX'|'PRODUCTION', accId: string, clientId: string, requestId: string, merchantUserId: string, merchantTransactionId: string }) ``` ::: | 属性 | 类型 | 必填 | 描述 | |-----------------------|--------|-----|---------------------------------------| | env | string | M | 当前调用服务环境SANDBOXPRODUCTION | | accId | string | M | PingPong店铺号 | | requestId | string | C | 端到端接入时候传送 | | merchantUserId | string | C | 持卡人在商户网站的会员标识 | | merchantTransactionId | string | C | 收银台应传 `merchantTransactionId` | ## 获取3DS 和风控参数 ### 获取generatedData 在向PingPongCheckout发起支付请求前, 执行该步骤获取`generatedData`, 并在支付时将其传递给支付接口。 ::: code-tabs @tab JavaScript ```js const generatedData = pp.getGeneratedData() ``` ::: 返回的generatedData结构如下: ::: code-tabs @tab JavaScript ```js { browserInfo: { acceptHeader: string, colorDepth: number, language: string, screenHeight: number screenWidth: number timeZoneOffset: number userAgent: string javaEnabled: boolean javaScriptEnabled: boolean }, jsGeneratedData: { fingerPrint: string, forterSiteId: string, forterTokenCookie: string | null } } ``` ::: ## 下单并支付接口报文组装 ### 填充browserInfo 请求PingPongCheckout 下单并支付接口。在参数 `browserInfo`中传送`generatedData`里面获取的`broswerInfo`参数。 | 属性 | 类型 | 描述 | |-------------------|--------|-----------------------------------------------------------------------------------------------------------------------------------------| | language | string | 购物者浏览器的navigator.language值(如IETF BCP 47中所定义)。 | | screenWidth | int | 持卡人终端屏幕宽度(单位:像素) | | javaEnabled | bool | 持卡人终端是否能够执行Java。 | | javaScriptEnabled | bool | 指示购物者的浏览器是否能够执行JavaScript。如果字段不存在,则假定为默认的`true`值。 | | acceptHeader | string | http响应头信息, 示例值: text/html, application/xhtml+xml, application/xml;q=0.9, image/webp, image/apng, *;q=0.8 | | colorDepth | string | | | screenHeight | int | 持卡人终端屏幕高度(单位:像素) | | jetLag | int | UTC时间和持卡人浏览器本地时间之间的时差,以分钟为单位。 | | userAgent | string | 浏览器用户代理信息 示例值:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36 | ### jsGeneratedData 填充 | 属性 | 类型 | 描述 | |-------------------|--------|------| | fingerPrint | string | 设备指纹 | | forterSiteId | string | 站点标识 | | forterTokenCookie | string | | ### 请求支付 完成上述额外的参数填充之后,还需要填充下单并支付接口必要的业务参数。成功发起支付之后,响应报文中会携带参数 `threeDUnionParams` 请求报文示例: ::: code-tabs @tab JSON ```json { "accId":"2090020315464510103001", "clientId":"2090020315464510103", "signType":"SHA256", "sign":"{{Sign}}", "version":"1.0", "bizContent":{ "captureDelayHours":"0", "amount":"3", "currency":"USD", "merchantTransactionId":"{{merchantTransactionId}}", "payResultUrl":"https://test-acquirerpay.pingpongx.com/qa/result.html", "payCancelUrl":"https://test-acquirerpay.pingpongx.com/qa/result.html", "notificationUrl":"https://test-acquirerpay.pingpongx.com/qa/result.html", "language":"en", "requestId":"{{requestId}}", "tradeCountry":"US", "shopperIP":"222.126.52.23", "paymentMethod":{ "type":"scheme", "cardInfo":{ "expireMonth":"12", "expireYear":"2024", "holderFirstName":"w", "holderLastName":"w", "number":"5200000000001096", "cvv":"103" } }, "customer":{ "firstName":"Jamesbb", "lastName":"LeBronbb", "email":"test@pingpongx.com", "phone":"9157030054" }, "goods":[ { "name":"商品名称mepsking1", "description":"商品描述", "sku":"产品SKU111", "unitPrice":"1000", "number":"1", "imgUrl":"https://xiu.mepsking.top/material/1/16606169805015585.png", "virtualProduct":"Y" } ], "shippingAddress":{ "firstName":"Jamesbb", "lastName":"LeBronbb", "phone":"9157030054", "email":"3ds@pingpongx.com", "street":"3888 Austin Secret Lane", "postcode":"84723", "city":"Circleville", "state":"UT", "country":"US" }, "billingAddress":{ "firstName":"Jamesbb", "lastName":"LeBronbb", "phone":"9157030054", "email":"3ds@pingpongx.com", "street":"3888 Austin Secret Lane", "postcode":"84723", "city":"Circleville", "state":"UT", "country":"US" }, "browserInfo":{ "acceptHeader":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", "colorDepth":"24", "jetLag":"480", "language":"nl-NL", "javaEnabled":"true", "screenHeight":"723", "screenWidth":"1536", "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36", "windowSize":"05" }, "device":{ "orderTerminal":"02" } } } ``` ::: ## 是否需要3DS验证 ### threeDContinue - `threeDUnionParams.threeDContinue`为`true`时候需要触发3d验证。 - `threeDUnionParams.threeDContinue`为`false`时候将会跳转到商户的支付结果页`shopperResultUrl`。 ## 3DS挑战页 ### 使用JS的trigger方法触发3DS挑战页 将支付接口返回的 `threeDUnionParams` 作为入参调用 `trigger` 函数,风控JS会引导浏览器到3D挑战页,持卡人需要正确的完成3D验证,才能成功交易 ::: code-tabs @tab JavaScript ```js pp.trigger(threeDUnionParams) ``` ::: ### 使用PingPongChekout提供的中间页触发3DS挑战页 从下单并支付接口的响应报文中获取`threeDUnionParams.threeDRedirectUrl`参数,通过GET方式跳转,随后PingPongChekout提供的中间页将会自动重定向到3DS挑战页。