fix(guest): make Swish QR scannable on guest payment page (#22) #25

Open
hermes wants to merge 1 commit from fix/guest-qr-scannability into master
2 changed files with 16 additions and 6 deletions

View file

@ -124,12 +124,16 @@ describe('GuestPaymentRedirect', () => {
})
})
it('renders QR code after loading swish info', async () => {
it('renders QR code with spec-compliant settings', async () => {
const { wrapper } = await mountPage()
await vi.waitFor(() => {
expect(wrapper.find('.payment__qr-img').exists()).toBe(true)
})
expect(mockToDataURL).toHaveBeenCalledTimes(1)
const options = mockToDataURL.mock.calls[0][1]
expect(options.margin).toBe(4)
expect(options.width).toBe(288)
expect(options.color).toEqual({ dark: '#000000', light: '#ffffff' })
})
it('renders Swish payment link', async () => {

View file

@ -52,9 +52,15 @@ onMounted(async () => {
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
if (swishPaymentUrl.value) {
qrDataUrl.value = await QRCode.toDataURL(swishPaymentUrl.value, {
width: 224,
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
margin: 2,
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
color: { dark: '#111827', light: '#ffffff' },
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
// Swish requires a reliably scannable black-on-white QR. The previous
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
// settings (margin 2, #111827, 224px) produced a 2-module quiet zone
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
// half the QR spec minimum which the Swish app's scanner fails to
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
// read when scanning off a screen. Use the spec-compliant 4-module
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
// quiet zone, pure black, and larger modules.
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
width: 288,
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
margin: 4,
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
errorCorrectionLevel: 'M',
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
color: { dark: '#000000', light: '#ffffff' },
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
})
}
} catch {
@ -269,8 +275,8 @@ async function confirmPayment() {
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
}
.payment__qr-img {
width: 224px;
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
height: 224px;
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
width: 288px;
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
height: 288px;
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
border-radius: var(--radius-md);
margin: 0 auto var(--space-sm);
}

Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.