doSale method

  1. @override
Future<Map<String, dynamic>> doSale({
  1. required BuildContext context,
  2. required double amount,
  3. String? traceNO,
})
override

transaction do sale

Implementation

@override
Future<Map<String, dynamic>> doSale({
  required BuildContext context,
  required double amount,
  String? traceNO,
}) async {
  NavigatorState navigator = Navigator.of(context);
  String traceNumber = traceNO ?? await traceNo();
  String amountStr = amount.toStringAsFixed(2);
  Map<String, dynamic> cardRet =
      await cardRead(amount: amountStr, tranType: 1, traceNo: traceNumber);
  if (cardRet["code"] == 0) {
    String? emv = cardRet["emv"];
    String? track2 = cardRet["track2"];
    int? detectType = cardRet["detect_type"];
    if (emv != null && track2 != null) {
      DataInitRet? initData = await _storage.initData;
      DownloadKeyRet? keyRet = await _storage.downloadKey;
      String tdk = "${keyRet?.tdk}";
      String tpk = "${keyRet?.tpk}";
      String merchantName = initData?.merchantName ?? "";
      String terminalId = initData?.terminalId ?? "";
      String merchantId = initData?.merchantId ?? "";
      String netEncKey = DtbLinkCrypto.decrypt("${initData?.netEncKey}");
      // PIN required condition
      String? encryptedPin;
      if (detectType == 3 || amount > 50000.0) {
        final result = await navigator.push(
          MaterialPageRoute(
            builder: (context) => PinCodeScreen(
              amount: amount,
              onConfirm: (pinCode) {
                navigator.pop({
                  "result": true,
                  "pin": pinCode,
                });
              },
              onCancel: () {
                navigator.pop({
                  "result": false,
                });
              },
            ),
          ),
        );
        if (result != null && result["result"] == true) {
          encryptedPin = result["pin"];
        } else {
          return {
            "status_code": "ng",
            "msg": Msg(code: "126", body: "ПИН боловсруулахад алдаа гарлаа.")
                .toJson(),
          };
        }
      }
      final saleBuildResp = await _doSaleBuild(
        entryMode: detectType == 3 ? "chip" : "",
        amount: amountStr,
        traceNo: traceNumber,
        track2: track2,
        emv: emv,
        tdk: tdk,
        tpk: tpk,
        terminalId: terminalId,
        merchantId: merchantId,
        merchantName: merchantName,
        netEncKey: netEncKey,
        pin: encryptedPin ?? "",
      );
      if (saleBuildResp["status_code"] == "ng") {
        return saleBuildResp;
      }
      String dbRefNo = saleBuildResp["db_ref_no"];
      Map<String, dynamic> bodySale = {
        "db_ref_no": dbRefNo,
        "service_data": saleBuildResp["service_data"],
        "terminal_id": saleBuildResp["terminal_id"],
      };
      String entryMode = '${saleBuildResp["entry_mode"]}';
      String entryModeText = '${saleBuildResp["entry_mode_text"]}';
      String reqID = "";
      ApiResponse<EncApiRet> apiResp = await DtbLinkNet.instance.request(
        method: Method.post,
        path: "/v1/sale",
        prefix: "sale tran",
        body: json.encode(bodySale),
        onRespHeader: (Map<String, String> headers) {
          reqID = headers["request-id"] ?? reqID;
        },
        fromJson: (dynamic ret) => EncApiRet.fromJson(ret),
        timeOut: const Duration(seconds: 20),
      );
      if (apiResp.statusCode == "ng") {
        return apiResp.toJson();
      }
      EncApiRet? encApiRet = apiResp.ret;
      final parseSaleResp = await _saleParse(
        isoData: "${encApiRet?.isoData}",
        track2: track2,
        tdk: tdk,
        netEncKey: netEncKey,
      );
      parseSaleResp.putIfAbsent("request_id", () => reqID);
      parseSaleResp.putIfAbsent(
          "db_ref_no", () => saleBuildResp["db_ref_no"]);
      if (parseSaleResp["resp_code"] == "000") {}
      final f55 = parseSaleResp["f55"];
      if (f55 != null && f55.isNotEmpty) {
        final respF55 = await _finishTran(f55);
        _log('respF55: $respF55');
      }
      String dayTime = tranDateFormatter.format(DateTime.now());
      final regParse = await _registerTran(
        operation: "SALE",
        reqId: reqID,
        amountStr: amountStr,
        traceNo: traceNumber,
        dbRefNo: dbRefNo,
        entryMode: entryMode,
        entryModeText: entryModeText,
        terminalId: terminalId,
        merchantId: merchantId,
        merchantName: merchantName,
        netEncKey: netEncKey,
        dayTime: dayTime,
        parseMap: parseSaleResp,
      );
      _log('regParse: $regParse');
      await _apiComplete(
        traceNo: traceNumber,
        dbRefNo: dbRefNo,
        terminalId: terminalId,
        netEncKey: netEncKey,
      );
      return {"status_code": "ok", "ret": parseSaleResp};
    } else {
      cardRet.putIfAbsent("msg", () => "Card not read");
      return cardRet;
    }
  } else {
    cardRet.putIfAbsent("msg", () => "Card not read");
    return cardRet;
  }
}