Callback API

Callback 호출

POST VEGA_VERIFICATION_CALLBACK_API_PATH

Enclave 환경 변수:

VEGA_VERIFICATION_CALLBACK_API_PATH 변수에, Callback API 엔드포인트를 명시합니다.

비동기 방식으로 API가 호출되었을 경우 사용되는 Callback API입니다.

비동기로 동작하는 API는 아래와 같습니다.

  • 사용자 검증 요청 API

  • 트랜잭션 결과 리포트 API

  • 에러 상황 리포트 API

  • Chainalysis KYT 기능을 이용한 위험 평가 API

  • Refinitiv WCO 기능을 이용한 위험 평가 API

Callback API는 enclave에서 호출하는 API로 다음과 같은 경우에 호출됩니다.

  • 이전에 요청했던 Verification에 대한 결괏값이 도착했을 경우 (callbackType : VERIFICATION_RESULT)

  • 송신 VASP에서 특정 verification에 대응되는 txHash 또는 txID의 report가 도착했을 경우 (callbackType : TX_REPORT)

  • 송신 VASP에서 특정 verification에 대응되는 에러 상황 report가 도착했을 경우 (callbackType : ERROR_REPORT)

  • 기존에 등록한 Chainalysis KYT 요청에 대한 위험 평가 결과를 수신했을 경우 (callbackType : CHAINALYSIS_KYT_RESULT)

  • 기존에 등록한 Refinitiv WCO 요청에 대한 위험 평가 결과를 수신했을 경우 (callbackType : REFINITIV_WCO_RESULT)

응답 시간:

이 Callback API는 1초 이내에 응답해야 합니다.

구현 정책

  • 200 OK 코드 외 다른 HTTP response status code를 반환해서는 안 됩니다.

  • API에 대한 response는 가급적 빨리 반환해야 합니다. 따라서 callback API 내부적으로 시간이 오래 걸리는 작업은 비동기로 처리해야 합니다.

  • 멱등성(Idempotent)을 보장하도록 구현해야 합니다.

    • enclave 내부에서 데이터 유실을 방지하기 위해 똑같은 데이터로 callback이 여러 번 호출될 수 있습니다.

    • 따라서 중복 데이터를 수신했을 경우에도 이전과 똑같은 동작을 하도록 보장해야 합니다. (예를 들어 이미 받은 데이터는 무시한다든지)

Request Header

Request Body

