Closed opensourcegps closed 6 years ago
Hey, just saying I'm currently working on this.
Hi, I've made it working for Android with the code below. I bit ugly solution for pull request, requires requesting list of purchases just after purchase was made.
Added new function in BillingPlugin.java:
private void fetchPurchasesFull(final Result result) {
executeServiceRequest(new Request() {
@Override
public void execute() {
final Purchase.PurchasesResult purchasesResult = billingClient.queryPurchases(SkuType.INAPP);
final int responseCode = purchasesResult.getResponseCode();
if (responseCode == BillingResponse.OK) {
result.success(getIdentifiersFull(purchasesResult.getPurchasesList()));
} else {
result.error("ERROR", "Failed to query purchases with error " + responseCode, null);
}
}
@Override
public void failed() {
result.error("UNAVAILABLE", "Billing service is unavailable!", null);
}
});
}
private List<Object> getIdentifiersFull(List<Purchase> purchases) {
if (purchases == null) return Collections.emptyList();
//final List<String> identifiers = new ArrayList<>(purchases.size());
final List<Object> identifiers = new ArrayList<>(purchases.size());
for (Purchase purchase : purchases) {
//debug edited - works
final List<String> purchase_single = new ArrayList<>(2);
String signature = purchase.getSignature(); //! important for verification
String OriginalJson = purchase.getOriginalJson(); //! important for verification
String sku = purchase.getSku();
purchase_single.add(sku);
purchase_single.add(OriginalJson);
purchase_single.add(signature);
//add more stuff about this purchase
//https://developer.android.com/reference/com/android/billingclient/api/Purchase
identifiers.add(purchase_single);
}
return identifiers;
}
And in Dart side:
Future<Set<Object>> getPurchasesFull() {
if (_purchasesFetchedFull) {
return new Future.value(new Set.from(_purchasedProductsFull));
}
return synchronized(this, () async {
try {
final List purchases = await _channel.invokeMethod('fetchPurchasesFull');
_purchasedProductsFull.addAll(purchases.cast());
// _purchasesFetchedFull = true; //always refresh purchases list
return _purchasedProductsFull;
} catch (e) {
if (_onError != null) _onError(e);
return new Set.identity();
}
});
}
@VolodymyrLykhonis ok, so I think for implemented it correctly, we need to review some logic. At the moment when a purchase is done, on the native side, you send an array with all purchases (as string identifiers) and check if result contains the given param identifier.
For iOS there is no problem because we can grab the receipt with a simple function call. But for Android this is an other story since it's linked to a purchase. And it seems, we are not able to grab it later.
I think we should unifiate the API in all cases. purchase
method on native side should return a Dictionnary/Hash/json string with those args: success
and receipt
(and probably more informations for Android). Then on dart side, returns also this object.
Finally, I sent a commit with the logic for grabbing the receipt on iOS. We can merge easily this code with what I said above. For Android it seems to be a bit more complicated since receipt are attached to product.
It's a bit complicated to contribute correctly, since with my fork I don't have the Xcode & Android projects coming, so no real API auto completion... feeling in JS land :)
Thanks for the code example @opensourcegps, a bit ugly but... it does the job quickly!
@alamboley can you share your version for iOS verification please?
Agree, we can unify, always can bump to version to v0.3.0. Though I would suggest to define objects to represent data rather than arbitrary sets or maps of data. I left a comment on this PR with example of how to define a Receipt for both Android/iOS.
@opensourcegps you can find it here https://github.com/VolodymyrLykhonis/flutter_billing/pull/10/commits/7b23c9aaf87859253beca08eb1df880c29891bc9.
In order to validate purchases server side, receipt data must be used. How to get it with this plugin?
purchase() only returns bool, however fake purchases are very frequent and server side validation is important.
Here is server code used for validation: https://gist.github.com/menny/1985010
Code implemented in cordova plugin that might be possible to use:
For Android: https://github.com/j3k0/cordova-plugin-purchase/blob/master/src/android/com/smartmobilesoftware/inappbilling/InAppBillingPlugin.java
purchase.getSignature()
For iOS: https://github.com/j3k0/cordova-plugin-purchase/blob/master/src/ios/InAppPurchase.m
Would be great if purchase() returned array of data, including status and signature/receipt for validation server side.