- Success Processing =
"R0" - Failed Processing =
"R1" - Unauthorized Request =
"R2" - Validation Failed =
"R3" - Not Enough Balance =
"R4"
This guide provides technical details for implementing the Seamless API webhook endpoint. For business context and integration flow, see the Seamless Integration Overview.
The Seamless API uses webhooks to send real-time game events from the API provider to your platform. Your webhook endpoint receives encrypted event notifications and responds with updated balance information.
You need to provide a single webhook endpoint URL that handles all event types.
All events from DOWINN are sent as:
POSTtext/plainPOSTHeader
{ "Content-Type": "text/plain", "Api-Id": "Api-Id Provided", "Api-Key": "Api-Key Provided"}Body
{ "transaction_id": "0_sandboxagent01_1763107509159_5036", "event_type": "login", "timestamp": 1763107509, "feedback_data": "TEST_FEEDBACK_DATA", "user_id": "edwincalma"}200Header
{ "Content-Type": "text/plain", "Api-Id": "Api-Id Provided", "Api-Key": "Api-Key Provided"}Body
{ "code": "R0", // Required, String "event_type": "login", // Required, String "timestamp": 1763107693, // Required, Number "user_id": "edwincalma", // Required, String "latest_balance": 1111000 // Required, Number}
"R0""R1""R2""R3""R4"Even for errors (insufficient balance, invalid player, etc.), return 200 OK with an encrypted error response:
Sample Error Response
{ "code": "R1", // Required, String "event_type": "logout", // Required, String "timestamp": 1763107508, // Required, Number "user_id": "edwincalma", // Required, String "latest_balance": 1111000 // OPTIONAL, Number}Your webhook must handle these event types:
Each event type has specific request/response schemas. See individual event documentation:
RESTful API used
All webhook requests and responses use AES encryption:
For detailed encryption implementation, see the Encryption Guide.
Below is a complete Express.js implementation showing how to receive and process webhook events:
const express = require('express')const app = express()const { encrypt, decrypt } = require('./utils');
const PORT = 3000const API_KEY = ''
app.use(express.text({ type: 'text/plain' }))
app.post('/endpoint_url', (req, res) => { const plainText = req.body const decryptedData = decrypt(plainText, API_KEY) // Process the webhook here... // Encrypt the raw data... const encryptedData = encrypt(rawResponse, API_KEY) // The response status must be HTTP 200 OK return res.status(200).json(encryptedData)})
app.listen(PORT, () => { console.log(`Server running on http://localhost:${PORT}`)})const crypto = require('crypto')
function encrypt(plainText, encryptionKey) { try { const cipher = crypto.createCipheriv( 'aes-256-ecb', Buffer.from(encryptionKey), null ) cipher.setAutoPadding(true) let encryptedData = cipher.update(plainText, 'utf8', 'base64') encryptedData += cipher.final('base64') return encryptedData } catch (error) { return null }}
function decrypt(encryptedData, encryptionKey) { try { const decipher = crypto.createDecipheriv( 'aes-256-ecb', Buffer.from(encryptionKey), null ) decipher.setAutoPadding(true) let decryptedData = decipher.update(encryptedData, 'base64', 'utf8') decryptedData += decipher.final('utf8') return decryptedData } catch (error) { return null }}
module.exports = { encrypt, decrypt }