VND Payments via InfoCMS
MCV stores wallet balances in USD cents. VND payment rails use a fixed internal exchange rate:
$1 = 26,000 VND
VND Top-up
Users can create a VND QR top-up from Billing.
VND amount -> convert to USD wallet amount -> create InfoCMS QuickQR request -> wait for callback -> credit wallet
Example:
| VND Paid | Wallet Credit |
|---|---|
| 2,600,000 VND | $100.00 |
The payment is stored as:
payments.provider = infocms_qrpayments.status = requires_paymentpayments.metadata.vnd_amountpayments.metadata.exchange_rate = 26000
InfoCMS UAT QuickQR uses:
POST {INFOCMS_BASE_URL}/ocms/v1/auth/login
Header AuthorizationHeaderParameters: base64(clientId)
Header Authorization: base64(hmac_sha512(clientId + yyyyMMdd + clientSecret, clientSecret))
Header bankCode: {INFOCMS_BANK_CODE}
Body: {"data": {"masterId": "{INFOCMS_MASTER_ID}", "clientId": "{INFOCMS_CLIENT_ID}"}}
MCV caches the returned token and uses it for QuickQR requests. If INFOCMS_ACCESS_TOKEN is configured, it is used directly instead of login.
POST {INFOCMS_BASE_URL}/ocms/v3/ec/create_quick_qr
Header token: {INFOCMS_ACCESS_TOKEN}
Header bankCode: {INFOCMS_BANK_CODE}
Header CMS-RSA-Signature: RSA-SHA256 signature of JSON-minified data
Body: {"data": {...}}
MCV keeps the RSA private key and sends only the RSA public key to InfoCMS/Infoplus.
The InfoCMS public key is stored separately and used to verify callbacks signed with the CMS-RSA-Signature header. When the callback body contains data, MCV verifies the JSON-minified data; otherwise it verifies the JSON-minified callback body.
When InfoCMS confirms the deposit, it should call:
POST https://ads.mcv.network/infocms/e-collect/callback
Accepted reference fields include orderId, order_id, transUUID, trans_uuid, provider_reference, or reference.
Callback verification:
Header CMS-RSA-Signature: RSA-SHA256 signature from InfoCMS
Verified by MCV with INFOCMS_PROVIDER_PUBLIC_KEY
The callback is idempotent. It credits the wallet only once using:
infocms_qr:{provider_reference}:posted
VND Withdrawal
Users can request a VND withdrawal from Billing.
VND amount -> convert to USD wallet amount -> reserve wallet balance -> create InfoCMS transfer request
Example:
| Withdrawal | Wallet Reserved |
|---|---|
| 2,600,000 VND | $100.00 |
Withdrawal requests are stored in withdrawal_requests.
When InfoCMS confirms or fails a transfer, it should call:
POST https://ads.mcv.network/infocms/transfer/callback
If the transfer fails, MCV refunds the reserved wallet amount once using:
withdrawal:{withdrawal_id}:refund
Environment Variables
INFOCMS_ENABLED=false
INFOCMS_BASE_URL=
INFOCMS_ACCESS_TOKEN=
INFOCMS_CLIENT_ID=
INFOCMS_CLIENT_SECRET=
INFOCMS_MERCHANT_ID=
INFOCMS_BANK_CODE=
INFOCMS_MASTER_ID=
INFOCMS_MOTHER_ACCOUNT=
INFOCMS_ECOLLECTION_NAME="MCV Network"
INFOCMS_SIGNATURE_PRIVATE_KEY=
INFOCMS_PROVIDER_PUBLIC_KEY=
INFOCMS_LOGIN_ENDPOINT=/ocms/v1/auth/login
INFOCMS_CREATE_QUICK_QR_ENDPOINT=/ocms/v3/ec/create_quick_qr
INFOCMS_TRANSFER_ENDPOINT=/transfer
When INFOCMS_ENABLED=false, requests run in sandbox mode and store the outbound payload in metadata. This lets product and finance test the workflow before production credentials are configured.