we-promise/sure · error · Provider::Simplefin::SimplefinError
payment_required
payment_required
Error message
Payment required to access this account
What it means
Raised by Provider::Simplefin#get_accounts when the accounts endpoint returns 402 Payment Required, with error_type :payment_required. SimpleFin bridges use 402 when the account/bridge requires payment — typically a lapsed bridge subscription or an institution tier not covered by the user's plan.
Source
Thrown at app/models/provider/simplefin.rb:94
accounts_url += "?#{URI.encode_www_form(query_params)}" unless query_params.empty?
# The access URL already contains HTTP Basic Auth credentials
# Use retry logic with exponential backoff for transient network failures
# Use self.class.get to inherit class-level SSL and timeout defaults
response = with_retries("GET /accounts") do
self.class.get(accounts_url)
end
case response.code
when 200
JSON.parse(response.body, symbolize_names: true)
when 400
Rails.logger.error "SimpleFin API: Bad request - #{response.body}"
raise SimplefinError.new("Bad request to SimpleFin API: #{response.body}", :bad_request)
when 403
raise SimplefinError.new("Access URL is no longer valid", :access_forbidden)
when 402
raise SimplefinError.new("Payment required to access this account", :payment_required)
when 429
Rails.logger.warn "SimpleFin API: Rate limited - #{response.body}"
raise SimplefinError.new("SimpleFin rate limit exceeded. Please try again later.", :rate_limited)
when 500..599
Rails.logger.error "SimpleFin API: Server error - Code: #{response.code}, Body: #{response.body}"
raise SimplefinError.new("SimpleFin server error (#{response.code}). Please try again later.", :server_error)
else
Rails.logger.error "SimpleFin API: Unexpected response - Code: #{response.code}, Body: #{response.body}"
raise SimplefinError.new("Failed to fetch accounts: #{response.code} #{response.message} - #{response.body}", :fetch_failed)
end
end
def get_info(base_url)
# Use self.class.get to inherit class-level SSL and timeout defaults
response = self.class.get("#{base_url}/info")
case response.code
when 200View on GitHub (pinned to e69894adb9)
Solutions
- Direct the user to their SimpleFin bridge billing page to restore the subscription
- Verify which institution triggered it — sometimes only one bank is behind the paywall
- Pause scheduled syncs for that connection until payment is resolved to avoid repeat failures
- Rescue :payment_required separately from :access_forbidden so the user gets the right 'billing' message
Defensive patterns
Strategy: try-catch
Type guard
def simplefin_payment_required?(error) error.is_a?(Provider::Simplefin::SimplefinError) && error.error_type == :payment_required end
Try / catch
begin client.get_accounts(access_url) rescue Provider::Simplefin::SimplefinError => e raise unless e.error_type == :payment_required pause_connection!(reason: "simplefin_billing") # user action required; stop scheduling end
Prevention
- Map :payment_required to a billing-specific user message, distinct from auth failures
- Pause the connection's sync schedule after the first 402 rather than burning retries daily
- Surface which institution is affected so the user knows what to pay for
When it happens
Trigger: Calling get_accounts after the user's SimpleFin bridge subscription expired or the linked institution moved to a paid tier the user hasn't purchased.
Common situations: Trial bridges converting to paid; subscription card expiring mid-cycle; self-hosted bridge users lacking an institution license.
Related errors
- Please provide a name and a complete US address (street, cit
- token_compromised
- claim_failed
- bad_request
- access_forbidden
AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21).
Data as JSON: /api/errors/9ae0e00999fba9c1.
Report an issue: GitHub.