Tài liệu / Tài liệu API Endpoints

Tài liệu API Endpoints

API Endpoints — EKYC Middleware

Tài liệu endpoints theo từng module. Base URL: /api/v1 API Docs (OpenAPI 3.0): http://at.ekyc.test/docs/api — tự động sinh từ code bởi Scramble

Module: Partner (Bank → BE)

Yêu cầu mTLS + JWT (header Authorization: Bearer <JWT>)

POST /partner/init-session

Khởi tạo session EKYC, trả webview URL cho Bank redirect user.

Request:

{
  "partner_tx_id": "TXN2026072901001",
  "user_id": "USER_123456",
  "account_number": "1903681845018",
  "bank_name": "Ngân hàng TMCP Việt Nam Thịnh Vượng",
  "bank_code": "VPB",
  "account_holder_name": "NGUYEN VAN A",
  "commission_status": "accumulated",
  "identity_info": {
    "full_name": "Nguyễn Văn A",
    "id_number": "079201012345",
    "date_of_birth": "1990-01-01",
    "phone": "0901234567",
    "email": "nguyenvana@email.com"
  },
  "contract_ref": "HD/2026/07/001",
  "expired_minutes": 30
}

Response 200:

{
  "status": "success",
  "data": {
    "session_id": "ekyc_abc123def456",
    "partner_code": "VPBANK",
    "partner_name": "VPBank",
    "webview_config": {
      "brand_name": "VPBank",
      "logo_url": "https://vpbank.com/logo.png",
      "theme": "#0d6efd",
      "theme_color": "#0d6efd",
      "language": "vi",
      "support_phone": null,
      "terms_url": null
    },
    "webview_url": "https://ekyc-middleware.example.com/webview/ekyc_abc123def456",
    "webview_token": "eyJhbGciOiJIUzI1NiIs...",
    "access_token": "eyJhbGciOiJSUzI1NiIs...",
    "access_token_expires_at": "2026-07-29T13:15:00+07:00",
    "expires_in": 900,
    "refresh_token": "refr_123456...",
    "refresh_token_expires_at": "2026-07-30T13:00:00+07:00",
    "session_expired_at": "2026-07-29T13:30:00+07:00"
  },
  "meta": {
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "timestamp": "2026-07-29T13:00:00+07:00",
    "response_time_ms": 185
  }
}

Validation rules:

FieldRules
partner_tx_idrequired, string, max:100, unique_in_partner
user_idrequired, string, max:100
account_numbernullable, string, max:50
bank_namenullable, string, max:150
bank_codenullable, string, max:50
account_holder_namenullable, string, max:150
identity_inforequired, array
identity_info.full_namerequired, string, max:255
identity_info.id_numberrequired, regex:/^\d{9,12}$/
identity_info.date_of_birthrequired, date_format:Y-m-d
expired_minutesinteger, min:5, max:1440

GET /partner/session/{session_id}

Tra cứu trạng thái session.

Response 200:

{
  "status": "success",
  "data": {
    "session_id": "ekyc_abc123def456",
    "partner_tx_id": "TXN2026072901001",
    "user_id": "USER_123456",
    "status": "awaiting_ekyc",
    "created_at": "2026-07-29T13:00:00+07:00",
    "expired_at": "2026-07-29T13:30:00+07:00",
    "steps": {
      "identity": "completed",
      "face_match": "pending",
      "ekyc_result": "pending",
      "sign_contract": "pending"
    }
  },
  "meta": { "...": "..." }
}

GET /partner/session/{session_id}/result

Lấy kết quả EKYC sau khi hoàn tất.

Response 200:

{
  "status": "success",
  "data": {
    "session_id": "ekyc_abc123def456",
    "partner_tx_id": "TXN2026072901001",
    "status": "completed",
    "ekyc_result": {
      "core_ekyc_tx_id": "core_tx_xyz789",
      "identity_verified": true,
      "face_matched": true,
      "liveness_passed": true,
      "score": 95.5,
      "verified_at": "2026-07-29T13:25:00+07:00"
    },
    "contract": {
      "contract_ref": "HD/2026/07/001",
      "status": "signed",
      "signed_at": "2026-07-29T13:28:00+07:00"
    }
  },
  "meta": { "...": "..." }
}

POST /partner/revoke-session

Thu hồi session (hủy quy trình).

Request:

