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

Official Dart/Flutter client for the Paperfly (Bangladesh) merchant courier API — create parcels, exchange orders, track shipments, cancel orders, and parse webhook events.

example/lib/main.dart

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

void main() => runApp(const PaperflyExampleApp());

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Paperfly Courier Example',
      theme: ThemeData(colorSchemeSeed: Colors.blue, useMaterial3: true),
      home: const CreateParcelPage(),
    );
  }
}

/// Demonstrates creating a parcel and then tracking or cancelling it.
///
/// Replace the placeholder credentials below with your own merchant
/// username, password, and `paperflykey` header value (Developer &
/// Plugins → API Docs in the merchant dashboard). Never ship real
/// credentials inside a client app you distribute publicly — call
/// Paperfly through your own backend instead, and use this page only as
/// a reference for the request/response shapes.
class CreateParcelPage extends StatefulWidget {
  const CreateParcelPage({super.key});

  @override
  State<CreateParcelPage> createState() => _CreateParcelPageState();
}

class _CreateParcelPageState extends State<CreateParcelPage> {
  final _formKey = GlobalKey<FormState>();
  final _nameController = TextEditingController(text: 'Jane Doe');
  final _phoneController = TextEditingController(text: '01700000000');
  final _addressController =
      TextEditingController(text: 'House 12, Road 5, Banani, Dhaka');
  final _productController = TextEditingController(text: 'Blue T-Shirt (L)');
  final _priceController = TextEditingController(text: '590');
  final _weightController = TextEditingController(text: '0.5');

  late final PaperflyClient _client = PaperflyClient(
    merchantUsername: 'YOUR_MERCHANT_USERNAME',
    merchantPassword: 'YOUR_MERCHANT_PASSWORD',
    paperflyKey: 'YOUR_PAPERFLY_KEY',
  );

  bool _loading = false;
  String? _resultText;
  String? _lastReference;

  @override
  void dispose() {
    _client.close();
    _nameController.dispose();
    _phoneController.dispose();
    _addressController.dispose();
    _productController.dispose();
    _priceController.dispose();
    _weightController.dispose();
    super.dispose();
  }

  Future<void> _createParcel() async {
    if (!_formKey.currentState!.validate()) return;
    setState(() {
      _loading = true;
      _resultText = null;
    });

    final reference = 'ORDER-${DateTime.now().millisecondsSinceEpoch}';
    try {
      final order = await _client.createOrder(
        PaperflyOrderRequest(
          merchantOrderReference: reference,
          storeName: 'My Shop',
          productBrief: _productController.text,
          packagePrice: num.parse(_priceController.text),
          maxWeight: num.parse(_weightController.text),
          customerName: _nameController.text,
          customerAddress: _addressController.text,
          customerPhone: _phoneController.text,
        ),
      );
      setState(() {
        _lastReference = reference;
        _resultText = 'Created ${order.trackingNumber} '
            '(barcode ${order.trackingBarcode})';
      });
    } on PaperflyException catch (e) {
      setState(() => _resultText = 'Error: $e');
    } finally {
      setState(() => _loading = false);
    }
  }

  Future<void> _trackParcel() async {
    final reference = _lastReference;
    if (reference == null) return;
    setState(() {
      _loading = true;
      _resultText = null;
    });
    try {
      final tracking = await _client.trackOrder(reference);
      final timeline = tracking.latest?.timeline ?? const [];
      setState(() {
        _resultText = timeline.isEmpty
            ? 'No tracking milestones yet.'
            : timeline.map((m) => '${m.stage}: ${m.time}').join('\n');
      });
    } on PaperflyException catch (e) {
      setState(() => _resultText = 'Error: $e');
    } finally {
      setState(() => _loading = false);
    }
  }

  Future<void> _cancelParcel() async {
    final reference = _lastReference;
    if (reference == null) return;
    setState(() {
      _loading = true;
      _resultText = null;
    });
    try {
      final cancelled = await _client.cancelOrder(reference);
      setState(() => _resultText = cancelled.message);
    } on PaperflyException catch (e) {
      setState(() => _resultText = 'Error: $e');
    } finally {
      setState(() => _loading = false);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Create Paperfly Parcel')),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16),
        child: Form(
          key: _formKey,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              TextFormField(
                controller: _nameController,
                decoration: const InputDecoration(labelText: 'Customer name'),
                validator: (v) => (v == null || v.isEmpty) ? 'Required' : null,
              ),
              const SizedBox(height: 8),
              TextFormField(
                controller: _phoneController,
                decoration: const InputDecoration(labelText: 'Customer phone'),
                validator: (v) => (v == null || v.isEmpty) ? 'Required' : null,
              ),
              const SizedBox(height: 8),
              TextFormField(
                controller: _addressController,
                decoration:
                    const InputDecoration(labelText: 'Customer address'),
                validator: (v) => (v == null || v.isEmpty) ? 'Required' : null,
              ),
              const SizedBox(height: 8),
              TextFormField(
                controller: _productController,
                decoration: const InputDecoration(labelText: 'Product brief'),
                validator: (v) => (v == null || v.isEmpty) ? 'Required' : null,
              ),
              const SizedBox(height: 8),
              TextFormField(
                controller: _priceController,
                decoration:
                    const InputDecoration(labelText: 'Package price (BDT)'),
                keyboardType: TextInputType.number,
                validator: (v) =>
                    num.tryParse(v ?? '') == null ? 'Enter a number' : null,
              ),
              const SizedBox(height: 8),
              TextFormField(
                controller: _weightController,
                decoration: const InputDecoration(labelText: 'Weight (kg)'),
                keyboardType: TextInputType.number,
                validator: (v) =>
                    num.tryParse(v ?? '') == null ? 'Enter a number' : null,
              ),
              const SizedBox(height: 16),
              FilledButton(
                onPressed: _loading ? null : _createParcel,
                child: const Text('Create parcel'),
              ),
              const SizedBox(height: 8),
              Row(
                children: [
                  Expanded(
                    child: OutlinedButton(
                      onPressed:
                          (_loading || _lastReference == null) ? null : _trackParcel,
                      child: const Text('Track'),
                    ),
                  ),
                  const SizedBox(width: 8),
                  Expanded(
                    child: OutlinedButton(
                      onPressed: (_loading || _lastReference == null)
                          ? null
                          : _cancelParcel,
                      child: const Text('Cancel'),
                    ),
                  ),
                ],
              ),
              const SizedBox(height: 16),
              if (_loading) const Center(child: CircularProgressIndicator()),
              if (_resultText != null) Text(_resultText!),
            ],
          ),
        ),
      ),
    );
  }
}
0
likes
160
points
63
downloads

Documentation

Documentation
API reference

Publisher

verified publishercarboncodes.net

Weekly Downloads

Official Dart/Flutter client for the Paperfly (Bangladesh) merchant courier API — create parcels, exchange orders, track shipments, cancel orders, and parse webhook events.

Repository (GitHub)
View/report issues

Topics

#courier #shipping #paperfly #ecommerce #bangladesh

License

MIT (license)

Dependencies

http

More

Packages that depend on paperfly_courier