Quick Start

SePay Webhooks allow your application to receive real-time transaction notifications whenever money flows in or out of your linked bank account. Instead of constantly polling, SePay proactively sends transaction data to your specified URL.


Sandbox Environment

If you need a test environment, register an account at my.dev.sepay.vn. Here you can create simulated transactions and webhooks for development purposes. After registration, please contact SePay to activate your account.


Integration Overview

The diagram below illustrates the complete integration flow — from configuring webhooks, generating payment QR codes, receiving transaction notifications via webhook, to periodic transaction reconciliation.

SePay Webhooks Flow
Rendering diagram...

How It Works

  1. A customer transfers money to your bank account
  2. SePay detects the new transaction and sends a POST request to your configured webhook URL
  3. Your server receives the data, processes it and responds with {"success": true}

Quick start

Step 1: Create a Webhook on Dashboard

Access WebHooks

Log in to my.sepay.vn → select WebHooks menu.

Add a New WebHook

Click the + Add webhooks button and fill in:

  • Name: Any name to identify the webhook
  • Select Event: Choose when to trigger the webhook: money in, money out, or both
  • Select Conditions: Choose the bank account(s) that will trigger webhooks
  • Call URL: The endpoint that will receive webhooks. To build a custom receiver, see the PHP guide or Node.js guide
  • Authentication: Choose OAuth 2.0, API Key or No authentication

Complete

Click Add to finish the integration.

Full configuration details: Create Webhooks


Step 2: WebHook Payload Data

SePay sends a POST request with the following JSON payload:

JSON
{
  "id": 92704,
  "gateway": "Vietcombank",
  "transactionDate": "2023-03-25 14:02:37",
  "accountNumber": "0123499999",
  "code": null,
  "content": "chuyen tien mua iphone",
  "transferType": "in",
  "transferAmount": 2277000,
  "accumulated": 19077000,
  "subAccount": null,
  "referenceCode": "MBVCB.3278907687",
  "description": ""
}
idinteger
Transaction ID on SePay
gatewaystring
Bank brand name
transactionDatestring
Transaction time from the bank
accountNumberstring
Bank account number
codestring
Payment code, automatically detected by SePay based on Company → General Settings. Can be null if not detected.
contentstring
Transfer description
transferTypestring
Transaction type: in = deposit, out = withdrawal
transferAmountinteger
Transaction amount (VND)
accumulatedinteger
Account balance (accumulated)
subAccountstring
Sub-account (virtual account / VA). Can be null.
referenceCodestring
Reference code from SMS
descriptionstring
Full SMS message content

Step 3: Sample Webhook Receiver Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php
// File: webhook/sepay.php
 
// Get data from POST request
$data = json_decode(file_get_contents('php://input'));
 
if (!is_object($data)) {
http_response_code(400);
echo json_encode(['success' => false, 'message' => 'Invalid data']);
exit;
}
 
// Verify API Key
$apiKey = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
if ($apiKey !== 'Apikey YOUR_API_KEY') {
http_response_code(401);
echo json_encode(['success' => false, 'message' => 'Unauthorized']);
exit;
}
 
// Deduplication: check if id has been processed
// if (transactionExists($data->id)) { ... return; }
 
// Process transaction
$transactionId = $data->id;
$amount = $data->transferAmount;
$code = $data->code; // Payment code (order ID)
$type = $data->transferType; // 'in' or 'out'
 
if ($type === 'in' && $code) {
// TODO: Update order status by $code
// updateOrderStatus($code, 'paid', $amount);
}
 
// Respond with success — REQUIRED
http_response_code(200);
echo json_encode(['success' => true]);
 

Detailed guides for saving transactions to MySQL: PHP · Node.js


Step 4: Recognizing Successful WebHooks
Important

When receiving a webhook from SePay, your server must respond correctly for SePay to mark it as successful:

  • OAuth 2.0: Response body {"success": true} — HTTP Status Code 201
  • API Key: Response body {"success": true} — HTTP Status Code 200 or 201
  • No authentication: Response body {"success": true} — HTTP Status Code 200 or 201

If the response does not meet these conditions, SePay will consider the webhook failed.

Timeout parameters:

Connection timeout
5 seconds
Response timeout
8 seconds — Maximum wait time for a response

Step 5: Testing WebHooks
  1. Demo account: Go to TransactionsSimulate Transaction to create a test transaction. See the Simulate Transaction guide.
  2. Real account: Send a small amount to your bank account to trigger a real transaction.
  3. View logs: Go to Logs → WebHooks Log to see all sent webhooks.
  4. Per-transaction view: Go to Transactions → Auto column → select Pay to see webhooks for each transaction.

Next Steps

  1. QR Code and Payment Form — Create bank transfer QR codes and build an auto-confirming payment page
  2. Create Webhooks — Detailed webhook configuration (events, conditions, retry, authentication)
  3. Webhooks Programming (PHP) — Step-by-step guide to save transactions to MySQL with PHP
  4. Webhooks Programming (Node.js) — Step-by-step guide with Node.js + Express
  5. Transaction Reconciliation — Ensure no transactions are missed