Card expiration input is greyed out at checkout

Objective

  • Let clients complete credit card payments on the client portal by reliably selecting expiration month and year on pay-beta checkout.
  • Remove false impressions that expiration is locked (greyed out) when the form should be editable for all portal visitors—clients and staff opening the same portal from a work order.

Background

  • Field report: expiration appeared greyed out with confusing “zeros and ones”; client could not choose month/year. Example property: 3180 Halifax Dr (job for tomorrow). Client: Lisa Conklin (762-699-0402 per Slack report).
  • Slack report / transcript
  • Checkout path: Attik confirmed jobs with Guardian enabled → /client/job/{slug}/pay-betaCredit Card tab (PaymentBetaClientCreditCardTab).
  • Code review (no role-based lock): Month and Year are separate HeroUI Select fields in CreditCardTab.tsx. They are not isDisabled in code, not gated on card number length (no requirement for 12 or 16 digits before expiry is editable), and not different for clients vs internal users—staff open the same client portal URL (often with access_token from the work order) and the same pay-beta page.
  • Card number validation (13–19 digits, Luhn) runs on Pay submit only, not to enable expiry fields. Only the Pay button disables when payment amount or billing ZIP is invalid.
  • Likely repro gap: Internal repro on desktop may succeed while the client was on phone (per support call). Plausible causes to validate: mobile Safari/Chrome + HeroUI Select (popover open/close, blur-on-scroll), browser/password-manager autofill overlaying grey read-only expiration UI, or broken interaction with Select refs (typed as HTMLSelectElement but not a native <select>). Expiry fields also lack autoComplete="cc-exp-month" / cc-exp-year" while card number and CVV have autocomplete hints.
  • Client quote (from report): “Yeah, you can't put it in there, it's just all zeros and one… my card expires in November I just went down eleven spaces… I have no way of guessing what the years are cause it's zeroes in one.”

Scope

Frontend

  • Primary UI: attik-frontend/src/app/client/job/[slug]/pay-beta/components/CreditCardTab.tsx — Month/Year Select + SelectItem (~lines 584–642); card Input; CVV Input; submit handler and validation in same file.
  • Host page: attik-frontend/src/app/client/job/[slug]/pay-beta/PaymentBetaClient.tsx, page.tsx (Guardian gate, access_token / portalPayerId for logging only—not form disable logic).
  • Portal entry from job: attik-frontend/src/app/client/job/[slug]/components/JobAccordion.tsx (pay-beta link); staff portal open: attik-frontend/src/app/tools/inspections/[id]/components/WorkorderActionsDropdown.tsx (same client URL in new tab).
  • Payment submit: attik-frontend/src/app/client/job/[slug]/pay-beta/actions/processCardPayment.ts → backend guardian-payments/process-card (expiry MMYY).
  • Existing tests: tests/app/client/job/pay-beta/CreditCardTab.fee.test.tsx (fees only); no mobile/expiry interaction coverage today.

Backend

  • Card processing and expiry format validation: attik-backend/src/routes/guardianPayments.ts (expects expiry as 4-digit MMYY on submit). Unlikely root cause of greyed UI, but confirm end-to-end after frontend fix.

Investigation outcomes (draft acceptance)

  • [ ] Reproduce on mobile Safari and desktop Chrome using same job slug / pay-beta URL.
  • [ ] Confirm whether failure is HeroUI Select, autofill overlay, or other—and document client device/browser when possible.
  • [ ] Fix so Month/Year are reliably selectable on supported client devices; add regression test where feasible.
  • [ ] Optional hardening: textValue on SelectItem, expiry autoComplete, consistent 2-digit year handling in validateExpiry vs year option keys.

Out of scope (unless investigation proves otherwise)

  • Spectora-native payment path (Spectora jobs are blocked from Guardian pay-beta).
  • Requiring a specific card length before enabling expiry (not current behavior; do not add unless product asks).

References

  • Slack report / client transcript
  • attik-frontend/src/app/client/job/[slug]/pay-beta/components/CreditCardTab.tsx
  • attik-frontend/src/app/client/job/[slug]/pay-beta/PaymentBetaClient.tsx
  • attik-frontend/src/app/client/job/[slug]/pay-beta/page.tsx
  • attik-frontend/src/app/client/job/[slug]/pay-beta/actions/processCardPayment.ts
  • attik-backend/src/routes/guardianPayments.ts

Please authenticate to join the conversation.

Upvoters
Status

Planned

Board
🏠

Main App

Date

12 days ago

Author

Linear

Subscribe to post

Get notified by email when there are changes.