3️Triển khai API Transaction Sync

Dùng để đồng bộ biến động số dư từ VietQR trả về cho đối tác.

3.1 POST API Transaction Sync

https://<your-host>/<your-basepath>/bank/api/transaction-sync

Headers

Name
Value

Content-Type

application/json

Authorization

Bearer <token> VietQR nhận được từ API Get Token của bạn trả về ở bước 2.

Body

Name
Type
Required
Description

bankaccount

String

Yes

Tài khoản ngân hàng tạo mã thanh toán.

amount

Long

Yes

Số tiền giao dịch.

transType

String

Yes

Phân loại giao dịch là ghi nợ/ghi có (giá trị: D/C).

content

String

Yes

Nội dung chuyển tiền.

transactionid

String

Optional

ID của giao dịch.

transactiontime

String

Optional

Tem thời gian giao dịch.

referencenumber

String

Optional

Mã giao dịch.

orderId

String

Optional

ID của đơn hàng.

terminalCode

String

Optional

Mã cửa hàng/điểm bán.

subTerminalCode

String

Optional

Mã cửa hàng phụ/điểm bán phụ.

serviceCode

String

Optional

Mã sản phẩm/dịch vụ.

urlLink

String

Optional

Link điều hướng sau khi thanh toán thành công.

sign

String

Optional

Chữ ký.

Respons

{
    "error": false,
    "errorReason": "mã_lỗi_trả_về_từ_đối_tác",
    "toastMessage": "mô_tả_lỗi_trả_về_từ_đối_tác",
    "object": {
        "reftransactionid": "ID_của_giao_dịch"
    }
}

3.2 Code cài đặt

namespace YourNamespace.Controllers
{
    [Route("bank/api")]
    [ApiController]
    public class TransactionSyncController : ControllerBase
    {
        private const string SECRET_KEY = "your-256-bit-secret"; // Secret key để kiểm tra JWT
        private const string BEARER_PREFIX = "Bearer ";

        // API để xử lý transaction-sync
        [HttpPost("transaction-sync")]
        public IActionResult TransactionSync([FromBody] TransactionCallback transactionCallback)
        {
            // Lấy token từ header Authorization
            string authHeader = Request.Headers["Authorization"];
            if (string.IsNullOrEmpty(authHeader) || !authHeader.StartsWith(BEARER_PREFIX))
            {
                return StatusCode(401, new ErrorResponse
                {
                    Error = true,
                    ErrorReason = "INVALID_AUTH_HEADER",
                    ToastMessage = "Authorization header is missing or invalid",
                    Object = null
                });
            }

            string token = authHeader.Substring(BEARER_PREFIX.Length).Trim();

            // Xác thực token
            if (!ValidateToken(token))
            {
                return StatusCode(401, new ErrorResponse
                {
                    Error = true,
                    ErrorReason = "INVALID_TOKEN",
                    ToastMessage = "Invalid or expired token",
                    Object = null
                });
            }

            // Xử lý logic của transaction
            try
            {
                // Ví dụ xử lý nghiệp vụ và sinh mã reftransactionid
                string refTransactionId = "GeneratedRefTransactionId"; // Tạo ID của giao dịch
                
                // Trả về response 200 OK với thông tin giao dịch
                return Ok(new SuccessResponse
                {
                    Error = false,
                    ErrorReason = null,
                    ToastMessage = "Transaction processed successfully",
                    Object = new TransactionResponseObject
                    {
                        reftransactionid = refTransactionId
                    }
                });
            }
            catch (Exception ex)
            {
                // Trả về lỗi trong trường hợp có exception
                return StatusCode(400, new ErrorResponse
                {
                    Error = true,
                    ErrorReason = "TRANSACTION_FAILED",
                    ToastMessage = ex.Message,
                    Object = null
                });
            }
        }

        // Phương thức để xác thực token JWT
        private bool ValidateToken(string token)
        {
            var tokenHandler = new JwtSecurityTokenHandler();
            var key = Encoding.ASCII.GetBytes(SECRET_KEY);

            try
            {
                tokenHandler.ValidateToken(token, new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(key),
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    ClockSkew = TimeSpan.Zero, // Không cho phép độ trễ thời gian
                }, out SecurityToken validatedToken);

                return true;
            }
            catch
            {
                return false;
            }
        }
    }

    // Lớp model cho request body
    public class TransactionCallback
    {
        public string transactionid { get; set; }
        public long transactiontime { get; set; }
        public string referencenumber { get; set; }
        public decimal amount { get; set; }
        public string content { get; set; }
        public string bankaccount { get; set; }
        public string orderId { get; set; }
        public string sign { get; set; }
        public string terminalCode { get; set; }
        public string urlLink { get; set; }
        public string serviceCode { get; set; }
        public string subTerminalCode { get; set; }
    }

    // Lớp model cho success response
    public class SuccessResponse
    {
        public bool Error { get; set; }
        public string ErrorReason { get; set; }
        public string ToastMessage { get; set; }
        public TransactionResponseObject Object { get; set; }
    }

    // Lớp model cho lỗi response
    public class ErrorResponse
    {
        public bool Error { get; set; }
        public string ErrorReason { get; set; }
        public string ToastMessage { get; set; }
        public object Object { get; set; }
    }

    // Lớp model cho object trả về trong success response
    public class TransactionResponseObject
    {
        public string reftransactionid { get; set; }
    }
}

// Đây là Sample Code mang tính chất tham khảo

3.3 - Các câu hỏi thường gặp triển khai API Transaction Sync

API Transaction Sync dùng để làm gì?

API Transaction Sync được sử dụng để đồng bộ dữ liệu giao dịch từ hệ thống của VietQR với hệ thống của khách hàng. Nó giúp đảm bảo rằng thông tin về các giao dịch luôn được cập nhật và nhất quán giữa hai hệ thống.

Cần chuẩn bị những gì trước khi triển khai API Transaction Sync?

Trước khi triển khai, bạn cần chuẩn bị thông tin xác thực (username và password) mà VietQR cung cấp, cùng với endpoint API mà bạn sẽ tích hợp. Đảm bảo hệ thống của bạn đã sẵn sàng để tiếp nhận và xử lý dữ liệu đồng bộ từ VietQR.

Dữ liệu đồng bộ qua API Transaction Sync bao gồm những gì?

Dữ liệu được đồng bộ qua API Transaction Sync thường bao gồm các thông tin giao dịch như mã giao dịch, số tiền, trạng thái giao dịch, và thời gian thực hiện. Các thông tin chi tiết sẽ phụ thuộc vào cấu hình của VietQR và yêu cầu cụ thể của hệ thống bạn.

Làm thế nào để xử lý nếu việc đồng bộ thất bại?

Nếu việc đồng bộ thất bại, API sẽ trả về mã lỗi và thông báo chi tiết. Bạn nên kiểm tra lại dữ liệu được gửi, đảm bảo rằng thông tin xác thực là chính xác và hệ thống của bạn có thể tiếp nhận dữ liệu từ API. Nếu lỗi vẫn tiếp diễn, hãy liên hệ với bộ phận kỹ thuật của VietQR.

Last updated