Skip to content

Commit

Permalink
Implemented validateReceiptIos and validateReceiptAndroid.
Browse files Browse the repository at this point in the history
  • Loading branch information
hyochan committed Oct 4, 2018
1 parent 4981066 commit f3c5a15
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.7.1
* Implemented receiptValidation for both android and ios.
- In Android, you need own backend to get your `accessToken`.

## 0.7.0
* Addition of Amazon In-App Purchases.

Expand Down
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

In App Purchase plugin for flutter. This project has been `forked` from [react-native-iap](https://github.com/dooboolab/react-native-iap). We are trying to share same experience of `in-app-purchase` in `flutter` as in `react-native`.
We will keep working on it as time goes by just like we did in `react-native-iap`.
Please give stars in github repository because we want to share this project in [opencollective](https://opencollective.com/react-native-iap). We need at least 100 stars to be there. Please help us to maintain and get more sponsors and backers.

`PR` is always welcomed.

Expand Down Expand Up @@ -37,6 +36,8 @@ For help on editing plugin code, view the [documentation](https://flutter.io/dev
| consumePurchase | `String` Purchase token | `String` | Consume a product (on Android.) No-op on iOS. |
| endConnection | | `String` | End billing connection (on Android.) No-op on iOS. |
| consumeAllItems | | `String` | Manually consume all items in android. Do NOT call if you have any non-consumables (one time purchase items). No-op on iOS. |
| validateReceiptIos | `Map<String,String>` receiptBody, `bool` isTest | `http.Response` | Validate receipt for ios. |
| validateReceiptAndroid | `String` packageName, `String` productId, `String` productToken, `String` accessToken, `bool` isSubscription | `http.Response` | Validate receipt for android. |


## Data Types
Expand Down Expand Up @@ -133,6 +134,21 @@ For help on adding as a dependency, view the [documentation](https://flutter.io/
}
```

#### Receipt validation
From `0.7.1`, we support receipt validation. For Android, you need separate json file from the service account to get the `access_token` from `google-apis`, therefore it is impossible to implement serverless. You should have your own backend and get `access_token`. With `access_token` you can simply call `validateReceiptAndroid` method we implemented. Further reading is [here](https://stackoverflow.com/questions/35127086/android-inapp-purchase-receipt-validation-google-play?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa).
Currently, serverless receipt validation is possible using `validateReceiptIos` method. The first parameter, you should pass `transactionReceipt` which returns after `buyProduct`. The second parameter, you should pass whether this is `test` environment. If `true`, it will request to `sandbox` and `false` it will request to `production`.

```dart
validateReceipt() async {
var receiptBody = {
'receipt-data': purchased.transactionReceipt,
'password': '******'
};
const result = await validateReceiptIos(receiptBody, false);
console.log(result);
}
```
For further information, please refer to [guide](https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html).

## Example
Below code is just a `cp` from example project. You can test this in real example project.
Expand Down
68 changes: 68 additions & 0 deletions lib/flutter_inapp_purchase.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io' show Platform;
import 'package:http/http.dart' as http;

import 'package:flutter/services.dart';

Expand Down Expand Up @@ -371,4 +372,71 @@ class FlutterInappPurchase {
throw PlatformException(
code: Platform.operatingSystem, message: "platform not supported");
}

/// Validate receipt in ios
///
/// Example:
/// ```
/// const receiptBody = {
/// 'receipt-data': purchased.transactionReceipt,
/// 'password': '******'
/// };
/// const result = await validateReceiptIos(receiptBody, false);
/// console.log(result);
/// ```
static Future<http.Response> validateReceiptIos({
Map<String, String> receiptBody,
bool isTest = true,
}) async {
assert(receiptBody != null);
assert(isTest != null);

final String url = isTest ? 'https://sandbox.itunes.apple.com/verifyReceipt' : 'https://buy.itunes.apple.com/verifyReceipt';
return await http.post(
url,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: json.encode(receiptBody),
);
}

/// Validate receipt in android
///
/// For Android, you need separate json file from the service account to get the access_token from google-apis, therefore it is impossible to implement serverless. You should have your own backend and get access_token.
/// Read: https://stackoverflow.com/questions/35127086/android-inapp-purchase-receipt-validation-google-play?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
///
/// Example:
/// ```
/// const result = await validateReceiptAndroid(
/// packageName: 'com.dooboolab.iap',
/// productId: 'product_1',
/// productToken: 'some_token_string',
/// accessToken: 'play_console_access_token',
/// isSubscription: false,
/// );
/// console.log(result);
/// ```
static Future<http.Response> validateReceiptAndroid({
String packageName,
String productId,
String productToken,
String accessToken,
bool isSubscription = false,
}) async {
assert(packageName != null);
assert(productId != null);
assert(productToken != null);
assert(accessToken != null);

final String type = isSubscription ? 'subscriptions' : 'products';
final String url = 'https://www.googleapis.com/androidpublisher/v2/applications/$packageName/purchases/$type/$productId/tokens/$productToken?access_token=$accessToken';
return await http.get(
url,
headers: {
'Accept': 'application/json',
},
);
}
}
5 changes: 4 additions & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
name: flutter_inapp_purchase
description: In App Purchase plugin for flutter. This project has been forked by react-native-iap and we are willing to share same experience with that on react-native.
version: 0.7.0
version: 0.7.1
author: dooboolab<dooboolab@gmail.com>
homepage: https://github.com/dooboolab/flutter_inapp_purchase/blob/master/pubspec.yaml
environment:
sdk: '>=1.20.1 <3.0.0'
dependencies:
http: ^0.11.3+16
flutter:
sdk: flutter



# For information on the generic Dart part of this file, see the
# following page: https://www.dartlang.org/tools/pub/pubspec

Expand Down

0 comments on commit f3c5a15

Please sign in to comment.