Reputation: 201
I am trying to implement a Stripe payment system in my flutter app using the stripe_payment package. In my code, I call Stripe.instance.initPaymentSheet(...), however when I try to call Stripe.instance.presentPaymentSheet(...) just a few lines later, I get this error:
flutter: StripeException(error: LocalizedErrorMessage(code: FailureCode.Failed, localizedMessage: No payment sheet has been initialized yet, message: No payment sheet has been initialized yet, stripeErrorCode: null, declineCode: null, type: null))
Here is my code:
Future<void> makePayment() async {
final url = Uri.parse(
'${firebaseFunction}');
final response =
await http.get(url, headers: {'Content-Type': 'application/json'});
this.paymentIntentData = json.decode(response.body);
await Stripe.instance.initPaymentSheet(
paymentSheetParameters: SetupPaymentSheetParameters(
paymentIntentClientSecret: paymentIntentData!['paymentIntent'],
applePay: true,
googlePay: true,
style: ThemeMode.dark,
merchantCountryCode: 'UK',
merchantDisplayName: 'Test Payment Service'));
setState(() {});
print('initialised');
try {
await Stripe.instance.presentPaymentSheet();
setState(() {
paymentIntentData = null;
});
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('Payment Successful!'),
));
} catch (e) {
print(e);
}
// await displayPaymentSheet();
}
And here is my node.js code (accessed through url):
const functions = require("firebase-functions");
const stripe = require('stripe')(functions.config().stripe.testkey);
exports.stripePayment = functions.https.onRequest(async (req, res) => {
const paymentIntent = await stripe.paymentIntents.create({
amount: 170,
currency: 'usd'
},
function(err, paymentIntent) {
if (err != null) {
console.log(err);
} else {
res.json({
paymentIntent: paymentIntent.client_secret
})
}
})
})
Why doesn't the Payment Sheet initialize (or stay initialized) when I try to use the presentPaymentSheet method?
Upvotes: 16
Views: 19027
Reputation:
Simply include this code within the catch statement :
if (e is _$_StripeException && e.error.localizedMessage == 'The payment flow has been canceled') {
// Handle canceled payment
print('Payment canceled by the user');
// You can show a message to the user or navigate back to the previous screen
} else {
// Handle other errors
print('Error during payment: $e');
// You might want to show a generic error message or log the error for debugging
}
Upvotes: 0
Reputation: 1222
if you have checked out all the above but nothing worked:
just set allowsDelayedPaymentMethods: true,
await Stripe.instance.initPaymentSheet(
paymentSheetParameters: SetupPaymentSheetParameters(
merchantDisplayName: 'Prospects',
customerId: data['customer'],
allowsDelayedPaymentMethods: true, // set this to true
paymentIntentClientSecret: data['client_secret'],
customerEphemeralKeySecret: data['ephemeralKey'],
));
Upvotes: 1
Reputation: 81
I had the same problem as I was following the official documentation found here. What was causing this problem was the value of paymentIntentClientSecret
.
Try changing:
paymentIntentClientSecret: data['paymentIntent']
To:
paymentIntentClientSecret: data['client_secret'],
Upvotes: 1
Reputation: 3
stripe version
flutter_stripe: ^7.0.0
await Stripe.instance.initPaymentSheet(
paymentSheetParameters: SetupPaymentSheetParameters(
merchantDisplayName: 'APP',
paymentIntentClientSecret: model.clientSecret,
customerEphemeralKeySecret: eph.secret,
customerId: model.customer,
style: ThemeMode.system,
billingDetails: billingDetail,
customFlow: true),
);
Adding the attribute 'customFlow' solves my problem
customFlow: true
Upvotes: 0
Reputation: 31
In case someone ends up here in the future and you've tried everything including adding extra settings in your main file, try also changing your customerId
field in the Stripe.instance.initPaymentSheet
to null
or some existing Id. What I found is for android it easily works but with iOS it needs a proper customerId or null.
Upvotes: 3
Reputation: 565
The Paymentsheet worked on android but did not work in iPhone for me. It took me hours to find this answer (was struggling as well). There needs to be an update in the stripe documentation but when initializing Stripe you will need to initialize Stripe.publishableKey but also initialize Stripe.merchantIdentifier
EXAMPLE
First you will need initialize Stripe in your main function. (Like shown below).
void main() async {
WidgetsFlutterBinding.ensureInitialized();
Stripe.publishableKey = stripePublishableKey;
Stripe.merchantIdentifier = 'any string works';
await Stripe.instance.applySettings();
runApp(const App());
}
Then the paymentsheet will appear without stating No payment sheet has been initialized yet
Upvotes: 38