Skip to content

Commit

Permalink
app: Upgrade Android IAP to billing API 6.2.
Browse files Browse the repository at this point in the history
  • Loading branch information
patniemeyer committed Aug 30, 2024
1 parent ad98f3c commit 644a27c
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 37 deletions.
4 changes: 3 additions & 1 deletion gui-orchid/lib/pages/purchase/purchase_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class _PurchasePageState extends State<PurchasePage> {
}

Widget buildPage(BuildContext context) {
// log("iap: purchase page storeDown: $_storeDown, showStoreMessage: $_showStoreMessage, storeStatus: $_storeStatus");
return SafeArea(
child: Stack(
children: <Widget>[
Expand Down Expand Up @@ -119,9 +120,10 @@ class _PurchasePageState extends State<PurchasePage> {
}

Widget _buildStoreMessage() {
// log("iap: buildStoreMessage");
Size size = MediaQuery.of(context).size;
var text = _storeStatus?.message != null
? _storeStatus!.message
? _storeStatus!.message!
: s.theOrchidStoreIsTemporarilyUnavailablePleaseCheckBackIn;
return Center(
child: Container(
Expand Down
57 changes: 37 additions & 20 deletions gui-orchid/lib/vpn/purchase/android_purchase.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import 'orchid_purchase.dart';
import 'package:in_app_purchase_android/billing_client_wrappers.dart';

class AndroidOrchidPurchaseAPI extends OrchidPurchaseAPI {

late BillingClient _billingClient;

AndroidOrchidPurchaseAPI() : super.internal();
Expand All @@ -28,17 +27,21 @@ class AndroidOrchidPurchaseAPI extends OrchidPurchaseAPI {
return OrchidPurchaseAPI.apiConfigWithOverrides(prodAPIConfig);
}


@override
Future<void> initStoreListenerImpl() async {
try {
_billingClient = BillingClient(_onPurchaseResult);
// UserSelectedAlternativeBillingListener alternativeBillingListener = (billingResult) {
// log('iap: alternative billing listener: $billingResult');
// };
UserSelectedAlternativeBillingListener? alternativeBillingListener = null;
_billingClient =
BillingClient(_onPurchaseResult, alternativeBillingListener);
// _billingClient.enablePendingPurchases();
var billingResult = await _billingClient.startConnection(
onBillingServiceDisconnected: () {
log('iap: billing client disconnected');
});

if (billingResult.responseCode == BillingResponse.ok) {
log('iap: billing client setup done');
} else {
Expand All @@ -52,7 +55,7 @@ class AndroidOrchidPurchaseAPI extends OrchidPurchaseAPI {
@override
Future<void> purchaseImpl(PAC pac) async {
var billingResultWrapper =
await _billingClient.launchBillingFlow(sku: pac.productId);
await _billingClient.launchBillingFlow(product: pac.productId);
log('iap: billing result response = ${billingResultWrapper.responseCode}');
}

Expand All @@ -67,7 +70,8 @@ class AndroidOrchidPurchaseAPI extends OrchidPurchaseAPI {
if (purchasesResult.responseCode != BillingResponse.ok) {
log('iap: Error: purchase result response code: ${purchasesResult.responseCode}');
(PacTransaction.shared.get())
?.error('iap failed 1: responseCode = ${purchasesResult.responseCode}')
?.error(
'iap failed 1: responseCode = ${purchasesResult.responseCode}')
.save();
return;
}
Expand Down Expand Up @@ -120,27 +124,40 @@ class AndroidOrchidPurchaseAPI extends OrchidPurchaseAPI {
var skuList = OrchidPurchaseAPI.pacProductIds;
log('iap: product ids requested: $skuList');

var skuDetailsResponse = await _billingClient.querySkuDetails(
skuType: SkuType.inapp, skusList: skuList);
log('iap: sku query billing result: ${skuDetailsResponse.billingResult}');
log('iap: sku details list: ${skuDetailsResponse.skuDetailsList}');

var toPAC = (SkuDetailsWrapper prod) {
double localizedPrice = prod.originalPriceAmountMicros / 1e6;
String currencyCode = prod.priceCurrencyCode;
String currencySymbol = prod.price[0];
log('iap: originalPriceAmountMicros=${prod.originalPriceAmountMicros}, currencyCode=${prod.priceCurrencyCode}, currencySymbol=${prod.price[0]}');
var productId = prod.sku;
return PAC(
List<ProductWrapper> productList = skuList.map((sku) {
return ProductWrapper(productId: sku, productType: ProductType.inapp);
}).toList();
var productDetailsResponse =
await _billingClient.queryProductDetails(productList: productList);
log('iap: sku query billing result: ${productDetailsResponse.billingResult}');
log('iap: sku details list: ${productDetailsResponse.productDetailsList}');

PAC? Function(ProductDetailsWrapper prod) toPAC =
(ProductDetailsWrapper prod) {
final otp = prod.oneTimePurchaseOfferDetails;
if (otp == null) {
log('iap: no oneTimePurchaseOfferDetails for product: ${prod.productId}');
return null;
}
// double localizedPrice = prod.originalPriceAmountMicros / 1e6;
double localizedPrice = otp.priceAmountMicros / 1e6;
// String currencyCode = prod.priceCurrencyCode;
String currencyCode = otp.priceCurrencyCode;
var productId = prod.productId;
var pac = PAC(
productId: productId,
localPrice: localizedPrice,
localCurrencyCode: currencyCode,
localCurrencySymbol: currencySymbol,
usdPriceExact: OrchidPurchaseAPI.usdPriceForProduct(productId),
);
log('iap: priceAmountMicros=${otp.priceAmountMicros}, currencyCode=${otp.priceCurrencyCode}, localCurrencySymbol=${pac.localCurrencySymbol}');
return pac;
};

var pacs = skuDetailsResponse.skuDetailsList.map(toPAC).toList();
var pacs = productDetailsResponse.productDetailsList
.map(toPAC)
.whereType() // remove nulls
.toList();
Map<String, PAC> products = {for (var pac in pacs) pac.productId: pac};
//productsCached = products;
log('iap: returning products: $products');
Expand Down
9 changes: 6 additions & 3 deletions gui-orchid/lib/vpn/purchase/orchid_pac.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class PAC {
final String productId;
final double localPrice;
final String localCurrencyCode; // e.g. 'USD'
final String localCurrencySymbol; // e.g. '$'
late String localCurrencySymbol; // e.g. '$'
final USD usdPriceExact;

/// Format the local price as a currency value with symbol.
Expand All @@ -24,9 +24,12 @@ class PAC {
required this.productId,
required this.localPrice,
required this.localCurrencyCode,
required this.localCurrencySymbol,
required this.usdPriceExact,
});
String? localCurrencySymbol,
}) {
this.localCurrencySymbol = localCurrencySymbol ??
NumberFormat.simpleCurrency(name: localCurrencyCode).currencySymbol;
}

@override
String toString() {
Expand Down
14 changes: 10 additions & 4 deletions gui-orchid/lib/vpn/purchase/orchid_pac_server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -377,9 +377,9 @@ class OrchidPACServer {
Json.toIntSafe(responseJson['store_status'], defaultValue: 0);

// parse store message
var jsonMessage = Json.trimStringOrNull(responseJson['message']);
String message = (OrchidUserConfig().getUserConfig())
.evalStringDefault('pacs.storeMessage', jsonMessage ?? '');
String? jsonMessage = Json.trimStringOrNull(responseJson['message']);
String? message = (OrchidUserConfig().getUserConfig())
.evalStringDefaultNullable('pacs.storeMessage', jsonMessage);

// parse the seller address map
// TODO: ...
Expand Down Expand Up @@ -462,12 +462,18 @@ class PACStoreStatus {
final bool open;

// Message to display or null if none.
final String message;
final String? message;

// product status
//Map<String, bool> product;

PACStoreStatus({required this.message, required this.open});

// tostring
@override
String toString() {
return 'PACStoreStatus{open: $open, message: $message}';
}
}

class PacAccount {
Expand Down
11 changes: 2 additions & 9 deletions gui-orchid/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,12 @@ dependencies:
font_awesome_flutter: 9.0.0
http: 1.1.0
in_app_purchase_storekit: 0.3.5+2
in_app_purchase_android: 0.2.3+7
# in_app_purchase_android: 0.2.3+7
in_app_purchase_android: 0.3.6+8
intl: 0.19.0
jdenticon_dart: 2.0.0
decimal: 3.0.2

# Tracking this issue which has been merged but is not yet in a tagged release.
# https://github.com/juliansteenbakker/mobile_scanner/issues/241
# mobile_scanner:
# git:
# url: https://github.com/juliansteenbakker/mobile_scanner.git
# ref: 9e4e9a167980f8413c1d8860873e582d0747edd9
mobile_scanner: 5.2.1

percent_indicator: 3.0.1
pointycastle: 3.7.3
provider: 5.0.0
Expand Down

0 comments on commit 644a27c

Please sign in to comment.