ctechpay 0.1.0 copy "ctechpay: ^0.1.0" to clipboard
ctechpay: ^0.1.0 copied to clipboard

Official Flutter and Dart SDK for CtechPay in-app Airtel Money payments and card checkout status checks.

example/main.dart

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

void main() {
  runApp(const CtechPayExampleApp());
}

class CtechPayExampleApp extends StatelessWidget {
  const CtechPayExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'CtechPay SDK Example',
      theme: ThemeData(
        useMaterial3: true,
        colorSchemeSeed: const Color(0xFF08A9E6),
      ),
      home: const CtechPayExamplePage(),
    );
  }
}

class CtechPayExamplePage extends StatefulWidget {
  const CtechPayExamplePage({super.key});

  @override
  State<CtechPayExamplePage> createState() => _CtechPayExamplePageState();
}

class _CtechPayExamplePageState extends State<CtechPayExamplePage> {
  final ctechpay = CtechPayClient(
    token: 'YOUR_CTECHPAY_SERVICE_TOKEN',
    // baseUrl: 'https://new-api.ctechpay.com',
  );

  final phoneController = TextEditingController(text: '99XXXXXXX');
  final airtelTransactionController = TextEditingController();
  final airtelMoneyIdController = TextEditingController();
  final cardOrderReferenceController = TextEditingController();

  bool isBusy = false;
  String output = 'Ready';

  @override
  void dispose() {
    phoneController.dispose();
    airtelTransactionController.dispose();
    airtelMoneyIdController.dispose();
    cardOrderReferenceController.dispose();
    ctechpay.close();
    super.dispose();
  }

  void showOutput(Object value) {
    setState(() {
      output = value.toString();
    });
  }

  Future<void> runAction(Future<void> Function() action) async {
    if (isBusy) {
      return;
    }

    setState(() => isBusy = true);
    try {
      await action();
    } finally {
      if (mounted) {
        setState(() => isBusy = false);
      }
    }
  }

  Future<void> openFullCheckout() async {
    await Navigator.of(context).push(
      MaterialPageRoute(
        builder: (_) => CtechPayCheckoutPage(
          client: ctechpay,
          amount: 100,
          customerReference: 'APP-ORDER-1001',
          customerMessage: 'Flutter SDK test payment',
          cardSuccessUrl: 'https://example.com/payment-success',
          cardCancelUrl: 'https://example.com/payment-cancelled',
          onCompleted: (result) {
            showOutput('Airtel completed: $result');
          },
          onCardCompleted: (result) {
            showOutput('Card completed: $result');
          },
          onFailed: (error) {
            showOutput('Payment failed: $error');
          },
          onCancelled: () {
            showOutput('Payment cancelled');
          },
          onCardCheckoutUrl: (checkout) {
            cardOrderReferenceController.text = checkout.orderReference;
            showOutput('Card checkout created: $checkout');
          },
        ),
      ),
    );
  }

  Future<void> airtelPayAndPoll() async {
    showOutput('Sending Airtel Money prompt...');

    final result = await ctechpay.airtel.payAndPoll(
      amount: 100,
      phone: phoneController.text,
      customerReference: 'APP-AIRTEL-1001',
      customerMessage: 'Flutter Airtel test',
      interval: const Duration(seconds: 5),
      timeout: const Duration(seconds: 90),
      onPoll: (status) {
        showOutput('Airtel polling: $status');
      },
    );

    airtelTransactionController.text = result.transactionId;
    showOutput('Airtel final result: $result');
  }

  Future<void> checkAirtelStatus() async {
    final response = await ctechpay.airtel.status(
      airtelTransactionController.text,
    );

    showOutput(response);
  }

  Future<void> getAirtelDetails() async {
    final response = await ctechpay.airtel.details(
      airtelTransactionController.text,
    );

    showOutput(response);
  }

  Future<void> getAirtelReference() async {
    final response = await ctechpay.airtel.reference(
      airtelMoneyIdController.text,
    );

    showOutput(response);
  }

