Skip to content

bushaHQ/veem_flutter

Repository files navigation

veem_flutter

Flutter SDK for Veem Global Payments.

Wraps Veem's Web SDK in a WebView and exposes a native Flutter API. The Web SDK runs inside the WebView; Flutter widgets and an imperative present() method are the public surface. Plugin updates ship from Veem's CDN, and PCI scope stays with Veem.

Status

Plugin v1 Notes
Card This release.
Bank Undetermined.
Payee Undetermined.
Beneficial Ownership Info Undetermined.
Plaid Undetermined. Bank OAuth redirects in WebView need attention.
Identity Check Undetermined. Requires camera permissions plumbing.

Install

This package is distributed via Git, not pub.dev. Add it to your app's pubspec.yaml and pin to a release tag:

dependencies:
  veem_flutter:
    git:
      url: https://github.com/bushaHQ/veem_flutter.git
      ref: v0.1.0

Always pin ref: to a tag. Pointing it at a branch (ref: main) means every flutter pub get can silently pull new code.

Releasing

  1. Bump version: in this package's pubspec.yaml.

  2. Update CHANGELOG.md.

  3. Commit, then tag and push:

    git tag v0.1.0
    git push origin dev --tags
  4. Consuming apps bump their ref: to the new tag and run flutter pub get.

Platform setup

WebView requires platform configuration. See the webview_flutter docs for the current minimum versions.

  • iOS: minimum deployment target 12.0. No additional Info.plist entries needed for the Card plugin in v1 (camera permissions arrive with Identity Check).
  • Android: minSdkVersion 21. Internet permission is included by default.

Quick start

1. Initialize once at app startup

import 'package:veem_flutter/veem_flutter.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Veem.initialize(const VeemConfig(
    environment: VeemEnvironment.sandbox,
    clientId: 'your-veem-client-id',
  ));
  runApp(const MyApp());
}

2. Fetch per-customer credentials from your backend

Your backend calls Veem's search customer by email endpoint using your partner OAuth token and returns the resulting accountId and sessionSecret to your app. Never embed your partner token, partner secret, or any long-lived credential in the mobile binary.

3. Launch the card plugin

Modal (imperative):

final result = await Veem.card.present(
  context,
  config: CardPluginConfig(
    accountId: accountId,
    sessionSecret: sessionSecret,
    referenceId: 'order_$orderId',
    preset: const CardPreset(amount: 500, currencyCode: 'USD'),
    headerText: 'Add your card',
  ),
);

switch (result) {
  case CardPluginCompleted(:final userInputs):
    final fundingId = userInputs.paymentMethod.fundingMethod.id;
    // Send fundingId to your backend; call Create Payment API with it.
  case CardPluginExited():
    // User cancelled.
  case CardPluginErrored(:final error):
    // Surface error.message to the user.
}

Embedded widget:

VeemCardPlugin(
  config: CardPluginConfig(...),
  onCompleted: (event) { /* ... */ },
  onExited: () { /* ... */ },
  onErrored: (error) { /* ... */ },
)

4. Custom styling

Style the plugin with a typed VeemStyle. The fastest path is to derive from your Material theme:

CardPluginConfig(
  // ...
  style: VeemStyle.fromTheme(Theme.of(context)),
)

Or build one explicitly:

CardPluginConfig(
  // ...
  style: VeemStyle(
    typography: VeemTypography(
      fontFamily: 'Roboto',
      color: Color(0xFF1A1A1A),
      fontSize: 14,
    ),
    button: VeemButtonStyle(
      backgroundColor: Color(0xFF0076F7),
      color: Colors.white,
      borderRadius: 8,
      padding: EdgeInsets.symmetric(horizontal: 24, vertical: 12),
    ),
  ),
)

Colors take Flutter Colors (serialized as #RRGGBB, alpha dropped), font weights take Flutter FontWeights (mapped to numeric CSS weights), and padding takes EdgeInsets. Anything not yet typed can be passed via VeemStyle(extra: {...}) and will be merged into the output map.

Note on fonts: fontFamily must resolve in the WebView's runtime — system fonts or web-loaded fonts work, but custom fonts you bundle in your Flutter app are NOT automatically available since the WebView runs an isolated rendering context. If you need a brand font, host it as a web font and reference it by name.

The full Veem style schema is documented at https://developer.veem.com/docs/card-plugin.

Architecture

┌─────────────────────────────────────────────────┐
│  Merchant Flutter app                           │
│  ─────────────────                              │
│  Veem.initialize(VeemConfig)                    │
│  Veem.card.present(context, config)             │
│  VeemCardPlugin(config: ...)                    │
└──────────────────┬──────────────────────────────┘
                   │
                   ▼
┌─────────────────────────────────────────────────┐
│  Bridge layer (Dart)                            │
│  ─────────────────                              │
│  VeemWebView — loads assets/web/index.html      │
│  BridgeMessage — JSON envelope, both directions │
│  JavaScriptChannel('VeemHost')                  │
└──────────────────┬──────────────────────────────┘
                   │
                   ▼
┌─────────────────────────────────────────────────┐
│  WebView                                        │
│  ─────────────────                              │
│  index.html (bundled asset)                     │
│   • injected config (env, clientId, etc.)       │
│   • loads veem-web-sdk from unpkg.com           │
│   • `new Veem.WebSDK({...})` mounts plugin      │
│   • onComplete/onExit/onError → VeemHost        │
└─────────────────────────────────────────────────┘

Web SDK version pinning

VeemConfig.webSdkVersion defaults to '0', which resolves to the latest 0.x release on unpkg. For production, pin to an exact version you've tested:

const VeemConfig(
  // ...
  webSdkVersion: '0.x.y',  // replace with the version you tested
)

Otherwise a breaking change in the Web SDK can ship into your app silently the next time a user opens the plugin.

Known limitations

  • Card plugin only available. Bank, Payee, BOI, Plaid, Identity Check coming in subsequent releases.
  • No offline detection. The Web SDK loads from a CDN; the plugin won't work without network, and the error surface for that case is generic (VeemErrorCode.networkError).
  • Web SDK exact init signature. This SDK assumes the Web SDK exposes itself as window.Veem.WebSDK and accepts the config shape documented on Veem's Card Plugin page. If Veem changes that shape, the bridge in assets/web/index.html is the place to adjust.

License

MIT

About

Flutter SDK for Veem Global Payments.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors