Cấu hình IPN URL
IPN URL được cấu hình tại trang quản lý merchant trên SePay:
- Đăng nhập vào SePay
- Vào Cổng thanh toán → Cấu hình → IPN
- Nhập URL endpoint của bạn để nhận IPN
- Lưu cấu hình
Lưu ý quan trọng
IPN URL phải là HTTPS công khai mà SePay gọi tới được từ Internet (không dùng localhost hay IP nội bộ như 127.0.0.1, 192.168.x), và endpoint phải trả về HTTP status code 200 để xác nhận đã nhận thành công. Khi phát triển ở máy cục bộ, hãy expose endpoint ra ngoài bằng ngrok, localtunnel, cloudflared hoặc tương tự để SePay gọi vào được.
Request từ SePay đến Merchant
POST
https://your-url (url bạn cấu hình trong IPN)Headers:
X-Secret-Key: <secret_key>
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ố
timestampintegerrequired
Unix timestamp khi gửi thông báo
notification_typestringrequired
Loại thông báo: ORDER_PAID (thanh toán thành công), TRANSACTION_VOID (hủy giao dịch)
orderobjectrequired
Thông tin đơn hàng
transactionobjectrequired
Thông tin giao dịch
customerobjectrequired
Thông tin khách hàng
Ví dụ request body:
REQUEST
{
"timestamp": 1757058220,
"notification_type": "ORDER_PAID",
"order": {
"id": "e2c195be-c721-47eb-b323-99ab24e52d85",
"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": "384c66dd-41e6-4316-a544-b4141682595c",
"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": "bae12d2f-0580-4669-8841-cc35cf671613",
"customer_id": "CUST_001"
}
}Xử lý IPN endpoint:
PHPPHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Route::post('/payment/ipn', function(Request $request) {// Verify secret keyif ($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 receiptreturn response()->json(['success' => true], 200);});