Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions apps/ex00_checkout_basic/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# https://dart.dev/guides/libraries/private-files
# Created by `dart pub`
.dart_tool/
.env
3 changes: 3 additions & 0 deletions apps/ex00_checkout_basic/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## 1.0.0

- Initial version.
2 changes: 2 additions & 0 deletions apps/ex00_checkout_basic/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
A sample command-line application with an entrypoint in `bin/`, library code
in `lib/`, and example unit test in `test/`.
30 changes: 30 additions & 0 deletions apps/ex00_checkout_basic/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# This file configures the static analysis results for your project (errors,
# warnings, and lints).
#
# This enables the 'recommended' set of lints from `package:lints`.
# This set helps identify many issues that may lead to problems when running
# or consuming Dart code, and enforces writing Dart using a single, idiomatic
# style and format.
#
# If you want a smaller set of lints you can change this to specify
# 'package:lints/core.yaml'. These are just the most critical lints
# (the recommended set includes the core lints).
# The core lints are also what is used by pub.dev for scoring packages.

include: package:lints/recommended.yaml

# Uncomment the following section to specify additional rules.

# linter:
# rules:
# - camel_case_types

# analyzer:
# exclude:
# - path/to/excluded/files/**

# For more information about the core and recommended set of lints, see
# https://dart.dev/go/core-lints

# For additional information about configuring this file, see
# https://dart.dev/guides/language/analysis-options
37 changes: 37 additions & 0 deletions apps/ex00_checkout_basic/bin/ex00_checkout_basic.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import 'package:ex00_checkout_basic/ex00_checkout_basic.dart'
as ex00_checkout_basic;

import 'dart:io';

void main(List<String> args) async {
final example = await ex00_checkout_basic.BasicCheckoutExample.create();

stdout.writeln('=== Basic Checkout Example ===');
stdout.writeln('Enter customer email:');
final email = stdin.readLineSync();
if (email == null || email.isEmpty) {
stderr.writeln('Email is required.');
exit(1);
}

stdout.writeln('Enter amount in Naira:');
final amountInput = stdin.readLineSync();
final amountNaira = int.tryParse(amountInput ?? '');
if (amountNaira == null || amountNaira <= 0) {
stderr.writeln('Invalid amount.');
exit(1);
}

final amountKobo = amountNaira * 100;

await example.startCheckout(email: email, amountKobo: amountKobo);

stdout.writeln('\n=== Optional: Verify payment ===');
stdout.writeln('Enter reference to verify (or press Enter to skip):');
final ref = stdin.readLineSync();
if (ref != null && ref.isNotEmpty) {
await example.verify(ref);
}

stdout.writeln('Done.');
}
63 changes: 63 additions & 0 deletions apps/ex00_checkout_basic/lib/ex00_checkout_basic.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import 'dart:io';

import 'package:dotenv/dotenv.dart';
import 'package:mind_paystack/mind_paystack.dart';

class BasicCheckoutExample {
final TransactionService transactionService;

BasicCheckoutExample({required this.transactionService});

/// Initialize transaction and print the checkout URL
Future<void> startCheckout({
required String email,
required int amountKobo,
String currency = 'NGN',
}) async {
final reference = 'txn_${DateTime.now().millisecondsSinceEpoch}';

stdout.writeln('Initializing transaction...');
final tx = await transactionService.initializeTransaction(
amount: amountKobo,
email: email,
currency: currency,
reference: reference,
);

stdout.writeln('Transaction initialized successfully!');
stdout.writeln('Reference: $reference');
stdout.writeln('Open this URL to complete payment:');
stdout.writeln(tx.authorizationUrl);
}

/// Verify transaction after payment
Future<void> verify(String reference) async {
stdout.writeln('Verifying transaction $reference...');
final verifyResponse = await transactionService.verifyTransaction(
reference,
);
stdout.writeln('Payment status: ${verifyResponse.status}');
stdout.writeln('Full response: $verifyResponse');
}

/// Factory method to create instance with credentials loaded from .env
static Future<BasicCheckoutExample> create() async {
final env = DotEnv(includePlatformEnvironment: true)..load();
final secretKey = env['PAYSTACK_SECRET_KEY'];
final publicKey = env['PAYSTACK_PUBLIC_KEY'];
if (secretKey == null || secretKey.isEmpty) {
stderr.writeln('Error: PAYSTACK_SECRET_KEY not set in .env');
exit(1);
} else if (publicKey == null || publicKey.isEmpty) {
stderr.writeln('Error: PAYSTACK_PUBLIC_KEY not set in .env');
exit(1);
}

// Here you might pass repository into TransactionService if your SDK requires it
MindPaystack.init(
PaystackConfig(publicKey: publicKey, secretKey: secretKey),
);
final mindPaystack = MindPaystack.instance;
return BasicCheckoutExample(transactionService: mindPaystack.transaction);
}
}
Loading