Bypass & Payback

This page covers the three administrative and user-facing override operations: requirements bypass (which affects float eligibility), manual payback (user-initiated early repayment), and user bans (which default active floats).

Requirements Bypass

A requirements bypass is a per-user record that allows the float creation flow to skip the standard underwriting eligibility check. It is granted by internal operations tooling and expires on a configured date.

API Endpoints

Method Path Description

GET

/{user_id}/floats/bypass

Returns the active bypass record for a user. Returns 404 if no bypass exists.

POST

/{user_id}/floats/bypass

Creates or replaces the bypass record for a user.

DELETE

/{user_id}/floats/bypass

Removes the bypass record for a user.

Request Body — POST /{user_id}/floats/bypass

Field Type Description

user_id

string (required)

The user to grant the bypass for.

expiration_date

string (required)

The date the bypass expires, in YYYY-MM-DD format. The bypass is inactive after this date.

reason

string (required)

Internal note describing why the bypass was granted.

Expiration & Effect

The bypass record is stored in the requirements-bypass DynamoDB table keyed by user_id. On float creation, the API checks whether an unexpired bypass exists. If it does:

  • The underwriting eligibility check via the Underwriting Service is skipped.

  • The fraud check still runs, but the Bypassed flag is passed to the Payments Service fraud check, which may apply relaxed rules.

  • Fraud check results are not saved back to the Payments Service for bypassed users.

The bypass is not automatically deleted when it expires — it remains in DynamoDB but is treated as inactive once expiration_date has passed. A subsequent DELETE call removes it explicitly.

See DynamoDB Tables for the full requirements-bypass schema and Fraud Detection for how bypass affects fraud checks.

Manual Payback

A user can pay back an active float before or on its due date via POST /{user_id}/floats/{float_id}/payback. The payback is routed to the Payments Service, and the float’s status is updated based on the payment method chosen.

Flow

POST /{user_id}/floats/{float_id}/payback
  {payback_option: "ACH" | "PINLESS"}
        │
        ▼
Get float from RDS
        │
        ▼
Float created >= 24 hours ago? ──No──► 404 (must wait before paying back)
Float status is COMPLETED or ACHSENT? ──Yes──► 404 (float not payable)
        │
        ▼
Acquire DynamoDB lock (prevents concurrent collection)
        │
        ▼
Calculate fee (for PINLESS / RTP floats)
        │
        ▼
Submit payment (Payments Service)
  payback_option == "ACH" ──► ACH payment request
  otherwise ──────────────── ► Pinless payment request
        │
        ├── Error / FAILED response
        │         │
        │         ▼
        │   Float status → RETRY
        │   Write collection log (process=MANUAL)
        │   Return 500
        │
        ├── ACH submitted (ACHSENT)
        │         │
        │         ▼
        │   Float status → ACHSENT
        │   Write collection log (process=MANUAL)
        │   Return 202 Accepted
        │   (status finalised async via ACH Handler on settlement)
        │
        └── Pinless collected (COMPLETED)
                  │
                  ▼
            Float status → COMPLETED
            Write collection log (process=MANUAL)
            Send digital receipt (Segment, Iterable, AppsFlyer)
            Trigger underwriting recalculation
            Return 202 Accepted
When the ACH path is chosen, the float moves to ACHSENT synchronously but is not yet COMPLETED. The ACH Handler Lambda processes the settlement callback from the prod-payments Kinesis stream and finalises the status asynchronously. See ACH Processing.

Payback for Account Reactivation

When a cancelled user reactivates their account, all past-due floats must be paid off before reactivation can proceed. This is handled by a dedicated endpoint that pays each past-due float sequentially using pinless debit only.

Endpoint

POST /{user_id}/floats/payback/reactivate

No request body. The endpoint discovers and pays all active floats whose due date has passed.

Key differences from manual payback:

  • Always uses pinless debit regardless of the float’s loan type.

  • The expected payback amount (float amount + fee) is validated before submission — a mismatch returns an error.

  • Returns the total amount collected, amount remaining, and masked card number used.

  • A 402 response indicates partial collection: at least one float was paid but another could not be collected.

See Float Lifecycle — Payback for Account Reactivation for the full multi-float flow diagram.

User Bans

When a user is banned from the FloatMe platform, the Float Service is notified via POST /{user_id}/floats/ban. This endpoint defaults any float that could still be collected, preventing further collection attempts.

Flow

POST /{user_id}/floats/ban
        │
        ▼
Get all active floats for user
  Active statuses: RETRY, DEFAULTED, SCHEDULING, ACHSENT, UNCOLLECTABLE
        │
        ├── No floats found ──► 200 (no-op)
        │
        ▼
For each float:
        │
        ├── Status is RETRY or SCHEDULING
        │         │
        │         ▼
        │   Update float status → DEFAULTED (debitID = "user_banned")
        │   Write collection log (process=SUPPORT, outcome=DEFAULTED)
        │
        └── Status is ACHSENT, DEFAULTED, or UNCOLLECTABLE
                  └── Ignored — no status change
        │
        ▼
Return 200

Floats already in ACHSENT are left in place — an in-flight ACH debit is not cancelled. The ACH Handler will update the status to COMPLETED or RETRY when the settlement callback arrives.

  • Float Lifecycle — How these operations fit into the end-to-end float state machine

  • DynamoDB Tablesrequirements-bypass and locks table schemas

  • Fraud Detection — How bypass affects fraud checks during float creation

  • ACH Processing — ACH settlement flow that finalises ACHSENT paybacks