MQ-Pay API Reference
Complete API reference for MQ-Pay payment integration.
Base URL
Production: https://api.your-domain.com/api/mq-pay
Development: http://localhost:3000/api/mq-payPayment Endpoints
Create Payment
http
POST /payments/checkout
Content-Type: application/json
{
"source": {
"type": "Order",
"id": "order-uuid-123",
"uid": "ORD-2024-001"
},
"payment": {
"provider": "VNPAY_QR_MMS",
"method": "100_QR_CODE",
"total": 100000,
"currency": "VND"
},
"expiration": {
"mode": "duration",
"milliseconds": 300000
}
}Response (200 OK)
json
{
"transaction": {
"id": "txn-uuid-001",
"number": "TXN001",
"status": "100_NEW",
"total": "100000.0000",
"paid": "0.0000"
},
"attempt": {
"id": "att-uuid-001",
"code": "ATT001",
"status": "204_SENT",
"provider": "VNPAY_QR_MMS",
"method": "100_QR_CODE"
},
"payment": {
"qrCode": "00020101021238...",
"qrUrl": "https://...",
"expiresAt": "2024-01-15T10:35:00Z"
}
}Confirm System Payment
http
POST /payments/system/ipn
Content-Type: application/json
{
"attempt": { "id": "att-uuid-001" },
"tendered": 100000,
"note": "Cash payment"
}Response (200 OK)
json
{
"transaction": {
"id": "txn-uuid-001",
"status": "304_SETTLED",
"paid": "100000.0000"
},
"attempt": {
"id": "att-uuid-001",
"status": "302_SUCCESS",
"tendered": "100000.0000"
},
"change": "0.0000"
}Cancel Payment Attempt
http
POST /payments/cancel
Content-Type: application/json
{
"attemptId": "att-uuid-001",
"reason": "Customer changed payment method"
}Response (200 OK)
json
{
"transaction": {
"id": "txn-uuid-001",
"status": "100_NEW"
},
"cancelledAttempts": [
{
"id": "cancel-att-uuid",
"type": "200_CANCEL_PAYMENT",
"status": "302_SUCCESS",
"parentId": "att-uuid-001"
}
]
}NOTE
You can also cancel all attempts for a transaction by sending { "transactionId": "txn-uuid-001" } instead of attemptId.
Verify Payment Attempt
http
POST /payments/verify
Content-Type: application/json
{
"attemptId": "att-uuid-001"
}Response (200 OK)
json
{
"attempt": {
"id": "att-uuid-001",
"status": "302_SUCCESS",
"provider": "VNPAY_QR_MMS"
},
"providerStatus": {
"responseCode": "00",
"message": "Success"
}
}Refund Payment
http
POST /payments/refund
Content-Type: application/json
{
"attemptId": "att-uuid-001",
"amount": 50000,
"reason": "Partial refund for returned item"
}Response (200 OK)
json
{
"refundAttempt": {
"id": "refund-att-uuid",
"type": "300_REFUND_PAYMENT",
"status": "302_SUCCESS",
"amount": "50000.0000",
"parentId": "att-uuid-001"
}
}IMPORTANT
Refund amount cannot exceed originalAmount - alreadyRefundedAmount. The original attempt must be in 302_SUCCESS status.
Transaction Endpoints (CRUD)
Auto-generated via ControllerFactory at base path /transactions.
| Method | Path | Description |
|---|---|---|
GET | /transactions | List transactions (supports filter, pagination, sorting) |
GET | /transactions/:id | Get transaction by ID |
GET | /transactions/count | Count transactions matching filter |
POST | /transactions | Create transaction |
PATCH | /transactions/:id | Update transaction |
DELETE | /transactions/:id | Soft-delete transaction |
Filter Example:
http
GET /transactions?filter={"where":{"sourceType":"Order","sourceId":"order-uuid"}}Payment Attempt Endpoints (CRUD)
Auto-generated via ControllerFactory at base path /payment-attempts.
| Method | Path | Description |
|---|---|---|
GET | /payment-attempts | List payment attempts |
GET | /payment-attempts/:id | Get attempt by ID |
GET | /payment-attempts/count | Count attempts matching filter |
POST | /payment-attempts | Create attempt |
PATCH | /payment-attempts/:id | Update attempt |
DELETE | /payment-attempts/:id | Soft-delete attempt |
Payment Result Endpoints (CRUD)
Auto-generated via ControllerFactory at base path /payment-results.
| Method | Path | Description |
|---|---|---|
GET | /payment-results | List payment results |
GET | /payment-results/:id | Get result by ID |
GET | /payment-results/count | Count results matching filter |
POST | /payment-results | Create result |
PATCH | /payment-results/:id | Update result |
DELETE | /payment-results/:id | Soft-delete result |
Transaction Item Endpoints (CRUD)
Auto-generated via ControllerFactory at base path /transaction-items.
| Method | Path | Description |
|---|---|---|
GET | /transaction-items | List transaction items |
GET | /transaction-items/:id | Get item by ID |
GET | /transaction-items/count | Count items matching filter |
POST | /transaction-items | Create item |
PATCH | /transaction-items/:id | Update item |
DELETE | /transaction-items/:id | Soft-delete item |
Status Codes
Transaction Statuses
| Status | Code | Description |
|---|---|---|
| NEW | 100_NEW | Created, no payment |
| PARTIAL | 300_PARTIAL | Partially paid |
| SETTLED | 304_SETTLED | Fully paid |
| CANCELLED | 505_CANCELLED | All attempts cancelled |
| BLOCKED | 403_BLOCKED | Temporarily blocked |
| CLOSED | 404_CLOSED | Permanently closed |
Attempt Statuses
| Status | Code | Description |
|---|---|---|
| NEW | 100_NEW | Created, not sent |
| SENT | 204_SENT | Sent to provider |
| SUCCESS | 302_SUCCESS | Payment confirmed |
| FAIL | 500_FAIL | Provider error |
| EXPIRED | 501_EXPIRED | Timed out |
Error Responses
json
{
"error": {
"code": "INVALID_TRANSACTION_STATUS",
"message": "Cannot add payment to completed transaction"
}
}Common Error Codes
| Code | Description |
|---|---|
| INVALID_TRANSACTION_STATUS | Wrong transaction state |
| PAYMENT_ATTEMPT_NOT_FOUND | Attempt ID not found |
| PROVIDER_NOT_CONFIGURED | Provider not enabled |
| SIGNATURE_MISMATCH | IPN verification failed |
| REFUND_EXCEEDS_REMAINING | Refund amount > remaining refundable |
| ATTEMPT_NOT_SUCCESS | Cannot refund non-success attempt |