{
  "session_id": "ekyc_abc123def456",
  "reason": "user_cancelled"
}

POST /partner/webhook-config

Cập nhật webhook URL nhận callback kết quả.

Request:

{
  "webhook_url": "https://api.vpbank.com/ekyc/callback",
  "secret": "whsec_abc123"
}

Module: Webview (Webview → BE)

Yêu cầu JWT — webview_token (header Authorization: Bearer <token>)

POST /webview/init

Khởi tạo webview, xác thực token và trả thông tin session + nhận diện thương hiệu của Partner cho webview render.

Request:

{
  "session_id": "ekyc_abc123def456"
}

Response 200:

{
  "status": "success",
  "data": {
    "session_id": "ekyc_abc123def456",
    "partner_code": "VPBANK",
    "partner_name": "VPBank",
    "webview_config": {
      "brand_name": "VPBank",
      "logo_url": "https://vpbank.com/logo.png",
      "theme": "#0d6efd",
      "theme_color": "#0d6efd",
      "language": "vi",
      "support_phone": null,
      "terms_url": null
    },
    "user_id": "USER_123456",
    "status": "pending",
    "identity_info": {
      "full_name": "Nguyễn Văn A",
      "id_number": "079201012345",
      "date_of_birth": "1990-01-01",
      "email": "nguyenvana@email.com"
    },
    "bank_info": {
      "bank_name": "Ngân hàng TMCP Việt Nam Thịnh Vượng",
      "bank_code": "VPB",
      "account_number": "1903681845018",
      "account_holder_name": "NGUYEN VAN A"
    },
    "contract_ref": "HD/2026/07/001",
    "expired_at": "2026-07-29T13:30:00+07:00",
    "ekyc_sdk_url": "https://sdk.ekyc.vendor.vn/frame?token=...",
    "ekyc_sdk_token": "...",
    "ekyc_sdk_token_name": "...",
    "ekyc_sdk_access_token": "...",
    "ekyc_sdk_resource_id": "..."
  }
}

POST /webview/submit-identity

Webview gửi thông tin định danh (sau khi user chụp CMND/CCCD).

Request:

{
  "session_id": "ekyc_abc123def456",
  "identity_data": {
    "front_image_url": "https://cdn.example.com/cccd_front.jpg",
    "back_image_url": "https://cdn.example.com/cccd_back.jpg",
    "id_number": "079201012345",
    "full_name": "Nguyễn Văn A",
    "date_of_birth": "1990-01-01"
  }
}

POST /webview/submit-face

Gửi dữ liệu face match + liveness.

Request:

{
  "session_id": "ekyc_abc123def456",
  "face_data": {
    "face_image_url": "https://cdn.example.com/face.jpg",
    "liveness_video_url": "https://cdn.example.com/liveness.mp4"
  }
}

POST /webview/submit-ekyc-result

Webview gửi kết quả EKYC (sau khi gọi Core EKYC bên phía webview).

Request:

{
  "session_id": "ekyc_abc123def456",
  "core_ekyc_result": {
    "tx_id": "core_tx_xyz789",
    "status": "completed",
    "identity_verified": true,
    "face_matched": true,
    "liveness_passed": true,
    "score": 95.5,
    "raw_response": {}
  }
}

POST /webview/sign-contract

User ký hợp đồng.

Request:

{
  "session_id": "ekyc_abc123def456",
  "sign_method": "otp",
  "sign_data": {
    "otp_ref": "OTP_20260729_001",
    "signed_content": "base64..."
  }
}

GET /webview/contract/{session_id}

Lấy nội dung hợp đồng.


GET /webview/session/{session_id}

Lấy thông tin session hiện tại và nhận diện thương hiệu Partner trên Webview.

Response 200:

{
  "status": "success",
  "data": {
    "session_id": "ekyc_abc123def456",
    "partner_code": "VPBANK",
    "partner_name": "VPBank",
    "webview_config": {
      "brand_name": "VPBank",
      "logo_url": "https://vpbank.com/logo.png",
      "theme": "#0d6efd",
      "theme_color": "#0d6efd",
      "language": "vi",
      "support_phone": null,
      "terms_url": null
    },
    "status": "pending",
    "bank_info": {
      "bank_name": "Ngân hàng TMCP Việt Nam Thịnh Vượng",
      "bank_code": "VPB",
      "account_number": "1903681845018",
      "account_holder_name": "NGUYEN VAN A"
    },
    "expired_at": "2026-07-29T13:30:00+07:00"
  }
}

