159 lines
4.8 KiB
Dart
159 lines
4.8 KiB
Dart
|
|
||
|
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<PlanState> {
|
||
|
PlanCubit() : super(PlanInitial());
|
||
|
String currentPlan = "";
|
||
|
String expiryDate = "";
|
||
|
bool isCurrentPlan = false;
|
||
|
List<PlanItem> plans = [];
|
||
|
static const platform = MethodChannel("razorpay_flutter");
|
||
|
Razorpay razorpay = Razorpay();
|
||
|
String razorpayKey = Storage.instance.razorpayKey;
|
||
|
String razorpaySecretKey = Storage.instance.razorpaySecretKey;
|
||
|
PlanItem? plan;
|
||
|
|
||
|
Future<void> 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<void> 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<void> 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();
|
||
|
}
|
||
|
);
|
||
|
}
|
||
|
|
||
|
}
|