Request Body Example for VERIFICATION_RESULT callbackType
{
  "callbackType": "VERIFICATION_RESULT",
  "data": {
    "verificationUuid": "64ab871b-14a3-47df-9b80-368e29fe8180",
    "verificationResult": "DENIED",
    "reason": "UNKNOWN-ADDRESS",
    "ivms101": {
      "originator": {
        "originatorPersons": [
          {
            "naturalPerson": {
              "name": {
                "nameIdentifier": [
                  {
                    "primaryIdentifier": "James",
                    "secondaryIdentifier": "Din",
                    "nameIdentifierType": "LEGL"
                  }
                ]
              }
            }
          }
        ],
        "accountNumber": ["0x5811001506550d8356a215be229c15b6ef371a9a"]
      },
      "beneficiary": {
        "beneficiaryPersons": [
          {
            "naturalPerson": {
              "name": {
                "nameIdentifier": [
                  {
                    "primaryIdentifier": "Taylor",
                    "secondaryIdentifier": "Robbins",
                    "nameIdentifierType": "LEGL"
                  }
                ]
              }
            }
          }
        ],
        "accountNumber": ["0xb0bFf9721871e22653358956cf59a5FdBF3D752F"]
      },
      "originatingVASP": {
        "legalPerson": {
          "name": {
            "nameIdentifier": [
              {
                "legalPersonName": "Lambda256",
                "legalPersonNameIdentifierType": "LEGL"
              }
            ]
          },
          "geographicAddress": [
            {
              "addressType": "GEOG",
              "postcode": "123123c",
              "townName": "Yeoksam-dong",
              "addressLine": ["sechogu street", "100-100"],
              "country": "KR"
            }
          ],
          "nationalIdentification": {
            "nationalIdentifier": "KR0001",
            "nationalIdentifierType": "RAID",
            "registrationAuthority": "RA000151"
          }
        }
      },
      "beneficiaryVASP": {
        "legalPerson": {
          "name": {
            "nameIdentifier": [
              {
                "legalPersonName": "Lambda256 Exchange",
                "legalPersonNameIdentifierType": "LEGL"
              }
            ]
          },
          "geographicAddress": [
            {
              "addressType": "GEOG",
              "postcode": "234234",
              "townName": "Yeoksam-dong",
              "addressLine": ["sechogu street", "100-100"],
              "country": "KR"
            }
          ],
          "nationalIdentification": {
            "nationalIdentifier": "123456",
            "nationalIdentifierType": "RAID",
            "registrationAuthority": "RA000677"
          }
        }
      }
    }
  }
}
Request Body Example for TX_REPORT callbackType
{
  "callbackType": "TX_REPORT",
  "data": {
    "verificationUuid": "64ab871b-14a3-47df-9b80-368e29fe8181",
    "txHash": "8a54d58ca4100112a5430818776d74898f2232770bae03046862575cb851a042",
    "vout": "2"
  }
}
Request Body Example for ERROR_REPORT callbackType
{
  "callbackType": "ERROR_REPORT",
  "data": {
    "verificationUuid": "64ab871b-14a3-47df-9b80-368e29fe8182",
    "result": "ERROR",
    "reason": "BLACKLISTED",
    "message": "Originator is included in the blacklist."
  }
}
Request Body Example for CHAINALYSIS_KYT_RESULT callbackType
{
  "callbackType": "CHAINALYSIS_KYT_RESULT",
  "data": {
    "verificationUuid": "69a310e6-810f-4a31-83d1-bcdafccf5304",
    "riskAssessment": {
      "chainalysisKYT": {
        "counterpartyVaspId": "15952089931162059995",
        "apiType": "ATTEMPT",
        "userId": "15952089931162059995",
        "direction": "OUTGOING",
        "network": "ETHEREUM",
        "asset": "ETH",
        "amount": "1",
        "usdPrice": "1820.17",
        "outputAddress": "bb3fd383d1c5540e52ef0a7bcb9433375793aeaf",
        "timestamp": "2023-05-18T12:39:44.000Z",
        "externalId": "79382ac9-c7be-3fab-ad56-8c61c654e2fc",
        "status": "PROCESSED",
        "alertCount": 1,
        "createdAt": "2023-05-18T12:39:46.000Z",
        "assessedAt": "2023-05-18T12:39:45.263Z"
      },
      "chainalysisKYTAlerts": [
        {
          "counterpartyVaspId": "15952089931162059995",
          "externalId": "79382ac9-c7be-3fab-ad56-8c61c654e2fc",
          "direction": "OUTGOING",
          "alertId": "118b8cc8-f579-11ed-b86d-a3210c6ca9b8",
          "alertLevel": "MEDIUM",
          "entityCategory": "high risk exchange",
          "serviceName": "HIGH RISK EXCHANGE: SimpleSwap.io bb3fd383d1c5540e52ef0a7bcb9433375793aeaf",
          "exposureType": "DIRECT",
          "alertAmount": "1820.17",
          "createdAt": "2023-05-18T12:39:52.461Z"
        }
      ]
    }
  }
}
Request Body Example for REFINITIV_WCO_RESULT callbackType
{
  "callbackType": "REFINITIV_WCO_RESULT",
  "data": {
    "verificationUuid": "69a310e6-810f-4a31-83d1-bcdafccf5304",
    "riskAssessment": {
      "refinitivWorldCheckOne": {
        "counterpartyVaspId": "15952089931162058999",
        "direction": "INCOMING",
        "caseSystemId": "5jb7r2c9xjfk1hoc95gfayv6m",
        "status": "PROCESSED",
        "matchStrength": "EXACT",
        "aggregatedSummaryResult": "{\"caseId\":\"69a310e6-810f-4a31-83d1-bcdafccf5304-INCOMING-1684413585757\", ... }}}",
        "createdAt": "2023-05-18T12:39:48.000Z",
        "assessedAt": "2023-05-18T12:39:57.834Z"
      }
    }
  }
}
  • callbackType 필드에는 다음과 같은 값이 들어갈 수 있습니다.

    • VERIFICATION_RESULT: 이전에 호출했던 사용자 검증 요청 API에 대한 결과가 도착했을 때 호출

    • TX_REPORT: Originating VASP로부터 트랜잭션 결과 리포트가 도착했을 때 호출

    • ERROR_REPORT: Beneficiary VASP로부터 에러 상황 리포트가 도착했을 때 호출

    • CHAINALYSIS_KYT_RESULT: Chainalysis KYT API를 이용하여 위험 평가를 수행한 결과가 도출되었을 때 호출

    • REFINITIV_WCO_RESULT: Refinitiv WCO API를 이용하여 위험 평가를 수행한 결과가 도출되었을 때 호출

  • data.reason 필드에는 다음과 같은 값이 들어갈 수 있습니다.

    • 단, 사용자 검증 요청에 대한 결과 data.result 필드의 값이 DENIED 일 때에만 유효합니다.

    • data.message 필드에는, 아래 표에 설명된 값을 string으로 전달합니다. (하단 표 내용 참조)

Response Body

Response Body Examples
  • 200 OK

{
  "result": true
}

Last updated