Customers reported that clicking "Pay now" at checkout either hung indefinitely or returned a generic 500 error. This had been happening for roughly 36 hours and had already cost at least 6 confirmed abandoned carts before the client reached out.
The payment gateway's client library had been auto-updated by the host to a new major version three days earlier. The new version renamed a required config field (apiVersion → apiVersionDate). The old field was silently ignored instead of erroring at boot, so the app started fine but every live payment request failed server-side. Nothing in the deploy logs flagged this because the failure only surfaced at request time, not at startup.
| Action | Detail |
|---|---|
| Config correction | Updated the payment config to the new field name and pinned the client library to a tested minor version so it can't silently drift again. |
| Startup validation | Added a boot-time check that fails loudly (not silently) if required payment config is missing or malformed, so this class of bug surfaces in minutes next time, not days. |
| Verification | Ran 4 test transactions (success, declined card, expired card, network timeout) against the sandbox gateway before confirming the fix live. |
| Severity | Finding | Status |
|---|---|---|
| High | Admin login endpoint was reachable at a predictable path with no rate limiting — open to credential stuffing. | Fixed — rate limiting added, path unchanged (no workflow disruption) |
| High | 3 npm dependencies had known CVEs (2 with public exploit code), one used in the checkout flow itself. | Fixed — dependencies updated, checked against test suite |
| Medium | Missing Strict-Transport-Security, X-Content-Type-Options, and X-Frame-Options headers site-wide. | Fixed — headers added at the edge |
| Medium | Default admin username still in place from initial setup (common target for automated attacks). | Fixed — renamed, old account disabled |
| Low | Server version string exposed in response headers. | Fixed — suppressed |
The host's auto-update policy on payment-adjacent packages is what caused this outage. We recommended pinning versions on anything in the payment path and reviewing changelogs before any auto-update runs on that dependency group — flagged to the client as a follow-up, not something we could fix by config alone.
Kickoff to verified fix: 41 hours. Full security pass and hardening included in the same window, no separate billing.
← Back to Stopgap Digital