Get Transaction Details
Lấy thông tin chi tiết về một giao dịch cụ thể. API này cho phép truy vấn giao dịch bằng transactionId hoặc bằng cặp orderId + referenceId.
Use Case
Nếu App không nhận được notify, Mini App/Payment SDK có thể tự gọi GET /api/payments/v1/transactions để lấy kết quả thanh toán.
Endpoint
GET /api/payments/v1/transactions
Authentication
API yêu cầu xác thực bằng Payment API Key. API này dành cho OrderBackend và các service nội bộ.
Headers
| Header | Bắt buộc | Kiểu dữ liệu | Mô tả |
|---|---|---|---|
X-Payment-API-Key | Có | String | Payment API Key để xác thực service |
Query Parameters
Phải cung cấp ít nhất một trong các tổ hợp sau:
transactionId(khuyến nghị)orderId+referenceId
| Parameter | Bắt buộc | Kiểu dữ liệu | Mô tả | Ví dụ |
|---|---|---|---|---|
transactionId | Không* | String (UUID) | ID của giao dịch | 550e8400-e29b-41d4-a716-446655440000 |
orderId | Không* | String | Mã đơn hàng | OrderId_001 |
referenceId | Không* | String | Mã tham chiếu | RefId_001 |
*Phải cung cấp transactionId HOẶC cả orderId và referenceId
Response
Giao dịch từ luồng thanh toán tập trung (Payment Session) hoặc có nhiều nguồn tiền (VPoint, voucher, cổng…) có thể kèm data.items[].breakdown. Field này optional — không có trong mọi giao dịch. Cấu trúc giống IPN và API chi tiết session: xem Breakdown trong IPN.
Success Response (200 OK)
{
"code": 0,
"message": "string",
"data": {
"items": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"referenceId": "ORDER_123456",
"orderId": "ORDER_123456",
"amount": 100000,
"currency": "VND",
"status": "COMPLETED",
"description": "Payment for order #123456",
"expiresAt": "2024-01-15T11:00:00Z",
"createdAt": "2024-01-15T10:45:00Z",
"updatedAt": "2024-01-15T10:45:00Z",
"merchant": {
"code": "GSM_VN",
"name": "GSM Vietnam"
},
"providerTransactionId": "ONEPAY_TXN_789",
"providerInvoiceId": "ONEPAY_INVOICE_789",
"paymentMethod": {
"id": "1",
"code": "CREDIT_CARD",
"name": "Credit Card",
"type": "CARD"
},
"provider": {
"id": "1",
"name": "OnePay"
},
"bankName": "Vietcombank",
"accountHolderName": "NGUYEN VAN A",
"cardNo": "411111******1111",
"orderInfo": {
"customerName": "Nguyen Van A",
"customerEmail": "[email protected]",
"customerPhone": "+84901234567",
"orderCreatedAt": 1640995200000,
"notes": "Giao hàng vào buổi sáng, gọi trước khi giao",
"items": [
{
"name": "Product A",
"sku": "Sku 001",
"quantity": 2,
"unitPrice": 50000,
"description": "High quality product"
}
]
}
}
]
}
}
Response Fields
| Field | Kiểu dữ liệu | Mô tả |
|---|---|---|
code | Integer | Mã trạng thái (0 = thành công) |
message | String | Thông báo kết quả |
data.items | Array | Danh sách giao dịch (thường là 1 item nếu query bằng transactionId) |
data.items[].id | String (UUID) | ID giao dịch |
data.items[].referenceId | String | Mã tham chiếu |
data.items[].orderId | String | Mã đơn hàng |
data.items[].amount | Integer | Số tiền (minor unit, VD: 100000 = 100,000 VND) |
data.items[].currency | String | Loại tiền tệ (VD: VND, USD) |
data.items[].status | String | Trạng thái giao dịch: PENDING, PROCESSING, HOLDING, COMPLETED, FAILED, CANCELLED |
data.items[].description | String | Mô tả giao dịch |
data.items[].expiresAt | String (ISO 8601) | Thời gian hết hạn giao dịch |
data.items[].createdAt | String (ISO 8601) | Thời gian tạo giao dịch |
data.items[].updatedAt | String (ISO 8601) | Thời gian cập nhật gần nhất |
data.items[].merchant | Object | Thông tin merchant |
data.items[].merchant.code | String | Mã merchant |
data.items[].merchant.name | String | Tên merchant |
data.items[].providerTransactionId | String/Null | ID giao dịch từ payment provider |
data.items[].providerInvoiceId | String/Null | ID invoice trả về cho PayCollect (OnePay: provider_invoice_id; có thể null) |
data.items[].paymentMethod | Object | Thông tin phương thức thanh toán |
data.items[].paymentMethod.id | String | ID phương thức thanh toán |
data.items[].paymentMethod.code | String | Mã phương thức thanh toán (VD: CREDIT_CARD, WALLET, BANK_TRANSFER) |
data.items[].paymentMethod.name | String | Tên phương thức (VD: Credit Card, E-Wallet) |
data.items[].paymentMethod.type | String | Loại phương thức (CARD, WALLET, BANK_TRANSFER, etc.) |
data.items[].provider | Object | Thông tin payment provider |
data.items[].provider.id | String | ID provider |
data.items[].provider.name | String | Tên provider (VD: OnePay, VNPay, Momo) |
data.items[].bankName | String/Null | Tên ngân hàng phát hành thẻ/tài khoản (có thể null) |
data.items[].accountHolderName | String/Null | Tên chủ thẻ/chủ tài khoản (có thể null) |
data.items[].cardNo | String/Null | Số thẻ đã masking (VD: 411111******1111), không trả full PAN (có thể null) |
data.items[].breakdown | Array / Null | (Optional) Phân bổ nguồn tiền (PAYMENT, VOUCHER, VPOINT…); thường có khi giao dịch gắn Payment Session / nhiều allocation. Cùng contract Breakdown trong IPN |
data.items[].breakdown[].type | String | Loại dòng breakdown (VD: PAYMENT, VOUCHER, VPOINT) |
data.items[].breakdown[].amount | Integer | Số tiền dòng đó (minor unit, cùng quy ước amount giao dịch) |
data.items[].breakdown[].status | String | Trạng thái từng item trong breakdown: PENDING, SUCCESS, FAILED, CANCELLED — xem Breakdown trong IPN |
data.items[].breakdown[].referenceId | String / Null | (Optional) ID tham chiếu downstream cho dòng đó |
data.items[].breakdown[].referenceType | String / Null | (Optional) TRANSACTION | RESERVATION | REDEMPTION… — xem tài liệu IPN |
data.items[].breakdown[].details | Object (map) / Null | (Optional) Map key-value theo type; không phải mảng ở root — xem payment-ipn. |
data.items[].orderInfo | Object/Null | Thông tin đơn hàng liên quan đến giao dịch (có thể null) |
data.items[].orderInfo.customerName | String | Tên khách hàng |
data.items[].orderInfo.customerEmail | String | Email khách hàng |
data.items[].orderInfo.customerPhone | String | Số điện thoại khách hàng |
data.items[].orderInfo.orderCreatedAt | Number | Unix timestamp (milliseconds) khi đơn hàng được tạo |
data.items[].orderInfo.notes | String | Ghi chú về đơn hàng (dạng text) |
data.items[].orderInfo.items | Array | Danh sách sản phẩm/dịch vụ trong đơn hàng |
data.items[].orderInfo.items[].name | String | Tên sản phẩm |
data.items[].orderInfo.items[].sku | String | Mã SKU sản phẩm |
data.items[].orderInfo.items[].quantity | Integer | Số lượng |
data.items[].orderInfo.items[].unitPrice | Number | Đơn giá (minor unit) |
data.items[].orderInfo.items[].description | String | Mô tả sản phẩm |
data.items[].orderInfo.items[].categoryCode | String | Mã danh mục/ngành hàng (optional) |
data.items[].orderInfo.items[].categoryName | String | Tên danh mục/ngành hàng (optional) |
Error Responses
| HTTP Status | Code | Message | Mô tả |
|---|---|---|---|
| 400 | 4661 | Invalid get transaction detail request | Thiếu parameters bắt buộc hoặc format không đúng |
| 401 | 4101 | X-API-Key header is required | Thiếu X-Payment-API-Key header |
| 401 | 4100 | Invalid API key | API Key không hợp lệ hoặc đã bị revoke |
| 403 | 4200 | Resource does not belong to this user | Giao dịch không thuộc merchant/terminal của API Key |
| 404 | 4301 | Transaction not found | Không tìm thấy giao dịch với thông tin đã cung cấp |
| 429 | 429 | Too Many Requests | Vượt quá rate limit |
| 500 | 5000 | Internal server error | Lỗi hệ thống |
| 500 | 5001 | Database error | Lỗi kết nối hoặc truy vấn database |
Cấu trúc Error Response
{
"code": 4301,
"message": "Transaction not found"
}
Lưu ý: HTTP status code được set ở response header tương ứng với error code.
Examples
Query bằng Transaction ID
Request:
curl -X GET "https://api.example.com/api/v1/payments/transactions?transactionId=550e8400-e29b-41d4-a716-446655440000" \
-H "X-Payment-API-Key: <your_payment_api_key_here>"
Success Response (200):
{
"code": 0,
"message": "Success",
"data": {
"items": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"referenceId": "ORDER_123456",
"orderId": "ORDER_123456",
"amount": 100000,
"currency": "VND",
"status": "COMPLETED",
"description": "Payment for order #123456",
"expiresAt": "2024-01-15T11:00:00Z",
"createdAt": "2024-01-15T10:45:00Z",
"updatedAt": "2024-01-15T10:45:00Z",
"merchant": {
"code": "GSM_VN",
"name": "GSM Vietnam"
},
"providerTransactionId": "ONEPAY_TXN_789",
"paymentMethod": {
"id": "1",
"code": "CREDIT_CARD",
"name": "Credit Card",
"type": "CARD"
},
"provider": {
"id": "1",
"name": "OnePay"
},
"orderInfo": {
"customerName": "Nguyen Van A",
"customerEmail": "[email protected]",
"customerPhone": "+84901234567",
"orderCreatedAt": 1640995200000,
"notes": "Giao hàng vào buổi sáng, gọi trước khi giao",
"items": [
{
"name": "Product A",
"sku": "Sku 001",
"quantity": 2,
"unitPrice": 50000,
"description": "High quality product"
}
]
}
}
]
}
}
Query bằng Order ID và Reference ID
Request:
curl -X GET "https://api.example.com/api/payments/v1/transactions?orderId=ORDER_123456&referenceId=ORDER_123456" \
-H "X-Payment-API-Key: <your_payment_api_key_here>"
Success Response (200):
{
"code": 0,
"message": "Success",
"data": {
"items": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"referenceId": "ORDER_123456",
"orderId": "ORDER_123456",
"amount": 100000,
"currency": "VND",
"status": "PENDING",
"description": "Payment for order #123456",
"expiresAt": "2024-01-15T11:00:00Z",
"createdAt": "2024-01-15T10:45:00Z",
"updatedAt": "2024-01-15T10:45:00Z",
"merchant": {
"code": "GSM_VN",
"name": "GSM Vietnam"
},
"providerTransactionId": null,
"paymentMethod": {
"id": "1",
"code": "E_WALLET",
"name": "E-Wallet",
"type": "WALLET"
},
"provider": {
"id": "1",
"name": "OnePay"
},
"orderInfo": {
"customerName": "Nguyen Van A",
"customerEmail": "[email protected]",
"customerPhone": "+84901234567",
"orderCreatedAt": 1640995200000,
"notes": "Giao hàng vào buổi sáng, gọi trước khi giao",
"items": [
{
"name": "Product A",
"sku": "Sku 001",
"quantity": 2,
"unitPrice": 50000,
"description": "High quality product"
}
]
}
}
]
}
}
Error Response Examples
Missing API Key (401):
{
"code": 4101,
"message": "X-API-Key header is required"
}
Transaction Not Found (404):
{
"code": 4301,
"message": "Transaction not found"
}
Ownership Mismatch (403):
{
"code": 4200,
"message": "Resource does not belong to this user"
}
Invalid Request (400):
{
"code": 4661,
"message": "Invalid get transaction detail request"
}
Routing qua Mule (Payment Hub)
Quan trọng: API lấy transaction được gọi trực tiếp từ Order Backend của MiniApp tới Payment Hub thông qua MuleSoft, không được gọi trực tiếp tới Payment Hub.
Internal (PnL)
Kết nối Internal dành cho các PnL trong Vingroup.
Base URL trên Mule (endpoint tới Payment Hub):
- DEV:
{MULE_INTERNAL_BASE_URL}/payment-hub/ - SIT:
{MULE_INTERNAL_BASE_URL}/sit/payment-hub/ - UAT:
{MULE_INTERNAL_BASE_URL}/uat/payment-hub/ - Production:
{MULE_INTERNAL_PROD_URL}/payment-hub/
Lưu ý: Với môi trường Production, các bên kết nối sẽ được team Mule cấp key riêng (client_id và client_secret). Với môi trường DEV/SIT/UAT dùng chung key.
Ví dụ gọi API lấy transaction (Internal - UAT Environment):
curl --location '{MULE_INTERNAL_BASE_URL}/payment-hub/api/payments/v1/transactions?transactionId=b68405a4-690f-4ab5-8d3b-0b202568be38' \
--header 'accept: */*' \
--header 'X-Payment-API-Key: <YOUR_PAYMENT_API_KEY>' \
--header 'X-Request-ID: 123123123' \
--header 'X-User-ID: 857652265' \
--header 'X-Auth-Audience: v-app' \
--header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \
--header 'client_id: YOUR_CLIENT_ID' \
--header 'client_secret: YOUR_CLIENT_SECRET' \
--header 'Content-Type: application/json'
Ví dụ gọi API lấy transaction (Internal - Production Environment):
curl --location '{MULE_INTERNAL_PROD_URL}/payment-hub/api/payments/v1/transactions?transactionId=b68405a4-690f-4ab5-8d3b-0b202568be38' \
--header 'accept: */*' \
--header 'X-Payment-API-Key: <YOUR_PAYMENT_API_KEY>' \
--header 'X-Request-ID: 123123123' \
--header 'X-User-ID: 857652265' \
--header 'X-Auth-Audience: v-app' \
--header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \
--header 'client_id: YOUR_CLIENT_ID' \
--header 'client_secret: YOUR_CLIENT_SECRET' \
--header 'Content-Type: application/json'
External (Đối tác)
Kết nối External dành cho các đối tác bên ngoài Vingroup. Chỉ hỗ trợ 2 môi trường: Production và UAT.
Base URL trên Mule (endpoint tới Payment Hub):
- UAT:
https://test-api.vingroup.net:7445/payment-hub/ - Production:
https://api-cloud.vingroup.net/payment-hub/
Yêu cầu kết nối External:
- Tất cả các request từ đối tác external cần cung cấp danh sách IPs để whitelist
- Phía Mule sẽ cấp
client_idvàclient_secretriêng cho từng đối tác - Có whitelist và limit access theo endpoint
Ví dụ gọi API lấy transaction (External - UAT Environment):
curl --location 'https://test-api.vingroup.net:7445/payment-hub/api/payments/v1/transactions?transactionId=b68405a4-690f-4ab5-8d3b-0b202568be38' \
--header 'accept: */*' \
--header 'X-Payment-API-Key: <YOUR_PAYMENT_API_KEY>' \
--header 'X-Request-ID: 123123123' \
--header 'X-User-ID: 857652265' \
--header 'X-Auth-Audience: v-app' \
--header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \
--header 'client_id: YOUR_CLIENT_ID' \
--header 'client_secret: YOUR_CLIENT_SECRET' \
--header 'Content-Type: application/json'
Ví dụ gọi API lấy transaction (External - Production Environment):
curl --location 'https://api-cloud.vingroup.net/payment-hub/api/payments/v1/transactions?transactionId=b68405a4-690f-4ab5-8d3b-0b202568be38' \
--header 'accept: */*' \
--header 'X-Payment-API-Key: <YOUR_PAYMENT_API_KEY>' \
--header 'X-Request-ID: 123123123' \
--header 'X-User-ID: 857652265' \
--header 'X-Auth-Audience: v-app' \
--header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \
--header 'client_id: YOUR_CLIENT_ID' \
--header 'client_secret: YOUR_CLIENT_SECRET' \
--header 'Content-Type: application/json'
Quy tắc chung:
- Yêu cầu các header cơ bản:
X-Payment-API-Key,X-Request-ID,X-Timestamp(hoặc theo từng API doc). Thêm header để pass MuleSoft:Authorization,client_id,client_secret, v.v. - Các request được forward qua Mule tới Payment Hub — đảm bảo token/client/config phù hợp với Mule khi gọi.
Lưu ý quan trọng
-
Xác thực quyền truy cập: Hệ thống sẽ verify giao dịch có thuộc về merchant/terminal tương ứng với Payment API Key hay không. Nếu không khớp sẽ trả về lỗi 403.
-
Service-to-service: API này dành cho OrderBackend và các service nội bộ, không dùng cho client trực tiếp.
-
Multiple results: Khi query bằng
orderId+referenceId, có thể trả về nhiều giao dịch trong mảngitems. Client cần xử lý trường hợp này. -
Transaction Status: Các giá trị status bao gồm:
PENDING: Đang chờ xử lýPROCESSING: Đang xử lýHOLDING: Đang giữ tiền, chờ xác nhậnCOMPLETED: Thành côngFAILED: Thất bạiCANCELLED: Đã hủy
-
Amount format: Giá trị
amountđược trả về dưới dạng integer minor unit (ví dụ: 100000 tương đương 100,000 VND). -
breakdown: Khi có, ý nghĩadata.items[].amountso với tổng các dòng trongbreakdowntuân cùng quy ước như Breakdown trong IPN (ví dụamountitem có thể là phần user trả qua cổng online khi có VPoint/voucher). -
Timestamp format: Tất cả timestamps (createdAt, updatedAt, expiresAt) đều ở định dạng ISO 8601.
-
Rate limiting: API có giới hạn số lượng request. Khi vượt quá sẽ nhận HTTP 429.
Security Considerations
- API sẽ được gọi qua MuleSoft. Xem phần "Routing qua Mule (Payment Hub)" ở trên để biết chi tiết về endpoint và authentication.