Claude Project Tracker

refreshed 2026-08-08 20:39:14Z

What's pending across every project

11 open · sorted by priority then due-date
priority all urgent high low
Filtered by tag razorpay  clear
todo urgent
Rotate Razorpay webhook secret — 'hopewell' is guessable
The RAZORPAY_SECRET_WEBHOOK value in /opt/ocpp/.env on the production VM is literally 'hopewell' — a common English word, effectively no protection. HMAC verification against a guessable secret means anyone who learns the plaintext can forge webhook calls and credit any wallet. Fix: 1. Razorpay Dashboard → Settings → Webhooks → regenerate a long random secret (32+ char base64). 2. Update /opt/ocpp/.env on the VM (SMTP_PASSWORD-style edit). 3. sudo systemctl restart ocpp.service. 4. Send a test webhook from Razorpay dashboard and confirm it verifies. This is the single most impactful hardening we can do.
/opt/ocpp/.envinternal/handlers/wallet_handler.go:239-254↗ https://dashboard.razorpay.com/app/webhooks
Vajra Volt Mobile App · vajra-mobile-app · by saravanan@scrumclaw.ai
from the conversationclaude: RAZORPAY_SECRET_WEBHOOK=hopewell in .env is weak - anyone who guesses the plaintext can forge webhooks (i.e., forge topups). Regenerate a long random secret in the Razorpay dashboard and update .env, then restart the service. This is the single most impactful hardening you can do. saravanan: put them in my project tracker - scrumclaw.ai
8d ago
07-31 02:51
blocker urgent
Enable Razorpay QR Codes product on merchant account
The Razorpay QR Codes API (`POST /v1/payments/qr_codes`) requires activation on your merchant account. Ping Razorpay support: "Please enable Payment Handle / QR Codes API on account acc_XXXX". Typically enabled within 24–48 hours, no additional cost for UPI QR. Confirmed during BRD Q15 as "not enabled". Blocks Phase 1 pilot — we can build the backend, but cannot create even the first test QR without this.</body>
Vajra Volt Mobile App · vajra-mobile-app · by saravanan@scrumclaw.ai
6d ago
08-02 11:44
todo high
Fix float equality in webhook amount check (can silently reject real topups)
ProcessTopupWebhook uses `if topup.Amount != amount` — direct float64 equality. A tiny rounding drift (e.g., 500.00 stored vs 499.99999998 derived from Razorpay's paise/100) will falsely reject the webhook as 'amount mismatch', leaving the user paying but not credited. Change to: if math.Abs(topup.Amount - amount) > 0.01 { ... } Or better: store amount as int64 paise everywhere and compare integers.
internal/repositories/wallet_repo.go:100
Vajra Volt Mobile App · vajra-mobile-app · by saravanan@scrumclaw.ai
8d ago
07-31 02:51
todo high
Razorpay QR admin provisioning endpoint (create + regen QR per gun)
Per BRD v1 §7.1 FR1–FR4.\n\nNew backend endpoints under /internal/admin/:\n\n- POST /admin/chargers/:id/connectors/:cid/qr — create if not exists; returns razorpay_qr_id + image_url\n- POST /admin/chargers/:id/connectors/:cid/qr/regen — close existing QR (via Razorpay POST /v1/payments/qr_codes/:id/close) and create new one; updates charger_qr_codes row\n- GET /admin/chargers/:id/connectors/:cid/qr — return current QR + image URL for reprint\n- GET /admin/chargers/qr — list all QRs across all stations, for admin console listing\n\nWraps Razorpay QR Codes API. All calls go server-to-server with Razorpay API key basic auth (reuse pattern in wallet_handler.go createRazorpayOrder).\n\nBlocked on Razorpay QR API enablement (#52) and TDD (#50).</body>
Vajra Volt Mobile App · vajra-mobile-app · by saravanan@scrumclaw.ai
6d ago
08-02 11:52
todo high
qr_code.credited webhook handler in existing PaymentWebhook
Per BRD v1 §7.2 FR6–FR9.\n\nExtend existing internal/handlers/wallet_handler.go PaymentWebhook to switch on hook.Event:\n\n switch hook.Event {\n case "payment.captured": // existing app topup path\n case "qr_code.credited": // NEW walk-in path\n h.handleQRCredit(payload)\n }\n\nhandleQRCredit implements:\n1. Lookup gun via notes.charger_id + notes.connector_id (cross-check charger_qr_codes row exists)\n2. Call resolveOrCreateUser(contact, email, vpa)\n3. Insert TOPUP ledger entry (idempotency key: qrpay:<payment_id>)\n4. Check OCPP status of connector — if Available, trigger RemoteStart via existing internal path with 3x5s retry (see #62)\n5. If not Available, credit persists in wallet only\n6. If WALKIN_QR_SMS_ENABLED flag on → dispatch appropriate SMS template (Phase 1.5)\n7. Return 200 to Razorpay\n\nBlocked on TDD (#50), migrations 0028–0029.</body>
Vajra Volt Mobile App · vajra-mobile-app · by saravanan@scrumclaw.ai
6d ago
08-02 11:52
todo
Fix topup amount range mismatch (min=1 vs error message '100')
Backend constant minTopupAmount is 1 but the error message and frontend both say the minimum is 100. Change minTopupAmount to 100 so the backend actually enforces what the message claims — otherwise a bespoke client can top up ₹1 (bypasses the intended floor). - const minTopupAmount = 1 + const minTopupAmount = 100
internal/handlers/wallet_handler.go:29-30internal/handlers/wallet_handler.go:87
Vajra Volt Mobile App · vajra-mobile-app · by saravanan@scrumclaw.ai
8d ago
07-31 02:51
todo
Fix Razorpay prefill.contact — uses email as fallback, breaks UPI autofill
Frontend passes `me.phone_number || storedEmail || ''` into Razorpay's prefill.contact. That field expects a phone number and is used to auto-detect UPI apps. Passing an email makes checkout look wrong and skips UPI autofill. Fix: only set prefill.contact when we have an actual phone number; put the email into prefill.email instead. prefill: { name: userName, contact: me?.phone_number?.trim() || undefined, email: storedEmail || undefined, }
app/(tabs)/profile/add-money.tsx:178-192
Vajra Volt Mobile App · vajra-mobile-app · by saravanan@scrumclaw.ai
8d ago
07-31 02:51
todo
Rate-limit / IP-allowlist /webhooks/payment endpoint
The webhook endpoint currently accepts any POST from anywhere. HMAC signature check is the only defense — cryptographically sound, but each invalid request still triggers signature compute + JSON parse + DB lookup, so it's a cheap DoS vector. Two things worth adding (nginx-level is easiest): 1. Restrict source IPs to Razorpay's published webhook IPs (they publish a list): allow only those in the nginx server block for /webhooks/*. 2. Rate-limit /webhooks/* at nginx (limit_req_zone). Even a modest 20 rps burst limit stops volumetric noise. Doesn't change functionality, just hardens.
internal/routes/routes.go:161-163internal/handlers/wallet_handler.go:239-303/etc/nginx/sites-available/vajraev
Vajra Volt Mobile App · vajra-mobile-app · by saravanan@scrumclaw.ai
8d ago
07-31 02:51
todo
Admin console: "list payments for QR" endpoint (Razorpay debug aid)
Useful for ops debugging (missing webhook, dispute lookup, reconciliation). Wraps Razorpay: GET https://api.razorpay.com/v1/payments/qr_codes/:qr_id/payments Backend endpoint: GET /admin/chargers/:charger_id/connectors/:connector_id/payments Returns array of payments captured against that gun's QR (all-time), each with vpa, contact, email, amount, timestamp, status. Enables ops to answer "who paid at this gun today" without querying our DB. Small addition to the admin endpoints in #65. Roughly 1 hour of Go + admin console UI work.</body>
scrumclaw#61scrumclaw#65
Vajra Volt Mobile App · vajra-mobile-app · by saravanan@scrumclaw.ai
6d ago
08-02 12:10
todo low
Remove deprecated Razorpay 'payment_capture: 1' from order create
Razorpay deprecated the payment_capture parameter for the Orders API — capture behavior is now controlled at the account/merchant level. Not a functional bug today, but noise, and Razorpay may eventually reject unknown fields in future API versions. Drop the key from the payload in createRazorpayOrder.
internal/handlers/wallet_handler.go:340
Vajra Volt Mobile App · vajra-mobile-app · by saravanan@scrumclaw.ai
8d ago
07-31 02:51
note low
Reference: Razorpay VPA + customer data extraction from qr_code.credited
Where to find each customer field in the qr_code.credited webhook payload. Confirmed from Razorpay official docs (docs/webhooks/qr-codes). **Payload path for VPA:** `payload.payment.entity.vpa` **Trimmed sample:** ```json { "event": "qr_code.credited", "contains": ["payment", "qr_code"], "payload": { "payment": { "entity": { "id": "pay_HO2fEpc9JeOQU5", "amount": 200, "method": "upi", "vpa": "gauri.kumar@okhdfcbank", "email": "gauri.kumari@example.com", "contact": "+919000090000", "customer_id": "cust_HKsR5se84c5LTO", "notes": {}, "acquirer_data": { "rrn": "116812981837" } } }, "qr_code": { "entity": { "id": "qr_HO2e0813YlchUn", "notes": { "charger_id": "VAJRA0001", "connector_id": "2" } } } } } ``` **Two subtle gotchas:** 1. **Two separate `notes` blocks** — `payload.payment.entity.notes` is per-payment (usually empty for QR), and `payload.qr_code.entity.notes` is the QR's notes (where we set charger_id + connector_id at QR creation). Read the second one for gun identification. 2. **VPA presence:** always present for QR-triggered payments (method is always upi). Fallback: null. **Go struct extraction:** see TDD §4.3 `qrCreditedPayload`. **Fallback retrieval (webhook lost):** - `GET /v1/payments/pay_XXX` — fetch single payment; includes vpa - `GET /v1/payments/qr_codes/qr_XXX/payments` — list all payments for a QR (great for admin ops "show all payments to this gun") Sources: - https://razorpay.com/docs/webhooks/qr-codes/ - https://razorpay.com/docs/webhooks/payloads/payments/</body>
Vajra Volt Mobile App · vajra-mobile-app · by saravanan@scrumclaw.ai
6d ago
08-02 12:10

Add an item