I do receive the client secret and all my test payments are shown on stripe dashboard. However when calling present payment it gives me the error 'No payment sheet has been initialized yet'.
// calling func on cloud functions
// create payment intent
final url = Uri.parse(
'https://us-central1-wpbakery-52166.cloudfunctions.net/stripePayment');
final response =
await http.get(url, headers: {'Content-Type': 'application/json'});
_paymentIntent = json.decode(response.body);
print(_paymentIntent);
await Stripe.instance.initPaymentSheet(
paymentSheetParameters: SetupPaymentSheetParameters(
paymentIntentClientSecret: _paymentIntent['paymentIntent'],
applePay: true,
style: ThemeMode.dark,
));
await Stripe.instance.presentPaymentSheet();
}```
I assume you're using the flutter_stripe library?
If so, then you need to also be passing in merchantCountryCode in SetupPaymentSheetParameters since the docs mention that it's required when Apple Pay is enabled [1].
You should also make sure you set Stripe.merchantIdentifier before calling initPaymentSheet.
Related
I have implemented Stripe in my Flutter app, but I would like to add some information to the payment done in order to recognize the payment inside the payments list inside the Stripe dashboard panel.
This is the response from Stripe when generating a payment:
// 1. Create a payment intent on the server
final response = await http.post(
Uri.parse(
'https://...stripePaymentIntentRequest'),
body: {
'email': email,
'amount': amount.toString(),
'description': widget.codigo_pedido ,
});
final jsonResponse = jsonDecode(response.body);
print("respuests stripe: ${jsonResponse.toString()}");
respuests stripe: {paymentIntent: pi_3M6dBTCcyi0G23rG0FoA7fEl_secret_h6dewQiWveMe5HsPg5MxCduTB, ephemeralKey: ek_test_YWNjdF8xR3NQRm5DY3lpMEcyM3JHLHFiV3ZQRkpBM3VHNHNFOFM3RHJvemxiYlpyaTRSazA_00HIJiGkLl, customer: cus_MqJLygEutMbF4X, success: true}
Is there a way to add some extra information inside the payment intent?
To store additional information on the Payment Intent object, you can add a metadata. Metadata is a key-value pairs that can be attached to an object. To learn more, you review this document.
Your server side code should look something like this:
$stripe->paymentIntents->create(
[
'amount' => 1099,
'currency' => 'usd',
'metadata' => ['order_id' => '6735'],
]
);
Unhandled Exception: StripeException(error: LocalizedErrorMessage(code: FailureCode.Failed, localizedMessage: There was an unexpected error -- try again in a few seconds, message: No such payment_intent: 'pi_3M9vFfDn3WtZLRhzO5kP10SM', stripeErrorCode: resource_missing, declineCode: null, type: invalid_request_error))
I hit apple pay then after payment , reverted to stripe payment intent and then I get client secret from response . I revert that response to Stripe for payment verification and I got response as No such payment_intent or getting payment method reuired
#ᴅ ᴇ ʙ ᴊ ᴇᴇ ᴛ and #orakaro here is what I done
Future<void> onApplePayResult(paymentResult) async {
debugPrint("paymentResult.toString() is ${paymentResult.toString()}");
var data = jsonDecode(paymentResult['token']);
debugPrint("data is $data");
String transactionId = data['data'];
var response = await PaymentService().makePayment(
context: context,
amount: 100
,
);
String clientSecret = response['client_secret'].toString();
final params = PaymentMethodParams.cardFromToken(
paymentMethodData: PaymentMethodDataCardFromToken(
token: token,
));
await Stripe.instance.confirmPayment(
"clientSecret",
params,
);
}
In my flutter project, I already have notifications set up using firebase_messaging for Android and iOS. I am trying to add the same for Web. I had tried it before (mostly changing index.html with firebase-configs and initializing), but it had not worked then and I had left it. Now their document asks to use the new way, which asks only to configure it in the dart-files, and talks nothing about doing anything on index or other js files. So I have removed imports, and initialization from index.html, and not added any other file ( I have tried adding empty firebase-messaging-sw.js and removing it). This is the error I am getting:
[firebase_messaging/failed-service-worker-registration] Messaging: We are unable to register the default service worker. Failed to register a ServiceWorker for scope ('http://localhost:44055/firebase-cloud-messaging-push-scope') with script ('http://localhost:44055/firebase-messaging-sw.js'): A bad HTTP response code (404) was received when fetching the script. .
What am I missing? Are those steps incomplete? I also tried the steps in this article , but still have the same issues.
Edit
These are all the code-parts related to firebase-messaging.
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
firebaseAnalytics = FirebaseAnalytics.instance;
firebaseMessaging = FirebaseMessaging.instance; //
final notificationSettings = await firebaseMessaging.requestPermission();
debugPrint('User granted permission: ${notificationSettings.authorizationStatus}');
if (!kIsWeb) {
FirebaseMessaging.onBackgroundMessage(
_firebaseMessagingBackgroundHandler);
channel = const AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title
description: 'This channel is used for important notifications.',
// description
importance: Importance.max,
);
flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
/// Create an Android Notification Channel.
///
/// We use this channel in the `AndroidManifest.xml` file to override the
/// default FCM channel to enable heads up notifications.
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
/// Update the iOS foreground notification presentation options to allow
/// heads up notifications.
await FirebaseMessaging.instance
.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
}
.
.
.
.
.
.
.
.
if (kIsWeb) {
// this is where the code throws error:
token = (await firebaseMessaging.getToken(
vapidKey: "BLn....pH8",
))!;
} else {
token = (await firebaseMessaging.getToken())!;
}
I'm new to flutter technology and trying to learn to work with API, the confusion I'm having is that when I look down and study the stripe documentation for payment or any other API, it is accepting everything as a parameter but in my code, I'm passing the body that is required by stripe as a parameter and it works fine, so I am confused why does it work fine while the stripe API wants the data as parameters
Below is the code I've written so please anyone help me understand this,
is this because of the content type I am providing or what?
Please Clarify me,
Thanks
Map<String, dynamic> body = {
'amount': amountInUSDCents.toString(),
'currency': currency,
'payment_method_types[]': 'card',
'receipt_email': widget.email,
};
Uri url = Uri.parse('https://api.stripe.com/v1/payment_intents');
var response = await http.post(url, headers: {
'Authorization':
'Bearer secret key here',
'Content-Type': 'application/x-www-form-urlencoded'
});
I have functions witch I use to get data from the api, and the user can be logged in, but the admin can change the password of the employee, so when the user comes back to the app the besic auth token that is saved in local storage isnt the same as the one that the admin changed to since the admin changed the password, so all i need is that if there is status code such as 401 or 403 to send the user back to the log in screen. And if the response code is 500 to show like an image to come back later.
Future<Response> fetchWorkingLocationData() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
var authorization = prefs.getString('authorization');
var url = 'https://dev.api.wurk.skyver.co/api/v1/projects';
basicAuth = 'Basic ' +
base64Encode(
utf8.encode('${phoneNumberController.text}:${passwordController.text}'),
);
response2 = await http.get(
Uri.parse(url),
headers: <String, String>{
'authorization': authorization ?? basicAuth.toString()
},
);
return response2;
}
You can write custom logic based on the statusCode
So something like:
if (response2.statusCode == HttpStatus.unauthorized) {
Navigator.pushNamed(
context,
'login',
);
}
If you don't have context for the Navigator, check out https://medium.com/flutter-community/navigate-without-context-in-flutter-with-a-navigation-service-e6d76e880c1c