createOrder method

Future<bool> createOrder({
  1. required num amountVal,
  2. num? coinsVal,
  3. required String coinPlanId,
  4. String? appId,
  5. String? merchantNo,
  6. String? apiUrl,
  7. String? privateKeyBase64,
  8. String? upiId,
  9. String currencyCode = "INR",
  10. String countryCode = "IN",
  11. String userId = "USER_DEMO_01",
  12. String paymentGatewayName = "PayerMax",
  13. bool testMode = false,
  14. dynamic onSuccess()?,
  15. dynamic onFailure()?,
  16. dynamic onToast()?,
})

Setup and initialize order creation with PayerMax

Implementation

Future<bool> createOrder({
  required num amountVal,
  num? coinsVal,
  required String coinPlanId,
  String? appId,
  String? merchantNo,
  String? apiUrl,
  String? privateKeyBase64,
  String? upiId,
  String currencyCode = "INR",
  String countryCode = "IN",
  String userId = "USER_DEMO_01",
  String paymentGatewayName = "PayerMax",
  bool testMode = false,
  Function()? onSuccess,
  Function()? onFailure,
  Function()? onToast,
}) async {
  this.paymentGatewayName = paymentGatewayName;
  this.testMode = testMode;
  amount.value = amountVal.toDouble();
  coins.value = (coinsVal ?? amountVal).toInt();
  planId.value = coinPlanId;
  currency.value = currencyCode;
  onPaymentSuccess = onSuccess;
  onPaymentFailure = onFailure;
  onShowToast = onToast;
  statusRx.value = PayerMaxStatusModel.waiting();
  isLoading.value = true;

  try {
    final nowUtc = DateTime.now().toUtc();
    final requestTime = "${nowUtc.year.toString().padLeft(4, '0')}-"
        "${nowUtc.month.toString().padLeft(2, '0')}-"
        "${nowUtc.day.toString().padLeft(2, '0')}T"
        "${nowUtc.hour.toString().padLeft(2, '0')}:"
        "${nowUtc.minute.toString().padLeft(2, '0')}:"
        "${nowUtc.second.toString().padLeft(2, '0')}."
        "${nowUtc.millisecond.toString().padLeft(3, '0')}+00:00";

    final currentOutTradeNo = "ORDER_${DateTime.now().millisecondsSinceEpoch}";
    outTradeNo.value = currentOutTradeNo;

    final targetAppId = appId ?? PayerMaxConfig.defaultAppId;
    final targetMerchantNo = merchantNo ?? PayerMaxConfig.defaultMerchantNo;
    final targetApiUrl = apiUrl ?? PayerMaxConfig.defaultApiUrl;
    final targetPrivateKey = privateKeyBase64 ?? PayerMaxConfig.defaultPrivateKeyBase64;

    final requestBodyMap = {
      "version": "1.4",
      "keyVersion": "1",
      "requestTime": requestTime,
      "appId": targetAppId,
      "merchantNo": targetMerchantNo,
      "data": {
        "outTradeNo": currentOutTradeNo,
        "subject": "Coin Recharge Plan $coinPlanId",
        "totalAmount": amountVal.toStringAsFixed(2),
        "currency": currencyCode,
        "country": countryCode,
        "userId": userId,
        "frontCallbackUrl": "https://example.com/payment-result",
        "notifyUrl": "https://example.com/notify",
      }
    };

    final jsonBodyString = jsonEncode(requestBodyMap);

    // Sign with RSA Private Key
    final privateKey = _parsePkcs8PrivateKey(base64Decode(targetPrivateKey));
    final signature = _signSha256WithRsa(utf8.encode(jsonBodyString), privateKey);

    final response = await http.post(
      Uri.parse(targetApiUrl),
      headers: {
        "Content-Type": "application/json;charset=utf-8",
        "Accept": "application/json",
        "sign": signature,
      },
      body: jsonBodyString,
    );

    final resData = jsonDecode(response.body) as Map<String, dynamic>;
    final code = resData["code"] ?? "";
    final msg = resData["msg"] ?? "";

    rawResponseMsg.value = msg.isNotEmpty ? msg : code;

    if (code == "APPLY_SUCCESS" || code == "SUCCESS") {
      final data = resData["data"] ?? {};
      redirectUrl.value = data["redirectUrl"] ?? "";
      tradeNo.value = data["payerMaxTradeNo"] ?? currentOutTradeNo;
    } else {
      tradeNo.value = currentOutTradeNo;
    }

    final payeeUpi = upiId ?? "";
    upiUri.value = "upi://pay?pa=$payeeUpi&pn=PayerMax&am=${amountVal.toStringAsFixed(2)}&cu=$currencyCode&tr=$currentOutTradeNo";

    isLoading.value = false;
    return true;
  } catch (e) {
    isLoading.value = false;
    debugPrint("PayerMaxController Exception => $e");
    final failureResponse = IncodesPaymentResponse(
      "Connection Error: $e",
      false,
      outTradeNo.value,
    );
    _handleFailure(failureResponse);
    return false;
  }
}