Documents every environment variable read by server/index.cjs and the Vite
frontend (grep-verified against process.env.* / import.meta.env.* usage),
with placeholder values only — no real secrets. Not gitignored (.gitignore
already carves out an exception for it).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Root README.md was frontend-only and didn't mention the backend at all.
server/README.md was stale relative to the endpoint/security changes in this
branch (missing POST /api/payment-links, the sanitized order_id behavior,
rate limiting, CORS, log retention, state persistence, admin auth) and linked
to a temp/README.md that no longer exists. Both now point to /docs, /openapi.json,
and the Postman collection as the source of truth for the API surface.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Reorganize into folders (Health & Config, Payment Links, Payment Operations,
Webhook, Logs & Docs, Dev/Test) and add every route that was missing:
GET/POST /api/config, POST /createtransaksi (ERP shape), Charge (Core API),
Create Snap Token, GET /api/logs, GET /api/logs/files, GET /api/logs/view,
GET /openapi.json, GET /docs, and the LOG_EXPOSE_API-only echo/echo2/
test-notify-erp endpoints. The Logs & Docs folder carries collection-level
Basic Auth (log_user/log_pass variables) shared by all its requests.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- server/logviewer.html: readable log viewer at GET /api/logs/view — level
filter chips, free-text search, and click-to-trace (clicking any field value
re-filters to every line sharing it, e.g. an order_id or request id across
its whole lifecycle). GET /api/logs/files/:filename now redirects browser
navigation here instead of returning raw JSON (Accept: application/json
still gets the JSON body).
- server/openapi.json + server/api-docs.html: OpenAPI 3.0 spec and a Scalar
reference page served at GET /openapi.json and GET /docs. Scalar is loaded
from a version-pinned CDN URL with a Subresource Integrity hash rather than
installed as a dependency.
- Generalize requireLogBasicAuth -> requireAdminAuth since the same HTTP Basic
Auth credentials now gate /api/logs*, /openapi.json, and /docs alike.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- ecosystem.config.cjs: NODE_ENV was hardcoded to "development" even for the
production pm2 process, silently disabling every isDevEnv()-gated security
check (API key bypass, admin auth bypass) in production. Now "production".
- Restrict CORS via configurable CORS_ALLOWED_ORIGINS (falls back to allow-all
with a warning when unset, so this doesn't break existing traffic on deploy).
- Add an in-process, dependency-free rate limiter on /createtransaksi,
/api/payment-links, /api/payments/charge, and /api/payments/snap/token to
curb bot abuse / card-testing on endpoints the browser checkout must be able
to call directly (an API-key gate would break that legitimate flow).
- Auto-delete LOGS_*.log files older than LOG_RETENTION_DAYS (default 30).
- Persist activeOrders, notifiedOrders, orderRetryCount, and orderMerchantId to
server/data/state.json via Proxy-wrapped Map/Set (schedulePersist on every
mutation), so idempotency and retry-suffix tracking survive restarts/crashes
instead of resetting to empty every deploy.
- Remove processPaymentCompletion, dead code with no call sites.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v4-backup/ and web-bundles/ contain the BMad-Method agent-orchestration
framework (agent definitions, checklists, templates, game-dev/creative-writing
expansion packs) accidentally left in the repo. Nothing in server/ or src/
references either directory.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
State maps (activeOrders, notifiedOrders, orderRetryCount, orderMerchantId)
were keyed by the raw order_id in /createtransaksi and /api/payment-links,
but Midtrans webhooks and status checks always report back the sanitized
('.'-joined) order_id. Whenever the original order_id contained characters
Midtrans disallows (e.g. ':'), the two never matched — breaking duplicate/
already-completed detection and retry-suffix lookups. Both endpoints now
key exclusively on the sanitized order_id, with retry-suffix support added
to /api/payment-links for parity with /createtransaksi.
Also add HTTP Basic Auth (requireLogBasicAuth) in front of /api/logs,
/api/logs/files, and /api/logs/files/:filename — these were previously
gated only by LOG_EXPOSE_API, which defaults to true, leaving order data
and transaction details publicly readable with no credentials.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds a new endpoint that creates a shareable Midtrans Snap payment link
straight from { order_id, nominal, customer, expire_at } without remapping
to the mercant_id/item[] shape required by /createtransaksi.
order_id is sanitized (':' and other disallowed chars -> '.') before being
sent to Midtrans, while the mercant_id used for ERP webhook notification is
derived from the original, unsanitized order_id so ERP always gets a clean
identifier instead of the full composite order_id.
Includes a Postman collection covering link creation, resolution, status
check, and replaying a captured Midtrans notification payload for local
webhook debugging.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Midtrans rejects order_id values containing ':' (only alphanumeric and
- _ ~ . are allowed). The composite mercant_id:item_id order_id and the
:rN retry suffix violated this, causing Snap token requests to fail
with a 400 once both a mercant_id and item_id were present.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Added 'Inter' font to global CSS and Tailwind config for improved typography.
- Deleted unused test files related to payment link creation and Snap token testing.
- Created comprehensive README for server setup, API endpoints, and payment flow.
- Added testing documentation for easier integration and usage of the payment system.
- Add customerName prop to PaymentSheet component
- Display customer name in payment summary below Order ID
- Pass customer name from CheckoutPage form to PaymentSheet
- Fix TypeScript build errors (remove unused variables)
- Improve error logging in API interceptor
- Clean up snapLoader (remove unused snapLoading variable)
- Clean up PayPage (remove unused allowedMethods, runtimeCfg)
- Move lockOrder call to onSuccess callback in PayPage
- Add BOM handling in test-create-payment-link script
- Update test payment data (REFNO-002, TKG-2512041)
- Add guard in AutoSnapPayment to only trigger when orderId and amount are valid
- Show loading state while waiting for payment data to resolve
- Prevent premature Snap token creation with empty/invalid data
- Fix PayPage and CheckoutPage auto-payment flow
- Add AutoSnapPayment component that auto-triggers Snap popup on mount
- Update CheckoutPage: auto-open Snap payment after form submission
- Update PayPage: auto-open Snap payment on page load
- Remove manual button clicks for smoother UX
- Add loading states and error handling for auto-payment flow
- Created src/lib/errorMessages.ts for user-friendly Bahasa Indonesia error messages
- Created src/components/LoadingOverlay.tsx with Framer Motion animations
- Updated BankTransferPanel with LoadingOverlay and mapErrorToUserMessage
- All 4 error catch blocks now use user-friendly messages
- GoPayPanel imports restored (ready for next iteration)
Story: 1.1 - Prevent Duplicate VA/QR/Code Generation & Improve Feedback
Status: Partial (BankTransferPanel complete, GoPayPanel & CStorePanel pending)
Update default payment link TTL from 30 minutes to 24 hours across frontend and backend. Also modify countdown display to show hours in addition to minutes and seconds.