  Future<void> startCardHostedCheckout() async {
    showOutput('Creating card checkout...');

    final checkout = await ctechpay.cards.createPaymentPage(
      amount: 100,
      customerReference: 'APP-CARD-1001',
      customerMessage: 'Flutter card test',
      redirectUrl: 'https://example.com/payment-success',
      cancelUrl: 'https://example.com/payment-cancelled',
    );

    cardOrderReferenceController.text = checkout.orderReference;

    final webResult =
        await Navigator.of(context).push<CtechPayCardWebViewResult>(
      MaterialPageRoute(
        builder: (_) => CtechPayCardWebViewPage(
          initialUrl: checkout.paymentPageUrl,
          successUrl: 'https://example.com/payment-success',
          cancelUrl: 'https://example.com/payment-cancelled',
        ),
      ),
    );

    if (webResult == null || webResult.cancelled) {
      showOutput('Card payment cancelled');
      return;
    }

    if (webResult.failed) {
      showOutput('Card payment failed');
      return;
    }

    showOutput('Checking card status...');

    final result = await ctechpay.cards.pollHostedStatus(
      orderReference: checkout.orderReference,
      finalUrl: webResult.url,
      interval: const Duration(seconds: 2),
      timeout: const Duration(seconds: 20),
      maxAttempts: 5,
      onPoll: (status) {
        showOutput('Card polling: $status');
      },
    );

    showOutput('Card final result: $result');
  }

  Future<void> checkCardStatus() async {
    final response = await ctechpay.cards.status(
      cardOrderReferenceController.text,
    );

    showOutput(response);
  }

  Future<void> rawApiExample() async {
    final response = await ctechpay.post(
      '/api/v1/hosted/payment',
      payload: {
        'amount': 100,
        'customer_reference': 'RAW-SDK-1001',
        'customer_message': 'Raw SDK request',
        'redirectUrl': 'https://example.com/success',
        'cancelUrl': 'https://example.com/cancelled',
      },
    );

    showOutput(response);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('CtechPay SDK Example'),
      ),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          TextField(
            controller: phoneController,
            keyboardType: TextInputType.phone,
            decoration: const InputDecoration(
              labelText: 'Airtel phone number',
              helperText: 'Example: 0999123456 or 999123456',
              border: OutlineInputBorder(),
            ),
          ),
          const SizedBox(height: 12),
          TextField(
            controller: airtelTransactionController,
            decoration: const InputDecoration(
              labelText: 'Airtel transaction ID',
              helperText: 'Filled after Airtel Pay and Poll succeeds.',
              border: OutlineInputBorder(),
            ),
          ),
          const SizedBox(height: 12),
          TextField(
            controller: airtelMoneyIdController,
            decoration: const InputDecoration(
              labelText: 'Airtel Money ID for reference lookup',
              border: OutlineInputBorder(),
            ),
          ),
          const SizedBox(height: 12),
          TextField(
            controller: cardOrderReferenceController,
            decoration: const InputDecoration(
              labelText: 'Card order reference',
              helperText: 'Filled after card checkout is created.',
              border: OutlineInputBorder(),
            ),
          ),
          const SizedBox(height: 20),
          FilledButton(
            onPressed: isBusy ? null : openFullCheckout,
            child: const Text('Open Full Checkout Page'),
          ),
          FilledButton(
            onPressed: isBusy ? null : () => runAction(airtelPayAndPoll),
            child: const Text('Airtel Pay and Poll'),
          ),
          OutlinedButton(
            onPressed: isBusy ? null : () => runAction(checkAirtelStatus),
            child: const Text('Check Airtel Status'),
          ),
          OutlinedButton(
            onPressed: isBusy ? null : () => runAction(getAirtelDetails),
            child: const Text('Get Airtel Details'),
          ),
          OutlinedButton(
            onPressed: isBusy ? null : () => runAction(getAirtelReference),
            child: const Text('Get Airtel Reference'),
          ),
          FilledButton(
            onPressed: isBusy ? null : () => runAction(startCardHostedCheckout),
            child: const Text('Start Card Hosted Checkout'),
          ),
          OutlinedButton(
            onPressed: isBusy ? null : () => runAction(checkCardStatus),
            child: const Text('Check Card Status'),
          ),
          OutlinedButton(
            onPressed: isBusy ? null : () => runAction(rawApiExample),
            child: const Text('Raw API Request Example'),
          ),
          const SizedBox(height: 20),
          const Text(
            'Output',
            style: TextStyle(fontWeight: FontWeight.bold),
          ),
          const SizedBox(height: 8),
          Container(
            width: double.infinity,
            padding: const EdgeInsets.all(12),
            decoration: BoxDecoration(
              color: const Color(0xFFEAF8FD),
              borderRadius: BorderRadius.circular(12),
              border: Border.all(color: const Color(0xFFBFE9F8)),
            ),
            child: SelectableText(output),
          ),
        ],
      ),
    );
  }
}
1
likes
130
points
77
downloads

Documentation

API reference

Publisher

verified publisherctechpay.com

Weekly Downloads

Official Flutter and Dart SDK for CtechPay in-app Airtel Money payments and card checkout status checks.

Homepage
Repository (GitHub)

License

MIT (license)

Dependencies

flutter, http, webview_flutter, webview_flutter_android, webview_flutter_wkwebview

More

Packages that depend on ctechpay