Skip to main content

Installation

Add to pubspec.yaml:
dependencies:
  steadpay_flutter:
    git:
      url: https://github.com/steadpay/steadpay-flutter.git

Quick start

Wrap the authenticated portion of your app in SteadpayGate:
import 'package:steadpay_flutter/steadpay_flutter.dart';

SteadpayGate(
  apiBase: 'https://api.steadpayhq.com',
  tenantSlug: 'acme',
  customerId: currentUser.stripeCustomerId,
  publishableKey: 'pk_live_abc123',
  child: YourApp(),
)
  • ActiveYourApp renders normally
  • Warning — dismissable banner above content
  • Lockout — full-screen overlay until card is updated

Parameters

ParameterTypeRequiredDefault
apiBaseString
tenantSlugString
customerIdString
publishableKeyString
pollIntervalDurationDuration(minutes: 10)
forcedStatusSteadpayStatus?null
callbacksSteadpayCallbacks?null
lockoutScreenLockoutScreenBuilder?built-in
warningBannerWarningBannerBuilder?built-in
childWidget

Callbacks

SteadpayGate(
  apiBase: 'https://api.steadpayhq.com',
  tenantSlug: 'acme',
  customerId: currentUser.stripeCustomerId,
  publishableKey: 'pk_live_abc123',
  callbacks: SteadpayCallbacks(
    onLockout: () => print('locked out'),
    onWarning: () => print('warning'),
    onActive: () => print('active'),
    onRecovered: () => print('recovered'),
    onError: (err) => print('error: $err'),
  ),
  child: YourApp(),
)
Callbacks fire on status transitions only — not on every poll tick.

Custom enforcement UI

SteadpayGate(
  // ...
  lockoutScreen: ({required triggerCardUpdate, entitlements}) =>
      MyBrandedLockout(onUpdate: triggerCardUpdate),
  warningBanner: ({required triggerCardUpdate, required dismissWarning}) =>
      MyBrandedBanner(onUpdate: triggerCardUpdate, onDismiss: dismissWarning),
  child: YourApp(),
)

Testing

Force a state

SteadpayGate(
  apiBase: 'https://api.steadpayhq.com',
  tenantSlug: 'acme',
  customerId: 'cus_test',
  publishableKey: 'pk_test_abc',
  forcedStatus: SteadpayStatus.lockout,
  child: YourApp(),
)
No network calls are made when forcedStatus is set. Remove before shipping.

Interactive sandbox

SteadpaySandbox(
  onLockout: () => print('locked out'),
  onWarning: () => print('warning'),
  onActive: () => print('active'),
  onError: (err) => print('error: $err'),
  child: YourApp(),
)
A DEV badge appears in the bottom-right corner. Tap to open a control sheet with state pills and a callback log. Remove before shipping to production.

Direct controller usage

For custom state management with Riverpod, Bloc, or other state managers:
final controller = SteadpayController(
  SteadpayConfig(
    apiBase: 'https://api.steadpayhq.com',
    tenantSlug: 'acme',
    customerId: currentUser.stripeCustomerId,
    publishableKey: 'pk_live_abc123',
  ),
)
controller.start()

StreamBuilder<SteadpayState>(
  stream: controller.stateStream,
  builder: (context, snap) { /* ... */ },
)
Call controller.dispose() when done.