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 200

View on GitHub (pinned to e69894adb9)

Solutions

  1. Direct the user to their SimpleFin bridge billing page to restore the subscription
  2. Verify which institution triggered it — sometimes only one bank is behind the paywall
  3. Pause scheduled syncs for that connection until payment is resolved to avoid repeat failures
  4. 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

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


AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21). Data as JSON: /api/errors/9ae0e00999fba9c1. Report an issue: GitHub.