2️⃣API Transaction Sync
Dùng nhận Callback biến động số dư VietQR trả về cho đối tác
Last updated
{
"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"
}
}{
"error": true,
"errorReason": "mã_lỗi_trả_về_từ_đối_tác",
"toastMessage": "mô_tả_lỗi_trả_về_từ_đối_tác",
"object": null
}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@RestController
@RequestMapping("/bank/api")
public class TransactionSyncController {
private static final String SECRET_KEY = "your-256-bit-secret"; // Secret key để kiểm tra JWT
private static final String BEARER_PREFIX = "Bearer ";
@PostMapping("/transaction-sync")
public ResponseEntity<Object> transactionSync(@RequestBody TransactionCallback transactionCallback,
HttpServletRequest request) {
// Lấy token từ header Authorization
String authHeader = request.getHeader("Authorization");
if (authHeader == null || !authHeader.startsWith(BEARER_PREFIX)) {
return new ResponseEntity<>(new ErrorResponse(true, "INVALID_AUTH_HEADER",
"Authorization header is missing or invalid", null), HttpStatus.UNAUTHORIZED);
}
String token = authHeader.substring(BEARER_PREFIX.length()).trim();
// Xác thực token
if (!validateToken(token)) {
return new ResponseEntity<>(new ErrorResponse(true, "INVALID_TOKEN",
"Invalid or expired token", null), HttpStatus.UNAUTHORIZED);
}
try {
// Xử lý nghiệp vụ, sinh mã refTransactionId (Giả sử tạo một mã ngẫu nhiên)
String refTransactionId = "GeneratedRefTransactionId"; // Sinh ID của giao dịch
// Trả về response 200 OK với thông tin giao dịch
TransactionResponseObject transactionResponse = new TransactionResponseObject(refTransactionId);
return ResponseEntity.ok(new SuccessResponse(false, null,
"Transaction processed successfully", transactionResponse));
} catch (Exception ex) {
// Trả về lỗi trong trường hợp có exception
return new ResponseEntity<>(new ErrorResponse(true, "TRANSACTION_FAILED", ex.getMessage(), null), HttpStatus.BAD_REQUEST);
}
}
// Phương thức để xác thực token JWT
private boolean validateToken(String token) {
// Đây là phương pháp giả sử validate token với SECRET_KEY
// Bạn có thể tích hợp JWT library như `io.jsonwebtoken` để validate
try {
// Giả sử giải mã token với SECRET_KEY
byte[] secretKeyBytes = SECRET_KEY.getBytes();
String decodedToken = new String(Base64.getDecoder().decode(token.getBytes()));
// Kiểm tra token hợp lệ (thực tế nên sử dụng JWT library như jjwt)
return decodedToken.contains(SECRET_KEY);
} catch (Exception e) {
return false;
}
}
}
// Lớp model cho request body
class TransactionCallback {
private String transactionid;
private long transactiontime;
private String referencenumber;
private double amount;
private String content;
private String bankaccount;
private String orderId;
private String sign;
private String terminalCode;
private String urlLink;
private String serviceCode;
private String subTerminalCode;
// Getters and Setters
// ...
}
// Lớp model cho success response
class SuccessResponse {
private boolean error;
private String errorReason;
private String toastMessage;
private TransactionResponseObject object;
public SuccessResponse(boolean error, String errorReason, String toastMessage, TransactionResponseObject object) {
this.error = error;
this.errorReason = errorReason;
this.toastMessage = toastMessage;
this.object = object;
}
// Getters and Setters
// ...
}
// Lớp model cho lỗi response
class ErrorResponse {
private boolean error;
private String errorReason;
private String toastMessage;
private Object object;
public ErrorResponse(boolean error, String errorReason, String toastMessage, Object object) {
this.error = error;
this.errorReason = errorReason;
this.toastMessage = toastMessage;
this.object = object;
}
// Getters and Setters
// ...
}
// Lớp model cho object trả về trong success response
class TransactionResponseObject {
private String reftransactionid;
public TransactionResponseObject(String reftransactionid) {
this.reftransactionid = reftransactionid;
}
// Getters and Setters
// ...
}
// Đây là Sample Code mang tính chất tham khảoconst express = require('express');
const bodyParser = require('body-parser');
const jwt = require('jsonwebtoken');
const app = express();
const PORT = process.env.PORT || 3000;
const SECRET_KEY = 'your-256-bit-secret'; // Secret key để kiểm tra JWT
const BEARER_PREFIX = 'Bearer ';
app.use(bodyParser.json());
// Model cho request body
class TransactionCallback {
constructor(transactionid, transactiontime, referencenumber, amount, content, bankaccount, orderId, sign, terminalCode, urlLink, serviceCode, subTerminalCode) {
this.transactionid = transactionid;
this.transactiontime = transactiontime;
this.referencenumber = referencenumber;
this.amount = amount;
this.content = content;
this.bankaccount = bankaccount;
this.orderId = orderId;
this.sign = sign;
this.terminalCode = terminalCode;
this.urlLink = urlLink;
this.serviceCode = serviceCode;
this.subTerminalCode = subTerminalCode;
}
}
// API để xử lý transaction-sync
app.post('/bank/api/transaction-sync', (req, res) => {
const authHeader = req.headers['authorization'];
if (!authHeader || !authHeader.startsWith(BEARER_PREFIX)) {
return res.status(401).json(new ErrorResponse(true, "INVALID_AUTH_HEADER", "Authorization header is missing or invalid", null));
}
const token = authHeader.substring(BEARER_PREFIX.length).trim();
// Xác thực token
if (!validateToken(token)) {
return res.status(401).json(new ErrorResponse(true, "INVALID_TOKEN", "Invalid or expired token", null));
}
const transactionCallback = new TransactionCallback(
req.body.transactionid,
req.body.transactiontime,
req.body.referencenumber,
req.body.amount,
req.body.content,
req.body.bankaccount,
req.body.orderId,
req.body.sign,
req.body.terminalCode,
req.body.urlLink,
req.body.serviceCode,
req.body.subTerminalCode
);
try {
// Ví dụ xử lý nghiệp vụ và sinh mã reftransactionid
const refTransactionId = "GeneratedRefTransactionId"; // Tạo ID của giao dịch
// Trả về response 200 OK với thông tin giao dịch
return res.status(200).json(new SuccessResponse(false, null, "Transaction processed successfully", new TransactionResponseObject(refTransactionId)));
} catch (error) {
// Trả về lỗi trong trường hợp có exception
return res.status(400).json(new ErrorResponse(true, "TRANSACTION_FAILED", error.message, null));
}
});
// Phương thức để xác thực token JWT
const validateToken = (token) => {
try {
const decoded = jwt.verify(token, SECRET_KEY);
return true;
} catch (error) {
return false;
}
};
// Lớp model cho success response
class SuccessResponse {
constructor(error, errorReason, toastMessage, object) {
this.error = error;
this.errorReason = errorReason;
this.toastMessage = toastMessage;
this.object = object;
}
}
// Lớp model cho lỗi response
class ErrorResponse {
constructor(error, errorReason, toastMessage, object) {
this.error = error;
this.errorReason = errorReason;
this.toastMessage = toastMessage;
this.object = object;
}
}
// Lớp model cho object trả về trong success response
class TransactionResponseObject {
constructor(reftransactionid) {
this.reftransactionid = reftransactionid;
}
}
// Khởi động server
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
//sample code mang tính chất tham khảo<?php
require 'vendor/autoload.php';
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Slim\Factory\AppFactory;
use Firebase\JWT\JWT;
use Firebase\JWT\ExpiredException;
$app = AppFactory::create();
$SECRET_KEY = 'your-256-bit-secret'; // Secret key để kiểm tra JWT
// Model cho request body
class TransactionCallback {
public $transactionid;
public $transactiontime;
public $referencenumber;
public $amount;
public $content;
public $bankaccount;
public $orderId;
public $sign;
public $terminalCode;
public $urlLink;
public $serviceCode;
public $subTerminalCode;
public function __construct($data) {
$this->transactionid = $data['transactionid'];
$this->transactiontime = $data['transactiontime'];
$this->referencenumber = $data['referencenumber'];
$this->amount = $data['amount'];
$this->content = $data['content'];
$this->bankaccount = $data['bankaccount'];
$this->orderId = $data['orderId'];
$this->sign = $data['sign'];
$this->terminalCode = $data['terminalCode'];
$this->urlLink = $data['urlLink'];
$this->serviceCode = $data['serviceCode'];
$this->subTerminalCode = $data['subTerminalCode'];
}
}
// Lớp model cho success response
class SuccessResponse {
public $error;
public $errorReason;
public $toastMessage;
public $object;
public function __construct($error, $errorReason, $toastMessage, $object) {
$this->error = $error;
$this->errorReason = $errorReason;
$this->toastMessage = $toastMessage;
$this->object = $object;
}
}
// Lớp model cho lỗi response
class ErrorResponse {
public $error;
public $errorReason;
public $toastMessage;
public $object;
public function __construct($error, $errorReason, $toastMessage, $object) {
$this->error = $error;
$this->errorReason = $errorReason;
$this->toastMessage = $toastMessage;
$this->object = $object;
}
}
// Lớp model cho object trả về trong success response
class TransactionResponseObject {
public $reftransactionid;
public function __construct($reftransactionid) {
$this->reftransactionid = $reftransactionid;
}
}
// API để xử lý transaction-sync
$app->post('/bank/api/transaction-sync', function (ServerRequestInterface $request, ResponseInterface $response) use ($SECRET_KEY) {
$authHeader = $request->getHeaderLine('Authorization');
$bearerPrefix = 'Bearer ';
if (empty($authHeader) || !str_starts_with($authHeader, $bearerPrefix)) {
return $this->respondWithError($response, new ErrorResponse(true, "INVALID_AUTH_HEADER", "Authorization header is missing or invalid", null), 401);
}
$token = substr($authHeader, strlen($bearerPrefix));
// Xác thực token
if (!validateToken($token, $SECRET_KEY)) {
return $this->respondWithError($response, new ErrorResponse(true, "INVALID_TOKEN", "Invalid or expired token", null), 401);
}
$data = json_decode($request->getBody(), true);
$transactionCallback = new TransactionCallback($data);
try {
// Ví dụ xử lý nghiệp vụ và sinh mã reftransactionid
$refTransactionId = "GeneratedRefTransactionId"; // Tạo ID của giao dịch
// Trả về response 200 OK với thông tin giao dịch
$successResponse = new SuccessResponse(false, null, "Transaction processed successfully", new TransactionResponseObject($refTransactionId));
$response->getBody()->write(json_encode($successResponse));
return $response->withStatus(200)->withHeader('Content-Type', 'application/json');
} catch (Exception $e) {
return $this->respondWithError($response, new ErrorResponse(true, "TRANSACTION_FAILED", $e->getMessage(), null), 400);
}
});
// Phương thức để xác thực token JWT
function validateToken($token, $secretKey) {
try {
JWT::decode($token, $secretKey, ['HS256']);
return true;
} catch (ExpiredException $e) {
return false;
} catch (Exception $e) {
return false;
}
}
// Phương thức để trả về lỗi response
function respondWithError($response, $errorResponse, $statusCode) {
$response->getBody()->write(json_encode($errorResponse));
return $response->withStatus($statusCode)->withHeader('Content-Type', 'application/json');
}
// Khởi động server
$app->run();
//sample code mang tính chất tham khảofrom flask import Flask, request, jsonify
import jwt
from jwt.exceptions import ExpiredSignatureError, InvalidTokenError
app = Flask(__name__)
SECRET_KEY = 'your-256-bit-secret' # Secret key để kiểm tra JWT
# Model cho request body
class TransactionCallback:
def __init__(self, data):
self.transactionid = data.get('transactionid')
self.transactiontime = data.get('transactiontime')
self.referencenumber = data.get('referencenumber')
self.amount = data.get('amount')
self.content = data.get('content')
self.bankaccount = data.get('bankaccount')
self.orderId = data.get('orderId')
self.sign = data.get('sign')
self.terminalCode = data.get('terminalCode')
self.urlLink = data.get('urlLink')
self.serviceCode = data.get('serviceCode')
self.subTerminalCode = data.get('subTerminalCode')
# Lớp model cho success response
class SuccessResponse:
def __init__(self, error, errorReason, toastMessage, object):
self.error = error
self.errorReason = errorReason
self.toastMessage = toastMessage
self.object = object
# Lớp model cho lỗi response
class ErrorResponse:
def __init__(self, error, errorReason, toastMessage, object):
self.error = error
self.errorReason = errorReason
self.toastMessage = toastMessage
self.object = object
# Lớp model cho object trả về trong success response
class TransactionResponseObject:
def __init__(self, reftransactionid):
self.reftransactionid = reftransactionid
@app.route('/bank/api/transaction-sync', methods=['POST'])
def transaction_sync():
auth_header = request.headers.get('Authorization')
bearer_prefix = 'Bearer '
if not auth_header or not auth_header.startswith(bearer_prefix):
return jsonify(ErrorResponse(True, "INVALID_AUTH_HEADER", "Authorization header is missing or invalid", None).__dict__), 401
token = auth_header[len(bearer_prefix):]
# Xác thực token
if not validate_token(token):
return jsonify(ErrorResponse(True, "INVALID_TOKEN", "Invalid or expired token", None).__dict__), 401
transaction_callback = TransactionCallback(request.json)
try:
# Ví dụ xử lý nghiệp vụ và sinh mã reftransactionid
ref_transaction_id = "GeneratedRefTransactionId" # Tạo ID của giao dịch
# Trả về response 200 OK với thông tin giao dịch
success_response = SuccessResponse(False, None, "Transaction processed successfully",
TransactionResponseObject(ref_transaction_id))
return jsonify(success_response.__dict__), 200
except Exception as e:
return jsonify(ErrorResponse(True, "TRANSACTION_FAILED", str(e), None).__dict__), 400
# Phương thức để xác thực token JWT
def validate_token(token):
try:
jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
return True
except (ExpiredSignatureError, InvalidTokenError):
return False
if __name__ == '__main__':
app.run(debug=True, port=5000)
//sample code mang tính chất tham khảo