bug fixes done
This commit is contained in:
663
android/build/reports/problems/problems-report.html
Normal file
663
android/build/reports/problems/problems-report.html
Normal file
File diff suppressed because one or more lines are too long
@@ -58,9 +58,10 @@ class StripePaymentBloc extends Bloc<StripePaymentEvent, StripePaymentState> {
|
||||
paymentIntentClientSecret: clientSecret,
|
||||
merchantDisplayName: "CityCards",
|
||||
style: ThemeMode.light,
|
||||
allowsDelayedPaymentMethods: true,
|
||||
),
|
||||
);
|
||||
|
||||
await Stripe.instance.presentPaymentSheet();
|
||||
emit(const StripePaymentSheetReady());
|
||||
|
||||
emit(const StripePaymentLoading(
|
||||
@@ -105,6 +106,8 @@ class StripePaymentBloc extends Bloc<StripePaymentEvent, StripePaymentState> {
|
||||
paymentIntentClientSecret: event.clientSecret,
|
||||
merchantDisplayName: "CityCards",
|
||||
style: ThemeMode.light,
|
||||
allowsDelayedPaymentMethods: true,
|
||||
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
|
||||
import '../bloc/stripe_payment_bloc.dart';
|
||||
import '../bloc/stripe_payment_event.dart';
|
||||
import '../bloc/stripe_payment_state.dart';
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'dart:async';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:citycards_customer/attraction_details/widgets/share_bottomsheet.dart';
|
||||
import 'package:citycards_customer/common_packages/app_bar.dart';
|
||||
@@ -309,11 +310,15 @@ class _PassAttractionDetailsViewState extends State<PassAttractionDetailsView> {
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(12.r),
|
||||
),
|
||||
child: QrImageView(
|
||||
data:
|
||||
"Details:\nQR No. : ${attraction.qr.qrNumber}\nQR Code : ${attraction.qr.qrCode}\nStatus : ${attraction.qr.qrStatus}\nExpires At: ${attraction.qr.qrExpiresAt}\nChecked In: ${attraction.qr.checkedInDatetime}\nRemaining : ${attraction.qr.qrRemainingMinutes} mins\nIs Active : ${attraction.qr.isQrActive ? "Yes" : "No"}",
|
||||
version: QrVersions.auto,
|
||||
size: 200.w,
|
||||
child: ImageFiltered(
|
||||
imageFilter: _isCheckedIn
|
||||
? ImageFilter.blur(sigmaX: 0, sigmaY: 0) // clear when checked in
|
||||
: ImageFilter.blur(sigmaX: 6, sigmaY: 6), // blurred before check-in
|
||||
child: QrImageView(
|
||||
data: "Details:\nQR No. : ${attraction.qr.qrNumber}\nQR Code : ${attraction.qr.qrCode}\nStatus : ${attraction.qr.qrStatus}\nExpires At: ${attraction.qr.qrExpiresAt}\nChecked In: ${attraction.qr.checkedInDatetime}\nRemaining : ${attraction.qr.qrRemainingMinutes} mins\nIs Active : ${attraction.qr.isQrActive ? "Yes" : "No"}",
|
||||
version: QrVersions.auto,
|
||||
size: 200.w,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16.h),
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
class ApiUrls {
|
||||
|
||||
// static const baseUrl = "https://devapi.citycards.betadelivery.com";//Normal API
|
||||
static const baseUrl = "https://testingapi.citycards.betadelivery.com";// Test API
|
||||
// static const baseUrl = "https://uatapi.citycard.betadelivery.com";// Production Lvl API
|
||||
// static const baseUrl = "https://testingapi.citycards.betadelivery.com";// Test API
|
||||
static const baseUrl = "https://uatapi.citycard.betadelivery.com";// Production Lvl API
|
||||
|
||||
static const refreshToken = "$baseUrl/auth/refresh";
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:citycards_customer/postcard/widgets/front_card_widget.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:flutter_stripe/flutter_stripe.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import '../../StripePayment/bloc/stripe_payment_bloc.dart';
|
||||
import '../../StripePayment/bloc/stripe_payment_event.dart';
|
||||
@@ -128,251 +129,105 @@ class _PostcardCheckoutPageViewState extends State<PostcardCheckoutPageView> {
|
||||
|
||||
/// 🆕 Handle payment flow with client secret
|
||||
Future<void> _handlePaymentFlow(BuildContext context, String clientSecret) async {
|
||||
// Show payment bottom sheet with BLoC
|
||||
final paymentSuccess = await showModalBottomSheet<bool>(
|
||||
context: context,
|
||||
isDismissible: false,
|
||||
enableDrag: false,
|
||||
isScrollControlled: true,
|
||||
backgroundColor: Colors.transparent,
|
||||
builder: (bottomSheetContext) {
|
||||
return BlocProvider(
|
||||
create: (_) => StripePaymentBloc(stripeService: StripeService())
|
||||
..add(InitiatePaymentWithClientSecret(clientSecret: clientSecret)),
|
||||
child: BlocConsumer<StripePaymentBloc, StripePaymentState>(
|
||||
listener: (context, state) {
|
||||
if (state is StripePaymentSuccess) {
|
||||
Navigator.of(bottomSheetContext).pop(true);
|
||||
} else if (state is StripePaymentFailure || state is StripePaymentCancelled) {
|
||||
Navigator.of(bottomSheetContext).pop(false);
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
return Container(
|
||||
height: MediaQuery.of(context).size.height * 0.5,
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(20),
|
||||
topRight: Radius.circular(20),
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(24.0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
if (state is StripePaymentLoading) ...[
|
||||
const CircularProgressIndicator(
|
||||
color: Color(0xffF95F62),
|
||||
strokeWidth: 3,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
Color(0xFFF95F62),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
const Text(
|
||||
"Processing payment...",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF333333),
|
||||
),
|
||||
),
|
||||
] else if (state is StripePaymentSuccess) ...[
|
||||
const Icon(
|
||||
Icons.check_circle,
|
||||
color: Colors.green,
|
||||
size: 64,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
const Text(
|
||||
"Payment Successful!",
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF333333),
|
||||
),
|
||||
),
|
||||
] else if (state is StripePaymentFailure) ...[
|
||||
const Icon(
|
||||
Icons.error,
|
||||
color: Colors.red,
|
||||
size: 64,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
const Text(
|
||||
"Payment Failed",
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF333333),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
state.error,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.grey[600],
|
||||
),
|
||||
),
|
||||
] else if (state is StripePaymentCancelled) ...[
|
||||
const Icon(
|
||||
Icons.cancel,
|
||||
color: Colors.orange,
|
||||
size: 64,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
const Text(
|
||||
"Payment Cancelled",
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF333333),
|
||||
),
|
||||
),
|
||||
],
|
||||
const SizedBox(height: 32),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 24,
|
||||
vertical: 16,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF5F5F5),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(
|
||||
color: const Color(0xFFE0E0E0),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
"Payment Amount",
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.grey[600],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
"\$${widget.totalAmount.toStringAsFixed(2)}",
|
||||
style: const TextStyle(
|
||||
fontSize: 32,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF333333),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.lock_outline,
|
||||
size: 16,
|
||||
color: Colors.grey[600],
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
"Secured by Stripe",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey[600],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
try {
|
||||
// Step 1: Initialize Stripe's native payment sheet
|
||||
await Stripe.instance.initPaymentSheet(
|
||||
paymentSheetParameters: SetupPaymentSheetParameters(
|
||||
paymentIntentClientSecret: clientSecret,
|
||||
merchantDisplayName: 'CityCards',
|
||||
allowsDelayedPaymentMethods: true, // ← enables UPI, netbanking, etc.
|
||||
style: ThemeMode.light,
|
||||
),
|
||||
);
|
||||
|
||||
// Step 2: Present Stripe's native UI (card, UPI, wallets, etc.)
|
||||
await Stripe.instance.presentPaymentSheet();
|
||||
|
||||
// Step 3: Payment succeeded
|
||||
if (!mounted) return;
|
||||
_onPaymentSuccess(context);
|
||||
|
||||
} on StripeException catch (e) {
|
||||
if (!mounted) return;
|
||||
if (e.error.code == FailureCode.Canceled) {
|
||||
_onPaymentCancelled(context);
|
||||
} else {
|
||||
_onPaymentFailed(context, e.error.message ?? 'Payment failed');
|
||||
}
|
||||
} catch (e) {
|
||||
if (!mounted) return;
|
||||
_onPaymentFailed(context, e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
void _onPaymentSuccess(BuildContext context) {
|
||||
context.read<MyPostCardBloc>().add(CheckLoginStatus());
|
||||
|
||||
if (widget.isEditMode) {
|
||||
Navigator.pushReplacement(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => OrderSuccessPageView(
|
||||
isEditMode: true,
|
||||
isCartMode: widget.isCartMode,
|
||||
pcImage: widget.pcImage,
|
||||
pcContent: widget.pcContent,
|
||||
pcState: widget.stateName,
|
||||
pcCountry: widget.countryName,
|
||||
pcCity: widget.cityName,
|
||||
pcZipCode: widget.zipCode,
|
||||
pcName: widget.fullname,
|
||||
pcAddress: widget.address1,
|
||||
senderName: widget.senderName,
|
||||
senderCity: widget.senderCity,
|
||||
senderCountry: widget.senderCountry,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
context.read<PostcardCheckoutBloc>().add(
|
||||
ConfirmPaymentEvent(
|
||||
stripeStatus: 'succeeded',
|
||||
paymentStatus: 'success',
|
||||
),
|
||||
);
|
||||
} else {
|
||||
context.read<PostcardCreationBloc>().add(GoToNextStep());
|
||||
context.read<PostcardCheckoutBloc>().add(
|
||||
ConfirmPaymentEvent(
|
||||
stripeStatus: 'succeeded',
|
||||
paymentStatus: 'success',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void _onPaymentCancelled(BuildContext context) {
|
||||
// User dismissed the sheet — just save draft if in edit mode
|
||||
if (widget.isEditMode) {
|
||||
context.read<PostcardCheckoutBloc>().add(SaveAsDraftEvent());
|
||||
context.read<PostcardCheckoutBloc>().add(
|
||||
UpdateCheckoutDataEvent(
|
||||
postcardId: widget.postcardId,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void _onPaymentFailed(BuildContext context, String error) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('Payment failed: $error'),
|
||||
backgroundColor: Colors.red,
|
||||
),
|
||||
);
|
||||
|
||||
// Handle payment result
|
||||
if (!mounted) return;
|
||||
|
||||
if (paymentSuccess == true) {
|
||||
context.read<MyPostCardBloc>().add(CheckLoginStatus());
|
||||
if (widget.isEditMode) {
|
||||
// For edit mode, navigate directly to OrderSuccessPageView
|
||||
Navigator.pushReplacement(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => OrderSuccessPageView(
|
||||
isEditMode: true,
|
||||
isCartMode: widget.isCartMode,
|
||||
// Front
|
||||
pcImage: widget.pcImage,
|
||||
// Back
|
||||
pcContent: widget.pcContent,
|
||||
pcState: widget.stateName,
|
||||
pcCountry: widget.countryName,
|
||||
pcCity: widget.cityName,
|
||||
pcZipCode: widget.zipCode,
|
||||
pcName: widget.fullname,
|
||||
pcAddress: widget.address1,
|
||||
senderName: widget.senderName,
|
||||
senderCity: widget.senderCity,
|
||||
senderCountry: widget.senderCountry,
|
||||
),
|
||||
),
|
||||
);
|
||||
final bloc = context.read<PostcardCheckoutBloc>();
|
||||
bloc.add(
|
||||
ConfirmPaymentEvent(
|
||||
stripeStatus: 'succeeded',
|
||||
paymentStatus: 'success',
|
||||
),
|
||||
);
|
||||
} else {
|
||||
// For new orders, use the normal step flow
|
||||
context.read<PostcardCreationBloc>().add(GoToNextStep());
|
||||
final bloc = context.read<PostcardCheckoutBloc>();
|
||||
bloc.add(
|
||||
ConfirmPaymentEvent(
|
||||
stripeStatus: 'succeeded',
|
||||
paymentStatus: 'success',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (widget.isEditMode) {
|
||||
context.read<PostcardCheckoutBloc>().add(SaveAsDraftEvent());
|
||||
context.read<PostcardCheckoutBloc>().add(
|
||||
UpdateCheckoutDataEvent(
|
||||
postcardId: widget.postcardId, // pass the id from widget
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Payment failed or cancelled - go to MyPostCardsView
|
||||
// Navigator.pushReplacement(
|
||||
// context,
|
||||
// MaterialPageRoute(
|
||||
// builder: (context) => const MyPostCardsView(),
|
||||
// ),
|
||||
// );
|
||||
|
||||
|
||||
// final bloc = context.read<PostcardCheckoutBloc>();
|
||||
// bloc.add(
|
||||
// ConfirmPaymentEvent(
|
||||
// stripeStatus: 'requires_payment_method',
|
||||
// paymentStatus: 'failed',
|
||||
// ),
|
||||
// );
|
||||
if (widget.isEditMode) {
|
||||
context.read<PostcardCheckoutBloc>().add(SaveAsDraftEvent());
|
||||
context.read<PostcardCheckoutBloc>().add(
|
||||
UpdateCheckoutDataEvent(
|
||||
postcardId: widget.postcardId,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ class _WriteMessageStepPageViewState extends State<WriteMessageStepPageView> {
|
||||
TextPosition(offset: _controller.text.length));
|
||||
|
||||
final fonts = [
|
||||
{"name": "Default", "font": GoogleFonts.caveat(), "cleanName": "Caveat"},
|
||||
{"name": "Default", "font": GoogleFonts.poppins(), "cleanName": "Poppins"},
|
||||
{"name": "Patrick Hand", "font": GoogleFonts.patrickHand(), "cleanName": "Patrick Hand"},
|
||||
{"name": "Indie Flower", "font": GoogleFonts.indieFlower(), "cleanName": "Indie Flower"},
|
||||
{"name": "Gloria Hallelujah", "font": GoogleFonts.gloriaHallelujah(), "cleanName": "Gloria Hallelujah"},
|
||||
|
||||
42
pubspec.lock
42
pubspec.lock
@@ -9,6 +9,38 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.3"
|
||||
app_links:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: app_links
|
||||
sha256: "3462d9defc61565fde4944858b59bec5be2b9d5b05f20aed190adb3ad08a7abc"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.0"
|
||||
app_links_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: app_links_linux
|
||||
sha256: f5f7173a78609f3dfd4c2ff2c95bd559ab43c80a87dc6a095921d96c05688c81
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
app_links_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: app_links_platform_interface
|
||||
sha256: "05f5379577c513b534a29ddea68176a4d4802c46180ee8e2e966257158772a3f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.2"
|
||||
app_links_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: app_links_web
|
||||
sha256: af060ed76183f9e2b87510a9480e56a5352b6c249778d07bd2c95fc35632a555
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
archive:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -597,6 +629,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.8"
|
||||
gtk:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: gtk
|
||||
sha256: e8ce9ca4b1df106e4d72dad201d345ea1a036cc12c360f1a7d5a758f78ffa42c
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
html:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1588,4 +1628,4 @@ packages:
|
||||
version: "3.1.3"
|
||||
sdks:
|
||||
dart: ">=3.10.0 <4.0.0"
|
||||
flutter: ">=3.38.0"
|
||||
flutter: ">=3.38.1"
|
||||
|
||||
@@ -71,6 +71,7 @@ dependencies:
|
||||
libphonenumber_plugin: ^0.3.3
|
||||
phone_numbers_parser: ^9.0.20
|
||||
qr_flutter: ^4.1.0
|
||||
app_links: ^7.0.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
||||
Reference in New Issue
Block a user