URL: /paas/fincard-virtual/webhooks
---
title: 'Webhooks'
description: 'Real-time event notifications for card operations, transactions, and cardholder status changes'
---
# Webhook Events
FinCard Virtual pushes real-time event notifications to your configured webhook URL. Events are signed with the platform RSA private key — verify using the platform public key.
**Callback URL:** `POST /api/v2.1/fincard/virtual/webhook/callback`
---
## Signature Verification
All webhook events include an `X-FC-SIGNATURE` header containing a SHA256withRSA signature of the response body, base64-encoded.
```javascript
// Verify: SHA256withRSA(responseBody, platformPublicKey) === X-FC-SIGNATURE
```
Your endpoint must return `{"success": true}` to acknowledge receipt.
---
## Event Types
### Card Operation Transaction Event
Triggered when card operations complete (create, deposit, withdraw, freeze, unfreeze, cancel, block, overdraft).
| Field | Type | Description |
|-------|------|-------------|
| `orderNo` | String | Transaction ID |
| `merchantOrderNo` | String | Client tx ID |
| `cardNo` | String | Card ID |
| `currency` | String | Currency |
| `amount` | BigDecimal | Amount |
| `fee` | BigDecimal | Fee |
| `receivedAmount` | BigDecimal | Net amount |
| `type` | String | `create` / `deposit` / `withdraw` / `Freeze` / `UnFreeze` / `cancel` / `blocked` / `overdraft_statement` |
| `status` | String | `success` / `fail` |
| `transactionTime` | Long | Millisecond timestamp |
---
### Card Authorization Transaction Event
Triggered for card consumption events (purchases, refunds, verifications).
| Field | Type | Description |
|-------|------|-------------|
| `cardNo` | String | Card ID |
| `tradeNo` | String | Transaction serial number |
| `originTradeNo` | String | Original transaction (for refunds/voids) |
| `currency` | String | Transaction currency |
| `amount` | BigDecimal | Transaction amount |
| `authorizedAmount` | BigDecimal | Authorized amount (card currency) |
| `authorizedCurrency` | String | Card currency |
| `fee` | BigDecimal | Authorization fee |
| `crossBoardFee` | BigDecimal | Cross-border fee |
| `merchantName` | String | Merchant name |
| `merchantData` | Object | Merchant details (MCC, country, city, etc.) |
| `type` | String | `auth` / `refund` / `verification` / `Void` / `maintain_fee` |
| `status` | String | `authorized` / `failed` / `succeed` |
| `transactionTime` | Long | Millisecond timestamp |
---
### Card Authorization Fee Transaction Event
Triggered when insufficient card balance causes fee deduction from merchant reserve.
| Field | Type | Description |
|-------|------|-------------|
| `cardNo` | String | Card ID |
| `tradeNo` | String | Fee transaction ID |
| `originTradeNo` | String | Original authorization transaction |
| `currency` | String | Fee currency |
| `amount` | BigDecimal | Fee amount |
| `type` | String | `card_patch_fee` / `card_patch_cross_border` |
| `deductionSourceFunds` | String | `wallet` (deducted from merchant account) |
| `status` | String | `success` |
| `transactionTime` | Long | Millisecond timestamp |
---
### Card 3DS Transaction Event
Triggered for 3DS verification (OTP), transaction authorization URLs, and physical card activation codes.
| Field | Type | Description |
|-------|------|-------------|
| `cardNo` | String | Card ID |
| `tradeNo` | String | Transaction serial number |
| `currency` | String | Currency |
| `amount` | BigDecimal | Amount |
| `merchantName` | String | Merchant/scenario name |
| `values` | String | **RSA-encrypted** value (OTP code, auth URL, or activation code) |
| `type` | String | `third_3ds_otp` / `auth_url` / `activation_code` |
| `expirationTime` | Long | Expiration time (ms) |
| `transactionTime` | Long | Millisecond timestamp |
The `values` field is encrypted with the merchant's RSA public key. Decrypt using your RSA private key.
---
### Card Holder Event
Triggered when cardholder approval status changes.
| Field | Type | Description |
|-------|------|-------------|
| `holderId` | Long | Cardholder ID |
| `statusFlowLocation` | String | `admin` / `channel` |
| `status` | String | `pass_audit` / `reject` / `under_review` |
| `description` | String | Reason (especially for rejections) |
---
### Activate Card Event
Triggered when a physical card is activated.
| Field | Type | Description |
|-------|------|-------------|
| `cardNo` | String | Card ID |
| `type` | String | `card_activated` |
| `status` | String | `success` / `fail` |
---
### Work Order Event
Triggered when work order status changes.
| Field | Type | Description |
|-------|------|-------------|
| `orderNo` | String | Work order ID |
| `merchantOrderNo` | String | Client tx ID |
| `tradeStatus` | String | `processing` / `success` / `fail` |
---
### Wallet Transaction Event (v2)
Triggered for crypto wallet deposit/withdrawal completions.
| Field | Type | Description |
|-------|------|-------------|
| `orderNo` | String | Transaction ID |
| `coinKey` | String | Coin key |
| `coinName` | String | Coin name |
| `txHash` | String | On-chain hash |
| `txAmount` | BigDecimal | On-chain amount |
| `receivedAmount` | BigDecimal | Net received |
| `receivedCurrency` | String | Currency |
| `type` | String | `DEPOSIT` / `WITHDRAW` |
| `status` | String | `success` / `fail` |
---
## Response Format
Your webhook endpoint must respond with:
```json
{
"success": true
}
```
If your endpoint fails to respond or returns an error, the platform will retry delivery. Ensure idempotent processing using `orderNo` / `tradeNo` as deduplication keys.