Mbonea Claude Sonnet 4.6 commited on
Commit
c2b1c17
Β·
1 Parent(s): e59b874

fix webhook payment processing and server URL logging

Browse files

- Remove 'processing' intermediate status (not in payments ENUM) β€” fetch
pending payment directly then mark completed in one step
- Fix double-protocol in Portal base log (PORTAL_HOST already has scheme)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Files changed (2) hide show
  1. src/routes/webhooks.routes.js +13 -19
  2. src/server.js +2 -1
src/routes/webhooks.routes.js CHANGED
@@ -53,29 +53,23 @@ async function handlePaymentCompleted(data) {
53
  if (!reference) return;
54
 
55
  // ── WiFi guest purchase ────────────────────────────────────────────────────
56
- // Atomically claim the payment β€” only one concurrent webhook can advance it
57
- const claim = await db.query(
58
- `UPDATE payments SET status = 'processing' WHERE reference = ? AND status = 'pending'`,
 
 
 
 
 
 
59
  [reference]
60
- );
61
-
62
- if (claim.affectedRows === 1) {
63
- const payment = await db.query(
64
- `SELECT p.*, wp.duration_seconds,
65
- wp.down_limit, wp.down_unit, wp.up_limit, wp.up_unit, wp.name AS plan_name,
66
- d.name AS device_name, c.phone AS client_phone
67
- FROM payments p
68
- JOIN wifi_plans wp ON wp.id = p.plan_id
69
- JOIN devices d ON d.id = p.device_id
70
- JOIN clients c ON c.id = p.client_id
71
- WHERE p.reference = ? LIMIT 1`,
72
- [reference]
73
- ).then(r => r[0]);
74
 
 
75
  const code = generateCode();
76
 
77
  // Create access token
78
- const tokenResult = await db.query(
79
  `INSERT INTO access_tokens
80
  (client_id, device_id, plan_id, payment_id, code, duration_seconds,
81
  down_limit, down_unit, up_limit, up_unit, status)
@@ -87,7 +81,7 @@ async function handlePaymentCompleted(data) {
87
  ]
88
  );
89
 
90
- // Mark payment completed (trigger fires here β€” credits client balance)
91
  await db.query(
92
  `UPDATE payments SET
93
  status = 'completed',
 
53
  if (!reference) return;
54
 
55
  // ── WiFi guest purchase ────────────────────────────────────────────────────
56
+ const payment = await db.query(
57
+ `SELECT p.*, wp.duration_seconds,
58
+ wp.down_limit, wp.down_unit, wp.up_limit, wp.up_unit, wp.name AS plan_name,
59
+ d.name AS device_name, c.phone AS client_phone
60
+ FROM payments p
61
+ JOIN wifi_plans wp ON wp.id = p.plan_id
62
+ JOIN devices d ON d.id = p.device_id
63
+ JOIN clients c ON c.id = p.client_id
64
+ WHERE p.reference = ? AND p.status = 'pending' LIMIT 1`,
65
  [reference]
66
+ ).then(r => r[0]);
 
 
 
 
 
 
 
 
 
 
 
 
 
67
 
68
+ if (payment) {
69
  const code = generateCode();
70
 
71
  // Create access token
72
+ await db.query(
73
  `INSERT INTO access_tokens
74
  (client_id, device_id, plan_id, payment_id, code, duration_seconds,
75
  down_limit, down_unit, up_limit, up_unit, status)
 
81
  ]
82
  );
83
 
84
+ // Mark payment completed β€” trigger fires here and credits client balance
85
  await db.query(
86
  `UPDATE payments SET
87
  status = 'completed',
src/server.js CHANGED
@@ -30,7 +30,8 @@ async function start() {
30
  // 3. Listen
31
  app.listen(PORT, () => {
32
  console.log(`[Server] Listening on http://0.0.0.0:${PORT}`);
33
- console.log(`[Server] Portal base: ${process.env.PORTAL_SCHEME}://${process.env.PORTAL_HOST}`);
 
34
  });
35
  }
36
 
 
30
  // 3. Listen
31
  app.listen(PORT, () => {
32
  console.log(`[Server] Listening on http://0.0.0.0:${PORT}`);
33
+ const host = (process.env.PORTAL_HOST || '').replace(/^https?:\/\//, '');
34
+ console.log(`[Server] Portal base: ${process.env.PORTAL_SCHEME || 'http'}://${host}`);
35
  });
36
  }
37