dtb_link 0.1.23+44 copy "dtb_link: ^0.1.23+44" to clipboard
dtb_link: ^0.1.23+44 copied to clipboard

DTB Link - utility app enabling applications to connect and integrate with NFC card readers over Bluetooth

example/lib/main.dart

import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:dtb_link/dtb_link.dart';

enum EasyKey { sKey, echo, saleTran, voidTran }

typedef OnDevice = Function;

void main() {
  runApp(const MaterialApp(home: MyApp()));
}

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _platformVersion = 'Unknown';
  DtbLink dtbLink = DtbLink();
  DataInitRet? initData;
  List<BluetoothDevice> deviceList = [];
  TextEditingController controller = TextEditingController();
  ScrollController scrollController = ScrollController();
  OnDevice? onDevice;
  Map<String, dynamic>? lastTran;
  InitType type = InitType.production;

  @override
  void initState() {
    super.initState();
    dtbLink.dtbLibInit(const bool.fromEnvironment("dart.vm.product") ? InitType.production : InitType.staging);
    WidgetsBinding.instance.addPostFrameCallback((_) {
      dtbLink.terminalInitData().then((data) {
        debugPrint("initData: ${data?.toJson()}");
        initData = data;
      });
      dtbLink.onEvent((onData) {
        debugPrint("onData: $onData");
        Map<String, dynamic> retData = json.decode(onData);
        if (retData["command"] == "bluetooth.device_found") {
          String? deviceId = retData["ret"]?["device_id"];
          String? deviceName = retData["ret"]?["device_name"];
          if (deviceId != null && deviceName != null) {
            final device = BluetoothDevice(deviceId: deviceId, deviceName: deviceName);
            if (!deviceList.contains(device)) {
              setState(() {
                deviceList.add(device);
                addMessage("${device.toJson()}");
              });
              onDevice?.call();
            }
          }
        } else if (retData["command"] == "bluetooth.download_file.pregress") {
          int? current = retData["ret"]?["current"];
          int? total = retData["ret"]?["total"];
          debugPrint("current: $current, total: $total");
        }
      });
      initPlatformState();
    });
  }

  Future<void> initPlatformState() async {
    String platformVersion;
    try {
      debugPrint("platformVersion before");
      platformVersion = await dtbLink.getPlatformVersion() ?? 'Unknown platform version';
      debugPrint("platformVersion: $platformVersion");
    } on PlatformException {
      platformVersion = 'Failed to get platform version.';
    }
    if (!mounted) return;

    setState(() {
      _platformVersion = platformVersion;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("DTB Link Flutter Demo $_platformVersion")),
      body: Padding(
        padding: const EdgeInsets.all(10),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Expanded(
                  child: Card(
                    child: Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Column(
                        children: [
                          const Text("Bluetooth"),
                          DtbButton(
                            onPressed: () {
                              deviceList.clear();
                              addMessage("=>Search device");
                              showSearchDialog(context);
                              dtbLink.bluetoothStartSearch();
                            },
                            title: "Search device",
                          ),
                          DtbButton(
                            onPressed: () {
                              addMessage("=>Is connected");
                              dtbLink.bluetoothIsConnected().then((result) {
                                addMessage("<=$result");
                              });
                            },
                            title: "Is connected",
                          ),
                          DtbButton(
                            onPressed: () {
                              addMessage("=>Contactless upload");
                              dtbLink
                                  .bluetoothContactlessFileUpload()
                                  .then((result) {
                                addMessage("<=$result");
                              });
                            },
                            title: "Contactless upload",
                          ),
                          DtbButton(
                            onPressed: () {
                              addMessage("=>EMV upload");
                              dtbLink.bluetoothEmvFileUpload().then((result) {
                                addMessage("<=$result");
                              });
                            },
                            title: "EMV upload",
                          ),
                          DtbButton(
                            onPressed: () {
                              addMessage("=>Device data");
                              dtbLink.bluetoothDeviceData().then((device) {
                                addMessage("<=${device.toJson()}");
                              });
                            },
                            title: "Device Data",
                          ),
                          DtbButton(
                            onPressed: () {
                              addMessage("=>Reconnect Device");
                              dtbLink.bluetoothReconnectDevice().then((ret) {
                                addMessage("<=$ret}");
                              });
                            },
                            title: "Reconnect Device",
                          ),
                          DtbButton(
                            onPressed: () {
                              addMessage("=>Card read");
                              dtbLink.traceNo.then((traceNo) {
                                dtbLink
                                    .bluetoothCardRead(
                                        amount: "100",
                                        tranType: 1,
                                        traceNo: traceNo)
                                    .then((ret) {
                                  addMessage("<=$ret");
                                });
                              });
                            },
                            title: "Card read",
                          ),
                        ],
                      ),
                    ),
                  ),
                ),
                Expanded(
                  child: Card(
                    child: Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Wrap(
                        children: [
                          const Text("Terminal"),
                          DtbSwitch(
                            type: type,
                            onChanged: (InitType initType) {
                              setState(() {
                                type = initType;
                              });
                            },
                          ),
                          DtbButton(
                            onPressed: () {
                              addMessage("=>Echo test");
                              dtbLink.terminalEchoTest().then((ret) {
                                addMessage("<=$ret");
                              });
                            },
                            title: "Echo Test",
                          ),
                          DtbButton(
                            onPressed: () {
                              addMessage("=>Init Data");
                              dtbLink.terminalInitData().then((ret) {
                                addMessage("<=${ret?.toJson()}");
                              });
                            },
                            title: "Init Data",
                          ),
                          DtbButton(
                            onPressed: () {
                              addMessage("=>Init terminal");
                              showTerminalTrcDialog(context).then((ret) {
                                String? terminalId = ret?["terminal_id"];
                                String? trcCode = ret?["trc_code"];
                                if (terminalId != null && trcCode != null) {
                                  dtbLink
                                      .terminalDoInit(
                                    terminalId: terminalId,
                                    trc: trcCode,
                                  )
                                      .then((ret) {
                                    addMessage("<=${ret.toJson()}");
                                  });
                                }
                              });
                            },
                            title: "Init Terminal",
                          ),
                          DtbButton(
                            onPressed: () {
                              addMessage("=>Sync Key");
                              dtbLink.syncKey().then((ret) {
                                addMessage("<=${ret.toJson()}");
                              });
                            },
                            title: "Sync Key",
                          ),
                          DtbButton(
                            onPressed: () {
                              addMessage("=>Do Sale");
                              showNumberInputDialog(context).then((amount) {
                                if (mounted && amount != null) {
                                  dtbLink
                                      .doSale(context: context, amount: amount)
                                      .then((ret) {
                                    addMessage("<=$ret");
                                    debugPrint("ret: $ret");
                                    if (ret["code"] == 0) {
                                      Map<String, dynamic> tranRet = ret["ret"];
                                      if (tranRet["resp_code"] == "000") {
                                        debugPrint("tranRet: $tranRet");
                                        setState(() {
                                          lastTran = tranRet;
                                        });
                                      }
                                    } else {
                                      setState(() {
                                        lastTran = ret;
                                      });
                                    }
                                  });
                                }
                              });
                            },
                            title: "Do Sale",
                          ),
                          DtbButton(
                            onPressed: lastTran != null ? doVoid : null,
                            title: "Do Void",
                          ),
                          DtbButton(
                            onPressed: () {
                              addMessage("=>Do User Cancel");
                              dtbLink.doCancelCardRead();
                            },
                            title: "Do UserCancel",
                          ),
                        ],
                      ),
                    ),
                  ),
                ),
              ],
            ),
            Expanded(
              child: SingleChildScrollView(
                controller: scrollController,
                child: TextField(
                  maxLines: null,
                  enabled: false,
                  controller: controller,
                  style: const TextStyle(fontSize: 11),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

  doVoid() {
    addMessage("=>Do Void");
    debugPrint("lastTran: $lastTran");
    final lastRet = lastTran?["ret"];
    if (lastRet != null) {
      if (lastRet["resp_code"] == "000") {
        String? amountStr = lastRet?["amount"];
        String? encTrack2 = lastRet?["enc_track"];
        String? rrn = lastRet?["rrn"];
        String? authCode = lastRet?["auth_code"];
        String? traceNo = lastRet?["trace_no"];
        if (amountStr != null &&
            encTrack2 != null &&
            rrn != null &&
            authCode != null &&
            traceNo != null) {
          dtbLink
              .doVoid(
                  amountStr: amountStr,
                  encTrack2: encTrack2,
                  rrn: rrn,
                  authCode: authCode,
                  traceNo: traceNo)
              .then(
            (ret) {
              addMessage("<=$ret");
            },
          );
        } else {
          addMessage("<=Data is not valid");
        }
      } else {
        addMessage("<=Last tran is invalid respCode: ${lastRet["resp_code"]}");
      }
    } else {
      addMessage("<=Last tran is empty");
    }
  }

  addMessage(String msg) {
    controller.text = "${controller.text}\n$msg";
    Future.delayed(const Duration(milliseconds: 200), () {
      scrollController.animateTo(scrollController.position.maxScrollExtent,
          duration: const Duration(milliseconds: 200), curve: Curves.easeInOut);
    });
  }

  showSearchDialog(BuildContext context) {
    showDialog(
      context: context,
      builder: (context) {
        return StatefulBuilder(
          builder:
              (BuildContext context, void Function(void Function()) setState) {
            onDevice = () {
              setState(() {});
            };

            Widget buildDevice(BluetoothDevice device) {
              return DtbButton(
                title: '${device.deviceName}\n${device.deviceId}',
                onPressed: () {
                  Navigator.of(context).pop();
                  onDevice = null;
                  dtbLink.connectDevice(device);
                },
              );
            }

            List<Widget> buildList() {
              List<Widget> list = [];
              for (BluetoothDevice device in deviceList) {
                list.add(buildDevice(device));
              }
              return list;
            }

            return AlertDialog(
              title: const Text('Dialog Title'),
              content: Column(
                mainAxisSize: MainAxisSize.min,
                children: buildList(),
              ),
            );
          },
        );
      },
    );
  }

  Future<double?> showNumberInputDialog(BuildContext context) async {
    TextEditingController controller = TextEditingController();
    return showDialog<double>(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: const Text("Гүйлгээний дүн"),
          content: TextField(
            controller: controller,
            keyboardType: TextInputType.number,
            decoration:
                const InputDecoration(hintText: "Тоон утгаа оруулна уу"),
          ),
          actions: <Widget>[
            TextButton(
              child: const Text("Болих"),
              onPressed: () {
                Navigator.of(context).pop(); // Хариуг буцаахгүй
              },
            ),
            ElevatedButton(
              child: const Text("Гүйлгээ"),
              onPressed: () {
                final input = controller.text;
                final number = double.tryParse(input);
                if (number != null) {
                  Navigator.of(context).pop(number);
                } else {
                  // Хэрэглэгч буруу утга оруулсан бол, тооцохгүй
                  Navigator.of(context).pop();
                }
              },
            ),
          ],
        );
      },
    );
  }

  Future<Map<String, String>?> showTerminalTrcDialog(
    BuildContext context,
  ) async {
    TextEditingController terminalController = TextEditingController();
    TextEditingController trcCodeController = TextEditingController();

    return showDialog<Map<String, String>>(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: const Text("Мэдээлэл оруулах"),
          content: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              TextField(
                controller: terminalController,
                decoration: const InputDecoration(labelText: "Terminal дугаар"),
              ),
              const SizedBox(height: 8),
              TextField(
                controller: trcCodeController,
                keyboardType: TextInputType.number,
                decoration: const InputDecoration(labelText: "TRC code"),
              ),
            ],
          ),
          actions: <Widget>[
            TextButton(
              child: const Text("Болих"),
              onPressed: () {
                Navigator.of(context).pop(); // Хариуг буцаахгүй
              },
            ),
            ElevatedButton(
              child: const Text("ОК"),
              onPressed: () {
                String terminal = terminalController.text.trim();
                String trcCode = trcCodeController.text.trim();

                if (terminal.isNotEmpty && trcCode.isNotEmpty) {
                  Navigator.of(context).pop({
                    'terminal_id': terminal,
                    'trc_code': trcCode,
                  });
                } else {
                  // Хоосон талбар байвал, утга буцаахгүй
                  Navigator.of(context).pop();
                }
              },
            ),
          ],
        );
      },
    );
  }
}

