import { createHmac } from "node:crypto"; const PORT = process.env.PORT || "3100"; const BASE = process.env.BASE_URL || `http://127.0.0.1:${PORT}`; const ADMIN_TOKEN = process.env.ADMIN_TOKEN || "admin-dev-token"; const DEVICE_TOKEN = process.env.DEVICE_TOKEN || "device-dev-token"; const SECRET = process.env.INTEGRATION_WEBHOOK_SECRET || "dev-callback-secret"; function short(data) { const json = typeof data === 'string' ? data : JSON.stringify(data || {}); return json.length > 180 ? `${json.slice(0, 180)}...` : json; } async function req(path, options = {}) { const response = await fetch(`${BASE}${path}`, { method: options.method || 'GET', headers: { 'Content-Type': 'application/json', ...(options.headers || {}) }, body: Object.prototype.hasOwnProperty.call(options, 'body') ? JSON.stringify(options.body) : undefined }); const text = await response.text(); let body = null; try { body = text ? JSON.parse(text) : null; } catch { body = text; } if (!response.ok) { throw new Error(`${options._label || path} failed: ${response.status}`); } console.log(`${options._label || `${options.method || 'GET'} ${path}`} => ${response.status} ${short(body)}`); return body; } async function reqAdmin(path, opts = {}) { return req(path, { ...opts, headers: { ...(opts.headers || {}), Authorization: `Bearer ${ADMIN_TOKEN}` } }); } async function reqDevice(path, opts = {}) { return req(path, { ...opts, headers: { ...(opts.headers || {}), Authorization: `Bearer ${DEVICE_TOKEN}` } }); } (async () => { await req('/health', { _label: 'GET /health' }); await req('/admin/login', { method: 'POST', body: { username: 'admin', password: 'admin' }, _label: 'POST /admin/login' }); await reqAdmin('/admin/seed/status', { _label: 'GET /admin/seed/status' }); const ts = Date.now(); const merchant = await reqAdmin('/admin/merchants', { method: 'POST', body: { legal_name: `Smoke Merchant ${ts}`, brand_name: `SMK-${ts}`, settlement_account_reference: `bank:${ts}`, settlement_account_type: 'merchant_bank_account', payout_mode: 'merchant_direct' }, _label: 'POST /admin/merchants' }); const merchantId = merchant?.data?.id; const outlet = await reqAdmin(`/admin/merchants/${merchantId}/outlets`, { method: 'POST', body: { name: `Outlet ${ts}` }, _label: 'POST /admin/merchants/:id/outlets' }); const outletId = outlet?.data?.id; const terminal = await reqAdmin(`/admin/outlets/${outletId}/terminals`, { method: 'POST', body: { terminal_code: `TERM-${ts}`, qr_mode: 'static' }, _label: 'POST /admin/outlets/:id/terminals' }); const terminalId = terminal?.data?.id; const device = await reqAdmin('/admin/devices', { method: 'POST', body: { device_code: `DEV-${ts}`, vendor: 'acme', model: 'v1', communication_mode: 'mqtt', status: 'active' }, _label: 'POST /admin/devices' }); const deviceId = device?.data?.id; await reqAdmin(`/admin/devices/${deviceId}/bind`, { method: 'POST', body: { merchant_id: merchantId, outlet_id: outletId, terminal_id: terminalId }, _label: 'POST /admin/devices/:id/bind' }); await reqDevice('/device/heartbeat', { method: 'POST', body: { device_id: deviceId, timestamp: new Date().toISOString(), firmware_version: '1.2.3', network_strength: 88, battery_level: 77, state: 'idle' }, _label: 'POST /device/heartbeat' }); const tx = await reqAdmin('/admin/transactions', { method: 'POST', body: { partner_reference: `PR-${ts}`, merchant_id: merchantId, outlet_id: outletId, terminal_id: terminalId, device_id: deviceId, amount: 19900, currency: 'IDR', qr_mode: 'static', initiation_mode: 'static', status: 'initiated' }, _label: 'POST /admin/transactions' }); const txId = tx?.data?.id; const callback = { partner_reference: `PR-${ts}`, partner_txn_id: `PTX-${ts}`, amount: 19900, currency: 'IDR', payment_status: 'paid', status: 'paid', paid_at: new Date().toISOString() }; const signature = createHmac('sha256', SECRET).update(JSON.stringify(callback)).digest('hex'); await req('/integrations/qris/callback', { method: 'POST', headers: { 'X-Partner-Signature': signature }, body: { ...callback, signature }, _label: 'POST /integrations/qris/callback' }); await reqAdmin(`/admin/transactions/${txId}`, { _label: 'GET /admin/transactions/:id' }); await reqAdmin(`/admin/transactions/${txId}/events`, { _label: 'GET /admin/transactions/:id/events' }); await reqAdmin(`/admin/transactions/${txId}/heartbeats`, { _label: 'GET /admin/transactions/:id/heartbeats' }); await reqAdmin(`/admin/devices/${deviceId}/heartbeats`, { _label: 'GET /admin/devices/:id/heartbeats' }); await reqAdmin('/admin/notifications/failed', { _label: 'GET /admin/notifications/failed' }); await reqAdmin(`/admin/transactions/${txId}/retry-notification`, { method: 'POST', body: {}, _label: 'POST /admin/transactions/:id/retry-notification' }); await reqAdmin('/admin/dashboard/summary', { _label: 'GET /admin/dashboard/summary' }); console.log(`Smoke point 4 flow done. tx=${txId} device=${deviceId}`); })();