Skip to content

Commit ecfa5b7

Browse files
committed
Merge branch 'release/1.1.0'
2 parents 4f8ff39 + c49da95 commit ecfa5b7

File tree

11 files changed

+171
-23
lines changed

11 files changed

+171
-23
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## 1.1.0
2+
* Add convenient `manualTrackPurchase` method to easily track purchases on Android
3+
14
## 1.0.1
25
* Downgrade Android Qonversion SDK to version 1.0.4 in order to use Android Billing Library ver. 2.2.0 instead of ver. 3.0.0 since Flutter in_app_purchases does not support it.
36

android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
group 'com.qonversion.flutter.sdk.qonversion_flutter_sdk'
2-
version '1.0-SNAPSHOT'
2+
version '1.1.0'
33

44
buildscript {
55
ext.kotlin_version = '1.3.50'

example/lib/main.dart

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
import 'package:flutter/material.dart';
21
import 'dart:async';
32

3+
import 'package:flutter/material.dart';
4+
import 'package:in_app_purchase/billing_client_wrappers.dart';
5+
import 'package:in_app_purchase/in_app_purchase.dart';
46
import 'package:qonversion_flutter/qonversion_flutter.dart';
57

68
void main() => runApp(MyApp());
@@ -22,7 +24,7 @@ class _MyAppState extends State<MyApp> {
2224
Future<void> initPlatformState() async {
2325
String uid;
2426
try {
25-
uid = await Qonversion.launch('');
27+
uid = await Qonversion.launch('PV77YHL7qnGvsdmpTs7gimsxUvY-Znl2');
2628
print(uid);
2729
} catch (e) {
2830
print('Failed to obtain uid from Qonversion.');
@@ -42,12 +44,69 @@ class _MyAppState extends State<MyApp> {
4244
title: const Text('Qonversion example app'),
4345
),
4446
body: Center(
45-
child: Text(
46-
'Qonversion uid: \n$_uid\n',
47-
textAlign: TextAlign.center,
47+
child: Column(
48+
mainAxisAlignment: MainAxisAlignment.center,
49+
children: [
50+
Text(
51+
'Qonversion uid: \n$_uid\n',
52+
textAlign: TextAlign.center,
53+
),
54+
FlatButton(
55+
child: Text('Track'),
56+
color: Colors.blue,
57+
textColor: Colors.white,
58+
onPressed: () async {
59+
final uid = await Qonversion.manualTrackPurchase(
60+
getProductDetails(), getPurchaseDetails());
61+
print(uid);
62+
},
63+
),
64+
],
4865
),
4966
),
5067
),
5168
);
5269
}
70+
71+
ProductDetails getProductDetails() {
72+
// ignore: invalid_use_of_visible_for_testing_member
73+
final original = SkuDetailsWrapper(
74+
description: 'description',
75+
freeTrialPeriod: 'freeTrialPeriod',
76+
introductoryPrice: 'introductoryPrice',
77+
introductoryPriceMicros: 'introductoryPriceMicros',
78+
introductoryPriceCycles: 'introductoryPriceCycles',
79+
introductoryPricePeriod: 'introductoryPricePeriod',
80+
price: 'price',
81+
priceAmountMicros: 1000,
82+
priceCurrencyCode: 'priceCurrencyCode',
83+
sku: 'sku',
84+
subscriptionPeriod: 'subscriptionPeriod',
85+
title: 'title',
86+
type: SkuType.inapp,
87+
isRewarded: true,
88+
originalPrice: 'originalPrice',
89+
originalPriceAmountMicros: 1000,
90+
);
91+
return ProductDetails.fromSkuDetails(original);
92+
}
93+
94+
PurchaseDetails getPurchaseDetails() {
95+
// ignore: invalid_use_of_visible_for_testing_member
96+
final original = PurchaseWrapper(
97+
orderId: 'orderId',
98+
packageName: 'packageName',
99+
purchaseTime: 0,
100+
signature: 'signature',
101+
sku: 'sku',
102+
purchaseToken: 'purchaseToken',
103+
isAutoRenewing: false,
104+
originalJson: '{}',
105+
developerPayload: 'dummyPayload',
106+
isAcknowledged: true,
107+
purchaseState: PurchaseStateWrapper.purchased,
108+
);
109+
110+
return PurchaseDetails.fromPurchase(original);
111+
}
53112
}

example/pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ dependencies:
1212
# The following adds the Cupertino Icons font to your application.
1313
# Use with the CupertinoIcons class for iOS style icons.
1414
cupertino_icons: ^0.1.2
15+
in_app_purchase: ^0.3.4+8
1516

1617
dev_dependencies:
1718
flutter_test:

ios/qonversion_flutter.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#
55
Pod::Spec.new do |s|
66
s.name = 'qonversion_flutter'
7-
s.version = '1.0.1'
7+
s.version = '1.1.0'
88
s.summary = 'Flutter Qonversion SDK'
99
s.description = <<-DESC
1010
Powerful yet simple subscription analytics

lib/qonversion.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// This file exists to support old way to import package: 'package:qonversion_flutter/qonversion.dart'.
2-
// Recommended way to import package no: 'package:qonversion_flutter/qonversion_flutter.dart'.
2+
// Recommended way to import package now is: 'package:qonversion_flutter/qonversion_flutter.dart'.
33

4-
export 'src/qonversion.dart';
54
export 'src/qa_provider.dart';
5+
export 'src/qonversion.dart';
6+
export 'src/serializer.dart';

lib/qonversion_flutter.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
export 'src/qonversion.dart';
21
export 'src/qa_provider.dart';
2+
export 'src/qonversion.dart';
3+
export 'src/serializer.dart';

lib/src/qonversion.dart

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import 'dart:io';
33

44
import 'package:flutter/foundation.dart';
55
import 'package:flutter/services.dart';
6+
import 'package:in_app_purchase/in_app_purchase.dart';
7+
import 'package:qonversion_flutter/src/serializer.dart';
68

79
import 'constants.dart';
810
import 'qa_provider.dart';
@@ -40,26 +42,45 @@ class Qonversion {
4042
return uid;
4143
}
4244

45+
/// This is a fallback method if you're not using [official in_app_purchase plugin](https://pub.dev/packages/in_app_purchase).
46+
///
47+
/// Use it only if you have to build SkuDetails and PurchaseDetails maps manually on your side.
48+
///
4349
/// Tracks purchases manually on Android.
4450
///
4551
/// Returns `null` if `!Platform.isAndroid`.
46-
///
47-
/// You can use [official in_app_purchase package](https://pub.dev/packages/in_app_purchase) and its
48-
/// [SkuDetailsWrapper](https://github.com/flutter/plugins/blob/master/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.dart)
49-
/// and [PurchaseWrapper](https://github.com/flutter/plugins/blob/master/packages/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.dart)
50-
/// to pass [details] and [purchase] arguments.
51-
Future<String> trackPurchase(
52-
Map<String, dynamic> details, Map<String, dynamic> purchase) async {
52+
static Future<String> trackPurchase(Map<String, dynamic> skuDetails,
53+
Map<String, dynamic> purchaseDetails) async {
5354
if (!Platform.isAndroid) return null;
5455

5556
final args = {
56-
Constants.kDetails: details,
57-
Constants.kPurchase: purchase,
57+
Constants.kDetails: skuDetails,
58+
Constants.kPurchase: purchaseDetails,
5859
};
5960

60-
final uid = await _channel.invokeMethod(Constants.mTrackPurchase, args);
61+
return _channel.invokeMethod(Constants.mTrackPurchase, args);
62+
}
6163

62-
return uid;
64+
/// Tracks purchases manually on Android.
65+
///
66+
/// Returns `null` if `!Platform.isAndroid`.
67+
///
68+
/// You have to use [official in_app_purchase plugin](https://pub.dev/packages/in_app_purchase) and instances of its
69+
/// [ProductDetails] and [PurchaseDetails] classes received on purchase success to track purchase with Qonversion.
70+
static Future<String> manualTrackPurchase(
71+
ProductDetails productDetails, PurchaseDetails purchaseDetails) async {
72+
if (!Platform.isAndroid) return null;
73+
74+
final skuDetails = QDetailsSerializer.buildSkuMap(productDetails.skuDetail);
75+
final billingClientPurchaseDetails = QDetailsSerializer.buildPurchaseMap(
76+
purchaseDetails.billingClientPurchase);
77+
78+
final args = {
79+
Constants.kDetails: skuDetails,
80+
Constants.kPurchase: billingClientPurchaseDetails,
81+
};
82+
83+
return _channel.invokeMethod(Constants.mTrackPurchase, args);
6384
}
6485

6586
/// Sends your attribution [data] to the [provider].

lib/src/serializer.dart

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import 'package:in_app_purchase/billing_client_wrappers.dart';
2+
3+
class QDetailsSerializer {
4+
/// Returns [Map] from billing client's [SkuDetailsWrapper]
5+
static Map<String, dynamic> buildSkuMap(SkuDetailsWrapper original) {
6+
return <String, dynamic>{
7+
'description': original.description,
8+
'freeTrialPeriod': original.freeTrialPeriod,
9+
'introductoryPrice': original.introductoryPrice,
10+
'introductoryPriceMicros': original.introductoryPriceMicros,
11+
'introductoryPriceCycles': original.introductoryPriceCycles,
12+
'introductoryPricePeriod': original.introductoryPricePeriod,
13+
'price': original.price,
14+
'priceAmountMicros': original.priceAmountMicros,
15+
'priceCurrencyCode': original.priceCurrencyCode,
16+
'sku': original.sku,
17+
'subscriptionPeriod': original.subscriptionPeriod,
18+
'title': original.title,
19+
'type': original.type.toString().substring(8),
20+
'isRewarded': original.isRewarded,
21+
'originalPrice': original.originalPrice,
22+
'originalPriceAmountMicros': original.originalPriceAmountMicros,
23+
};
24+
}
25+
26+
/// Returns [Map] from billing client's [PurchaseWrapper]
27+
static Map<String, dynamic> buildPurchaseMap(PurchaseWrapper original) {
28+
const _purchaseStateWrapperEnumMap = {
29+
PurchaseStateWrapper.unspecified_state: 0,
30+
PurchaseStateWrapper.purchased: 1,
31+
PurchaseStateWrapper.pending: 2,
32+
};
33+
return <String, dynamic>{
34+
'orderId': original.orderId,
35+
'packageName': original.packageName,
36+
'purchaseTime': original.purchaseTime,
37+
'signature': original.signature,
38+
'sku': original.sku,
39+
'purchaseToken': original.purchaseToken,
40+
'isAutoRenewing': original.isAutoRenewing,
41+
'originalJson': original.originalJson,
42+
'developerPayload': original.developerPayload,
43+
'purchaseState': _purchaseStateWrapperEnumMap[original.purchaseState],
44+
'isAcknowledged': original.isAcknowledged,
45+
};
46+
}
47+
}

pubspec.lock

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,20 @@ packages:
6060
description: flutter
6161
source: sdk
6262
version: "0.0.0"
63+
in_app_purchase:
64+
dependency: "direct main"
65+
description:
66+
name: in_app_purchase
67+
url: "https://pub.dartlang.org"
68+
source: hosted
69+
version: "0.3.4+8"
70+
json_annotation:
71+
dependency: transitive
72+
description:
73+
name: json_annotation
74+
url: "https://pub.dartlang.org"
75+
source: hosted
76+
version: "3.0.1"
6377
matcher:
6478
dependency: transitive
6579
description:
@@ -144,4 +158,4 @@ packages:
144158
version: "2.0.8"
145159
sdks:
146160
dart: ">=2.9.0-14.0.dev <3.0.0"
147-
flutter: ">=1.10.0 <2.0.0"
161+
flutter: ">=1.12.13+hotfix.5 <2.0.0"

0 commit comments

Comments
 (0)