Skip to content

API hủy đơn Collection Link ​

POST https://payment.pay2s.vn/v1/gateway/api/cancel

API dành cho đối tác sử dụng accessKey/partnerCode/secretKey của API create. API app POST /api/v1/orders/cancel dùng Bearer token giữ nguyên.

Áp dụng cho đơn tạo bằng Collection Link V1 và Collection Link V2. Chỉ hủy đơn chưa thanh toán.

Request và chữ ký ​

Gửi JSON, tất cả trường là chuỗi:

json
{
  "accessKey": "ACCESS_KEY",
  "partnerCode": "PARTNER_CODE",
  "orderId": "ORDER_123",
  "requestId": "CANCEL_123",
  "requestType": "cancel",
  "signature": "HMAC_SHA256_HEX"
}
  • orderId: đúng orderId khách gửi lúc tạo đơn, không phải mã PAY2SJSC do Pay2S sinh.
  • requestId: mã yêu cầu hủy do khách tạo, được trả lại để đối chiếu. Không phải requestId của lần create.
  • requestType: bắt buộc cancel.
  • Không gửi secretKey, extraData hoặc signatureVersion.
  • Chuỗi ký nối đúng thứ tự dưới đây, không URL-encode, không thêm khoảng trắng:
text
accessKey=ACCESS_KEY&orderId=ORDER_123&partnerCode=PARTNER_CODE&requestId=CANCEL_123&requestType=cancel

signature = HMAC-SHA256(rawSignature, secretKey) dạng hex. Thực hiện ký từ backend; không đưa secretKey lên trình duyệt.

Postman pre-request script ​

Đặt Environment: accessKey, partnerCode, secretKey, orderId. Chọn Body → raw → JSON trước khi chạy:

js
const CryptoJS = pm.require('npm:crypto-js@4.2.0');
const accessKey = pm.environment.get('accessKey');
const partnerCode = pm.environment.get('partnerCode');
const secretKey = pm.environment.get('secretKey');
const orderId = pm.environment.get('orderId');
if (![accessKey, partnerCode, secretKey, orderId].every(Boolean)) {
  throw new Error('Thiếu accessKey, partnerCode, secretKey hoặc orderId');
}
const requestId = 'CANCEL-' + Date.now();
const requestType = 'cancel';
const raw = `accessKey=${accessKey}&orderId=${orderId}&partnerCode=${partnerCode}&requestId=${requestId}&requestType=${requestType}`;
const signature = CryptoJS.HmacSHA256(raw, secretKey).toString(CryptoJS.enc.Hex);
pm.request.headers.upsert({key: 'Content-Type', value: 'application/json'});
pm.request.body.update(JSON.stringify({accessKey, partnerCode, orderId, requestId, requestType, signature}));

Kết quả ​

HTTP 200 khi hủy thành công hoặc đơn đã hủy trước đó:

json
{
  "partnerCode": "PARTNER_CODE",
  "requestId": "CANCEL_123",
  "orderId": "ORDER_123",
  "invoiceNumber": "PAY2SJSC...",
  "status": "cancelled",
  "resultCode": 0,
  "message": "Đơn hàng đã được hủy thành công."
}

Lỗi trả {"status":false,"message":"..."}:

HTTPÝ nghĩa
400Trường dữ liệu hoặc requestType không hợp lệ
401Thông tin xác thực hoặc chữ ký sai
404Không có đơn trong phạm vi khóa đang dùng
409Đơn không còn pending, hoặc orderId trùng nhiều đơn
429Quá nhiều yêu cầu từ cùng IP
500Lỗi xử lý; có thể gọi lại và kiểm tra trạng thái

Chỉ cập nhật pending → cancelled, không xóa đơn hoặc hoàn tiền. Gọi lại đơn đã hủy trả thành công; không ghi lại trạng thái. Khóa cửa hàng chỉ truy cập đơn của cửa hàng đó; khóa chủ tài khoản truy cập đơn không gắn cửa hàng, giống phạm vi create. Nếu legacy tạo nhiều đơn cùng orderId với nội dung khác nhau, trả 409 để tránh chọn nhầm. Nên dùng orderId duy nhất cho mỗi đơn.

Hủy đơn trên Pay2S không vô hiệu hóa khả năng chuyển khoản tới tài khoản ngân hàng. API này không gọi hủy QR phía ngân hàng, không phát webhook hủy, không hủy hóa đơn điện tử. Khách tích hợp nhận kết quả trực tiếp từ response.