Sub Virtual Account RFI — Integration Guide#
1. Overview#
When a Sub Virtual Account (Sub VA) requires additional compliance materials (RFI — Request for Information), the platform notifies the merchant via webhook, then the merchant:1.
Receives Sub Virtual Account RFI Required
2.
Calls Get Sub Virtual Account RFI Template Info to load the question / file checklist
3.
Calls Sub Virtual Account Submit RFI to upload answers and documents
4.
Continues to receive the same webhook as review progresses — use data.rfiStatus for the latest outcome
2. Step 1 — Receive webhook: Sub Virtual Account RFI Required#
Example payload#
{
"eventId": "36190155-28a2-42f9-a55a-1359654b7384",
"eventType": "SUB_VIRTUAL_ACCOUNT_RFI_REQUIRED",
"referenceId": "538",
"status": "SUCCESS",
"timestamp": 1764235978954,
"data": {
"virtualAccountId": "3100",
"externalAccountId": "",
"accountName": "ALBrooks",
"currency": "MXN",
"status": "SUCCESS",
"awaitingRfiTypeList": [
"SUB_ACCOUNT_RFI_TIER_1"
],
"rfiStatus": "AWAITING_SUBMISSION"
}
}
Key fields for the RFI flow#
| Field | Source | How to use |
|---|
data.virtualAccountId | Webhook | Pass as virtualAccountId to the template API, and as accountId when submitting RFI |
data.awaitingRfiTypeList | Webhook | Pass as bizTypeList to Get Sub Virtual Account RFI Template Info |
data.rfiStatus | Webhook | Current RFI lifecycle status (AWAITING_SUBMISSION / SUBMITTED/ RESUBMIT_REQUIRED / APPROVED or REJECTED) |
rfiStatus values#
Subsequent review outcomes are also delivered through this same webhook. Always read data.rfiStatus:rfiStatus | Meaning | Merchant action |
|---|
AWAITING_SUBMISSION | Materials required | Fetch template → submit RFI |
RESUBMIT_REQUIRED | Compliance requested resubmission | Fetch template / feedback → resubmit |
SUBMITTED | Materials received; under review | Wait for next webhook |
APPROVED | Review approved | No further RFI action |
REJECTED | Review rejected | Follow compliance guidance |
Note: When materials are still required, awaitingRfiTypeList lists the biz types (tiers) that need answers. Use that list as bizTypeList for the template API.
3. Step 2 — Get materials checklist: Get Sub Virtual Account RFI Template Info#
Query parameters (map from webhook)#
| Parameter | Required | Map from webhook |
|---|
bizTypeList | Yes | data.awaitingRfiTypeList (e.g. SUB_ACCOUNT_RFI_TIER_1) |
virtualAccountId | Recommended | data.virtualAccountId |
currency | Optional | data.currency |
Example request#
What you get#
A list of KYB/RFI templates. Each item contains bizType and questions[]. For each question use:| Question field | Use when submitting |
|---|
id | answerList[].questionId |
type | FILE → upload via base64Files / file; TEXT (etc.) → fill answer |
required | Must provide content when true |
label / description | UI labels and hints |
4. Step 3 — Submit materials: Sub Virtual Account Submit RFI#
Request mapping#
| Submit field | Value |
|---|
accountId | Webhook data.virtualAccountId |
answerList[].bizType | Same tier as in awaitingRfiTypeList / template bizType |
answerList[].questionId | Template question id |
answerList[].answer | Text answer (for text questions); may be empty for file-only questions |
answerList[].file | Existing file key(s), comma-separated (optional if using base64Files) |
answerList[].base64Files | Base64-encoded file contents (PDF / JPEG / PNG, etc.) |
Example request body#
{
"accountId": "4059",
"answerList": [
{
"bizType": "SUB_ACCOUNT_RFI_TIER_1",
"questionId": "RFI_TIER1_Individual_Identity_Document",
"answer": "",
"file": "",
"base64Files": [
"JVBERi0xLjQKJcfs...",
"iVBORw0KGgoAAAANSUhEUgAA..."
]
},
{
"bizType": "SUB_ACCOUNT_RFI_TIER_1",
"questionId": "RFI_TIER1_Individual_Address_Proof",
"answer": "",
"file": "",
"base64Files": [
"JVBERi0xLjQKJcfs...",
"iVBORw0KGgoAAAANSUhEUgAA..."
]
},
{
"bizType": "SUB_ACCOUNT_RFI_TIER_1",
"questionId": "RFI_TIER1_Individual_Business_Proof",
"answer": "",
"file": "",
"base64Files": [
"JVBERi0xLjQKJcfs...",
"iVBORw0KGgoAAAANSUhEUgAA..."
]
},
{
"bizType": "SUB_ACCOUNT_RFI_TIER_1",
"questionId": "RFI_TIER1_Individual_Supporting_Documents",
"answer": "",
"file": "",
"base64Files": [
"JVBERi0xLjQKJcfs...",
"iVBORw0KGgoAAAANSUhEUgAA..."
]
},
{
"bizType": "SUB_ACCOUNT_RFI_TIER_1",
"questionId": "RFI_TIER1_Individual_Additional_Information",
"answer": "",
"file": ""
}
]
}
Success response (data)#
true when the submission is accepted. After a successful submit, expect another Sub Virtual Account RFI Required webhook with an updated rfiStatus (typically SUBMITTED, then later APPROVED / REJECTED / RESUBMIT_REQUIRED).
5. End-to-end checklist#
Configure your Stable webhook URL to accept eventType = SUB_VIRTUAL_ACCOUNT_RFI_REQUIRED.
On receive: persist eventId for idempotency; read data.virtualAccountId, awaitingRfiTypeList, and rfiStatus.
Call GET /v1/virtual-account/sub/rfi-template with bizTypeList = awaitingRfiTypeList and virtualAccountId = virtualAccountId.
Build answerList from template questions (bizType + questionId + answer / base64Files).
Call POST /v1/virtual-account/sub/submit-rfi with accountId = virtualAccountId.
Treat later webhooks of the same event type as status updates; branch on data.rfiStatus.