I am trying to create an application that can handle In App Purchases Using Flutter.I am using the in_app_purchase 0.2.1 plugin .I have managed to setup my product on google play developer console as required but however when try to retrieve it from the application i am able to connect to the store successfully but i am not able to retrieve my product ,it always shows up as product not found.
I have followed a this tutorial https://joebirch.co/2019/05/31/adding-in-app-purchases-to-flutter-apps/ and also looked at the package documentation https://pub.dev/packages/in_app_purchase.
My google play setup for the product is shown below
google play console setup
google play console setup2
The function i am using is shown below.
Future<List<ProductDetails>> retrieveProducts() async {
final bool available = await InAppPurchaseConnection.instance.isAvailable();
if (!available) {
// Handle store not available
print("Store Temporarily Unavailable");
return null;
} else {
print("Store Temporarily Available");
const Set<String> _kIds = {'airtime123'};
final ProductDetailsResponse response =
await InAppPurchaseConnection.instance.queryProductDetails(_kIds);
if (response.notFoundIDs.isNotEmpty) {
print("product not found");
print(response.notFoundIDs[0]);
return null;
}
print("product found");
return response.productDetails;
}
}
This is the result i get
I/flutter ( 7254): Store Temporarily Available
I/flutter ( 7254): product not found
I/flutter ( 7254): airtime123
You need to use a reserved SKU for the test: android.test.purchased
const Set<String> _kIds = {'android.test.purchased'};
final ProductDetailsResponse response =
await InAppPurchaseConnection.instance.queryProductDetails(_kIds);
Related
My Use Case:
Users in my app can create lists of items. I want the users to be able to share a link to one of their lists.
I want individuals who click the shared link to see the list of items in a web browser and not need the app installed.
Create the Dynamic Link
The first thing I need to do is create a dynamic link for a user to share. I struggled with this at first and then looked at this question here: Flutter - How to pass custom arguments in firebase dynamic links for app invite feature?
After looking at that I build my own class like so:
class PackDynamicLinkService {
Future<Uri> createDynamicLink({required String packID}) async {
final DynamicLinkParameters parameters = DynamicLinkParameters(
// This should match firebase but without the username query param
uriPrefix: 'ttps://appName.app/p',
// This can be whatever you want for the uri, https://yourapp.com/groupinvite?username=$userName
link: Uri.parse('https://appName.app/p?pack=$packID'),
androidParameters: const AndroidParameters(
packageName: 'com.test.demo',
minimumVersion: 1,
),
iosParameters: const IOSParameters(
bundleId: 'com.test.demo',
minimumVersion: '1',
appStoreId: '',
),
);
final dynamicLink = await FirebaseDynamicLinks.instance.buildShortLink(
parameters,
shortLinkType: ShortDynamicLinkType.unguessable,
);
return dynamicLink.shortUrl;
}
}
I then called that function in my app and I am able to get a URL that looks like this: https://appName.app/p?pack=lVeSBUHoLX52zPqAiB9A
So far so good. Now I just need to click the link and read the parameter $packID that I passed to it inside my web app. Then I can route them to the correct view and display the list.
Processing Dynamic Link
in my marin.dart I tried to retrieve the params with:
//get link stuff
final PendingDynamicLinkData? initialLink =
await FirebaseDynamicLinks.instance.getInitialLink();
if (initialLink != null) {
final Uri fullLink = initialLink.link;
print(fullLink.queryParameters['pack']);
}
but when I upload to firebase hosting to see if this code works for testing, I get this error:
Uncaught MissingPluginException(No implementation found for method
FirebaseDynamicLinks#getInitialLink on channel
plugins.flutter.io/firebase_dynamic_links)
After doing some more research it seems that firebase_dynamic_links package may not be available for web? So does that mean my original use case is not possible with flutter at this time?
You would want to take the link received and parse it using something like:
var PendingDynamicLinkData? initialLink =
await FirebaseDynamicLinks.instance.getInitialLink();
if (kIsWeb) {
String link = Uri.base;
initialLink = await
FirebaseDynamicLinks.instance.getDynamicLink(Uri.parse(link));
}
if (initialLink != null) {
final Uri fullLink = initialLink.link;
print(fullLink.queryParameters['pack']);
}
Here, we are checking if its a web app and then we can parse the dynamic link and get the info for it. We just check for the Uri that was used in our web app.
I'm using the official in_app_purchase plugin, version ^1.0.4, and I'm following the official guide from Google insert my first iap (https://codelabs.developers.google.com/codelabs/flutter-in-app-purchases#0).
My consumable iap product is active on Play console with name "pacchetto_25", I've already submitted to the alpha channel my app and is accepted, the tester email is correctly configured in the Tester Group and in Licence Testing.
Now I'm trying to load the iap products in my app, the code is the same of the guide:
Future<void> loadPurchases() async {
final available = await _iap.isAvailable();
if (!available) {
print("STORE NOT AVAILABLE");
return;
} else {
print("STORE AVAILABLE");
const ids = <String>{
"pacchetto_25",
};
final response = await _iap.queryProductDetails(ids);
response.notFoundIDs.forEach((element) {
print('Purchase $element not found');
});
response.productDetails.forEach((element) {
print("Purchase $element found");
});
// products =
// response.productDetails.map((e) => PurchasableProduct(e)).toList();
}
}
In my console I have the "STORE AVAILABLE" message, but then nothing else. If I put same debug point it does not stops on them, this problem appear after this line:
final response = await _iap.queryProductDetails(ids);
Do someone know what's happening? I've no errors in my console and the code after loadPurchases() is not executed, it's like is waiting forever... Any ideas?
Solved! If you have the same issue DON'T put
implementation("com.android.billingclient:billing:4.0.0")
in your build.gradle
Already I have built a flutter project. Now I need to print from a pos embedded device. I am googling, but I don't get any solution.
Please help me if there is any solution.
Actually I need for Android Q2 device
I have the same device and i already built flutter application , and ran into the same probleme .
I contacted the company and they provided me with android sdk so i added a channel and called the print from the flutter code.
EDIT:
In your case, you can download the SDK provided by the company and write native code to print the receipt.
example:
in flutter
static const platform = const MethodChannel('com.example.myapplication');
Future<void> _print() async {
try {
final bool result = await platform.invokeMethod('print',{"data":Printdata});
if (result) {
// success
} else {
// failed
}
} on PlatformException catch (e) {
//failed to print
}
}
Then in the Main.java / Main.kt implement the method from the SDK documentation
example:
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
if (call.method.equals("print")) {
data = call.argument("data");
// Code from SDK documentation
} else {
result.notImplemented();
}
}
ref: Example Nativcode in flutter
Add third party SDK to android
Try this library "flutter_bluetooth_serial" and connect to the printer via direct mac address like this:
BluetoothConnection connection = await BluetoothConnection.toAddress("mac");
I've used health-3.0.3 in my flutter application to get the Google fit data. I'm able to get every data other than STEP-data which shows zero always.
You can refer to the health package here
Health 3.0.3 Flutter
This is the code block to access the STEP datatype in my application
List<HealthDataType> types = [
HealthDataType.STEPS,
HealthDataType.WEIGHT,
//HealthDataType.HEIGHT,
];
setState(() => _state = AppState.FETCHING_DATA);
/// You MUST request access to the data types before reading them
bool accessWasGranted = await health.requestAuthorization(types);
double steps = 0;
if (accessWasGranted) {
try {
/// Fetch new data
List<HealthDataPoint> healthData =
await health.getHealthDataFromTypes(startDate, endDate, types);
/// Save all the new data points
_healthDataList.addAll(healthData);
} catch (e) {
print("Caught exception in getHealthDataFromTypes: $e");
}
/// Filter out duplicates
_healthDataList = HealthFactory.removeDuplicates(_healthDataList);
/// Print the results
_healthDataList.forEach((x) {
print("Data point: $x");
steps += (x.value as double);
});
print("Steps: $steps");
You can refer to the full code under the examples tab in the given link. Does anyone know what's wrong here?
health: 3.0.4 is more stable, when I'm writing this answer.
From Android 10. you have to add ACTIVITY_RECOGNITION for getting STEP Count permission in AndroidManifest.xml.
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
And then using permission_handler ask for permission.
if (Platform.isAndroid) {
final permissionStatus = Permission.activityRecognition.request();
if (await permissionStatus.isDenied ||
await permissionStatus.isPermanentlyDenied) {
showToast(
'activityRecognition permission required to fetch your steps count');
return;
}
}
I am creating an application in Flutter Web that needs to collect payment information to create subscription charges. My plan was to use Stripe to do this, however, after making all the necessary methods for Stripe, I found that Stripe only accepts card data through Stripe Elements. Upon further research, I saw that essentially all payment platforms do this to maintain PCI compliance.
Is there any method of embedding Stripe elements(or any equivalent) into my application or is there an easier method of accepting payments with Flutter Web?
There's an unofficial Flutter Stripe package that might be what you're after: https://pub.dev/packages/stripe_payment
There's a new package called stripe_sdk, that appears to have Web support. I haven't tried it yet, but it says Web support in the description and has a web demo aswell :)
Also the old packages for mobile won't work for web, because they rely on WebView, which is not supported (and wouldn't make much sense) on web.
In case you're using Firebase as a backend, there's a stripe payments extension you can install in Firebase which makes it easy. How it works is you add a checkout_session in to a user collection and keep listening on the document. Stripe extension will update the document with a unique payments url and we just open that URL in a new tab to make the payment in the tab. We're using it in our web app, and it's working.
Something like :
buyProduct(Product pd) async {
setState(() {
loadingPayment = true;
});
String userUid = FirebaseAuth.instance.currentUser!.uid;
var docRef = await FirebaseFirestore.instance
.collection('users')
.doc(userUid)
.collection('checkout_sessions')
.add({
'price': pd.priceId,
'quantity': pd.quantity,
'mode': 'payment',
'success_url': 'https://yourwebsite/purchase-complete',
'cancel_url': 'https://yourwebsite/payment-cancelled',
});
docRef.snapshots().listen(
(ds) async {
if (ds.exists) {
//check any error
var error;
try {
error = ds.get('error');
} catch (e) {
error = null;
}
if (error != null) {
print(error);
} else {
String url = ds.data()!.containsKey('url') ? ds.get('url') : '';
if (url != '') {
//open the url in a new tab
if (!isStripeUrlOpen) {
isStripeUrlOpen = true;
setState(
() {
loadingPayment = false;
},
);
launchUrl(Uri.parse(url));
}
}
}
}
}
},
);
}