credo_flutter 1.0.0 copy "credo_flutter: ^1.0.0" to clipboard
credo_flutter: ^1.0.0 copied to clipboard

Official Credo checkout SDK for Flutter.

Credo Flutter SDK #

A Flutter SDK for integrating Credo payment gateway into your mobile app.

Installation #

Add to your pubspec.yaml:

dependencies:
  credo_flutter: ^1.0.0

Quick Start #

If your backend initializes transactions and provides a checkout URL, you can use open() directly — no SDK configuration required:

import 'package:credo_flutter/credo_flutter.dart';

// Your backend initializes the transaction and returns a checkout URL
final checkoutUrl = await yourBackend.initializePayment();

final result = await CredoCheckout.open(
  context,
  checkoutUrl: checkoutUrl,
);

if (result.isSuccess) {
  print('Payment successful: ${result.transaction?.reference}');
} else if (result.isCancelled) {
  print('User cancelled');
} else {
  print('Payment failed: ${result.transaction?.message}');
}

Option B: Initialize and pay in one call #

If you want the SDK to initialize transactions (simpler but exposes your public key in the app), configure the SDK first:

import 'package:credo_flutter/credo_flutter.dart';

void main() {
  // Required only for CredoCheckout.pay()
  CredoCheckout.configure(
    publicKey: 'your_public_key',
    environment: CredoEnvironment.demo, // or .live for production
  );

  runApp(MyApp());
}

Then use pay():

final result = await CredoCheckout.pay(
  context,
  PaymentInitConfig(
    amount: 10000, // Amount in lowest unit (kobo for NGN)
    email: 'customer@example.com',
    currency: Currency.ngn,
    bearer: FeeBearer.customer,
    reference: 'unique_transaction_ref', // Optional
  ),
);

if (result.isSuccess) {
  print('Payment successful: ${result.transaction?.reference}');
} else if (result.isCancelled) {
  print('User cancelled');
} else {
  print('Payment failed: ${result.transaction?.message}');
}

Configuration Options #

CredoCheckout.configure() #

Parameter Type Required Description
publicKey String Yes Your Credo public key
environment CredoEnvironment No .demo or .live (default: .live)
debug bool No Enable debug logging (default: false)

PaymentInitConfig #

Parameter Type Required Description
amount int Yes Amount in lowest currency unit (kobo/cents)
email String Yes Customer email address
currency Currency Yes .ngn or .usd
bearer FeeBearer Yes .customer or .merchant
reference String? No Unique transaction reference
channels List<PaymentChannel>? No Allowed payment channels
customerPhoneNumber String? No Customer phone number
customerFirstName String? No Customer first name
customerLastName String? No Customer last name
callbackUrl String? No URL for redirect after payment
metadata TransactionMetadata? No Additional transaction data
narration String? No Transaction description

Payment Channels #

PaymentInitConfig(
  // ...
  channels: [
    PaymentChannel.card,
    PaymentChannel.bank,
    PaymentChannel.ussd,
    PaymentChannel.wallet,
    PaymentChannel.opay,
    PaymentChannel.payoutlet,
  ],
)

Handling Results #

final result = await CredoCheckout.pay(context, config);

switch (result.status) {
  case CheckoutStatus.success:
    // Payment successful
    final txn = result.transaction!;
    print('Amount: ${txn.amount} ${txn.currency}');
    print('Reference: ${txn.reference}');
    break;

  case CheckoutStatus.failed:
    // Payment failed
    print('Error: ${result.transaction?.message}');

    // Check for field-specific validation errors
    if (result.hasFieldErrors) {
      result.fieldErrors!.forEach((field, error) {
        print('$field: $error');
      });
    }
    break;

  case CheckoutStatus.cancelled:
    // User cancelled the checkout
    break;

  case CheckoutStatus.unknown:
    // Unknown state (e.g., timeout)
    break;
}

CheckoutResult Properties #

Property Type Description
status CheckoutStatus success, failed, cancelled, unknown
transaction TransactionDetails? Transaction details from gateway
fieldErrors Map<String, String>? Field-specific validation errors
reference String? Transaction reference (convenience getter)
isSuccess bool Whether payment succeeded
isFailure bool Whether payment failed
isCancelled bool Whether user cancelled
hasFieldErrors bool Whether validation errors exist

TransactionDetails Properties #

Property Type Description
reference String? Merchant transaction reference
transRef String? Credo transaction reference
amount double? Transaction amount
currency String? Currency code
processorFee double? Fee charged
message String? Status message

CredoWebview Widget #

