Skip to content

RED-1 follow-up · Handle non-enrolled providers in the merchant settings screen #375

Description

@ericmt-98

Follow-up to RED-1 (#371 / PR #373). Filed so the regression that PR
introduces is accepted knowingly rather than discovered by a user.

Problem

RED-1 stops getOrCreateMerchantConfig from auto-creating a merchant config for
users who are not enrolled providers, which is correct: reading settings should
not silently publish someone as a cash provider. The service now throws
BadRequestError for provider_status = 'not_enrolled', and the migration
backfills every existing user to that state.

The retail app has no concept of enrollment yet, so the merchant settings screen
simply breaks. MerchantSettings.tsx:36-57 loads getMerchantConfig() and
getCurrentUser() together in one Promise.all, catches whatever fails and
renders a generic error string. After RED-1 lands, every non-enrolled user
opening Ajustes gets that error and an empty form, with nothing telling them
enrollment exists or how to start it.

The same 400 reaches updateMerchantConfigWithOfflineSupport
(api.ts:548-556) and the offline queue's direct fetch('/merchants/me/config')
(offlineQueueManager.ts:74).

Why this is a separate issue

The proper fix is the provider onboarding UI, which is RED-2, and RED-2 sits
behind RED-3, KYC-1 and CASH-7 in the queue. That is a long time to leave a
screen erroring. This issue is the smaller, unblocked piece: make the app
explain the state instead of failing into a generic error, without waiting for
the full onboarding flow.

In scope

  • Represent "not an enrolled provider" as a first-class state in the merchant
    settings screen, distinct from a network or server failure.
  • Show what the state means and what the user would gain from enrolling, in
    plain language, per docs/UX_MANIFESTO.md.
  • Stop MerchantSettings.tsx from collapsing both requests into one anonymous
    failure: a 400 from the config endpoint is a known state, not an error toast.
  • Do not queue config mutations offline for a user the backend will reject
    anyway (offlineQueueManager.ts:74).
  • Replace the read of the nonexistent verification_status field
    (MerchantSettings.tsx:44) with the real provider_status / availability
    the backend now returns.

Out of scope

  • The enrollment flow itself, its screens and its KYC steps — that is RED-2.
  • Calling POST /providers/enroll from the app. A link or a disabled
    "próximamente" affordance is enough here; wiring the action belongs with RED-2.
  • Any backend change. RED-1 owns the backend contract.

Source ownership at 312e921

Range This issue owns
micopay/frontend/src/pages/MerchantSettings.tsx:30-57 load path and the not-enrolled state
micopay/frontend/src/pages/MerchantSettings.tsx:44 replacing verification_status with the real fields
micopay/frontend/src/services/offlineQueueManager.ts:74 not queueing mutations that will be rejected

Do not change micopay/backend/src/services/merchant.service.ts or the
/providers/* routes; RED-1 owns those.

Acceptance criteria

  • A non-enrolled user opening Ajustes sees an explanation of the state, not
    a generic error message.
  • A network failure and a "not enrolled" response are still distinguishable
    on screen.
  • An enrolled provider sees the settings form exactly as before.
  • No config mutation is queued offline for a non-enrolled user.
  • verification_status no longer appears in the frontend.

Dependencies

Blocked on #373 (RED-1) merging — the backend contract has to exist first.
Superseded in part by RED-2 when that lands.

Campaign

Not labelled for Drips by default. Campaign eligibility follows the same review
as the rest of the 2026-08-26 queue (docs/AUDITORIA_CASHOUT_AGENTE_2026-08-26.md §10).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Stellar WaveEligible for Stellar Drips Wave rewardscomplexity: lowReproducible con curl/DevTools, sin setup especialwave:blockedBlocked on product or upstream dependencywave:frontendmicopay/frontend surfacewave:merchantMerchant-side flows (profile, inbox, limits)wave:retailMicoPay retail mobile app work (micopay/frontend + micopay/backend)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions