feat: Phase 1 — remove Stripe, switch to e-Transfer

- Drop stripe_payment + stripe_sdk deps; delete stripe pay pages/widgets
- New ETransferPay widget: shows payment@wisetronic.com + R#<orderId> remark
- goPayment stripe/native branches now route to e-Transfer
- pay_now widgets: strip saved-cards section & dead nativePay logic
- my_cards pages rewritten as e-Transfer info (route kept)
- models/utils/constants cleaned of stripe; env constraint -> Dart 3

See UPGRADE_NOTES.md. (Null-safety migration is Phase 3; deps upgrade Phase 2.)
This commit is contained in:
2026-07-24 02:47:13 +08:00
parent f8a90ad305
commit 7ffcc848d0
17 changed files with 371 additions and 1548 deletions

View File

@@ -15,7 +15,6 @@ import 'package:hive/hive.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:stripe_payment/stripe_payment.dart';
import '../constants.dart';
import '../events/eventbus.dart';
@@ -24,12 +23,11 @@ import '../generated/l10n.dart';
import '../models/comment.dart';
import '../models/order.dart';
import '../models/payment_platform.dart';
import '../models/stripe_payment_method.dart';
import '../models/user.dart';
import '../routes.dart';
import '../store/actions.dart';
import '../store/store.dart';
import '../widgets/general/stripe_pay.dart';
import '../widgets/general/e_transfer_pay.dart';
import 'http_util.dart';
import 'utils.dart';
@@ -507,62 +505,14 @@ class Util {
}
Widget getNativePay(BuildContext context, Order order, PaymentPlatform paymentPlatform) {
return GestureDetector(
child: Container(
padding: EdgeInsets.only(top: 16.0, left: 16.0, right: 16.0, bottom: 16.0),
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
margin: EdgeInsets.only(right: 6.0),
child: Text(
Platform.isAndroid ? S.of(context).pay_with : S.of(context).pay_with,
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.bold,
),
),
),
Container(
padding: EdgeInsets.only(right: 10.0),
child: Platform.isAndroid ? Image.asset(
'assets/images/google_pay.png',
height: 22.0,
fit: BoxFit.fitHeight,
) : Image.asset(
'assets/images/apple_pay.png',
height: 22.0,
fit: BoxFit.fitHeight,
),
),
],
),
),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
width: 10,
color: Colors.black26,
),
),
),
),
onTap: () {
print(paymentPlatform);
PaymentPlatform newPaymentPlatform = PaymentPlatform.fromJson(json.decode(json.encode(paymentPlatform)));
newPaymentPlatform.code = Constants.PAYMENT_METHOD_NATIVE_PAY;
goPayment(context, order, newPaymentPlatform);
},
);
// Native (Apple/Google) pay removed with Stripe. Web uses e-Transfer.
return SizedBox.shrink();
}
static void goPayment(BuildContext context, Order order,
PaymentPlatform paymentPlatform, {
bool googlePay=false,
bool applePay=false,
StripePaymentMethod stripePaymentMethod,
}) {
switch(paymentPlatform.code) {
case Constants.PAYMENT_METHOD_CODE_SQUARE:
@@ -584,102 +534,23 @@ class Util {
break;
case Constants.PAYMENT_METHOD_NATIVE_PAY:
StripePayment.setOptions(
StripeOptions(publishableKey: paymentPlatform.publishableKey,
merchantId: paymentPlatform.merchantId,
androidPayMode: paymentPlatform.publishableKey.contains('_test_')
? 'test'
: 'production'
)
);
StripePayment.paymentRequestWithNativePay(
androidPayOptions: AndroidPayPaymentRequest(
totalPrice: order.totalPrice.toStringAsFixed(2),
currencyCode: order.businessInfo.currency,
),
applePayOptions: ApplePayPaymentOptions(
currencyCode: order.businessInfo.currency,
countryCode: order.businessInfo.address.country,
items: [
ApplePayItem(
label: order.businessInfo.name,
amount: order.totalPrice.toStringAsFixed(2),
),
],
),
).then((token) {
print('return native token: ${token.tokenId}');
processNativePay(context, token, order);
}).catchError((error) {
print('native pay error: $error');
});
// Native (Apple/Google) pay removed with Stripe; route to e-Transfer.
Navigator.pushReplacement(context, MaterialPageRoute(
builder: (BuildContext context) {
return ETransferPay(order: order);
}
));
break;
case Constants.PAYMENT_METHOD_CODE_STRIPE:
Navigator.pushReplacement(context, MaterialPageRoute(
builder: (BuildContext context) {
return StripePay(order, paymentPlatform, stripePaymentMethod: stripePaymentMethod,);
return ETransferPay(order: order);
}
));
break;
}
}
static void processNativePay(BuildContext context, Token token, Order order) async {
PaymentMethod paymentMethod = await StripePayment.createPaymentMethod(
PaymentMethodRequest(
card: CreditCard(
token: token.tokenId,
),
),
);
if (paymentMethod != null) {
Utils.stripePaymentIntent(order, null, paymentMethod.id, paymentMethod.type, (response) {
if (response.data['status'] == Constants.STRIPE_STATUS_REQUIRES_CONFIRMATION) {
StripePayment.confirmPaymentIntent(
PaymentIntent(
clientSecret: response.data[Constants.STRIPE_CLIENT_SECRET],
paymentMethodId: response.data['payment_method'],
),
).then((paymentIntentResult) {
if (paymentIntentResult.status == Constants.STRIPE_STATUS_SUCCEDED) {
Utils.stripeChargedSuccess(order,
paymentMethod.id,
paymentIntentResult.paymentIntentId,
(response) {
StripePayment.completeNativePayRequest().then((_) {
eventBus.fire(OnOrderUpdated());
Routes.router.navigateTo(context, '/orderdetail/${order.id}', replace: true);
}).catchError((error) {
Utils.showMessageDialog(context, error, onOk: () {
Navigator.of(context).pop();
});
});
},
(error) {
Utils.showMessageDialog(context, error, onOk: () {
Navigator.of(context).pop();
});
}
);
} else {
Utils.showMessageDialog(context, Exception('Unknown error'));
}
}).catchError((error) {
Utils.showMessageDialog(context, error, onOk: () {
Navigator.of(context).pop();
});
});
}
}, (error) {
Utils.showMessageDialog(context, error, onOk: () {
Navigator.of(context).pop();
});
});
} else {
}
}
static Future<Uint8List> getBytesFromAsset(String path, int width) async {
ByteData data = await rootBundle.load(path);
ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List(), targetWidth: width);