POST /webview/cancel

Hủy quy trình EKYC từ phía user.


POST /webview/bank-account

Cập nhật / sửa đổi thông tin tài khoản ngân hàng của phiên EKYC từ phía User.

Request:

{
  "bank_name": "Ngân hàng TMCP Quân đội",
  "bank_code": "MB",
  "account_number": "090123456789",
  "account_holder_name": "NGUYEN VAN A"
}

Response 200:

{
  "status": "success",
  "data": {
    "session_id": "ekyc_abc123def456",
    "bank_name": "Ngân hàng TMCP Quân đội",
    "bank_code": "MB",
    "account_number": "090123456789",
    "account_holder_name": "NGUYEN VAN A",
    "updated_at": "2026-08-20T06:45:00+07:00"
  }
}

Module: Common (Public)

GET /common/banks

Lấy danh mục ngân hàng tại Việt Nam (chuẩn VietQR / Napas). Hỗ trợ tìm kiếm theo tên, mã code, mã BIN qua query param ?q=.

Response 200:

{
  "status": "success",
  "data": {
    "total": 38,
    "banks": [
      {
        "id": 1,
        "name": "Ngân hàng TMCP Ngoại Thương Việt Nam",
        "code": "VCB",
        "bin": "970436",
        "short_name": "Vietcombank",
        "logo_url": "https://api.vietqr.io/img/VCB.png",
        "is_transfer": true
      },
      {
        "id": 7,
        "name": "Ngân hàng TMCP Việt Nam Thịnh Vượng",
        "code": "VPB",
        "bin": "970432",
        "short_name": "VPBank",
        "logo_url": "https://api.vietqr.io/img/VPB.png",
        "is_transfer": true
      }
    ]
  }
}

GET /common/banks/{code}

Lấy chi tiết 1 ngân hàng theo mã CODE (VD: VPB, VCB) hoặc mã BIN (VD: 970432).


Module: Webhook (Core EContract Inbound Callback)

POST /api/v1/webhook/core-ekyc (hoặc /api/v1/webhook/contract)

Tiếp nhận callback cập nhật trạng thái hợp đồng điện tử từ Core EContract / Vendor gửi về Middleware.

{
  "contract_id": "HD-20240818-001",
  "contract_status": "SIGNED",
  "reason": null
}
FieldTypeRequiredMô tả
contract_idstringCóMã định danh hợp đồng (tương ứng contract_ref trong DB)
contract_statusstringCóTrạng thái hợp đồng từ Core (SIGNED, PROCESSING, WAITING_TO_SIGN, SUBMIT, FAIL, SUBMIT_FAIL, VOIDED, REJECT, OVERDUE)
reasonstringKhôngLý do khi hợp đồng bị hủy hoặc từ chối
{
  "status": "success",
  "data": {
    "contract_ref": "HD-20240818-001",
    "contract_number": "HD-20240818-001",
    "status": "signed",
    "core_status": "SIGNED",
    "reason": null,
    "signed_at": "2024-08-20T17:45:00+07:00"
  },
  "meta": {
    "request_id": "848e0fe9-4e7a-4c28-98e3-0d3fe6db3c8b",
    "timestamp": "2024-08-20T17:45:00+07:00",
    "response_time_ms": 12,
    "message": "Cập nhật trạng thái hợp đồng thành công."
  }
}
curl -X POST "http://localhost:8000/api/v1/webhook/core-ekyc" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer core_cb_token_secret123" \
  -d '{
    "contract_id": "HD-20240818-001",
    "contract_status": "SIGNED",
    "reason": null
  }'

Session Status Flow

pending → processing → awaiting_ekyc → awaiting_sign → completed
                                                  ↓
                                              failed
                                                
Tất cả các trạng thái → expired (khi hết hạn)
StatusMô tả
pendingVừa tạo, Bank chờ user vào webview
processingĐang xử lý dữ liệu
awaiting_ekycUser đang thực hiện EKYC trên webview
awaiting_signEKYC xong, chờ user ký hợp đồng
completedHoàn thành
failedThất bại (user hủy, lỗi, ...)
expiredHết thời gian

📝 Ghi chú: Các endpoint chi tiết (request body đầy đủ, response mẫu, error codes) sẽ được update trong quá trình implement. Scramble tự động sinh docs từ code.