import 'dart:convert'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:medcify/models/plan_item.dart'; import 'package:medcify/storage/storage.dart'; import 'package:razorpay_flutter/razorpay_flutter.dart'; import '../../../components/alert.dart'; import '../../../models/api/razor_pay_failure_response.dart'; import '../../../navigation/navigation.dart'; import '../../../network/api_provider.dart'; abstract class PlanState{} class PlanInitial extends PlanState{} class PlanLoading extends PlanState{} class PlanSuccess extends PlanState{} class PlanFailure extends PlanState{ String error; PlanFailure(this.error); } class PlanCubit extends Cubit { PlanCubit() : super(PlanInitial()); String currentPlan = ""; String expiryDate = ""; bool isCurrentPlan = false; List plans = []; static const platform = MethodChannel("razorpay_flutter"); Razorpay razorpay = Razorpay(); String razorpayKey = Storage.instance.razorpayKey; String razorpaySecretKey = Storage.instance.razorpaySecretKey; PlanItem? plan; Future fetchPlan() async{ emit(PlanLoading()); final response = await ApiProvider.instance.fetchPlan(); if((response.error ?? "").isEmpty){ plans = response.plans ?? []; currentPlan = response.currentPlan ?? ""; expiryDate = response.expiryDate ?? ""; isCurrentPlan = response.planStatus ?? false; emit(PlanSuccess()); }else{ emit(PlanFailure(response.error ?? "Something went wrong")); } } void listenRazorPayEvents(){ razorpay.on(Razorpay.EVENT_PAYMENT_SUCCESS, (PaymentSuccessResponse response){ _handlePaymentSuccess(response); }); razorpay.on(Razorpay.EVENT_PAYMENT_ERROR, _handlePaymentError); razorpay.on(Razorpay.EVENT_EXTERNAL_WALLET, _handleExternalWallet); } Future fetchOrderId(PlanItem item) async { plan = item; int payableAmount = (plan?.amount) * 100; Navigation.instance.navigate("/loading"); var orderOptions = { 'amount': payableAmount, 'currency': "INR", }; final client = HttpClient(); final request = await client.postUrl(Uri.parse('https://api.razorpay.com/v1/orders')); request.headers.set(HttpHeaders.contentTypeHeader, "application/json; charset=UTF-8"); String basicAuth = 'Basic ${base64Encode(utf8.encode('$razorpayKey:$razorpaySecretKey'))}'; request.headers.set(HttpHeaders.authorizationHeader, basicAuth); request.add(utf8.encode(json.encode(orderOptions))); final response = await request.close(); Navigation.instance.goBack(); response.transform(utf8.decoder).listen((contents) { String orderId = contents.split(',')[0].split(":")[1]; orderId = orderId.substring(1, orderId.length - 1); print(orderId); openRazorPay(orderId); }); } void openRazorPay(String orderId){ int payableAmount = (plan?.amount) * 100; var options = { 'key': razorpayKey, 'amount': payableAmount, 'name': 'Medcify', 'order_id': orderId, 'retry': {'enabled': true, 'max_count': 1}, 'send_sms_hash': true, 'external': { 'wallets': ['paytm'] }, 'prefill': { 'contact': '8888888888', 'email': 'test@razorpay.com' } }; try { razorpay.open(options); } catch (e) { showToast(e.toString()); } } Future addSubscription(PaymentSuccessResponse successData) async{ Navigation.instance.navigate("/loading"); final response = await ApiProvider.instance.addSubscription(plan!, successData); Navigation.instance.goBack(); if(response.status ?? false){ showToast("Subscription added successfully"); plan = null; fetchPlan(); }else{ showAlert(response.message ?? "Something went wrong"); } } void _handlePaymentSuccess(PaymentSuccessResponse response) { addSubscription(response); } void _handlePaymentError(PaymentFailureResponse failureResponse) { RazorPayFailureResponse response = RazorPayFailureResponse.fromJson(jsonDecode(failureResponse.message!)); showToast(response.error?.desc ?? "Something went wrong"); } void _handleExternalWallet(ExternalWalletResponse response) { } void showToast(String msg) { Fluttertoast.showToast( msg: msg, toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, timeInSecForIosWeb: 1, backgroundColor: Colors.grey.shade200, textColor: Colors.black, fontSize: 14.0 ); } void showAlert(String err){ AlertX.instance.showAlert( title: "Error", msg: err, positiveButtonText: "Done", positiveButtonPressed: (){ Navigation.instance.goBack(); } ); } }