IPN

IPN là cơ chế thông báo thanh toán tự động mà cổng thanh toán (ví dụ SePay, PayPal, Stripe...) gửi đến máy chủ của bạn (server) khi có thay đổi trạng thái giao dịch — như thanh toán thành công, thất bại hoặc bị hủy.


Cấu hình IPN URL

  • IPN URL được cấu hình tại trang quản lý merchant trên SePay:
  1. Đăng nhập vào SePay
  2. Vào Cổng thanh toán → Cấu hình → IPN
  3. Nhập URL endpoint của bạn để nhận IPN
  4. Lưu cấu hình
Lưu ý quan trọng
  • IPN URL phải là HTTPS
  • Endpoint phải trả về HTTP status code 200 để xác nhận đã nhận thành công

Request từ SePay đến Merchant

POSThttps://your-url (url bạn cấu hình trong IPN)
  -H "X-Secret-Key: <secret_key>" \
  -H "Content-Type: application/json" \
Ghi chú

X-Secret-Key: Secret key để xác thực (chỉ có khi merchant cấu hình auth type = SECRET_KEY)

  • Danh sách tham số
TênLoạiBắt buộcMô tả
timestamp
integerBắt buộc

Unix timestamp khi gửi thông báo

notification_type
stringBắt buộc

Loại thông báo: ORDER_PAID, RENEWAL_ORDER_PAID, TRANSACTION_VOID

order
objectBắt buộc

Thông tin đơn hàng

transaction
objectBắt buộc

Thông tin giao dịch

customer
objectBắt buộc

Thông tin khách hàng

  • Ví dụ request body:
REQUEST
{
  "timestamp": 1757058220,
  "notification_type": "ORDER_PAID",
  "order": {
    "id": "256",
    "order_id": "NPSETVI00101000042R",
    "order_status": "CAPTURED",
    "order_currency": "VND",
    "order_amount": "50000.00",
    "order_invoice_number": "SUB_202509_001",
    "custom_data": [],
    "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
    "ip_address": "14.xxx.xxx.xxx",
    "order_description": "Thanh toán định kỳ gói Premium tháng 9/2025"
  },
  "transaction": {
    "id": "189",
    "payment_method": "CARD",
    "transaction_id": "68ba94ac80123",
    "transaction_type": "PAYMENT",
    "transaction_date": "2025-09-01 00:00:15",
    "transaction_status": "APPROVED",
    "transaction_amount": "50000",
    "transaction_currency": "VND",
    "authentication_status": "AUTHENTICATION_SUCCESSFUL",
    "card_number": "4111XXXXXXXX1111",
    "card_holder_name": "NGUYEN VAN A",
    "card_expiry": "12/26",
    "card_funding_method": "CREDIT",
    "card_brand": "VISA"
  },
  "customer": {
    "id": "45",
    "customer_id": "CUST_001"
  }
}
  • Xử lý IPN endpoint:
PHP
Route::post('/payment/ipn', function(Request $request) {
    // Verify secret key
    if ($request->header('X-Secret-Key') !== $secretKey) {
        return response()->json(['error' => 'Unauthorized'], 401);
    }

    $data = $request->json()->all();

    if ($data['notification_type'] === 'ORDER_PAID') {
        $order = Order::where('invoice_number', $data['order']['order_invoice_number'])->first();
        $order->status = 'paid';
        $order->save();
    }

    // Return 200 to acknowledge receipt
    return response()->json(['success' => true], 200);
});
  • Các loại thông báo (notification_type):
Loại thông báoKhi nào gửiXử lý
ORDER_PAIDThanh toán một lần thành côngCập nhật đơn hàng, kích hoạt dịch vụ
RENEWAL_ORDER_PAIDThanh toán định kỳ tự động (chu kỳ tiếp theo)Tạo đơn hàng mới, gia hạn dịch vụ
TRANSACTION_VOIDHủy giao dịch thành côngHoàn tiền, hủy/tạm dừng dịch vụ