Skip to content

Flutter / Dart SDK

Flutter 3.10+   Dart 3+

Pure Dart SDK — no code generation required. Works in Flutter apps (iOS, Android, Web, Desktop) and Dart server/CLI projects.

Install

yaml
# pubspec.yaml
dependencies:
  astro_sdk:
    git:
      url: https://github.com/Tellesy/neptune-astro.git
      path: packages/astro-flutter
  # Once published to pub.dev:
  # astro_sdk: ^1.0.0
bash
flutter pub get

Quick Start

dart
import 'package:astro_sdk/astro_sdk.dart';

final astro = AstroClient(AstroConfig(
  baseUrl: Uri.parse('https://astro.neptune.ly/api/v1'),
  merchantKey: const String.fromEnvironment('ASTRO_KEY'),
));

// Create a payment session (server-side / secure context only)
final session = await astro.payments.createSession(
  amount: 50000,           // 50.000 LYD
  currency: 'LYD',
  destination: Destination(type: 'alias', value: 'mtellesy'),
  reference: 'order_1042',
  redirectUrl: 'myapp://payment/result',
);

print('Checkout URL: ${session.checkoutUrl}');

Payments

dart
// Get session status
final updated = await astro.payments.getSession(session.sessionId);
print(updated.status); // PENDING | PROCESSING | COMPLETED | FAILED

// List sessions
final sessions = await astro.payments.listSessions(status: 'COMPLETED');

// Cancel
await astro.payments.cancelSession(session.sessionId);

// Recurring mandate
final mandate = await astro.payments.createMandate(
  customerAlias: 'mtellesy',
  amount: 5000,
  currency: 'LYD',
  interval: 'monthly',
  description: 'Monthly subscription',
  startDate: '2026-05-01',
);

Opening the Checkout URL

The customer must complete payment in the Astro checkout UI. Open session.checkoutUrl externally:

dart
import 'package:url_launcher/url_launcher.dart';

await launchUrl(
  Uri.parse(session.checkoutUrl),
  mode: LaunchMode.externalApplication,
);

Then handle the deep link callback when Astro redirects back:

dart
// In your GoRouter / auto_route callback:
// redirect_url was set to 'myapp://payment/result'
// Parse the result from the query parameters

void onCallback(Uri uri) {
  if (uri.host == 'payment' && uri.path == '/result') {
    final status = uri.queryParameters['status'];
    final sessionId = uri.queryParameters['session_id'];

    if (status == 'completed') {
      // Verify on your backend, then fulfil order
      Navigator.pushReplacementNamed(context, '/order/success', arguments: sessionId);
    } else {
      Navigator.pushReplacementNamed(context, '/order/failed');
    }
  }
}

Alias Resolution

dart
// Resolve an alias to IBAN + bank
final resolved = await astro.alias.resolve('mtellesy');
print('${resolved.bankHandle}: ${resolved.iban}');

// Get linked accounts
final accounts = await astro.alias.getAccounts('mtellesy');

Open Banking

dart
import 'package:astro_sdk/astro_sdk.dart';
import 'package:url_launcher/url_launcher.dart';

// 1. Create consent (requires bank partner key)
final consent = await astro.openBanking.createConsent(
  bankHandle: 'andalus',
  scopes: ['accounts:read', 'transactions:read'],
  redirectUri: 'myapp://ob/callback',
  state: generateState(),
  codeChallenge: pkce.challenge,
);

// 2. Open consent URL
await launchUrl(Uri.parse(consent.consentUrl), mode: LaunchMode.externalApplication);

// 3. Handle callback deep link and exchange code
final tokens = await astro.openBanking.exchangeCode(
  code: callbackUri.queryParameters['code']!,
  redirectUri: 'myapp://ob/callback',
  consentId: consent.consentId,
  codeVerifier: pkce.verifier,
);

// 4. Fetch account data
final accounts = await astro.openBanking.getAccounts(tokens.accessToken, consent.consentId);
final txns = await astro.openBanking.getTransactions(
  tokens.accessToken, consent.consentId, accounts.first.accountId,
);

Webhook Verification (Dart server)

dart
import 'package:astro_sdk/astro_sdk.dart';
import 'package:shelf/shelf.dart';

final verifier = WebhookVerifier(
  secret: Platform.environment['ASTRO_WEBHOOK_SECRET']!,
);

Handler webhookHandler = (Request request) async {
  final body = await request.readAsString();
  final sig = request.headers['x-openwave-signature'] ?? '';

  verifier.handleRaw(body, sig, {
    'payment.completed': (payload) {
      final ref = (payload['data'] as Map)['reference'] as String?;
      db.markPaid(ref);
    },
  });
  return Response.ok('ok');
};

Error Handling

dart
try {
  final session = await astro.payments.createSession(...);
} on AstroError catch (e) {
  print('${e.statusCode}: [${e.code}] ${e.message}');
  if (e.statusCode == 422) {
    // Insufficient funds — show user-friendly message
  }
}

Source

packages/astro-flutter/ in the neptune-astro repo.

Built on the OpenWave open standard.