jebin2 commited on
Commit
aed0646
·
1 Parent(s): 7296d4a
core/models.py CHANGED
@@ -178,6 +178,7 @@ class PaymentTransaction(Base):
178
 
179
  # Status tracking
180
  status = Column(String(20), default="created", index=True) # created, paid, failed, refunded
 
181
 
182
  # Timestamps
183
  created_at = Column(DateTime(timezone=True), server_default=func.now())
 
178
 
179
  # Status tracking
180
  status = Column(String(20), default="created", index=True) # created, paid, failed, refunded
181
+ verified_by = Column(String(20), nullable=True) # client, webhook, or both
182
 
183
  # Timestamps
184
  created_at = Column(DateTime(timezone=True), server_default=func.now())
routers/blink.py CHANGED
@@ -258,6 +258,7 @@ async def get_payment_transactions(
258
  "amount_rupees": item.amount_paise / 100,
259
  "currency": item.currency,
260
  "status": item.status,
 
261
  "error_message": item.error_message,
262
  "created_at": item.created_at.isoformat() if item.created_at else None,
263
  "paid_at": item.paid_at.isoformat() if item.paid_at else None
 
258
  "amount_rupees": item.amount_paise / 100,
259
  "currency": item.currency,
260
  "status": item.status,
261
+ "verified_by": item.verified_by,
262
  "error_message": item.error_message,
263
  "created_at": item.created_at.isoformat() if item.created_at else None,
264
  "paid_at": item.paid_at.isoformat() if item.paid_at else None
routers/payments.py CHANGED
@@ -298,6 +298,12 @@ async def verify_payment(
298
  transaction.razorpay_signature = request.razorpay_signature
299
  transaction.paid_at = datetime.utcnow()
300
 
 
 
 
 
 
 
301
  # Add credits to user
302
  user.credits += transaction.credits_amount
303
 
@@ -389,6 +395,12 @@ async def razorpay_webhook(
389
  transaction.gateway_payment_id = payment_id
390
  transaction.paid_at = datetime.utcnow()
391
 
 
 
 
 
 
 
392
  # Find user and add credits
393
  user_result = await db.execute(
394
  select(User).where(User.user_id == transaction.user_id)
 
298
  transaction.razorpay_signature = request.razorpay_signature
299
  transaction.paid_at = datetime.utcnow()
300
 
301
+ # Track who verified - if webhook already set it, mark as "both"
302
+ if transaction.verified_by == "webhook":
303
+ transaction.verified_by = "both"
304
+ else:
305
+ transaction.verified_by = "client"
306
+
307
  # Add credits to user
308
  user.credits += transaction.credits_amount
309
 
 
395
  transaction.gateway_payment_id = payment_id
396
  transaction.paid_at = datetime.utcnow()
397
 
398
+ # Track who verified - if client already set it, mark as "both"
399
+ if transaction.verified_by == "client":
400
+ transaction.verified_by = "both"
401
+ else:
402
+ transaction.verified_by = "webhook"
403
+
404
  # Find user and add credits
405
  user_result = await db.execute(
406
  select(User).where(User.user_id == transaction.user_id)
templates/index.html CHANGED
@@ -470,13 +470,14 @@
470
  <th>Credits</th>
471
  <th>Amount</th>
472
  <th>Status</th>
 
473
  <th>Created At</th>
474
  <th>Paid At</th>
475
  </tr>
476
  </thead>
477
  <tbody id="paymentsBody">
478
  <tr>
479
- <td colspan="12">
480
  <div class="loading">
481
  <div class="spinner"></div>Loading...
482
  </div>
@@ -699,9 +700,20 @@
699
  function renderPaymentsTable(items) {
700
  const tbody = document.getElementById('paymentsBody');
701
  if (items.length === 0) {
702
- tbody.innerHTML = '<tr><td colspan="12"><div class="empty-state">No payment transactions found</div></td></tr>';
703
  return;
704
  }
 
 
 
 
 
 
 
 
 
 
 
705
  tbody.innerHTML = items.map(item => `
706
  <tr>
707
  <td>${item.id}</td>
@@ -714,6 +726,7 @@
714
  <td><span class="credits-badge">${item.credits_amount}</span></td>
715
  <td>₹${item.amount_rupees}</td>
716
  <td><span class="status-badge status-${item.status === 'paid' ? 'success' : item.status === 'failed' ? 'failed' : 'queued'}">${item.status}</span></td>
 
717
  <td class="timestamp">${item.created_at ? new Date(item.created_at).toLocaleString() : '-'}</td>
718
  <td class="timestamp">${item.paid_at ? new Date(item.paid_at).toLocaleString() : '-'}</td>
719
  </tr>
 
470
  <th>Credits</th>
471
  <th>Amount</th>
472
  <th>Status</th>
473
+ <th>Verified By</th>
474
  <th>Created At</th>
475
  <th>Paid At</th>
476
  </tr>
477
  </thead>
478
  <tbody id="paymentsBody">
479
  <tr>
480
+ <td colspan="13">
481
  <div class="loading">
482
  <div class="spinner"></div>Loading...
483
  </div>
 
700
  function renderPaymentsTable(items) {
701
  const tbody = document.getElementById('paymentsBody');
702
  if (items.length === 0) {
703
+ tbody.innerHTML = '<tr><td colspan="13"><div class="empty-state">No payment transactions found</div></td></tr>';
704
  return;
705
  }
706
+
707
+ const getVerifiedByBadge = (value) => {
708
+ if (!value) return '-';
709
+ const colors = {
710
+ 'client': 'background: rgba(59, 130, 246, 0.2); color: #3b82f6;',
711
+ 'webhook': 'background: rgba(234, 179, 8, 0.2); color: #eab308;',
712
+ 'both': 'background: rgba(34, 197, 94, 0.2); color: #22c55e;'
713
+ };
714
+ return `<span class="status-badge" style="${colors[value] || ''}">${value}</span>`;
715
+ };
716
+
717
  tbody.innerHTML = items.map(item => `
718
  <tr>
719
  <td>${item.id}</td>
 
726
  <td><span class="credits-badge">${item.credits_amount}</span></td>
727
  <td>₹${item.amount_rupees}</td>
728
  <td><span class="status-badge status-${item.status === 'paid' ? 'success' : item.status === 'failed' ? 'failed' : 'queued'}">${item.status}</span></td>
729
+ <td>${getVerifiedByBadge(item.verified_by)}</td>
730
  <td class="timestamp">${item.created_at ? new Date(item.created_at).toLocaleString() : '-'}</td>
731
  <td class="timestamp">${item.paid_at ? new Date(item.paid_at).toLocaleString() : '-'}</td>
732
  </tr>