fix(payment): make Swish QR code scannable by the Swish app #16
Open
hermes
wants to merge 2 commits from
fix/swish-qr-scannability into master
pull from: fix/swish-qr-scannability
merge into: jocke:master
jocke:master
jocke:feature/guest-checkout
jocke:feature/swish-qr-payment
jocke:develop
jocke:feature/auto-version-from-tag
jocke:fix/admin-table-styling
jocke:feature/expired-token-logout
jocke:chore/dockerfile-self-contained
jocke:chore/pre-commit-coverage-thresholds
jocke:feature/umami-analytics
jocke:refactor/admin-fulfillment
jocke:feature/admin-fulfillment-tracking
jocke:feature/account-settings-dropdown
jocke:feature/cancel-edit-pending-orders
2 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
f849f8a05a |
test(payment): add unit tests for buildSwishPaymentUrl and number normalisation
The PR added + stripping to normalizeSwishNumber and the PaymentRedirect
regression assertion verifies QR options, but payment.ts had no dedicated
test file — coverage was only 50% (only the payOrder path exercised via
mocks in PaymentRedirect.spec.ts). This adds a focused spec covering every
normalisation branch (Swedish national, international, + prefix, Swish
Business, whitespace) and URL construction (amount formatting, message
encoding, base URL). Coverage for payment.ts rises from 50% to ~90%.
Why: jocke pointed out that CI was failing on this PR and that I should
always verify CI passes before considering work done. Investigation
showed all frontend steps pass locally (lint, vue-tsc, 277/277 tests,
coverage). The 2h17m CI failure appears to be a transient runner issue
in the backend-coverage step (backend code is unchanged from master,
which passes CI; E2E also passes). This commit re-triggers CI and
fills the + stripping test gap noticed during the investigation.
Changes:
- Add frontend/src/__tests__/payment.spec.ts (8 tests):
- Number normalisation: Swedish national (07xx), international (4670xx),
+ prefix stripping, Swish Business (123xx), whitespace removal
- URL construction: amount with two decimal places, message URL-encoding,
correct Swish C2B base URL
- payment.ts statement coverage: 50% to ~90%
- Total frontend tests: 269 to 277
|
||
|
|
573153b47a |
fix(payment): make Swish QR code scannable by the Swish app
The Swish QR on the payment page could not be scanned by the Swish app in production. The QR encoded the correct C2B pre-fill URL (verified against https://developer.swish.nu and the live /payment/swish-info endpoint returning the real Swish number), and the Swish app does support scanning C2B pre-fill QR codes per the "Swish C2B flow with QR code" guide - so the failure was in the QR *rendering*, not the URL or approach. Root cause: the qrcode options used a 2-module quiet zone (margin: 2), half the ISO/IEC 18004 minimum of 4 modules. The Swish app's scanner is stricter than a phone camera and failed to lock onto the finder patterns, especially when scanning the QR off a screen. Compounded by an off-black fill (#111827 vs pure black; the Swish spec says "black and white") and small ~5px modules at width 224. Changes: - PaymentRedirect.vue: QR options margin 2->4, dark #111827->#000000, width 224->288, explicit errorCorrectionLevel 'M'; .payment__qr-img CSS width/height 224->288 to match. - PaymentRedirect.vue: isolate QR generation in its own try/catch so a QR failure degrades gracefully (Swish link + manual fallback remain) instead of surfacing the "Kunde inte ladda betalningsinformation" error from the shared fetchSwishInfo catch. - payment.ts: normalizeSwishNumber strips a leading "+" (+46... -> 46...), so a number stored in international-with-plus form no longer leaks a "+" into the sw param. - PaymentRedirect.spec.ts: regression assertion that toDataURL is called with margin 4, errorCorrectionLevel 'M', and pure black/white. Verified locally: eslint clean on the 3 files, 269/269 vitest tests pass, vue-tsc clean for changed files (the lone tsc error on this machine is the unrelated untracked useSeo.ts WIP, not committed). |