class DtbButton extends ElevatedButton {
  DtbButton({
    super.key,
    super.onPressed,
    required String title,
  }) : super(
          child: Text(title, style: const TextStyle(fontSize: 11)),
          style: ElevatedButton.styleFrom(
            elevation: 0.5,
            minimumSize: const Size.fromHeight(38),
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(4), // <-- Radius
            ),
          ),
        );
}

class DtbSwitch extends StatelessWidget {
  final InitType type;
  final Function(InitType) onChanged;

  const DtbSwitch({super.key, required this.type, required this.onChanged});

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        onChanged.call(
          type == InitType.production ? InitType.staging : InitType.production,
        );
      },
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Text(type == InitType.production ? "Production" : "Staging"),
          Transform.scale(
            scale: 0.7,
            child: Switch(
              padding: EdgeInsets.zero,
              value: type == InitType.production,
              onChanged: (value) {
                onChanged.call(value ? InitType.production : InitType.staging);
              },
            ),
          ),
        ],
      ),
    );
  }
}
3
likes
0
points
6
downloads

Publisher

verified publisherdatabank.mn

Weekly Downloads

DTB Link - utility app enabling applications to connect and integrate with NFC card readers over Bluetooth

Homepage

License

unknown (license)

Dependencies

crypto, decimal, device_info_plus, device_marketing_names, flutter, http, intl, package_info_plus, path_provider, plugin_platform_interface, pointycastle, shared_preferences

More

Packages that depend on dtb_link

Packages that implement dtb_link