For full control over how the checkout is presented, use CredoWebview directly. Embed it in a modal bottom sheet, a custom page with your own AppBar, or anywhere in your widget tree.

In a Modal Bottom Sheet #

showModalBottomSheet(
  context: context,
  isScrollControlled: true,
  useSafeArea: true,
  builder: (sheetContext) => SizedBox(
    height: MediaQuery.of(sheetContext).size.height * 0.9,
    child: Column(
      children: [
        AppBar(
          title: const Text('Checkout'),
          leading: IconButton(
            icon: const Icon(Icons.close),
            onPressed: () => Navigator.pop(sheetContext),
          ),
        ),
        Expanded(
          child: CredoWebview(
            checkoutUrl: checkoutUrl,
            onResult: (result) {
              Navigator.pop(sheetContext);
              // Handle result
            },
          ),
        ),
      ],
    ),
  ),
);

In a Custom Page #

Scaffold(
  appBar: AppBar(title: const Text('Pay')),
  body: CredoWebview(
    checkoutUrl: checkoutUrl,
    onResult: (result) {
      Navigator.pop(context);
      // Handle result
    },
    onLoadingChanged: (isLoading) {
      // Show/hide your own loading indicator
    },
    timeout: const Duration(minutes: 5),
  ),
)

CredoWebview Properties #

Parameter Type Required Description
checkoutUrl String Yes The checkout URL to load
onResult ValueChanged<CheckoutResult> Yes Called exactly once when checkout completes
onLoadingChanged ValueChanged<bool>? No Called when loading state changes
timeout Duration? No Auto-complete with unknown after timeout

Note: CredoWebview does not require configure() — it works with any valid checkout URL.

Advanced Features #

Split Payments #

Configure split settlements for marketplace scenarios:

PaymentInitConfig(
  // ...
  splitConfiguration: [
    SplitEntry(
      accountId: '0441234567890', // Bank code + account number
      splitType: SplitType.percentage,
      splitValue: 10,
      isDefault: true,
    ),
    SplitEntry(
      accountId: '0449876543210',
      splitType: SplitType.flat,
      splitValue: 500, // Flat amount
      isDefault: false,
    ),
  ],
)

Custom Metadata #

PaymentInitConfig(
  // ...
  metadata: TransactionMetadata(
    customFields: [
      CustomField(
        variableName: 'orderId',
        value: 'ORD-12345',
        displayName: 'Order ID',
      ),
    ],
  ),
)

Timeout #

Set a timeout for the checkout session:

final result = await CredoCheckout.pay(
  context,
  config,
  timeout: const Duration(minutes: 5),
);

Debug Logging #

Enable debug mode to see detailed logs:

CredoCheckout.configure(
  publicKey: 'your_key',
  environment: CredoEnvironment.demo,
  debug: true, // Enable logging
);

This logs:

  • HTTP requests and responses
  • WebView navigation events
  • Gateway messages
  • Errors with details

View logs in Flutter DevTools or your IDE's debug console.

Error Handling #

Network Errors #

final result = await CredoCheckout.pay(context, config);

if (result.isFailure) {
  final message = result.transaction?.message;

  if (message?.contains('Network error') == true) {
    // Handle network issues
  }
}

Validation Errors #

The API may return field-specific errors:

if (result.hasFieldErrors) {
  // Example: {"reference": "Reference must be unique"}
  result.fieldErrors!.forEach((field, error) {
    showFieldError(field, error);
  });
}

Platform Setup #

Android #

Add internet permission to android/app/src/main/AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET"/>

iOS #

No additional setup required.

Example App #

See the example directory for a complete working example.

import 'package:flutter/material.dart';
import 'package:credo_flutter/credo_flutter.dart';

void main() {
  CredoCheckout.configure(
    publicKey: 'your_public_key',
    environment: CredoEnvironment.demo,
  );
  runApp(MyApp());
}

class PaymentPage extends StatelessWidget {
  Future<void> _pay(BuildContext context) async {
    final result = await CredoCheckout.pay(
      context,
      PaymentInitConfig(
        amount: 50000, // 500 NGN
        email: 'customer@example.com',
        currency: Currency.ngn,
        bearer: FeeBearer.customer,
      ),
    );

    if (result.isSuccess) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Payment successful!')),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: () => _pay(context),
      child: Text('Pay Now'),
    );
  }
}
0
likes
150
points
68
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Official Credo checkout SDK for Flutter.

Homepage
Repository (GitHub)
View/report issues

Topics

#payments #checkout #flutter #fintech #sdk

License

BSD-3-Clause (license)

Dependencies

flutter, http, webview_flutter

More

Packages that depend on credo_flutter