From 24c0f9072c94bd9f258fbe7b8ddddfadd2a8b1e0 Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Tue, 12 Aug 2025 04:30:08 -0400 Subject: [PATCH 01/34] feat: payments v4 Bump Android billing v8 Use StoreKitV2 & V1 for older devices --- apps/demo/src/plugin-demos/payments.ts | 160 +- packages/payments/failure/common.ts | 32 - packages/payments/failure/index.android.ts | 59 - packages/payments/failure/index.d.ts | 5 - packages/payments/failure/index.ios.ts | 57 - packages/payments/index.android.ts | 709 +- packages/payments/index.d.ts | 66 +- packages/payments/index.ios.ts | 488 +- packages/payments/item/common.ts | 36 - packages/payments/item/index.android.ts | 52 - packages/payments/item/index.d.ts | 9 - packages/payments/item/index.ios.ts | 37 - packages/payments/order/common.ts | 28 - packages/payments/order/index.android.ts | 53 - packages/payments/order/index.d.ts | 9 - packages/payments/order/index.ios.ts | 51 - packages/payments/package.json | 2 +- .../platforms/android/AndroidManifest.xml | 11 +- .../payments/platforms/android/include.gradle | 8 +- .../nativescript/plugins/payments/Payments.kt | 420 + .../nativescript/plugins/payments/Product.kt | 62 + .../plugins/payments/Transaction.kt | 115 + .../platforms/ios/src/NSCPayment.swift | 690 ++ packages/payments/typings/android.d.ts | 5380 +----------- .../typings/billingclient.android.d.ts | 7689 +++++++++++++++++ .../payments/typings/objc!NSCPayments.d.ts | 149 + 26 files changed, 9860 insertions(+), 6517 deletions(-) delete mode 100644 packages/payments/failure/common.ts delete mode 100644 packages/payments/failure/index.android.ts delete mode 100644 packages/payments/failure/index.d.ts delete mode 100644 packages/payments/failure/index.ios.ts delete mode 100644 packages/payments/item/common.ts delete mode 100644 packages/payments/item/index.android.ts delete mode 100644 packages/payments/item/index.d.ts delete mode 100644 packages/payments/item/index.ios.ts delete mode 100644 packages/payments/order/common.ts delete mode 100644 packages/payments/order/index.android.ts delete mode 100644 packages/payments/order/index.d.ts delete mode 100644 packages/payments/order/index.ios.ts create mode 100644 packages/payments/platforms/android/java/org/nativescript/plugins/payments/Payments.kt create mode 100644 packages/payments/platforms/android/java/org/nativescript/plugins/payments/Product.kt create mode 100644 packages/payments/platforms/android/java/org/nativescript/plugins/payments/Transaction.kt create mode 100644 packages/payments/platforms/ios/src/NSCPayment.swift create mode 100644 packages/payments/typings/billingclient.android.d.ts create mode 100644 packages/payments/typings/objc!NSCPayments.d.ts diff --git a/apps/demo/src/plugin-demos/payments.ts b/apps/demo/src/plugin-demos/payments.ts index bd6b5d0..610467f 100644 --- a/apps/demo/src/plugin-demos/payments.ts +++ b/apps/demo/src/plugin-demos/payments.ts @@ -1,5 +1,5 @@ import { EventData, ItemEventData, Observable, ObservableArray, Page } from '@nativescript/core'; -import { buyItem, BuyItemOptions, canMakePayments, fetchItems, finalizeOrder, init as initPayments, Item, PaymentEvent, paymentEvents, toMainThread } from '@nativescript/payments'; +import { Product, Payment } from '@nativescript/payments'; import { ObservableProperty } from '../obs-prop'; let subscription; @@ -11,14 +11,16 @@ export function navigatedTo(args: EventData) { export class DemoModel extends Observable { @ObservableProperty() - items: ObservableArray; + items: ObservableArray; private _isPaymentSystemInitialized = false; private _inPurchaseFlow = false; - + private _payment: Payment; constructor() { super(); + console.log('is payment supported: ' + Payment.isSupported()); + if (this._isPaymentSystemInitialized === true) { // if already initialized don't run everything again return; @@ -26,77 +28,107 @@ export class DemoModel extends Observable { // Subscribe the Handlers - paymentEvents.pipe(toMainThread()).subscribe((event: PaymentEvent.Type) => { - switch (event.context) { - case PaymentEvent.Context.CONNECTING_STORE: - if (event.result === PaymentEvent.Result.SUCCESS) { - if (!this._isPaymentSystemInitialized) { - console.log('🟢 Initialized In App Purchase Payments 🟢'); - const canPay = canMakePayments(); - console.log(`${canPay ? '🟢 Can Make Payments 🟢' : '🛑 Unable to make payments 🛑'}`); - - if (canPay) { - fetchItems(['io.nstudio.iapdemo.coinsfive', 'io.nstudio.iapdemo.coinsone', 'io.nstudio.iapdemo.coinsonethousand']); - // fetchSubscriptions(['io.nstudio.iapdemo.monthly_subscription']); - } - this._isPaymentSystemInitialized = true; - } - } - break; - case PaymentEvent.Context.RETRIEVING_ITEMS: - console.log('RETRIEVING_ITEMS STATUS: ' + event.result); - if (event.result === PaymentEvent.Result.SUCCESS) { - console.log(event); - this.items = new ObservableArray(event.payload); - console.log(`🟢 Got ${this.items.length} In App Purchase Items 🟢`); - } - break; - case PaymentEvent.Context.PROCESSING_ORDER: - // console.log(event); - if (event.result === PaymentEvent.Result.FAILURE) { - console.log(`🛑 Payment Failure - ${event.payload.description} ${event.payload.nativeCode} ${event.payload.type} 🛑`); - this._inPurchaseFlow = false; - } else if (event.result === PaymentEvent.Result.SUCCESS) { - console.log('🟢 Payment Success 🟢'); - // console.log(event); - console.log(`Order Id: ${event.payload.orderId}`); - console.log(`Order Date: ${event.payload.orderDate}`); - console.log(`Receipt Token: ${event.payload.receiptToken}`); - finalizeOrder(event.payload); - } - break; - case PaymentEvent.Context.FINALIZING_ORDER: - if (event.result === PaymentEvent.Result.SUCCESS) { - console.log('Order Finalized'); + // paymentEvents.pipe(toMainThread()).subscribe((event: PaymentEvent.Type) => { + // switch (event.context) { + // case PaymentEvent.Context.CONNECTING_STORE: + // if (event.result === PaymentEvent.Result.SUCCESS) { + // if (!this._isPaymentSystemInitialized) { + // console.log('🟢 Initialized In App Purchase Payments 🟢'); + // const canPay = canMakePayments(); + // console.log(`${canPay ? '🟢 Can Make Payments 🟢' : '🛑 Unable to make payments 🛑'}`); + + // if (canPay) { + // fetchItems(['io.nstudio.iapdemo.coinsfive', 'io.nstudio.iapdemo.coinsone', 'io.nstudio.iapdemo.coinsonethousand']); + // // fetchSubscriptions(['io.nstudio.iapdemo.monthly_subscription']); + // } + // this._isPaymentSystemInitialized = true; + // } + // } + // break; + // case PaymentEvent.Context.RETRIEVING_ITEMS: + // console.log('RETRIEVING_ITEMS STATUS: ' + event.result); + // if (event.result === PaymentEvent.Result.SUCCESS) { + // console.log(event); + // this.items = new ObservableArray(event.payload); + // console.log(`🟢 Got ${this.items.length} In App Purchase Items 🟢`); + // } + // break; + // case PaymentEvent.Context.PROCESSING_ORDER: + // // console.log(event); + // if (event.result === PaymentEvent.Result.FAILURE) { + // console.log(`🛑 Payment Failure - ${event.payload.description} ${event.payload.nativeCode} ${event.payload.type} 🛑`); + // this._inPurchaseFlow = false; + // } else if (event.result === PaymentEvent.Result.SUCCESS) { + // console.log('🟢 Payment Success 🟢'); + // // console.log(event); + // console.log(`Order Id: ${event.payload.orderId}`); + // console.log(`Order Date: ${event.payload.orderDate}`); + // console.log(`Receipt Token: ${event.payload.receiptToken}`); + // finalizeOrder(event.payload); + // } + // break; + // case PaymentEvent.Context.FINALIZING_ORDER: + // if (event.result === PaymentEvent.Result.SUCCESS) { + // console.log('Order Finalized'); + // } + // break; + // case PaymentEvent.Context.RESTORING_ORDERS: + // console.log(event); + // break; + // default: + // console.log(`Invalid EventContext: ${event}`); + // break; + // } + // }); + + // subscription = paymentEvents.connect(); + + // Here we initialize the payment system + // initPayments(); + this._payment = new Payment(); + this._payment.onPurchaseUpdate = (purchases, error) => { + if (error) { + console.error(`🛑 Purchase Update Error: ${error} 🛑`); + } else { + console.log(`🟢 Purchase Update: ${purchases.length} items 🟢`); + purchases.forEach((transaction) => { + if (transaction.state === 'pending') { + transaction.finish(); + } else if (transaction.state === 'purchased') { + console.log(`🟢 Purchase Update: ${JSON.stringify(transaction.json)} 🟢`); } - break; - case PaymentEvent.Context.RESTORING_ORDERS: - console.log(event); - break; - default: - console.log(`Invalid EventContext: ${event}`); - break; + }); } - }); + }; + this._payment.onReady = async () => { + try { + console.log('🟢 Payment System Ready 🟢'); + const purchases = await this._payment.fetchPurchases(); + console.log(`🟢 Fetched previous ${purchases.length} In App Purchase Items 🟢`); - subscription = paymentEvents.connect(); + const products = await this._payment.fetchProducts(['io.nstudio.iapdemo.coinsfive', 'io.nstudio.iapdemo.coinsone', 'io.nstudio.iapdemo.coinsonethousand'], 'inapp'); - // Here we initialize the payment system - initPayments(); + this.items = new ObservableArray(products); + } catch (error) { + console.error(`🛑 Error: ${error} 🛑`); + } + }; } // The event will be raise when an item inside the ListView is tapped. onItemTap(args: ItemEventData) { const item = this.items.getItem(args.index); - this._inPurchaseFlow = true; - const opts: BuyItemOptions = { - // accountUserName: 'bradwaynemartin@gmail.com', - ios: { - quantity: 1, - }, - }; + this._payment.purchaseProduct(item); + + // this._inPurchaseFlow = true; + // const opts: BuyItemOptions = { + // // accountUserName: 'bradwaynemartin@gmail.com', + // ios: { + // quantity: 1, + // }, + // }; - buyItem(item, opts); + // buyItem(item, opts); } } diff --git a/packages/payments/failure/common.ts b/packages/payments/failure/common.ts deleted file mode 100644 index f1afaca..0000000 --- a/packages/payments/failure/common.ts +++ /dev/null @@ -1,32 +0,0 @@ -export abstract class BaseFailure { - protected _type: FailureTypes | null; - protected _description: string; - protected _nativeCode: number | null; - - constructor(errorCode: number | null) { - this._nativeCode = errorCode; - } - - public get type(): FailureTypes | null { - return this._type; - } - - public get description(): string { - return this._description; - } - - public get nativeCode(): number | null { - return this._nativeCode; - } -} - -export enum FailureTypes { - PRODUCT_UNAVAILABLE = 'PRODUCT_UNAVAILABLE', - DEVELOPER_USAGE = 'DEVELOPER_USAGE', - PRODUCT_ALREADY_OWNED = 'PRODUCT_ALREADY_OWNED', - PRODUCT_NOT_OWNED = 'PRODUCT_NOT_OWNED', - USER_CANCELLED = 'USER_CANCELLED', - NETWORK_AVAILABILITY = 'NETWORK_AVAILABILITY', - BILLING_AVAILABILITY = 'BILLING_AVAILABILITY', - UNSPECIFIED = 'UNSPECIFIED' -} diff --git a/packages/payments/failure/index.android.ts b/packages/payments/failure/index.android.ts deleted file mode 100644 index 5713726..0000000 --- a/packages/payments/failure/index.android.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { BaseFailure, FailureTypes } from './common'; - -export { FailureTypes } from './common'; - -export class Failure extends BaseFailure { - constructor(errorCode: number | null) { - super(errorCode); - switch (errorCode) { - case com.android.billingclient.api.BillingClient.BillingResponseCode.FEATURE_NOT_SUPPORTED /*-2*/: - this._type = FailureTypes.BILLING_AVAILABILITY; - this._description = 'Requested feature is not supported by Play Store on the current device.'; - break; - case com.android.billingclient.api.BillingClient.BillingResponseCode.SERVICE_DISCONNECTED /*-1*/: - this._type = FailureTypes.BILLING_AVAILABILITY; - this._description = 'Play Store service is not connected now - potentially transient state.'; - break; - case com.android.billingclient.api.BillingClient.BillingResponseCode.OK /*0*/: - this._type = null; - this._description = 'Success. Not an error.'; - break; - case com.android.billingclient.api.BillingClient.BillingResponseCode.USER_CANCELED /*1*/: - this._type = FailureTypes.USER_CANCELLED; - this._description = 'User pressed back or canceled a dialog.'; - break; - case com.android.billingclient.api.BillingClient.BillingResponseCode.SERVICE_UNAVAILABLE /*2*/: - this._type = FailureTypes.BILLING_AVAILABILITY; - this._description = 'Network connection is down.'; - break; - case com.android.billingclient.api.BillingClient.BillingResponseCode.BILLING_UNAVAILABLE /*3*/: - this._type = FailureTypes.BILLING_AVAILABILITY; - this._description = 'Billing API version is not supported for the type requested.'; - break; - case com.android.billingclient.api.BillingClient.BillingResponseCode.ITEM_UNAVAILABLE /*4*/: - this._type = FailureTypes.PRODUCT_UNAVAILABLE; - this._description = 'Requested product is not available for purchase.'; - break; - case com.android.billingclient.api.BillingClient.BillingResponseCode.DEVELOPER_ERROR /*5*/: - this._type = FailureTypes.DEVELOPER_USAGE; - this._description = 'Invalid arguments provided to the API.'; - break; - case com.android.billingclient.api.BillingClient.BillingResponseCode.ERROR /*6*/: - this._type = FailureTypes.UNSPECIFIED; - this._description = 'Fatal error during the API action.'; - break; - case com.android.billingclient.api.BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED /*7*/: - this._type = FailureTypes.PRODUCT_ALREADY_OWNED; - this._description = 'Failure to purchase since item is already owned.'; - break; - case com.android.billingclient.api.BillingClient.BillingResponseCode.ITEM_NOT_OWNED /*8*/: - this._type = FailureTypes.PRODUCT_NOT_OWNED; - this._description = 'Failure to consume since item is not owned. (Or restored and already consumed).'; - break; - default: - this._type = FailureTypes.UNSPECIFIED; - this._description = 'Not a known native error code.'; - break; - } - } -} diff --git a/packages/payments/failure/index.d.ts b/packages/payments/failure/index.d.ts deleted file mode 100644 index 0c84629..0000000 --- a/packages/payments/failure/index.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { BaseFailure } from './common'; -export { FailureTypes } from './common'; -export declare class Failure extends BaseFailure { - constructor(errorCode: number | null); -} diff --git a/packages/payments/failure/index.ios.ts b/packages/payments/failure/index.ios.ts deleted file mode 100644 index 152b08b..0000000 --- a/packages/payments/failure/index.ios.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { BaseFailure, FailureTypes } from './common'; - -export { FailureTypes } from './common'; - -export class Failure extends BaseFailure { - constructor(errorCode: number | null) { - super(errorCode); - switch ( - errorCode // TODO Handle Domain? - ) { - case SKErrorCode.Unknown /*0*/: - this._type = FailureTypes.UNSPECIFIED; - this._description = 'Indicates that an unknown or unexpected error occurred.'; - break; - case SKErrorCode.ClientInvalid /*1*/: - this._type = FailureTypes.PRODUCT_ALREADY_OWNED; - this._description = 'Indicates that the client is not allowed to perform the attempted action.'; - break; - case SKErrorCode.PaymentCancelled /*2*/: - this._type = FailureTypes.USER_CANCELLED; - this._description = 'Indicates that the user cancelled a payment request.'; - break; - case SKErrorCode.PaymentInvalid /*3*/: - this._type = FailureTypes.DEVELOPER_USAGE; - this._description = 'Indicates that one of the payment parameters was not recognized by the Apple App Store.'; - break; - case SKErrorCode.PaymentNotAllowed /*4*/: - this._type = FailureTypes.BILLING_AVAILABILITY; - this._description = 'Indicates that the user is not allowed to authorize payments.'; - break; - case SKErrorCode.StoreProductNotAvailable /*5*/: - this._type = FailureTypes.PRODUCT_UNAVAILABLE; - this._description = 'Indicates that the requested product is not available in the store.'; - break; - case SKErrorCode.CloudServicePermissionDenied /*6*/: - this._type = FailureTypes.BILLING_AVAILABILITY; - this._description = 'Indicates that the user has not allowed access to Cloud service information.'; - break; - case SKErrorCode.CloudServiceNetworkConnectionFailed /*7*/: - this._type = FailureTypes.NETWORK_AVAILABILITY; - this._description = 'Indicates that the device could not connect to the network.'; - break; - case SKErrorCode.CloudServiceRevoked /*8*/: - this._type = FailureTypes.BILLING_AVAILABILITY; - this._description = 'Indicates that the user has revoked permission to use this cloud service.'; - break; - case 999 /*Custom for attempting to finish an incomplete transaction*/: - this._type = FailureTypes.PRODUCT_NOT_OWNED; - this._description = 'Indicates attempt to finalize invalid, provisional, or restored order.'; - break; - default: - this._type = FailureTypes.UNSPECIFIED; - this._description = 'Not a known native error code.'; - break; - } - } -} diff --git a/packages/payments/index.android.ts b/packages/payments/index.android.ts index 9cd0cbc..f905a60 100644 --- a/packages/payments/index.android.ts +++ b/packages/payments/index.android.ts @@ -1,516 +1,281 @@ -import { Application, Utils } from '@nativescript/core'; -import { BuyItemOptions, PaymentEvent, _payments$ } from './common'; -import { Failure } from './failure'; -import { Item } from './item'; -import { Order, OrderState } from './order'; - -export { PaymentEvent, paymentEvents, payments$, toMainThread } from './common'; -export * from './failure'; -export * from './item'; -export * from './order'; - -let _billingClient: com.android.billingclient.api.BillingClient | null; -let _isBillingAvailable: boolean; - -export function init(): void { - if (!_billingClient) { - _payments$.next({ - context: PaymentEvent.Context.CONNECTING_STORE, - result: PaymentEvent.Result.STARTED, - payload: null, - }); - const context = Utils.android.getApplicationContext(); - if (context) { - _billingClient = com.android.billingclient.api.BillingClient.newBuilder(context) - .enablePendingPurchases() - .setListener( - new com.android.billingclient.api.PurchasesUpdatedListener({ - onPurchasesUpdated(result, purchases: java.util.List): void { - _purchaseHandler(result.getResponseCode(), purchases); - }, - }) - ) - .build(); - _payments$.next({ - context: PaymentEvent.Context.CONNECTING_STORE, - result: PaymentEvent.Result.PENDING, - payload: null, - }); - _billingClient.startConnection( - new com.android.billingclient.api.BillingClientStateListener({ - onBillingSetupFinished(result: com.android.billingclient.api.BillingResult): void { - const resultCode = result.getResponseCode(); - if (_billingClient) { - if (resultCode === com.android.billingclient.api.BillingClient.BillingResponseCode.OK) { - // use this boolean so the user can call `canMakePayments()` - _isBillingAvailable = true; - _billingClient.queryPurchaseHistoryAsync( - com.android.billingclient.api.BillingClient.SkuType.INAPP, - new com.android.billingclient.api.PurchaseHistoryResponseListener({ - onPurchaseHistoryResponse: (historyResult, purchaseList) => { - const responseCode = historyResult.getResponseCode(); - _purchaseHandler(responseCode, purchaseList, com.android.billingclient.api.BillingClient.SkuType.INAPP); - _payments$.next({ - context: PaymentEvent.Context.CONNECTING_STORE, - result: PaymentEvent.Result.SUCCESS, - payload: null, - }); - }, - }) - ); - _billingClient.queryPurchaseHistoryAsync( - com.android.billingclient.api.BillingClient.SkuType.SUBS, - new com.android.billingclient.api.PurchaseHistoryResponseListener({ - onPurchaseHistoryResponse: (historyResult, purchaseList) => { - const responseCode = historyResult.getResponseCode(); - _purchaseHandler(responseCode, purchaseList, com.android.billingclient.api.BillingClient.SkuType.SUBS); - _payments$.next({ - context: PaymentEvent.Context.CONNECTING_STORE, - result: PaymentEvent.Result.SUCCESS, - payload: null, - }); - }, - }) - ); - } else { - const code = _mapBillingResponseCode(resultCode); - console.log(new Error(`🛑 In App Billing Response Error Code: ${resultCode} - ${code}`)); - if (resultCode === com.android.billingclient.api.BillingClient.BillingResponseCode.BILLING_UNAVAILABLE) { - console.log('The device you are testing on may not have Google Play setup.'); - } - // use this boolean so the user can call `canMakePayments()` - _isBillingAvailable = false; - _payments$.next({ - context: PaymentEvent.Context.CONNECTING_STORE, - result: PaymentEvent.Result.FAILURE, - payload: new Failure(resultCode), - }); - } - } else { - console.error(new Error('BillingClient missing.')); - } - }, - onBillingServiceDisconnected(): void { - console.log('Billing Service disconnected.'); - // .startConnection // TODO Handle retrying connection ? - }, - }) - ); - } else { - console.error(new Error('Application context missing.')); - } +import { Utils } from '@nativescript/core'; +declare const kotlin: any; + +export class PaymentError extends Error { + private nativeError: any; + constructor(message: string, nativeError?: any) { + super(message); + this.nativeError = nativeError; } -} -export function tearDown() { - if (_billingClient) { - _billingClient.endConnection(); + get code(): number { + return this.nativeError?.getCode() ?? Number.MAX_SAFE_INTEGER; } - _billingClient = null; -} -export function fetchItems(itemIds: Array): void { - fetchProducts(itemIds, com.android.billingclient.api.BillingClient.SkuType.INAPP); -} + get subCode(): number { + return this.nativeError?.getSubCode() ?? Number.MAX_SAFE_INTEGER; + } -export function fetchSubscriptions(itemIds: Array): void { - fetchProducts(itemIds, com.android.billingclient.api.BillingClient.SkuType.SUBS); + get native(): any { + return this.nativeError; + } + + private _resolution: string; + get resolution(): string { + if (this._resolution) { + return this._resolution; + } + if (this.nativeError && this.nativeError.getResolution) { + this._resolution = this.nativeError.getResolution(); + } + return this._resolution ?? ''; + } } -export function fetchProducts(itemIds: Array, skuType: string) { - if (_billingClient) { - _payments$.next({ - context: PaymentEvent.Context.RETRIEVING_ITEMS, - result: PaymentEvent.Result.STARTED, - payload: itemIds, - }); +export class Transaction { + readonly native: org.nativescript.plugins.payments.Transaction; + constructor(native: org.nativescript.plugins.payments.Transaction) { + this.native = native; + } - const skuList = new java.util.ArrayList(); - itemIds.forEach((value) => { - return skuList.add(value); - }); + static fromNative(native: org.nativescript.plugins.payments.Transaction): Transaction { + if (native instanceof org.nativescript.plugins.payments.Transaction) { + return new Transaction(native); + } + return null; + } - // const params = com.android.billingclient.api.SkuDetailsParams.newBuilder(); - // params.setSkusList(skuList).setType(skuType); - - const details = com.android.billingclient.api.QueryProductDetailsParams.newBuilder() - .setProductList( - java.util.Arrays.asList( - itemIds.map((id) => { - return com.android.billingclient.api.QueryProductDetailsParams.Product.newBuilder().setProductId(id).setProductType(skuType).build(); - }) - ) - ) - .build(); - - _billingClient.queryProductDetailsAsync( - details, - new com.android.billingclient.api.ProductDetailsResponseListener({ - onProductDetailsResponse(result: com.android.billingclient.api.BillingResult, detailsList: java.util.List) { - const responseCode = result.getResponseCode(); - if (responseCode === com.android.billingclient.api.BillingClient.BillingResponseCode.OK) { - const products = []; - const size = detailsList.size(); - for (let i = 0; i < size; i++) { - products.push(new Item(detailsList.get(i))); - } - _payments$.next({ - context: PaymentEvent.Context.RETRIEVING_ITEMS, - result: PaymentEvent.Result.SUCCESS, - payload: products, - }); - } else { - const code = _mapBillingResponseCode(responseCode); - console.log(new Error(`Failed to fetch products for purchase: ${responseCode} - ${code}`)); - _payments$.next({ - context: PaymentEvent.Context.RETRIEVING_ITEMS, - result: PaymentEvent.Result.FAILURE, - payload: new Failure(responseCode), - }); - } - }, - }) - ); + get receiptToken(): string { + return this.native.getToken(); + } - _payments$.next({ - context: PaymentEvent.Context.RETRIEVING_ITEMS, - result: PaymentEvent.Result.PENDING, - payload: itemIds, - }); - } else { - console.error(new Error('BillingClient missing.')); + get signature(): string { + return this.native.getSignature(); } -} -export function buyItem(item: Item, buyItemOptions?: BuyItemOptions): void { - startOrder(item, com.android.billingclient.api.BillingClient.SkuType.INAPP, buyItemOptions); -} -export function startSubscription(item: Item, options?: BuyItemOptions) { - startOrder(item, com.android.billingclient.api.BillingClient.SkuType.SUBS, options); -} + get quantity(): number { + return this.native.getQuantity(); + } -export function startOrder(item: Item, skuType: string, options?: BuyItemOptions) { - if (_billingClient) { - let pendingCount = 0; - _billingClient.queryPurchasesAsync( - skuType, - new com.android.billingclient.api.PurchasesResponseListener({ - onQueryPurchasesResponse(result: com.android.billingclient.api.BillingResult, pending: java.util.List) { - // const pending = _billingClient.queryPurchases(skuType).getPurchasesList(); - if (pending) { - pendingCount = pending.size(); - } - if (!pendingCount) { - _payments$.next({ - context: PaymentEvent.Context.PROCESSING_ORDER, - result: PaymentEvent.Result.PENDING, - payload: pendingCount + 1, - }); - - const paramsBuilder = com.android.billingclient.api.BillingFlowParams.newBuilder(); - - let details; - if (skuType == com.android.billingclient.api.BillingClient.SkuType.INAPP) { - details = com.android.billingclient.api.BillingFlowParams.ProductDetailsParams.newBuilder() - .setProductDetails(item.nativeValue as com.android.billingclient.api.ProductDetails) - .build(); - } else if (skuType == com.android.billingclient.api.BillingClient.SkuType.SUBS) { - details = com.android.billingclient.api.BillingFlowParams.ProductDetailsParams.newBuilder() - .setProductDetails(item.nativeValue as com.android.billingclient.api.ProductDetails) - .setOfferToken(item.offerToken) - .build(); - } + get productId(): string { + return this.native.getProductId(); + } - paramsBuilder.setProductDetailsParamsList(java.util.Arrays.asList([details])); + get orderId(): string { + return this.native.getOrderId(); + } - if (options) { - if (options?.accountUserName) { - paramsBuilder.setObfuscatedProfileId(options.accountUserName); - } + get orderDate(): Date { + return new Date(this.native.getOrderDate()); + } - if (options?.android?.obfuscatedProfileId) { - paramsBuilder.setObfuscatedProfileId(options.android.obfuscatedProfileId); - } + get state(): 'pending' | 'purchased' | 'unknown' { + switch (this.native.getState()) { + case org.nativescript.plugins.payments.Transaction.State.Pending: + return 'pending'; + case org.nativescript.plugins.payments.Transaction.State.Purchased: + return 'purchased'; + default: + return 'unknown'; + } + } - if (options?.android?.obfuscatedAccountId) { - paramsBuilder.setObfuscatedAccountId(options.android.obfuscatedAccountId); - } + finish() { + return new Promise((resolve, reject) => { + this.native.finish( + new kotlin.jvm.functions.Function1({ + invoke(response): void { + if (response) { + reject(new Error(response.getMessage())); + return; } - const result = _billingClient.launchBillingFlow(Application.android.foregroundActivity, paramsBuilder.build()); - const responseCode = result.getResponseCode(); - if (responseCode === com.android.billingclient.api.BillingClient.BillingResponseCode.OK) { - _payments$.next({ - context: PaymentEvent.Context.PROCESSING_ORDER, - result: PaymentEvent.Result.STARTED, - payload: item, - }); - } else { - _payments$.next({ - context: PaymentEvent.Context.PROCESSING_ORDER, - result: PaymentEvent.Result.FAILURE, - payload: new Failure(responseCode), - }); - } - } else { - _payments$.next({ - context: PaymentEvent.Context.PROCESSING_ORDER, - result: PaymentEvent.Result.PENDING, - payload: pendingCount, - }); - } - }, - }) - ); - } else { - console.error(new Error('BillingClient missing.')); + resolve(); + }, + }), + ); + }); + } + + toJSON() { + return { + json: this.json, + signature: this.signature, + quantity: this.quantity, + orderId: this.orderId, + state: this.state, + }; } } -export function finalizeOrder(order: Order): void { - if (_billingClient) { - if (order.isSubscription) { - if (order.acknowledged) { - _payments$.next({ - context: PaymentEvent.Context.FINALIZING_ORDER, - result: PaymentEvent.Result.SUCCESS, - payload: new Order(order.nativeValue, order.restored), - }); - - return; - } +export class Product { + readonly native: org.nativescript.plugins.payments.Product; + constructor(native: org.nativescript.plugins.payments.Product) { + this.native = native; + } - const params = com.android.billingclient.api.AcknowledgePurchaseParams.newBuilder().setPurchaseToken(order.receiptToken).build(); - - _billingClient.acknowledgePurchase( - params, - new com.android.billingclient.api.AcknowledgePurchaseResponseListener({ - onAcknowledgePurchaseResponse: (result) => { - if (result.getResponseCode() === com.android.billingclient.api.BillingClient.BillingResponseCode.OK) { - _payments$.next({ - context: PaymentEvent.Context.FINALIZING_ORDER, - result: PaymentEvent.Result.SUCCESS, - payload: new Order(order.nativeValue, order.restored), - }); - } else { - _payments$.next({ - context: PaymentEvent.Context.FINALIZING_ORDER, - result: PaymentEvent.Result.FAILURE, - payload: new Failure(result.getResponseCode()), - }); - } - }, - }) - ); - } else { - _payments$.next({ - context: PaymentEvent.Context.FINALIZING_ORDER, - result: PaymentEvent.Result.STARTED, - payload: order, - }); - if (order.state === OrderState.VALID && !order.restored) { - const consumeParams = com.android.billingclient.api.ConsumeParams.newBuilder().setPurchaseToken(order.receiptToken).build(); - _billingClient.consumeAsync( - consumeParams, - new com.android.billingclient.api.ConsumeResponseListener({ - onConsumeResponse: (result, purchaseToken) => { - const responseCode = result.getResponseCode(); - if (_billingClient) { - if (responseCode === com.android.billingclient.api.BillingClient.BillingResponseCode.OK) { - _payments$.next({ - context: PaymentEvent.Context.FINALIZING_ORDER, - result: PaymentEvent.Result.SUCCESS, - payload: new Order(order.nativeValue, order.restored), - }); - } else { - _payments$.next({ - context: PaymentEvent.Context.FINALIZING_ORDER, - result: PaymentEvent.Result.FAILURE, - payload: new Failure(responseCode), - }); - } - - _billingClient.queryPurchasesAsync( - com.android.billingclient.api.BillingClient.SkuType.INAPP, - new com.android.billingclient.api.PurchasesResponseListener({ - onQueryPurchasesResponse(param0: com.android.billingclient.api.BillingResult, pending: java.util.List) { - _payments$.next({ - context: PaymentEvent.Context.PROCESSING_ORDER, - result: PaymentEvent.Result.PENDING, - payload: pending ? pending.size() : 0, - }); - }, - }) - ); - } else { - console.error(new Error('BillingClient missing.')); - } - }, - }) - ); - _payments$.next({ - context: PaymentEvent.Context.FINALIZING_ORDER, - result: PaymentEvent.Result.PENDING, - payload: order, - }); - } else { - _payments$.next({ - context: PaymentEvent.Context.FINALIZING_ORDER, - result: PaymentEvent.Result.FAILURE, - payload: new Failure(8), - }); - } + static fromNative(native: org.nativescript.plugins.payments.Product): Product { + if (native instanceof org.nativescript.plugins.payments.Product) { + return new Product(native); } - } else { - console.error(new Error('BillingClient missing.')); + return null; + } + + get id(): string { + return this.native.getId(); + } + get name(): string { + return this.native.getName(); + } + get description(): string { + return this.native.getDescription(); + } + get title(): string { + return this.native.getTitle(); + } + + get localizedTitle(): string { + return this.native.getProduct().getTitle(); + } + + get type(): 'inapp' | 'subs' { + return this.native.getType().getToType$payments_release() as 'inapp' | 'subs'; + } + + get priceFormatted(): string | null { + return this.native.getPriceFormatted(); + } + + get priceAmountMicros(): number | null { + return this.native.getPriceAmountMicros(); + } + + toJSON() { + return { + id: this.id, + name: this.name, + description: this.description, + title: this.title, + type: this.type, + }; } } -export function restoreOrders(skuType?: string): void { - if (_billingClient) { - _payments$.next({ - context: PaymentEvent.Context.RESTORING_ORDERS, - result: PaymentEvent.Result.STARTED, - payload: null, - }); - if (skuType === 'sub') { - skuType = com.android.billingclient.api.BillingClient.SkuType.SUBS; - } else { - skuType = com.android.billingclient.api.BillingClient.SkuType.INAPP; - } - _billingClient.queryPurchaseHistoryAsync( - skuType, - new com.android.billingclient.api.PurchaseHistoryResponseListener({ - onPurchaseHistoryResponse: (result, purchasesList) => { - const responseCode = result.getResponseCode(); - if (responseCode === com.android.billingclient.api.BillingClient.BillingResponseCode.OK) { - const size = purchasesList.size(); - for (let i = 0; i < size; i++) { - const purchase: com.android.billingclient.api.PurchaseHistoryRecord = purchasesList.get(i); - if (purchase) { - _payments$.next({ - context: PaymentEvent.Context.PROCESSING_ORDER, - result: PaymentEvent.Result.SUCCESS, - payload: new Order(purchase, true), - }); - _payments$.next({ - context: PaymentEvent.Context.RESTORING_ORDERS, - result: PaymentEvent.Result.PENDING, - payload: new Order(purchase, true), - }); +export class Payment { + readonly native: org.nativescript.plugins.payments.Payments; + onReady?: () => void; + onPurchaseUpdate?: (purchases: Array, error: Error | null) => void; + constructor() { + this.native = new org.nativescript.plugins.payments.Payments(Utils.android.getCurrentActivity() || Utils.android.getApplicationContext()); + const ref = new WeakRef(this); + this.native.setOnReadyListener( + new kotlin.jvm.functions.Function0({ + invoke(): void { + const owner = ref.get(); + if (owner && owner.onReady) { + owner.onReady(); + } + }, + }), + ); + + this.native.setOnPurchaseUpdateListener( + new kotlin.jvm.functions.Function2({ + invoke(purchase: List, info): void { + const owner = ref.get(); + if (owner && owner.onPurchaseUpdate) { + if (purchase) { + const size = purchase.size(); + const transactions: Array = []; + for (let i = 0; i < size; i++) { + transactions.push(Transaction.fromNative(purchase.get(i))); } + owner.onPurchaseUpdate(transactions, null); + } else { + owner.onPurchaseUpdate([], new PaymentError(info.getMessage(), info)); } - _payments$.next({ - context: PaymentEvent.Context.RESTORING_ORDERS, - result: PaymentEvent.Result.SUCCESS, - payload: null, - }); - } else { - _payments$.next({ - context: PaymentEvent.Context.RESTORING_ORDERS, - result: PaymentEvent.Result.FAILURE, - payload: new Failure(responseCode), - }); } }, - }) + }), ); - } else { - console.error(new Error('BillingClient missing.')); } -} -export function canMakePayments(/*types*/): boolean { - if (_billingClient) { - return _isBillingAvailable; - } else { - console.log('🛑 Call `init` prior to checking if the payments are configured correctly. 🛑'); - return false; + static isSupported(): boolean { + return org.nativescript.plugins.payments.Payments.isSupported(Utils.android.getCurrentActivity() || Utils.android.getApplicationContext()); } -} -function _purchaseHandler(responseCode: number, purchases: List, skuType?: string) { - if (_billingClient) { - const pending = purchases; - if (!skuType) { - _billingClient.queryPurchasesAsync( - com.android.billingclient.api.BillingClient.SkuType.INAPP, - new com.android.billingclient.api.PurchasesResponseListener({ - onQueryPurchasesResponse(param0: com.android.billingclient.api.BillingResult, pending: java.util.List) { - if (responseCode === com.android.billingclient.api.BillingClient.BillingResponseCode.OK) { - const size = purchases?.size?.() ?? 0; - if (purchases && size) { - for (let i = 0; i < size; i++) { - const purchase: com.android.billingclient.api.Purchase | com.android.billingclient.api.PurchaseHistoryRecord = purchases.get(i); - if (purchase) { - const order = new Order(purchase, false); - // order.isSubscription = isSubscription; - _payments$.next({ - context: PaymentEvent.Context.PROCESSING_ORDER, - result: PaymentEvent.Result.SUCCESS, - payload: order, - }); - } - } - } - } else { - _payments$.next({ - context: PaymentEvent.Context.PROCESSING_ORDER, - result: PaymentEvent.Result.FAILURE, - payload: new Failure(responseCode), - }); + canMakePayments(): boolean { + return this.native.canMakePayments(); + } + + restartConnection() { + this.native.restartConnection(); + } + + fetchProducts(productIdentifiers: string[], type: 'subs' | 'inapp') { + const items = Array.create(java.lang.String, productIdentifiers.length); + for (let i = 0; i < productIdentifiers.length; i++) { + items[i] = productIdentifiers[i]; + } + return new Promise((resolve, reject) => { + if (type !== 'subs' && type !== 'inapp') { + return reject(new Error('Invalid type, must be "subs" or "inapp"')); + } + + this.native.fetchProducts( + items, + type === 'subs' ? org.nativescript.plugins.payments.Product.Type.Subs : org.nativescript.plugins.payments.Product.Type.InApp, + new kotlin.jvm.functions.Function2({ + invoke(products: java.util.List, error): void { + if (error) { + return reject(new Error(error)); + } + const size = products ? products.size() : 0; + if (!products || size === 0) { + return resolve([]); + } + const productList = []; + for (let i = 0; i < size; i++) { + productList.push(new Product(products.get(i))); } + resolve(productList); }, - }) + }), ); - } - // var isSubscription = skuType === com.android.billingclient.api.BillingClient.SkuType.SUBS; - _payments$.next({ - context: PaymentEvent.Context.PROCESSING_ORDER, - result: PaymentEvent.Result.PENDING, - payload: pending ? pending.size() : 0, }); - } else { - console.error(new Error('BillingClient missing.')); } -} - -function _mapBillingResponseCode(code: number) { - switch (code) { - case 0: - return 'OK'; - case 1: - return 'USER_CANCELED'; - - case 2: - return 'SERVICE_UNAVAILABLE'; - - case 3: - return 'BILLING_UNAVAILABLE'; - - case 4: - return 'ITEM_UNAVAILABLE'; - - case 5: - return 'DEVELOPER_ERROR'; - case 6: - return 'ERROR'; - - case 7: - return 'ITEM_ALREADY_OWNED'; - - case 8: - return 'ITEM_NOT_OWNED'; - - case -1: - return 'SERVICE_DISCONNECTED'; - - case -2: - return 'FEATURE_NOT_SUPPORTED'; + fetchPurchases() { + return new Promise((resolve, reject) => { + this.native.fetchPurchases( + new kotlin.jvm.functions.Function2({ + invoke(transactions: java.util.List, error): void { + if (error) { + return reject(new Error(error)); + } + const size = transactions ? transactions.size() : 0; + if (!transactions || size === 0) { + return resolve([]); + } + const productList = []; + for (let i = 0; i < size; i++) { + productList.push(new Transaction(transactions.get(i))); + } + resolve(productList); + }, + }), + ); + }); + } - case -3: - return 'SERVICE_TIMEOUT'; - default: - return ''; + purchaseProduct(product: Product): Promise { + return new Promise((resolve, reject) => { + const response = this.native.purchaseProduct(Utils.android.getCurrentActivity(), product.native); + const code = response.getCode(); + if (code === 0) { + resolve(); + } else { + reject(new PaymentError(response.getMessage(), response)); + } + }); } } diff --git a/packages/payments/index.d.ts b/packages/payments/index.d.ts index 60b58ce..73a9505 100644 --- a/packages/payments/index.d.ts +++ b/packages/payments/index.d.ts @@ -1,31 +1,59 @@ -import { BuyItemOptions } from './common'; -import { Item } from './item'; -import { Order } from './order'; +export class Payment { + onReady?: () => void; + onPurchaseUpdate?: (purchases: Array, error: Error | null) => void; + fetchProducts(itemIds: Array, type: 'inapp' | 'subs'): Promise>; + purchaseProduct(product: Product): Promise; + fetchPurchases(): Promise>; -export { BuyItemOptions, PaymentEvent, paymentEvents, payments$ } from './common'; -export * from './failure'; -export * from './item'; -export * from './order'; + static isSupported(): boolean; -export declare function init(): void; + canMakePayments(): boolean; +} -export declare function tearDown(): void; +export class Transaction { + readonly native: org.nativescript.plugins.payments.Transaction | NSCTransaction; -export declare function fetchItems(itemIds: Array): void; + readonly receiptToken: string; -export declare function buyItem(item: Item, options?: BuyItemOptions): void; + readonly signature: string; -export function fetchSubscriptions(itemIds: Array): void; + readonly quantity: number; -export function startSubscription(item: Item, options?: BuyItemOptions): void; + readonly productId: string; -export declare function finalizeOrder(order: Order): void; + readonly orderId: string; -export declare function restoreOrders(skuType?: string): void; + readonly orderDate: Date; -export declare function canMakePayments(): boolean; + readonly state: 'pending' | 'purchased' | 'unknown'; -export function toMainThread(); + finish(): Promise; +} -// TODO Manage subscriptions -// TODO map subscriptions (Android) +export class Product { + readonly native: org.nativescript.plugins.payments.Product | NSCProduct; + + readonly id: string; + readonly name: string; + readonly description: string; + + readonly title: string; + + readonly localizedTitle: string; + + readonly type: 'inapp' | 'subs'; + + readonly priceFormatted: string | null; + + readonly priceAmountMicros: number | null; +} + +export class Transaction { + native: org.nativescript.plugins.payments.Transaction; + readonly json: any; + readonly signature: string; + readonly quantity: number; + readonly orderId: string; + readonly state: 'pending' | 'purchased' | 'unknown'; + finish(): Promise; +} diff --git a/packages/payments/index.ios.ts b/packages/payments/index.ios.ts index b154b6a..aeea951 100644 --- a/packages/payments/index.ios.ts +++ b/packages/payments/index.ios.ts @@ -1,339 +1,247 @@ -import { BuyItemOptions, PaymentEvent, _payments$ } from './common'; -import { Failure } from './failure'; -import { Item } from './item'; -import { Order, OrderState } from './order'; +import { Utils } from '@nativescript/core'; export { PaymentEvent, paymentEvents, payments$, toMainThread } from './common'; -export * from './failure'; -export * from './item'; -export * from './order'; - -let _productRequest: SKProductsRequest | null; -let _productRequestDelegate: SKProductRequestDelegateImpl | null; -let _paymentTransactionObserver: SKPaymentTransactionObserverImpl | null; - -export function init(): void { - if (!_paymentTransactionObserver) { - _payments$.next({ - context: PaymentEvent.Context.CONNECTING_STORE, - result: PaymentEvent.Result.STARTED, - payload: null, - }); - _paymentTransactionObserver = new SKPaymentTransactionObserverImpl(); - _payments$.next({ - context: PaymentEvent.Context.CONNECTING_STORE, - result: PaymentEvent.Result.PENDING, - payload: null, - }); - try { - SKPaymentQueue.defaultQueue().addTransactionObserver(_paymentTransactionObserver); - _payments$.next({ - context: PaymentEvent.Context.CONNECTING_STORE, - result: PaymentEvent.Result.SUCCESS, - payload: null, - }); - } catch (e) { - const errorPayload = typeof e === 'object' ? e.message : e; - console.error(new Error(`Init failed: ${errorPayload}`)); - _payments$.next({ - context: PaymentEvent.Context.CONNECTING_STORE, - result: PaymentEvent.Result.FAILURE, - payload: new Failure(null), - }); - } - } -} -export function tearDown(): void { - if (_paymentTransactionObserver) { - SKPaymentQueue.defaultQueue().removeTransactionObserver(_paymentTransactionObserver); +export class PaymentError extends Error { + private nativeError: NSCPaymentsResponse; + constructor(message: string, nativeError?: any) { + super(message); + this.nativeError = nativeError; } - _paymentTransactionObserver = null; -} -export function fetchSubscriptions(itemIds: Array): void { - fetchItems(itemIds); -} + get code(): number { + return this.nativeError?.code ?? Number.MAX_SAFE_INTEGER; + } -export function fetchItems(itemIds: Array): void { - _payments$.next({ - context: PaymentEvent.Context.RETRIEVING_ITEMS, - result: PaymentEvent.Result.STARTED, - payload: itemIds, - }); - const productIds: NSMutableSet = NSMutableSet.alloc().init(); - itemIds.forEach((value: string) => productIds.addObject(value)); - _productRequest = SKProductsRequest.alloc().initWithProductIdentifiers(productIds); - _productRequestDelegate = new SKProductRequestDelegateImpl(); - _productRequest.delegate = _productRequestDelegate; - _productRequest.start(); - _payments$.next({ - context: PaymentEvent.Context.RETRIEVING_ITEMS, - result: PaymentEvent.Result.PENDING, - payload: itemIds, - }); -} + get subCode(): number { + return Number.MAX_SAFE_INTEGER; + } -export function startSubscription(item: Item, options?: BuyItemOptions): void { - buyItem(item, options); -} + get native(): any { + return this.nativeError; + } -export function buyItem(item: Item, buyItemOptions: BuyItemOptions): void { - if (SKPaymentQueue.defaultQueue().transactions) { - const pendingCount = SKPaymentQueue.defaultQueue().transactions.count; - if (!pendingCount) { - _payments$.next({ - context: PaymentEvent.Context.PROCESSING_ORDER, - result: PaymentEvent.Result.PENDING, - payload: pendingCount + 1, - }); - const payment = SKMutablePayment.paymentWithProduct(item.nativeValue); - if (buyItemOptions) { - payment.applicationUsername = buyItemOptions?.accountUserName || ''; - payment.simulatesAskToBuyInSandbox = buyItemOptions.ios?.simulatesAskToBuyInSandbox || false; - payment.quantity = buyItemOptions.ios?.quantity || 1; - } - try { - SKPaymentQueue.defaultQueue().addPayment(payment); - _payments$.next({ - context: PaymentEvent.Context.PROCESSING_ORDER, - result: PaymentEvent.Result.STARTED, - payload: item, - }); - } catch (e) { - const errorPayload = typeof e === 'object' ? e.message : e; - console.error(new Error(`Error while adding payment: ${errorPayload}`)); - _payments$.next({ - context: PaymentEvent.Context.PROCESSING_ORDER, - result: PaymentEvent.Result.FAILURE, - payload: new Failure(null), - }); - } - } else { - _payments$.next({ - context: PaymentEvent.Context.PROCESSING_ORDER, - result: PaymentEvent.Result.PENDING, - payload: pendingCount, - }); + private _resolution: string; + get resolution(): string { + if (this._resolution) { + return this._resolution; } - } else { - console.error(new Error('SKPaymentQueue.defaultQueue().transactions missing.')); + if (this.nativeError && this.nativeError.resolution) { + this._resolution = this.nativeError.resolution; + } + return this._resolution ?? ''; } } -export function finalizeOrder(order: Order): void { - _payments$.next({ - context: PaymentEvent.Context.FINALIZING_ORDER, - result: PaymentEvent.Result.STARTED, - payload: order, - }); - if (order.state === OrderState.VALID && !order.restored) { - try { - SKPaymentQueue.defaultQueue().finishTransaction(order.nativeValue); - _payments$.next({ - context: PaymentEvent.Context.FINALIZING_ORDER, - result: PaymentEvent.Result.PENDING, - payload: order, - }); - } catch (e) { - const errorPayload = typeof e === 'object' ? e.message : e; - console.error(new Error(`Error while finalizing order: ${errorPayload}`)); - _payments$.next({ - context: PaymentEvent.Context.FINALIZING_ORDER, - result: PaymentEvent.Result.FAILURE, - payload: new Failure(null), - }); +export class Transaction { + readonly native: NSCTransaction; + constructor(native: NSCTransaction) { + this.native = native; + } + + static fromNative(native: NSCTransaction): Transaction { + if (native instanceof NSCTransaction) { + return new Transaction(native); } - } else { - _payments$.next({ - context: PaymentEvent.Context.FINALIZING_ORDER, - result: PaymentEvent.Result.FAILURE, - payload: new Failure(999), - }); + return null; } -} -export function restoreOrders(): void { - _payments$.next({ - context: PaymentEvent.Context.RESTORING_ORDERS, - result: PaymentEvent.Result.STARTED, - payload: null, - }); - try { - SKPaymentQueue.defaultQueue().restoreCompletedTransactions(); - } catch (e) { - const errorPayload = typeof e === 'object' ? e.message : e; - console.error(new Error(`Error while restoring order: ${errorPayload}`)); - _payments$.next({ - context: PaymentEvent.Context.RESTORING_ORDERS, - result: PaymentEvent.Result.FAILURE, - payload: new Failure(null), - }); + get receiptToken(): string { + return this.native.receipt; } -} -export function canMakePayments(): boolean { - // TODO ? - return SKPaymentQueue.canMakePayments(); -} + get signature(): string { + return ''; + } + + get quantity(): number { + return 1; + } -@NativeClass -class SKProductRequestDelegateImpl extends NSObject implements SKProductsRequestDelegate { - public static ObjCProtocols = [SKProductsRequestDelegate]; + get orderId(): string { + return this.native.orderId; + } - public productsRequestDidReceiveResponse(request: SKProductsRequest, response: SKProductsResponse) { - const products: NSArray = response.products; + get productId(): string { + return this.native.productId; + } - // log the invalid IDs if any - if (response.invalidProductIdentifiers.count >= 1) { - console.log('Invalid product identifiers: ' + JSON.stringify(response.invalidProductIdentifiers.componentsJoinedByString(', '))); - } + get orderDate(): Date { + return this.native.orderDate; + } - const result: Array = []; - const count = products.count; - for (let i = 0; i < count; i++) { - result.push(new Item(products.objectAtIndex(i))); + get state(): 'pending' | 'purchased' | 'unknown' { + switch (this.native.state) { + case NSCTransactionState.Pending: + return 'pending'; + case NSCTransactionState.Purchased: + return 'purchased'; + default: + return 'unknown'; } + } - _payments$.next({ - context: PaymentEvent.Context.RETRIEVING_ITEMS, - result: PaymentEvent.Result.SUCCESS, - payload: result, + finish() { + return new Promise((resolve, reject) => { + this.native.finish((response) => { + if (response) { + reject(new PaymentError(response.message)); + return; + } + resolve(); + }); }); + } - this._cleanup(); + toJSON() { + return { + receiptToken: this.receiptToken, + signature: this.signature, + quantity: this.quantity, + orderId: this.orderId, + state: this.state, + }; } +} - public requestDidFailWithError(request: SKRequest, error: NSError) { - _payments$.next({ - context: PaymentEvent.Context.RETRIEVING_ITEMS, - result: PaymentEvent.Result.FAILURE, - payload: new Failure(error.code), - }); - this._cleanup(); +export class Product { + readonly native: NSCProduct; + constructor(native: NSCProduct) { + this.native = native; } - private _cleanup() { - _productRequestDelegate = null; - _productRequest = null; + static fromNative(native: NSCProduct): Product { + if (native instanceof NSCProduct) { + return new Product(native); + } + return null; } -} -@NativeClass -class SKPaymentTransactionObserverImpl extends NSObject implements SKPaymentTransactionObserver { - public static ObjCProtocols = [SKPaymentTransactionObserver]; + get id(): string { + return this.native.id; + } + get name(): string { + return this.native.displayName; + } + get description(): string { + return this.native.description; + } + get title(): string { + return this.native.displayName; + } - public paymentQueueUpdatedTransactions(queue: SKPaymentQueue, transactions: NSArray): void { - _transactionHandler(queue, transactions); + get localizedTitle(): string { + return this.native.displayName; } - public paymentQueueRestoreCompletedTransactionsFinished(queue: SKPaymentQueue): void { - _payments$.next({ - context: PaymentEvent.Context.RESTORING_ORDERS, - result: PaymentEvent.Result.SUCCESS, - payload: null, - }); + get type(): 'inapp' | 'subs' | 'unknown' { + return this.native.type as any; } - public paymentQueueRestoreCompletedTransactionsFailedWithError(queue: SKPaymentQueue, error: NSError): void { - _payments$.next({ - context: PaymentEvent.Context.RESTORING_ORDERS, - result: PaymentEvent.Result.FAILURE, - payload: new Failure(error.code), - }); + get priceFormatted(): string | null { + return this.native.priceFormatted; + } + + get priceAmountMicros(): number | null { + return this.native.price; } - public paymentQueueRemovedTransactions(queue: SKPaymentQueue, transactions: NSArray): void { - if (transactions && transactions.count) { - for (let i = 0; i < transactions.count; i++) { - const transaction: SKPaymentTransaction = transactions.objectAtIndex(i); - if (transaction.transactionState === SKPaymentTransactionState.Purchased) { - _payments$.next({ - context: PaymentEvent.Context.FINALIZING_ORDER, - result: PaymentEvent.Result.SUCCESS, - payload: new Order(transaction), - }); + toJSON() { + return { + id: this.id, + name: this.name, + description: this.description, + title: this.title, + type: this.type, + }; + } +} + +export class Payment { + readonly native: NSCPayments; + onReady?: () => void; + onPurchaseUpdate?: (purchases: Array, error: Error | null) => void; + constructor() { + this.native = NSCPayments.new(); + this.native.transactionUpdateListener = (transaction) => { + if (this.onPurchaseUpdate) { + if (transaction.error) { + this.onPurchaseUpdate([Transaction.fromNative(transaction)], null); + } else { + const error = NSCPaymentsResponse.alloc().initWithCodeMessageResolution(NSCPaymentsResponseFailure.Error, `Usage error: ${transaction.error.localizedDescription}`, ''); + this.onPurchaseUpdate([], new PaymentError(transaction.error.localizedDescription, error)); } } - } - _payments$.next({ - context: PaymentEvent.Context.PROCESSING_ORDER, - result: PaymentEvent.Result.PENDING, - payload: queue.transactions ? queue.transactions.count : 0, - }); + }; + + setTimeout(() => { + this.onReady(); + }, 100); } - public paymentQueueShouldAddStorePaymentForProduct(queue: SKPaymentQueue, payment: SKPayment, product: SKProduct): boolean { - return true; + static isSupported(): boolean { + return NSCPayments.isSupported(); } - public paymentQueueUpdatedDownloads(queue: SKPaymentQueue, downloads: NSArray): void { - console.log('paymentQueueUpdatedDownloads called. Not implemented.'); + canMakePayments(): boolean { + return this.native.canMakePayments(); + } + + restartConnection() { + // noop } -} -function _transactionHandler(queue: SKPaymentQueue, transactions: NSArray): void { - _payments$.next({ - context: PaymentEvent.Context.PROCESSING_ORDER, - result: PaymentEvent.Result.PENDING, - payload: queue.transactions ? queue.transactions.count : 0, - }); - const count = transactions?.count ?? 0; - if (count) { - for (let i = 0; i < count; i++) { - const transaction: SKPaymentTransaction = transactions.objectAtIndex(i); - - switch (transaction.transactionState) { - case SKPaymentTransactionState.Purchased: - _payments$.next({ - context: PaymentEvent.Context.PROCESSING_ORDER, - result: PaymentEvent.Result.SUCCESS, - payload: new Order(transaction), - }); - break; - case SKPaymentTransactionState.Failed: - _payments$.next({ - context: PaymentEvent.Context.PROCESSING_ORDER, - result: PaymentEvent.Result.FAILURE, - payload: new Failure(transaction.error.code), - }); - try { - queue.finishTransaction(transaction); - } catch (e) { - const errorPayload = typeof e === 'object' ? e.message : e; - console.error(new Error(`Error while finalizing failed order: ${errorPayload}`)); - } - break; - case SKPaymentTransactionState.Restored: - _payments$.next({ - context: PaymentEvent.Context.PROCESSING_ORDER, - result: PaymentEvent.Result.SUCCESS, - payload: new Order(transaction.originalTransaction, true), - }); - _payments$.next({ - context: PaymentEvent.Context.RESTORING_ORDERS, - result: PaymentEvent.Result.PENDING, - payload: new Order(transaction.originalTransaction, true), - }); - try { - queue.finishTransaction(transaction); - } catch (e) { - const errorPayload = typeof e === 'object' ? e.message : e; - console.error(new Error(`Error while finalizing restored order: ${errorPayload}`)); - } - break; - case SKPaymentTransactionState.Purchasing: - case SKPaymentTransactionState.Deferred: // TODO ? - break; - default: - console.error(new Error('Missing or unknown transaction state.')); - break; + fetchProducts(productIdentifiers: string[], type: 'subs' | 'inapp') { + return new Promise((resolve, reject) => { + if (type !== 'subs' && type !== 'inapp') { + return reject(new Error('Invalid type, must be "subs" or "inapp"')); } - } + + this.native.fetchProducts(productIdentifiers, (products, error) => { + if (error) { + const ret = NSCPaymentsResponse.alloc().initWithCodeMessageResolution(NSCPaymentsResponseFailure.Error, `Usage error: ${error.localizedDescription}`, ''); + return reject(new PaymentError(error.localizedDescription, ret)); + } + const size = products ? products.count : 0; + if (!products || size === 0) { + return resolve([]); + } + const productList = []; + for (let i = 0; i < size; i++) { + productList.push(new Product(products.objectAtIndex(i))); + } + resolve(productList); + }); + }); + } + + fetchPurchases() { + return new Promise((resolve, reject) => { + this.native.fetchPurchases((purchases, error) => { + if (error) { + return reject(new PaymentError(error.message, error)); + } + const size = purchases ? purchases.count : 0; + if (!purchases || size === 0) { + return resolve([]); + } + const productList = []; + for (let i = 0; i < size; i++) { + productList.push(new Transaction(purchases.objectAtIndex(i))); + } + resolve(productList); + }); + }); + } + + purchaseProduct(product: Product): Promise { + return new Promise((resolve, reject) => { + const response = this.native.purchaseProduct(product.native, Utils.ios.getVisibleViewController(Utils.ios.getRootViewController()), (response) => { + if (response) { + reject(new PaymentError(response.message, response)); + } + resolve(); + }); + }); } - _payments$.next({ - context: PaymentEvent.Context.PROCESSING_ORDER, - result: PaymentEvent.Result.PENDING, - payload: queue.transactions ? queue.transactions.count : 0, - }); } diff --git a/packages/payments/item/common.ts b/packages/payments/item/common.ts deleted file mode 100644 index fef8bca..0000000 --- a/packages/payments/item/common.ts +++ /dev/null @@ -1,36 +0,0 @@ -type ProductDetails = com.android.billingclient.api.ProductDetails; - -export enum RecurrenceMode { - FINITE_RECURRING = 2, - INFINITE_RECURRING = 1, - NON_RECURRING = 3, -} - -export abstract class BaseItem { - public nativeValue: ProductDetails | SKProduct; - public abstract readonly debug: string | null; - - public itemId: string; - public localizedTitle: string; - public localizedDescription: string; - public priceAmount: number; - public priceFormatted: string; - public priceCurrencyCode: string; - /** Android only */ - public type: string; - public offerToken: string; - public pricingPhases: Array<{ - priceAmount: number; - priceFormatted: string; - priceCurrencyCode: string; - billingPeriod: string; - billingCycleCount: number; - recurrenceMode: RecurrenceMode; - }> = []; - /** iOS only */ - public isFamilyShareable: boolean; - - constructor(nativeValue: ProductDetails | SKProduct) { - this.nativeValue = nativeValue; - } -} diff --git a/packages/payments/item/index.android.ts b/packages/payments/item/index.android.ts deleted file mode 100644 index 78d7fa6..0000000 --- a/packages/payments/item/index.android.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { BaseItem } from './common'; -export { RecurrenceMode } from './common'; -type ProductDetails = com.android.billingclient.api.ProductDetails; - -export class Item extends BaseItem { - public nativeValue: ProductDetails; - - constructor(nativeValue: ProductDetails) { - super(nativeValue); - - this.itemId = nativeValue.getProductId(); - this.localizedDescription = nativeValue.getDescription(); - this.localizedTitle = nativeValue.getTitle(); - this.type = nativeValue.getProductType(); - if (this.type === com.android.billingclient.api.BillingClient.SkuType.INAPP) { - const details = nativeValue.getOneTimePurchaseOfferDetails(); - this.priceAmount = details.getPriceAmountMicros() / 1000000; - this.priceFormatted = details.getFormattedPrice(); - this.priceCurrencyCode = details.getPriceCurrencyCode(); - } else if (this.type === com.android.billingclient.api.BillingClient.SkuType.SUBS) { - const subscriptionOfferDetails: com.android.billingclient.api.ProductDetails.SubscriptionOfferDetails = nativeValue.getSubscriptionOfferDetails().get(0); - this.offerToken = subscriptionOfferDetails.getOfferToken(); - const pricingPhaseList = subscriptionOfferDetails.getPricingPhases().getPricingPhaseList(); - const listSize = pricingPhaseList.size(); - for (let i = 0; i < listSize; i++) { - const details: com.android.billingclient.api.ProductDetails.PricingPhase = pricingPhaseList.get(i); - // what matters is the final price. For example: - // 3 months free trial - // 6 months at $1.99 - // rest is $9.99 - // the sub price is $9.99 - if (i === listSize - 1) { - this.priceAmount = details.getPriceAmountMicros() / 1000000; - this.priceFormatted = details.getFormattedPrice(); - this.priceCurrencyCode = details.getPriceCurrencyCode(); - } - this.pricingPhases.push({ - priceAmount: details.getPriceAmountMicros() / 1000000, - priceFormatted: details.getFormattedPrice(), - priceCurrencyCode: details.getPriceCurrencyCode(), - billingPeriod: details.getBillingPeriod(), - billingCycleCount: details.getBillingCycleCount(), - recurrenceMode: details.getRecurrenceMode(), - }); - } - } - } - - public get debug(): string { - return this.nativeValue.toString(); - } -} diff --git a/packages/payments/item/index.d.ts b/packages/payments/item/index.d.ts deleted file mode 100644 index 8ccdb4f..0000000 --- a/packages/payments/item/index.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { BaseItem } from './common'; -export { RecurrenceMode } from './common'; -export declare type ProductDetails = com.android.billingclient.api.ProductDetails; - -export declare class Item extends BaseItem { - public readonly debug: string | null; - - constructor(nativeValue: ProductDetails | SKProduct); -} diff --git a/packages/payments/item/index.ios.ts b/packages/payments/item/index.ios.ts deleted file mode 100644 index 149b37f..0000000 --- a/packages/payments/item/index.ios.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { BaseItem } from './common'; -export { RecurrenceMode } from './common'; - -export class Item extends BaseItem { - public nativeValue: SKProduct; - - constructor(nativeValue: SKProduct) { - super(nativeValue); - - const formatter = NSNumberFormatter.alloc().init(); - formatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle; - formatter.locale = nativeValue.priceLocale; - - this.itemId = nativeValue.productIdentifier; - this.localizedDescription = nativeValue.localizedDescription; - this.localizedTitle = nativeValue.localizedTitle; - this.priceAmount = nativeValue.price.doubleValue; - this.priceFormatted = formatter.stringFromNumber(nativeValue.price as any); - this.priceCurrencyCode = nativeValue.priceLocale.objectForKey(NSLocaleCurrencyCode); - this.isFamilyShareable = nativeValue.isFamilyShareable; - } - - public get debug(): string | null { - if (this.nativeValue) { - const temp: any = {}; - for (const i in this.nativeValue) { - if ((this.nativeValue)[i] != null) { - temp[i] = (this.nativeValue)[i]; - } - } - - return JSON.stringify(temp); - } else { - return null; - } - } -} diff --git a/packages/payments/order/common.ts b/packages/payments/order/common.ts deleted file mode 100644 index 1b8ab62..0000000 --- a/packages/payments/order/common.ts +++ /dev/null @@ -1,28 +0,0 @@ -export abstract class BaseOrder { - public nativeValue: com.android.billingclient.api.Purchase | com.android.billingclient.api.PurchaseHistoryRecord | SKPaymentTransaction; - public abstract readonly debug: string | null; - - public state: OrderState; - public itemId: string; - public orderId: string | null; - public orderDate: Date; - public receiptToken: string; - public userData: string; - public restored: boolean; - /** Android only */ - public isSubscription: boolean; - public dataSignature: string; - public acknowledged: boolean; - public quantity: number; - - constructor(nativeValue: com.android.billingclient.api.Purchase | com.android.billingclient.api.PurchaseHistoryRecord | SKPaymentTransaction, restored: boolean = false) { - this.nativeValue = nativeValue; - this.restored = restored; - } -} - -export enum OrderState { - INVALID = 'INVALID', - PROVISIONAL = 'PROVISIONAL', - VALID = 'VALID' -} diff --git a/packages/payments/order/index.android.ts b/packages/payments/order/index.android.ts deleted file mode 100644 index 61d56b2..0000000 --- a/packages/payments/order/index.android.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { BaseOrder, OrderState } from './common'; - -export { OrderState } from './common'; - -export class Order extends BaseOrder { - public nativeValue: com.android.billingclient.api.Purchase; - - constructor(nativeValue: com.android.billingclient.api.Purchase | com.android.billingclient.api.PurchaseHistoryRecord, restored: boolean = false) { - super(nativeValue, restored); - - const jsonObject: any = JSON.parse(nativeValue.getOriginalJson()); - // TODO: treat multiple SKUs - this.itemId = nativeValue.getSkus().get(0) as string; - this.receiptToken = nativeValue.getPurchaseToken(); - this.dataSignature = nativeValue.getSignature(); - this.userData = jsonObject.developerPayload; - this.isSubscription = jsonObject.autoRenewing; - this.orderDate = new Date(nativeValue.getPurchaseTime()); - this.quantity = nativeValue.getQuantity(); - this.acknowledged = true; - this.orderId = null; - if (nativeValue instanceof com.android.billingclient.api.Purchase) { - // PurchaseHistoryRecord is a subset of purchase, so let's fill the gaps here - this.acknowledged = nativeValue.isAcknowledged(); - this.orderId = nativeValue.getOrderId(); - } - if (typeof jsonObject.purchaseState !== 'undefined') { - // console.log('jsonObject.purchaseState:', jsonObject.purchaseState); - switch (jsonObject.purchaseState) { - case 0: - this.state = OrderState.VALID; - break; - case 1: - case 2: - default: - if (this.isSubscription) { - // for now try this: - this.state = OrderState.VALID; - } else { - this.state = OrderState.INVALID; - } - break; - } - } else { - // force it to be processed and consumed so it doesn't get stuck - this.state = OrderState.VALID; - } - } - - get debug(): string { - return this.nativeValue.getOriginalJson(); - } -} diff --git a/packages/payments/order/index.d.ts b/packages/payments/order/index.d.ts deleted file mode 100644 index 8af91d1..0000000 --- a/packages/payments/order/index.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { BaseOrder } from './common'; - -export { OrderState } from './common'; - -export declare class Order extends BaseOrder { - public readonly debug: string | null; - - constructor(nativeValue: com.android.billingclient.api.Purchase | com.android.billingclient.api.PurchaseHistoryRecord | SKPaymentTransaction, restored?: boolean); -} diff --git a/packages/payments/order/index.ios.ts b/packages/payments/order/index.ios.ts deleted file mode 100644 index 37fb7b7..0000000 --- a/packages/payments/order/index.ios.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { BaseOrder, OrderState } from './common'; - -export { OrderState } from './common'; - -export class Order extends BaseOrder { - public nativeValue: SKPaymentTransaction; - - constructor(nativeValue: SKPaymentTransaction, restored: boolean = false) { - super(nativeValue, restored); - - switch (nativeValue.transactionState) { - case SKPaymentTransactionState.Purchased: - this.state = OrderState.VALID; - break; - - case SKPaymentTransactionState.Deferred: - case SKPaymentTransactionState.Purchasing: - case SKPaymentTransactionState.Restored: - this.state = OrderState.PROVISIONAL; - break; - - case SKPaymentTransactionState.Failed: - default: - this.state = OrderState.INVALID; - break; - } - - this.itemId = nativeValue.payment ? nativeValue.payment.productIdentifier : 'undefined'; - this.orderId = nativeValue.transactionIdentifier; - this.orderDate = nativeValue.transactionDate; - const receiptData = NSData.dataWithContentsOfURL(NSBundle.mainBundle.appStoreReceiptURL); - this.receiptToken = receiptData ? receiptData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.Encoding64CharacterLineLength) : undefined; - // this.receiptToken = nativeValue.transactionReceipt ? nativeValue.transactionReceipt.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.Encoding64CharacterLineLength) : 'undefined'; - this.userData = nativeValue.payment ? nativeValue.payment.applicationUsername : 'undefined'; - } - - get debug(): string | null { - if (this.nativeValue) { - const temp: any = {}; - for (const i in this.nativeValue) { - if ((this.nativeValue)[i] != null) { - temp[i] = (this.nativeValue)[i]; - } - } - - return JSON.stringify(temp); - } else { - return null; - } - } -} diff --git a/packages/payments/package.json b/packages/payments/package.json index 8a39a84..d2bb0b0 100644 --- a/packages/payments/package.json +++ b/packages/payments/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/payments", - "version": "3.0.2", + "version": "4.0.0-alpha.0", "description": "In-App Purchase and Subscriptions for NativeScript", "main": "index", "typings": "index.d.ts", diff --git a/packages/payments/platforms/android/AndroidManifest.xml b/packages/payments/platforms/android/AndroidManifest.xml index 4854fc7..128135c 100644 --- a/packages/payments/platforms/android/AndroidManifest.xml +++ b/packages/payments/platforms/android/AndroidManifest.xml @@ -1,8 +1,7 @@ - - - - - + + + + + \ No newline at end of file diff --git a/packages/payments/platforms/android/include.gradle b/packages/payments/platforms/android/include.gradle index e281f53..112a95f 100644 --- a/packages/payments/platforms/android/include.gradle +++ b/packages/payments/platforms/android/include.gradle @@ -1,3 +1,9 @@ +android { + defaultConfig { + minSdkVersion 21 + } +} + dependencies { - implementation 'com.android.billingclient:billing:7.1.1' + implementation 'com.android.billingclient:billing:8.0.0' } diff --git a/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Payments.kt b/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Payments.kt new file mode 100644 index 0000000..ca67708 --- /dev/null +++ b/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Payments.kt @@ -0,0 +1,420 @@ +package org.nativescript.plugins.payments + +import android.app.Activity +import android.content.Context +import android.content.Intent +import android.net.Uri +import android.util.Log +import com.android.billingclient.api.BillingClient +import com.android.billingclient.api.BillingClientStateListener +import com.android.billingclient.api.BillingFlowParams +import com.android.billingclient.api.BillingResult +import com.android.billingclient.api.PendingPurchasesParams +import com.android.billingclient.api.QueryProductDetailsParams +import com.android.billingclient.api.QueryPurchasesParams +import org.json.JSONObject +import java.util.concurrent.CountDownLatch +import java.util.concurrent.Executors + +class Payments(context: Context) { + private var isReady = false + private var isSetup = false + internal var billing = BillingClient.newBuilder(context).apply { + val pendingParams = PendingPurchasesParams.newBuilder() + .enablePrepaidPlans() + .enablePrepaidPlans() + .enableOneTimeProducts() + .build() + enablePendingPurchases(pendingParams) + enableAutoServiceReconnection() + setListener { response, purchases -> + { + if (response.responseCode == BillingClient.BillingResponseCode.OK && purchases != null) { + val value = purchases.map { + val json = JSONObject(it.originalJson) + Transaction( + it, if (json.optBoolean("autoRenewing", false)) { + Product.Type.Subs + } else { + Product.Type.InApp + }, this@Payments + ) + } + onPurchaseUpdateListener?.let { + it(value, null) + } + } else { + onPurchaseUpdateListener?.let { + it(null, mapResponseCode(response.responseCode)) + } + } + } + } + }.build() + + private val executor = Executors.newCachedThreadPool() + + var onReadyListener: (() -> Unit)? = null + + var onPurchaseUpdateListener: ((List?, BillingResponse?) -> Unit)? = null + + class BillingResponse( + val code: Int, + val message: String, + val resolution: String, + val subCode: Int = Int.MAX_VALUE + ) + + enum class Features(val value: String) { + Subscriptions(BillingClient.FeatureType.SUBSCRIPTIONS), + SubscriptionsUpdate(BillingClient.FeatureType.SUBSCRIPTIONS_UPDATE), + PriceChangeConfirmation(BillingClient.FeatureType.PRICE_CHANGE_CONFIRMATION), + InAppMessaging(BillingClient.FeatureType.IN_APP_MESSAGING), + ProductDetails(BillingClient.FeatureType.PRODUCT_DETAILS), + BillingConfig(BillingClient.FeatureType.BILLING_CONFIG), + AlternativeBillingOnly(BillingClient.FeatureType.ALTERNATIVE_BILLING_ONLY), + ExternalOffer(BillingClient.FeatureType.EXTERNAL_OFFER), + } + + class PurchaseOptions { + enum class ReplacementMode(val value: Int) { + Unknown(0), + WithTimeProration(1), + ChargeProratedPrice(2), + WithoutProration(3), + ChargeFullPrice(5), + Deferred(6); + } + + var profileId: String? = null + var accountId: String? = null + var setIsOfferPersonalized = false + var subscriptionUpdateToken: String? = null + var subscriptionUpdateReplacementMode: ReplacementMode? = null + } + + init { + billing.startConnection(object : BillingClientStateListener { + override fun onBillingServiceDisconnected() { + this@Payments.isReady = false + } + + override fun onBillingSetupFinished(p0: BillingResult) { + isSetup = p0.responseCode == BillingClient.BillingResponseCode.OK + if (!this@Payments.isReady) { + onReadyListener?.let { + it() + } + this@Payments.isReady = true + } + } + }) + } + + fun connect() { + when (billing.connectionState) { + BillingClient.ConnectionState.DISCONNECTED, BillingClient.ConnectionState.CLOSED -> { + billing.startConnection(object : BillingClientStateListener { + override fun onBillingServiceDisconnected() { + this@Payments.isReady = false + } + + override fun onBillingSetupFinished(p0: BillingResult) { + isSetup = p0.responseCode == BillingClient.BillingResponseCode.OK + if (!this@Payments.isReady) { + onReadyListener?.let { + it() + } + this@Payments.isReady = true + } + } + }) + } + + else -> {} + } + } + + fun disconnect() { + billing.endConnection() + } + + fun showInAppMessaging(activity: Activity) { +// val params = InAppMessageParams.newBuilder() +// .apply { +// addInAppMessageCategoryToShow(InAppMessageParams.InAppMessageCategoryId.TRANSACTIONAL) +// } +// .build() +// billing.showInAppMessages(activity, params, object : InAppMessageResponseListener { +// override fun onInAppMessageResponse(p0: InAppMessageResult) { +// +// } +// }) + } + + fun canMakePayments(): Boolean { + return isReady && billing.isReady + } + + fun isFeatureSupported(feature: Features): Boolean { + if (!billing.isReady) { + return false + } + return billing.isFeatureSupported(feature.value).responseCode == BillingClient.BillingResponseCode.OK + } + + fun fetchProducts( + identifiers: Array, + type: Product.Type, + callback: (List?, BillingResponse?) -> Unit + ) { + val products = identifiers.map { + QueryProductDetailsParams.Product.newBuilder() + .setProductType(type.toType) + .setProductId(it) + .build() + } + val params = QueryProductDetailsParams.newBuilder() + .setProductList(products) + .build() + + billing.queryProductDetailsAsync(params) { p0, p1 -> + if (p0.responseCode == BillingClient.BillingResponseCode.OK) { + val products = p1.productDetailsList.map { + Product(it) + } + callback(products, null) + } else { + callback(null, mapResponseCode(p0.responseCode)) + } + } + } + + + @JvmOverloads + fun purchaseProduct( + activity: Activity, + product: Product, + options: PurchaseOptions? = null + ): BillingResponse { + val param = BillingFlowParams.ProductDetailsParams.newBuilder() + .apply { + setProductDetails(product.product) + if (product.type == Product.Type.Subs) { + product.product.subscriptionOfferDetails?.first()?.let { + setOfferToken(it.offerToken) + } + } + } + .build() + + val flow = BillingFlowParams.newBuilder() + .apply { + options?.let { + setIsOfferPersonalized(it.setIsOfferPersonalized) + it.profileId?.let { id -> + setObfuscatedProfileId(id) + } + + it.accountId?.let { id -> + setObfuscatedAccountId(id) + } + + it.subscriptionUpdateToken?.let { token -> + val params = BillingFlowParams.SubscriptionUpdateParams.newBuilder() + .apply { + it.subscriptionUpdateReplacementMode?.let { mode -> + setSubscriptionReplacementMode(mode.value) + } + } + .setOldPurchaseToken(token) + .build() + + setSubscriptionUpdateParams(params) + } + } + setProductDetailsParamsList(listOf(param)) + } + .build() + + val response = billing.launchBillingFlow(activity, flow) + + if (response.responseCode != BillingClient.BillingResponseCode.OK) { + return when (response.onPurchasesUpdatedSubResponseCode) { + BillingClient.OnPurchasesUpdatedSubResponseCode.PAYMENT_DECLINED_DUE_TO_INSUFFICIENT_FUNDS -> { + BillingResponse( + Int.MAX_VALUE, + "The payment was declined due to insufficient funds.", + "The user must either add funds/increase limits or retry the transaction with a different payment method", + response.onPurchasesUpdatedSubResponseCode + ) + } + + BillingClient.OnPurchasesUpdatedSubResponseCode.USER_INELIGIBLE -> { + BillingResponse( + Int.MAX_VALUE, + "the user does not currently meet offer eligibility requirements.", + "This offer isn’t available in your region or for your account type.”", + response.onPurchasesUpdatedSubResponseCode + ) + } + + else -> { + if (enableDebug) { + Log.d( + "JS", + "mapSubResponseCode ${response.onPurchasesUpdatedSubResponseCode}" + ) + } + BillingResponse(Int.MAX_VALUE, "", "", Int.MAX_VALUE) + } + } + } + + return mapResponseCode(response.responseCode) + } + + fun fetchPurchases(callback: (List?, BillingResponse?) -> Unit) { + executor.execute { + val inapp = QueryPurchasesParams.newBuilder() + .setProductType(BillingClient.ProductType.INAPP) + .build() + val subs = QueryPurchasesParams.newBuilder() + .setProductType(BillingClient.ProductType.SUBS) + .build() + val ret = arrayOf>(mutableListOf(), mutableListOf()) + val error = arrayOfNulls(1) + val lock = CountDownLatch(2) + billing.queryPurchasesAsync(inapp) { p0, p1 -> + if (p0.responseCode == BillingClient.BillingResponseCode.OK) { + p1.forEach { purchase -> + purchase?.let { + ret[0].add(Transaction(it, Product.Type.InApp, this)) + } + } + } else { + error[0] = mapResponseCode(p0.responseCode) + } + lock.countDown() + } + + billing.queryPurchasesAsync(subs) { p0, p1 -> + if (p0.responseCode == BillingClient.BillingResponseCode.OK) { + p1.forEach { purchase -> + purchase?.let { + ret[1].add(Transaction(it, Product.Type.Subs, this)) + } + } + } else { + error[0] = mapResponseCode(p0.responseCode) + } + lock.countDown() + } + + try { + lock.await() + ret[0].addAll(ret[1]) + callback( + ret[0], null + ) + } catch (_: Exception) { + callback(null, error[0]) + } + } + } + + companion object { + @JvmStatic + var enableDebug = false + + @JvmStatic + internal fun mapResponseCode(code: Int): BillingResponse { + return when (code) { + BillingClient.BillingResponseCode.OK -> BillingResponse(code, "OK", "") + + BillingClient.BillingResponseCode.BILLING_UNAVAILABLE -> BillingResponse( + code, + "A user billing error occurred during processing.", + "Automatic retries are unlikely to help in this case. However, a manual retry can help if the user addresses the condition that caused the issue." + ) + + BillingClient.BillingResponseCode.NETWORK_ERROR -> BillingResponse( + code, + "A network error occurred during the operation.", + "" + ) + + BillingClient.BillingResponseCode.USER_CANCELED -> BillingResponse( + code, + "The user has clicked out of the billing flow UI.", + "This is informational only and can fail gracefully." + ) + + BillingClient.BillingResponseCode.ITEM_UNAVAILABLE -> BillingResponse( + code, + "The requested product is not available for purchase.", + "Make sure your app refreshes the product details via queryProductDetailsAsync as recommended." + ) + + BillingClient.BillingResponseCode.DEVELOPER_ERROR -> BillingResponse( + code, + "Error resulting from incorrect usage of the API.", + "Make sure that you are correctly using the different Play Billing Library calls. Also, check the debug message for more info about the error." + ) + + BillingClient.BillingResponseCode.FEATURE_NOT_SUPPORTED -> BillingResponse( + code, + "The requested feature is not supported by the Play Store on the current device.", + "Use isFeatureSupported() to check feature support before making the call to the Play Billing Library." + ) + + BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED -> BillingResponse( + code, + "The purchase failed because the item is already owned.", + "To avoid this error happening when the cause is not a cache issue, don't offer a product for purchase when the user already owns it." + ) + + BillingClient.BillingResponseCode.ITEM_NOT_OWNED -> BillingResponse( + code, + "Requested action on the item failed since it is not owned by the user.", + "When the error is received because of a cache issue, the error triggers Google Play’s cache to get updated with the latest data from Play’s backend." + ) + + BillingClient.BillingResponseCode.SERVICE_UNAVAILABLE -> BillingResponse( + code, + "The service is currently unavailable.", + "This is usually a transient issue. Retry the request using either either a simple or exponential backoff strategy, depending on which action returned the error." + ) + + BillingClient.BillingResponseCode.SERVICE_DISCONNECTED -> BillingResponse( + code, + "The app is not connected to the Play Store service via the Google Play Billing Library.", + "To attempt recovery from SERVICE_DISCONNECTED , your client app should try to re-establish the connection using .restartConnection." + ) + + BillingClient.BillingResponseCode.ERROR -> BillingResponse( + code, + "Fatal error during the API action.", + "Sometimes internal Google Play problems that lead to ERROR are transient, and a retry with an exponential backoff can be implemented for mitigation. When users are in session, a simple retry is preferable." + ) + + else -> { + if (enableDebug) { + Log.d("JS", "mapResponseCode $code") + } + return BillingResponse(Int.MAX_VALUE, "", "") + } + } + } + + @JvmStatic + fun isSupported(context: Context): Boolean { + val playStoreIntent = Intent(Intent.ACTION_VIEW).apply { + data = Uri.parse("market://details?id=${context.packageName}") + setPackage("com.android.vending") + } + return playStoreIntent.resolveActivity(context.packageManager) != null + } + } + +} diff --git a/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Product.kt b/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Product.kt new file mode 100644 index 0000000..2efe764 --- /dev/null +++ b/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Product.kt @@ -0,0 +1,62 @@ +package org.nativescript.plugins.payments + +import com.android.billingclient.api.BillingClient +import com.android.billingclient.api.ProductDetails + +class Product(val product: ProductDetails) { + enum class Type(val value: Int) { + InApp(0), + Subs(1); + + internal val toType: String + get() { + return when (this) { + InApp -> BillingClient.ProductType.INAPP + Subs -> BillingClient.ProductType.SUBS + } + } + } + + val id: String + get() { + return product.productId + } + + val name: String + get() { + return product.name + } + + val title: String + get() { + return product.title + } + + val description: String + get() { + return product.description + } + + val priceAmountMicros: Long? + get() { + return product.oneTimePurchaseOfferDetails?.priceAmountMicros + ?: product.subscriptionOfferDetails?.firstOrNull()?.pricingPhases?.pricingPhaseList?.firstOrNull()?.priceAmountMicros + } + + val priceFormatted: String? + get() { + return product.oneTimePurchaseOfferDetails?.formattedPrice + ?: product.subscriptionOfferDetails?.firstOrNull()?.pricingPhases?.pricingPhaseList?.firstOrNull()?.formattedPrice + } + + val type: Product.Type + get() { + return when (product.productType) { + BillingClient.ProductType.INAPP -> Type.InApp + BillingClient.ProductType.SUBS -> Type.Subs + else -> { + throw Error("Unknown ProductType ${product.productType}") + } + } + } +} diff --git a/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Transaction.kt b/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Transaction.kt new file mode 100644 index 0000000..99b5129 --- /dev/null +++ b/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Transaction.kt @@ -0,0 +1,115 @@ +package org.nativescript.plugins.payments + +import com.android.billingclient.api.AcknowledgePurchaseParams +import com.android.billingclient.api.BillingClient +import com.android.billingclient.api.ConsumeParams +import com.android.billingclient.api.Purchase +import org.json.JSONObject + +class Transaction(val purchase: Purchase, val type: Product.Type, private val payments: Payments) { + + enum class State(val value: Int) { + Unknown(-1), Purchased(1), Pending(2) + } + + val orderId: String? + get() { + return purchase.orderId + } + + val productId: String? + get() { + return purchase.products.first() + } + + val orderDate: Long + get() { + return purchase.purchaseTime + } + + val isSubscription: Boolean + get() { + return purchase.isAutoRenewing + } + + val products: List + get() { + return purchase.products + } + + val quantity: Int + get() { + return purchase.quantity + } + + val token: String + get() { + return purchase.purchaseToken + } + + val signature: String + get() { + return purchase.signature + } + + val state: State + get() { + return when (purchase.purchaseState) { + Purchase.PurchaseState.PURCHASED -> State.Purchased + Purchase.PurchaseState.PENDING -> State.Pending + else -> State.Unknown + } + } + + val developerPayload: String + get() { + return purchase.developerPayload + } + + val originalJsonString: String + get() { + return purchase.originalJson + } + + private var json: JSONObject? = null + val originalJson: JSONObject + get() { + if (json == null) { + try { + json = JSONObject(purchase.originalJson) + } catch (_: Exception) { + } + } + return json ?: JSONObject() + } + + fun finish(callback: (Payments.BillingResponse?) -> Unit) { + if (purchase.isAutoRenewing) { + if (purchase.isAcknowledged) { + callback(null) + return + } + val params = AcknowledgePurchaseParams.newBuilder() + .setPurchaseToken(purchase.purchaseToken) + .build() + payments.billing.acknowledgePurchase(params) { p0 -> + if (p0.responseCode == BillingClient.BillingResponseCode.OK) { + callback(null) + } else { + callback(Payments.mapResponseCode(p0.responseCode)) + } + } + } else { + val params = ConsumeParams.newBuilder() + .setPurchaseToken(purchase.purchaseToken) + .build() + payments.billing.consumeAsync(params) { p0, p1 -> + if (p0.responseCode == BillingClient.BillingResponseCode.OK) { + callback(null) + } else { + callback(Payments.mapResponseCode(p0.responseCode)) + } + } + } + } +} diff --git a/packages/payments/platforms/ios/src/NSCPayment.swift b/packages/payments/platforms/ios/src/NSCPayment.swift new file mode 100644 index 0000000..dd8ac91 --- /dev/null +++ b/packages/payments/platforms/ios/src/NSCPayment.swift @@ -0,0 +1,690 @@ +// +// NSCPayments.swift +// @nativescript/payments +// +// Created by Osei Fortune on 09/08/2025. +// Copyright © 2025 NativeScript. All rights reserved. +// +import UIKit +import StoreKit + + +@objc(NSCPaymentsStoreKitVersion) +public enum NSCPaymentsStoreKitVersion: Int32, RawRepresentable { + case v1 + case v2 + + public typealias RawValue = Int32 + + public init?(rawValue: Int32) { + switch rawValue { + case 0: + self = .v1 + break + case 1: + self = .v2 + default: + return nil + } + } + + public var rawValue: Int32 { + switch self {case .v1: + return 0 + case .v2: + return 1 + } + } + + var storeKit2Available: Bool { + if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { + return true + } + return false + } + +} + + +@objc(NSCTransactionState) +public enum NSCTransactionState: Int32, RawRepresentable { + case unknown + case purchased + case pending + + public typealias RawValue = Int32 + + public init?(rawValue: Int32) { + switch rawValue { + case -1: + self = .unknown + break + case 1: + self = .purchased + case 2: + self = .pending + default: + return nil + } + } + + public var rawValue: Int32 { + switch self { + case .unknown: + return -1 + case .purchased: + return 1 + case .pending: + return 2 + } + } +} + +@objc(NSCTransaction) +@objcMembers +public class NSCTransaction: NSObject { + public let version: NSCPaymentsStoreKitVersion + internal var transaction: Any + init(transaction: Any, _ version : NSCPaymentsStoreKitVersion) { + self.version = version + self.transaction = transaction + } + + public var orderId: String? { + if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { + return "\(v2!.id)" + } + return v1!.transactionIdentifier + } + + public var productId: String { + if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { + return v2!.productID + } + return v1!.payment.productIdentifier + } + + public var orderDate: Date? { + if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { + return v2!.purchaseDate + } + return v1!.transactionDate + } + + + internal var errorValue: Error? = nil + var error: Error? { + get { + switch(version){ + case .v1: + return v1!.error + case .v2: + return errorValue + } + } + } + + var state: NSCTransactionState { + get { + if(version == .v2 && version.storeKit2Available){ + if #available(iOS 15.0, *) { + switch v2!.revocationReason { + case .some: + return .unknown + default: + return .purchased + } + } else { + return .unknown + } + } + + switch(v1!.transactionState){ + case .purchasing: + return .pending + case .purchased: + return .purchased + case .failed: + return .unknown + case .restored: + return .purchased + case .deferred: + return .pending + } + + } + } + + var receipt: String? { + get { + if version == .v2 && version.storeKit2Available { + if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { + return String(data:v2!.jsonRepresentation, encoding: .utf8) + } + } + return nil + } + } + + @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) + internal var v2: Transaction? { + if version.storeKit2Available { + return transaction as? Transaction + } + return nil + } + + internal var v1: SKPaymentTransaction? { + if version == .v1 { + return transaction as? SKPaymentTransaction + } + return nil + } + + public func finish(_ callback: @escaping (NSCPaymentsResponse?) -> Void) { + if version == .v2 && version.storeKit2Available { + Task { + if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { + await v2!.finish() + for await complete in Transaction.all { + switch complete { + case .unverified(let t, let error): + if(t.id == v2!.id){ + self.errorValue = error + callback(NSCPaymentsResponse(code: .Error, message: "Usage error: \(error.localizedDescription)", resolution: "")) + break + } + break + case .verified(let t): + if(t.id == v2!.id){ + self.transaction = transaction + callback(nil) + break + } + } + } + } + } + } else { + SKPaymentQueue.default().finishTransaction(v1!) + } + } +} + +@objc(NSCProduct) +@objcMembers +public class NSCProduct: NSObject { + public let version: NSCPaymentsStoreKitVersion + internal let product: Any + init(product: Any, _ version : NSCPaymentsStoreKitVersion) { + self.product = product + self.version = version + } + + public var receiptToken: String? { + if let url = Bundle.main.appStoreReceiptURL { + do { + return try Data(contentsOf: url).base64EncodedString() + }catch { + return nil + } + } + return nil + } + + @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) + internal var v2: Product? { + if version.storeKit2Available { + return product as? Product + } + return nil + } + + internal var v1: SKProduct? { + if version == .v1 { + return product as? SKProduct + } + return nil + } + + public var type: String { + if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { + switch(v2!.type){ + case .autoRenewable, .nonRenewable: + return "sub" + default: + return "inapp" + } + } + + if #available(iOS 11.2, macOS 10.13.2, tvOS 11.2, watchOS 6.2, *){ + if(v1?.subscriptionPeriod != nil){ + return "sub" + }else { + return "inapp" + } + } + + return "inapp" + } + + + public var productIdentifier: String { + return id + } + + public var id: String { + if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { + return v2!.id + } + return v1!.productIdentifier + } + + public override var description: String { + if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { + return v2!.description + } + return v1!.localizedDescription + } + + public var displayName: String { + if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { + return v2!.displayName + } + return v1!.localizedTitle + } + + public var price: Double { + if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { + return NSDecimalNumber(decimal: v2!.price).doubleValue + } + return v1!.price.doubleValue + } + + public var isFamilyShareable: Bool { + if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { + return v2!.isFamilyShareable + } + if #available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) { + return v1!.isFamilyShareable + } else { + return false + } + } + + public var priceCurrencyCode: String? { + if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { + return v2!.priceFormatStyle.currencyCode + } + return v1!.priceLocale.currencyCode + } + + public var priceFormatted: String? { + if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { + return v2!.displayPrice + } + let formatter = NumberFormatter() + formatter.numberStyle = .currency + formatter.locale = v1!.priceLocale + return formatter.string(from: v1!.price) + } +} + +@objc(NSCPaymentsResponseFailure) +public enum NSCPaymentsResponseFailure: Int32, RawRepresentable { + case ProductUnavailable + case DeveloperUsage + case ProductAlreadyOwned + case ProductNotOwned + case UserCancelled + case NetworkAvailability + case BillingAvailability + case Unspecified + case PurchaseNotAllowed + case DeferredPayment + case Error + public typealias RawValue = Int32 + + public init?(rawValue: Int32) { + switch rawValue { + case 0: + self = .ProductUnavailable + break + case 1: + self = .DeveloperUsage + break + case 2: + self = .ProductAlreadyOwned + break + case 3: + self = .ProductNotOwned + break + case 4: + self = .UserCancelled + break + case 5: + self = .NetworkAvailability + break + case 6: + self = .BillingAvailability + break + case 7: + self = .Unspecified + break + case 8: + self = .PurchaseNotAllowed + break + case 9: + self = .DeferredPayment + break + case 10: + self = .Error + break + default: + return nil + } + } + + public var rawValue: Int32 { + switch self { + case .ProductUnavailable: + return 0 + case .DeveloperUsage: + return 1 + case .ProductAlreadyOwned: + return 2 + case .ProductNotOwned: + return 3 + case .UserCancelled: + return 4 + case .NetworkAvailability: + return 5 + case .BillingAvailability: + return 6 + case .Unspecified: + return 7 + case .PurchaseNotAllowed: + return 8 + case .DeferredPayment: + return 9 + case .Error: + return 10 + } + } +} + +@objc(NSCPaymentsResponse) +@objcMembers +public class NSCPaymentsResponse: NSObject { + public let code: NSCPaymentsResponseFailure + public let message: String + public let resolution: String + + public init( + code: NSCPaymentsResponseFailure, + message: String, + resolution: String + ){ + self.code = code + self.message = message + self.resolution = resolution + } +} + +@objc(NSCPayments) +@objcMembers +public class NSCPayments: NSObject { + internal var updatesListener: AnyObject? + internal var pendingTasks: [AnyObject] = [] + public let version: NSCPaymentsStoreKitVersion + public var transactionUpdateListener: ((NSCTransaction) -> Void)? + internal var isRestoring = false + internal var fetchingPurchases: [([NSCTransaction]?, NSCPaymentsResponse?) -> Void] = [] + internal var previousPurcahses: [NSCTransaction] = [] + public override init() { + if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { + version = .v2 + super.init() + updatesListener = Task(priority: .background) { + for await transaction in Transaction.updates { + switch transaction { + case .unverified(let transaction, let error): + let ret = NSCTransaction(transaction: transaction, .v2) + ret.errorValue = error + transactionUpdateListener?(ret) + break + case .verified(let transaction): + transactionUpdateListener?(NSCTransaction(transaction: transaction, .v2)) + break + } + } + } as AnyObject + }else { + version = .v1 + super.init() + let instance: SKPaymentTransactionObserver = { + class TransactionObserver: NSObject, SKPaymentTransactionObserver { + var payments: NSCPayments + + init(payments instance : NSCPayments) { + payments = instance + super.init() + } + + func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { + if(payments.isRestoring){ + for transaction in transactions where transaction.transactionState == .restored { + payments.previousPurcahses.append(NSCTransaction(transaction: transaction, .v1)) + } + }else { + for transaction in transactions { + payments.transactionUpdateListener?(NSCTransaction(transaction: transaction, .v1)) + } + } + } + + func paymentQueue(_ queue: SKPaymentQueue, removedTransactions transactions: [SKPaymentTransaction]) { + + } + + func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: Error) { + if(payments.isRestoring){ + for callback in payments.fetchingPurchases { + callback(nil,NSCPaymentsResponse(code: .Error, message: "Usage error: \(error.localizedDescription)", resolution: "")) + } + } + } + + func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) { + if(payments.isRestoring){ + for callback in payments.fetchingPurchases { + callback(payments.previousPurcahses, nil) + } + + payments.fetchingPurchases.removeAll() + payments.previousPurcahses.removeAll() + payments.isRestoring = false + } + } + + func paymentQueue(shouldAddStorePayment payment: SKPayment, forTransaction transaction: SKPaymentTransaction) -> Bool { + return true + } + } + return TransactionObserver(payments: self) + }() + SKPaymentQueue.default().add(instance) + updatesListener = instance + } + + } + + deinit { + switch(version){ + case .v1: + SKPaymentQueue.default().remove(self.updatesListener as! SKPaymentTransactionObserver) + break + case .v2: + if let listener = updatesListener as? Task { + listener.cancel() + } + break + } + } + + public func canMakePayments() -> Bool { + return NSCPayments.isSupported() + } + + public func fetchProducts(_ identifiers: [String], _ callback: @escaping ([NSCProduct], Error?) -> Void) { + switch(version){ + case .v1: + let request = SKProductsRequest(productIdentifiers: Set(identifiers)) + + let delegate: SKProductsRequestDelegate = { + class SKProductsRequestDelegateImpl: NSObject, SKProductsRequestDelegate { + let callback: ([NSCProduct], Error?) -> Void + let version: NSCPaymentsStoreKitVersion + init(_ cb: @escaping ([NSCProduct], Error?) -> Void, _ storeVerion: NSCPaymentsStoreKitVersion){ + version = storeVerion + callback = cb + super .init() + + } + + func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) { + let products = response.products.map {NSCProduct(product: $0, version)} + callback( products, nil) + } + + func request(_ request: SKRequest, didFailWithError error: Error) { + callback([], error) + } + } + return SKProductsRequestDelegateImpl(callback, version) + }() + + request.delegate = delegate + request.start() + + break + case .v2: + if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { + Task { + do { + + let products = try await Product.products(for: Set(identifiers)) + let ret = products.map {NSCProduct(product: $0, version)} + callback(ret,nil) + }catch { + callback([], error) + } + } + } + break + } + } + + public func purchaseProduct(_ product: NSCProduct, _ confirmIn: UIViewController, _ callback: @escaping (NSCPaymentsResponse?)->Void){ + switch(version){ + case .v1: + let payment = SKPayment(product: product.v1!) + SKPaymentQueue.default().add(payment) + break + case .v2: + Task { + do { + if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { + var result: Product.PurchaseResult + if #available(iOS 18.2, *) { + if let scene = await confirmIn.view.window?.windowScene { + result = try await product.v2!.purchase(confirmIn: scene) + }else { + result = try await product.v2!.purchase() + } + }else { + result = try await product.v2!.purchase() + } + + switch result { + case .success(let success): + switch(success){ + case .unverified(_, let verificationError): + callback( + NSCPaymentsResponse(code: .Error, message: "Usage error: \(verificationError.localizedDescription)", resolution: "") + ) + break + case .verified(let transaction): + transactionUpdateListener?(NSCTransaction(transaction: transaction, .v2)) + callback(nil) + break + } + case .userCancelled: + callback(NSCPaymentsResponse(code: .UserCancelled, message: "Indicates that the user cancelled a payment request.", resolution: "")) + break + case .pending: + callback(NSCPaymentsResponse(code: .DeferredPayment, message: "Indicated that is in the queue, but its final status is pending external action such as Ask to Buy.", resolution: "")) + break + + } + + } + }catch { + callback( + NSCPaymentsResponse(code: .Error, message: "Usage error: \(error.localizedDescription)", resolution: "") + ) + } + } + break + } + } + + + // return error + transaction ? + public func fetchPurchases(_ callback: @escaping ([NSCTransaction]?, NSCPaymentsResponse?) -> Void){ + if(version == .v2 && version.storeKit2Available){ + if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *){ + Task(priority: .background) { + do { + try await AppStore.sync() + var purchases: [NSCTransaction] = [] + var hasError: Bool = false + for await transaction in Transaction.currentEntitlements { + switch transaction { + case .unverified(_, let error): + callback(nil,NSCPaymentsResponse(code: .Error, message: "Usage error: \(error.localizedDescription)", resolution: "")) + hasError = true + return + case .verified(let transaction): + purchases.append(NSCTransaction(transaction: transaction, .v2)) + break + } + } + + if(!hasError){ + callback(purchases, nil) + } + + }catch { + callback(nil, NSCPaymentsResponse(code: .Error, message: "Usage error: \(error.localizedDescription)", resolution: "") + ) + } + } + } + }else { + if(isRestoring){ + fetchingPurchases.append(callback) + return + } + SKPaymentQueue.default().restoreCompletedTransactions() + } + } + + public static func isSupported() -> Bool { + if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { + return AppStore.canMakePayments + }else { + return SKPaymentQueue.canMakePayments() + } + } +} diff --git a/packages/payments/typings/android.d.ts b/packages/payments/typings/android.d.ts index a510c55..cee3471 100644 --- a/packages/payments/typings/android.d.ts +++ b/packages/payments/typings/android.d.ts @@ -1,5239 +1,147 @@ -/* eslint-disable @typescript-eslint/prefer-namespace-keyword */ - -declare module com { - export module android { - export module billingclient { - export class BuildConfig { - public static class: java.lang.Class; - public static APPLICATION_ID: string; - public static VERSION_NAME: string; - public constructor(); - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class AccountIdentifiers { - public static class: java.lang.Class; - public getObfuscatedAccountId(): string; - public getObfuscatedProfileId(): string; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class AcknowledgePurchaseParams { - public static class: java.lang.Class; - public static newBuilder(): com.android.billingclient.api.AcknowledgePurchaseParams.Builder; - public getPurchaseToken(): string; - } - export module AcknowledgePurchaseParams { - export class Builder { - public static class: java.lang.Class; - public setPurchaseToken(param0: string): com.android.billingclient.api.AcknowledgePurchaseParams.Builder; - public build(): com.android.billingclient.api.AcknowledgePurchaseParams; - } - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class AcknowledgePurchaseResponseListener { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.android.billingclient.api.AcknowledgePurchaseResponseListener interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - onAcknowledgePurchaseResponse(param0: com.android.billingclient.api.BillingResult): void; - }); - public constructor(); - public onAcknowledgePurchaseResponse(param0: com.android.billingclient.api.BillingResult): void; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class AlternativeBillingListener { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.android.billingclient.api.AlternativeBillingListener interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - userSelectedAlternativeBilling(param0: com.android.billingclient.api.AlternativeChoiceDetails): void; - }); - public constructor(); - public userSelectedAlternativeBilling(param0: com.android.billingclient.api.AlternativeChoiceDetails): void; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class AlternativeChoiceDetails { - public static class: java.lang.Class; - public getProducts(): java.util.List; - public getExternalTransactionToken(): string; - public getOriginalExternalTransactionId(): string; - } - export module AlternativeChoiceDetails { - export class Product { - public static class: java.lang.Class; - public getOfferToken(): string; - public getType(): string; - public hashCode(): number; - public equals(param0: any): boolean; - public getId(): string; - public toString(): string; - } - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export abstract class BillingClient { - public static class: java.lang.Class; - public isReady(): boolean; - public queryPurchaseHistoryAsync(param0: com.android.billingclient.api.QueryPurchaseHistoryParams, param1: com.android.billingclient.api.PurchaseHistoryResponseListener): void; - public launchBillingFlow(param0: globalAndroid.app.Activity, param1: com.android.billingclient.api.BillingFlowParams): com.android.billingclient.api.BillingResult; - public endConnection(): void; - public acknowledgePurchase(param0: com.android.billingclient.api.AcknowledgePurchaseParams, param1: com.android.billingclient.api.AcknowledgePurchaseResponseListener): void; - public showInAppMessages(param0: globalAndroid.app.Activity, param1: com.android.billingclient.api.InAppMessageParams, param2: com.android.billingclient.api.InAppMessageResponseListener): com.android.billingclient.api.BillingResult; - /** @deprecated */ - public querySkuDetailsAsync(param0: com.android.billingclient.api.SkuDetailsParams, param1: com.android.billingclient.api.SkuDetailsResponseListener): void; - public getConnectionState(): number; - public static newBuilder(param0: globalAndroid.content.Context): com.android.billingclient.api.BillingClient.Builder; - public isFeatureSupported(param0: string): com.android.billingclient.api.BillingResult; - public startConnection(param0: com.android.billingclient.api.BillingClientStateListener): void; - public constructor(); - public queryPurchasesAsync(param0: com.android.billingclient.api.QueryPurchasesParams, param1: com.android.billingclient.api.PurchasesResponseListener): void; - public queryProductDetailsAsync(param0: com.android.billingclient.api.QueryProductDetailsParams, param1: com.android.billingclient.api.ProductDetailsResponseListener): void; - /** @deprecated */ - public queryPurchasesAsync(param0: string, param1: com.android.billingclient.api.PurchasesResponseListener): void; - public consumeAsync(param0: com.android.billingclient.api.ConsumeParams, param1: com.android.billingclient.api.ConsumeResponseListener): void; - /** @deprecated */ - public queryPurchaseHistoryAsync(param0: string, param1: com.android.billingclient.api.PurchaseHistoryResponseListener): void; - } - export module BillingClient { - export class BillingResponseCode { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.android.billingclient.api.BillingClient$BillingResponseCode interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - }); - public constructor(); - public static ITEM_ALREADY_OWNED: number; - public static SERVICE_TIMEOUT: number; - public static FEATURE_NOT_SUPPORTED: number; - public static SERVICE_DISCONNECTED: number; - public static ITEM_NOT_OWNED: number; - public static ITEM_UNAVAILABLE: number; - public static NETWORK_ERROR: number; - public static USER_CANCELED: number; - public static SERVICE_UNAVAILABLE: number; - public static ERROR: number; - public static OK: number; - public static BILLING_UNAVAILABLE: number; - public static DEVELOPER_ERROR: number; - } - export class Builder { - public static class: java.lang.Class; - public build(): com.android.billingclient.api.BillingClient; - public setListener(param0: com.android.billingclient.api.PurchasesUpdatedListener): com.android.billingclient.api.BillingClient.Builder; - public enableAlternativeBilling(param0: com.android.billingclient.api.AlternativeBillingListener): com.android.billingclient.api.BillingClient.Builder; - public enablePendingPurchases(): com.android.billingclient.api.BillingClient.Builder; - } - export class ConnectionState { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.android.billingclient.api.BillingClient$ConnectionState interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - }); - public constructor(); - public static CONNECTED: number; - public static DISCONNECTED: number; - public static CLOSED: number; - public static CONNECTING: number; - } - export class FeatureType { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.android.billingclient.api.BillingClient$FeatureType interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - }); - public constructor(); - public static SUBSCRIPTIONS: string; - public static PRODUCT_DETAILS: string; - public static IN_APP_MESSAGING: string; - public static SUBSCRIPTIONS_UPDATE: string; - public static PRICE_CHANGE_CONFIRMATION: string; - } - export class ProductType { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.android.billingclient.api.BillingClient$ProductType interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - }); - public constructor(); - public static INAPP: string; - public static SUBS: string; - } - export class SkuType { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.android.billingclient.api.BillingClient$SkuType interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - }); - public constructor(); - public static INAPP: string; - public static SUBS: string; - } - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class BillingClientImpl extends com.android.billingclient.api.BillingClient { - public static class: java.lang.Class; - public isReady(): boolean; - public queryPurchaseHistoryAsync(param0: com.android.billingclient.api.QueryPurchaseHistoryParams, param1: com.android.billingclient.api.PurchaseHistoryResponseListener): void; - public launchBillingFlow(param0: globalAndroid.app.Activity, param1: com.android.billingclient.api.BillingFlowParams): com.android.billingclient.api.BillingResult; - public endConnection(): void; - public acknowledgePurchase(param0: com.android.billingclient.api.AcknowledgePurchaseParams, param1: com.android.billingclient.api.AcknowledgePurchaseResponseListener): void; - public querySkuDetailsAsync(param0: com.android.billingclient.api.SkuDetailsParams, param1: com.android.billingclient.api.SkuDetailsResponseListener): void; - public showInAppMessages(param0: globalAndroid.app.Activity, param1: com.android.billingclient.api.InAppMessageParams, param2: com.android.billingclient.api.InAppMessageResponseListener): com.android.billingclient.api.BillingResult; - /** @deprecated */ - public querySkuDetailsAsync(param0: com.android.billingclient.api.SkuDetailsParams, param1: com.android.billingclient.api.SkuDetailsResponseListener): void; - public queryPurchaseHistoryAsync(param0: string, param1: com.android.billingclient.api.PurchaseHistoryResponseListener): void; - public queryPurchasesAsync(param0: string, param1: com.android.billingclient.api.PurchasesResponseListener): void; - public getConnectionState(): number; - public isFeatureSupported(param0: string): com.android.billingclient.api.BillingResult; - public startConnection(param0: com.android.billingclient.api.BillingClientStateListener): void; - public queryPurchasesAsync(param0: com.android.billingclient.api.QueryPurchasesParams, param1: com.android.billingclient.api.PurchasesResponseListener): void; - public queryProductDetailsAsync(param0: com.android.billingclient.api.QueryProductDetailsParams, param1: com.android.billingclient.api.ProductDetailsResponseListener): void; - /** @deprecated */ - public queryPurchasesAsync(param0: string, param1: com.android.billingclient.api.PurchasesResponseListener): void; - public consumeAsync(param0: com.android.billingclient.api.ConsumeParams, param1: com.android.billingclient.api.ConsumeResponseListener): void; - /** @deprecated */ - public queryPurchaseHistoryAsync(param0: string, param1: com.android.billingclient.api.PurchaseHistoryResponseListener): void; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class BillingClientStateListener { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.android.billingclient.api.BillingClientStateListener interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - onBillingServiceDisconnected(): void; - onBillingSetupFinished(param0: com.android.billingclient.api.BillingResult): void; - }); - public constructor(); - public onBillingSetupFinished(param0: com.android.billingclient.api.BillingResult): void; - public onBillingServiceDisconnected(): void; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class BillingFlowParams { - public static class: java.lang.Class; - public static EXTRA_PARAM_KEY_ACCOUNT_ID: string; - public static newBuilder(): com.android.billingclient.api.BillingFlowParams.Builder; - } - export module BillingFlowParams { - export class Builder { - public static class: java.lang.Class; - public setObfuscatedProfileId(param0: string): com.android.billingclient.api.BillingFlowParams.Builder; - /** @deprecated */ - public setSkuDetails(param0: com.android.billingclient.api.SkuDetails): com.android.billingclient.api.BillingFlowParams.Builder; - public setIsOfferPersonalized(param0: boolean): com.android.billingclient.api.BillingFlowParams.Builder; - public setObfuscatedAccountId(param0: string): com.android.billingclient.api.BillingFlowParams.Builder; - public build(): com.android.billingclient.api.BillingFlowParams; - public setSubscriptionUpdateParams(param0: com.android.billingclient.api.BillingFlowParams.SubscriptionUpdateParams): com.android.billingclient.api.BillingFlowParams.Builder; - public setProductDetailsParamsList(param0: java.util.List): com.android.billingclient.api.BillingFlowParams.Builder; - } - export class ProductDetailsParams { - public static class: java.lang.Class; - public static newBuilder(): com.android.billingclient.api.BillingFlowParams.ProductDetailsParams.Builder; - } - export module ProductDetailsParams { - export class Builder { - public static class: java.lang.Class; - public setOfferToken(param0: string): com.android.billingclient.api.BillingFlowParams.ProductDetailsParams.Builder; - public build(): com.android.billingclient.api.BillingFlowParams.ProductDetailsParams; - public setProductDetails(param0: com.android.billingclient.api.ProductDetails): com.android.billingclient.api.BillingFlowParams.ProductDetailsParams.Builder; - } - } - export class ProrationMode { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.android.billingclient.api.BillingFlowParams$ProrationMode interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - }); - public constructor(); - public static IMMEDIATE_WITH_TIME_PRORATION: number; - public static DEFERRED: number; - public static UNKNOWN_SUBSCRIPTION_UPGRADE_DOWNGRADE_POLICY: number; - public static IMMEDIATE_AND_CHARGE_PRORATED_PRICE: number; - public static IMMEDIATE_AND_CHARGE_FULL_PRICE: number; - public static IMMEDIATE_WITHOUT_PRORATION: number; - } - export class SubscriptionUpdateParams { - public static class: java.lang.Class; - public static newBuilder(): com.android.billingclient.api.BillingFlowParams.SubscriptionUpdateParams.Builder; - } - export module SubscriptionUpdateParams { - export class Builder { - public static class: java.lang.Class; - /** @deprecated */ - public setOldSkuPurchaseToken(param0: string): com.android.billingclient.api.BillingFlowParams.SubscriptionUpdateParams.Builder; - /** @deprecated */ - public setReplaceSkusProrationMode(param0: number): com.android.billingclient.api.BillingFlowParams.SubscriptionUpdateParams.Builder; - /** @deprecated */ - public setReplaceProrationMode(param0: number): com.android.billingclient.api.BillingFlowParams.SubscriptionUpdateParams.Builder; - public build(): com.android.billingclient.api.BillingFlowParams.SubscriptionUpdateParams; - public setSubscriptionReplacementMode(param0: number): com.android.billingclient.api.BillingFlowParams.SubscriptionUpdateParams.Builder; - public setOriginalExternalTransactionId(param0: string): com.android.billingclient.api.BillingFlowParams.SubscriptionUpdateParams.Builder; - public setOldPurchaseToken(param0: string): com.android.billingclient.api.BillingFlowParams.SubscriptionUpdateParams.Builder; - } - export class ReplacementMode { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.android.billingclient.api.BillingFlowParams$SubscriptionUpdateParams$ReplacementMode interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - }); - public constructor(); - public static WITHOUT_PRORATION: number; - public static CHARGE_FULL_PRICE: number; - public static WITH_TIME_PRORATION: number; - public static DEFERRED: number; - public static CHARGE_PRORATED_PRICE: number; - public static UNKNOWN_REPLACEMENT_MODE: number; - } - } - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class BillingResult { - public static class: java.lang.Class; - public toString(): string; - public getResponseCode(): number; - public constructor(); - public static newBuilder(): com.android.billingclient.api.BillingResult.Builder; - public getDebugMessage(): string; - } - export module BillingResult { - export class Builder { - public static class: java.lang.Class; - public build(): com.android.billingclient.api.BillingResult; - public setDebugMessage(param0: string): com.android.billingclient.api.BillingResult.Builder; - public setResponseCode(param0: number): com.android.billingclient.api.BillingResult.Builder; - } - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class ConsumeParams { - public static class: java.lang.Class; - public static newBuilder(): com.android.billingclient.api.ConsumeParams.Builder; - public getPurchaseToken(): string; - } - export module ConsumeParams { - export class Builder { - public static class: java.lang.Class; - public setPurchaseToken(param0: string): com.android.billingclient.api.ConsumeParams.Builder; - public build(): com.android.billingclient.api.ConsumeParams; - } - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class ConsumeResponseListener { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.android.billingclient.api.ConsumeResponseListener interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - onConsumeResponse(param0: com.android.billingclient.api.BillingResult, param1: string): void; - }); - public constructor(); - public onConsumeResponse(param0: com.android.billingclient.api.BillingResult, param1: string): void; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class InAppMessageParams { - public static class: java.lang.Class; - public static newBuilder(): com.android.billingclient.api.InAppMessageParams.Builder; - } - export module InAppMessageParams { - export class Builder { - public static class: java.lang.Class; - public constructor(); - public addInAppMessageCategoryToShow(param0: number): com.android.billingclient.api.InAppMessageParams.Builder; - public addAllInAppMessageCategoriesToShow(): com.android.billingclient.api.InAppMessageParams.Builder; - public build(): com.android.billingclient.api.InAppMessageParams; - } - export class InAppMessageCategoryId { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.android.billingclient.api.InAppMessageParams$InAppMessageCategoryId interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - }); - public constructor(); - public static TRANSACTIONAL: number; - public static UNKNOWN_IN_APP_MESSAGE_CATEGORY_ID: number; - } - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class InAppMessageResponseListener { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.android.billingclient.api.InAppMessageResponseListener interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - onInAppMessageResponse(param0: com.android.billingclient.api.InAppMessageResult): void; - }); - public constructor(); - public onInAppMessageResponse(param0: com.android.billingclient.api.InAppMessageResult): void; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class InAppMessageResult { - public static class: java.lang.Class; - public getResponseCode(): number; - public constructor(param0: number, param1: string); - public getPurchaseToken(): string; - } - export module InAppMessageResult { - export class InAppMessageResponseCode { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.android.billingclient.api.InAppMessageResult$InAppMessageResponseCode interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - }); - public constructor(); - public static SUBSCRIPTION_STATUS_UPDATED: number; - public static NO_ACTION_NEEDED: number; - } - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class ProductDetails { - public static class: java.lang.Class; - public getTitle(): string; - public equals(param0: any): boolean; - public getProductId(): string; - public toString(): string; - public getName(): string; - public getProductType(): string; - public getSubscriptionOfferDetails(): java.util.List; - public hashCode(): number; - public getOneTimePurchaseOfferDetails(): com.android.billingclient.api.ProductDetails.OneTimePurchaseOfferDetails; - public getDescription(): string; - } - export module ProductDetails { - export class OneTimePurchaseOfferDetails { - public static class: java.lang.Class; - public getFormattedPrice(): string; - public getPriceCurrencyCode(): string; - public getPriceAmountMicros(): number; - } - export class PricingPhase { - public static class: java.lang.Class; - public getFormattedPrice(): string; - public getPriceCurrencyCode(): string; - public getRecurrenceMode(): number; - public getPriceAmountMicros(): number; - public getBillingPeriod(): string; - public getBillingCycleCount(): number; - } - export class PricingPhases { - public static class: java.lang.Class; - public getPricingPhaseList(): java.util.List; - } - export class RecurrenceMode { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.android.billingclient.api.ProductDetails$RecurrenceMode interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - }); - public constructor(); - public static FINITE_RECURRING: number; - public static NON_RECURRING: number; - public static INFINITE_RECURRING: number; - } - export class SubscriptionOfferDetails { - public static class: java.lang.Class; - public getOfferToken(): string; - public getOfferId(): string; - public getPricingPhases(): com.android.billingclient.api.ProductDetails.PricingPhases; - public getOfferTags(): java.util.List; - public getBasePlanId(): string; - } - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class ProductDetailsResponseListener { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.android.billingclient.api.ProductDetailsResponseListener interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - onProductDetailsResponse(param0: com.android.billingclient.api.BillingResult, param1: java.util.List): void; - }); - public constructor(); - public onProductDetailsResponse(param0: com.android.billingclient.api.BillingResult, param1: java.util.List): void; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class ProxyBillingActivity { - public static class: java.lang.Class; - public onActivityResult(param0: number, param1: number, param2: globalAndroid.content.Intent): void; - public onSaveInstanceState(param0: globalAndroid.os.Bundle): void; - public onCreate(param0: globalAndroid.os.Bundle): void; - public constructor(); - public onDestroy(): void; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class Purchase { - public static class: java.lang.Class; - public getOrderId(): string; - /** @deprecated */ - public getSkus(): java.util.ArrayList; - public getPurchaseState(): number; - public getPackageName(): string; - public isAcknowledged(): boolean; - public getQuantity(): number; - public getPurchaseToken(): string; - public constructor(param0: string, param1: string); - public equals(param0: any): boolean; - public toString(): string; - public getSignature(): string; - public getPurchaseTime(): number; - public getOriginalJson(): string; - public getDeveloperPayload(): string; - public isAutoRenewing(): boolean; - public hashCode(): number; - public getAccountIdentifiers(): com.android.billingclient.api.AccountIdentifiers; - public getProducts(): java.util.List; - } - export module Purchase { - export class PurchaseState { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.android.billingclient.api.Purchase$PurchaseState interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - }); - public constructor(); - public static PENDING: number; - public static PURCHASED: number; - public static UNSPECIFIED_STATE: number; - } - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class PurchaseHistoryRecord { - public static class: java.lang.Class; - public constructor(param0: string, param1: string); - public equals(param0: any): boolean; - public toString(): string; - public getSignature(): string; - /** @deprecated */ - public getSkus(): java.util.ArrayList; - public getPurchaseTime(): number; - public getOriginalJson(): string; - public getDeveloperPayload(): string; - public hashCode(): number; - public getQuantity(): number; - public getPurchaseToken(): string; - public getProducts(): java.util.List; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class PurchaseHistoryResponseListener { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.android.billingclient.api.PurchaseHistoryResponseListener interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - onPurchaseHistoryResponse(param0: com.android.billingclient.api.BillingResult, param1: java.util.List): void; - }); - public constructor(); - public onPurchaseHistoryResponse(param0: com.android.billingclient.api.BillingResult, param1: java.util.List): void; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class PurchasesResponseListener { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.android.billingclient.api.PurchasesResponseListener interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - onQueryPurchasesResponse(param0: com.android.billingclient.api.BillingResult, param1: java.util.List): void; - }); - public constructor(); - public onQueryPurchasesResponse(param0: com.android.billingclient.api.BillingResult, param1: java.util.List): void; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class PurchasesUpdatedListener { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.android.billingclient.api.PurchasesUpdatedListener interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - onPurchasesUpdated(param0: com.android.billingclient.api.BillingResult, param1: java.util.List): void; - }); - public constructor(); - public onPurchasesUpdated(param0: com.android.billingclient.api.BillingResult, param1: java.util.List): void; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class QueryProductDetailsParams { - public static class: java.lang.Class; - public static newBuilder(): com.android.billingclient.api.QueryProductDetailsParams.Builder; - } - export module QueryProductDetailsParams { - export class Builder { - public static class: java.lang.Class; - public setProductList(param0: java.util.List): com.android.billingclient.api.QueryProductDetailsParams.Builder; - public build(): com.android.billingclient.api.QueryProductDetailsParams; - } - export class Product { - public static class: java.lang.Class; - public static newBuilder(): com.android.billingclient.api.QueryProductDetailsParams.Product.Builder; - } - export module Product { - export class Builder { - public static class: java.lang.Class; - public build(): com.android.billingclient.api.QueryProductDetailsParams.Product; - public setProductType(param0: string): com.android.billingclient.api.QueryProductDetailsParams.Product.Builder; - public setProductId(param0: string): com.android.billingclient.api.QueryProductDetailsParams.Product.Builder; - } - } - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class QueryPurchaseHistoryParams { - public static class: java.lang.Class; - public static newBuilder(): com.android.billingclient.api.QueryPurchaseHistoryParams.Builder; - } - export module QueryPurchaseHistoryParams { - export class Builder { - public static class: java.lang.Class; - public setProductType(param0: string): com.android.billingclient.api.QueryPurchaseHistoryParams.Builder; - public build(): com.android.billingclient.api.QueryPurchaseHistoryParams; - } - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class QueryPurchasesParams { - public static class: java.lang.Class; - public static newBuilder(): com.android.billingclient.api.QueryPurchasesParams.Builder; - } - export module QueryPurchasesParams { - export class Builder { - public static class: java.lang.Class; - public build(): com.android.billingclient.api.QueryPurchasesParams; - public setProductType(param0: string): com.android.billingclient.api.QueryPurchasesParams.Builder; - } - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class SkuDetails { - public static class: java.lang.Class; - public getTitle(): string; - public constructor(param0: string); - public getPriceCurrencyCode(): string; - public getIntroductoryPriceCycles(): number; - public equals(param0: any): boolean; - public toString(): string; - public getIntroductoryPrice(): string; - public getSubscriptionPeriod(): string; - public getPriceAmountMicros(): number; - public getOriginalJson(): string; - public getIntroductoryPricePeriod(): string; - public getSku(): string; - public getIntroductoryPriceAmountMicros(): number; - public getOriginalPriceAmountMicros(): number; - public hashCode(): number; - public getDescription(): string; - public getType(): string; - public getIconUrl(): string; - public getOriginalPrice(): string; - public getPrice(): string; - public getFreeTrialPeriod(): string; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class SkuDetailsParams { - public static class: java.lang.Class; - public getSkusList(): java.util.List; - public constructor(); - public static newBuilder(): com.android.billingclient.api.SkuDetailsParams.Builder; - public getSkuType(): string; - } - export module SkuDetailsParams { - export class Builder { - public static class: java.lang.Class; - public setType(param0: string): com.android.billingclient.api.SkuDetailsParams.Builder; - public setSkusList(param0: java.util.List): com.android.billingclient.api.SkuDetailsParams.Builder; - public build(): com.android.billingclient.api.SkuDetailsParams; - } - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class SkuDetailsResponseListener { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.android.billingclient.api.SkuDetailsResponseListener interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - onSkuDetailsResponse(param0: com.android.billingclient.api.BillingResult, param1: java.util.List): void; - }); - public constructor(); - public onSkuDetailsResponse(param0: com.android.billingclient.api.BillingResult, param1: java.util.List): void; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zza { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzaa { - public static class: java.lang.Class; - public onReceiveResult(param0: number, param1: globalAndroid.os.Bundle): void; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzab { - public static class: java.lang.Class; - public newThread(param0: java.lang.Runnable): java.lang.Thread; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzac { - public static class: java.lang.Class; - public call(): any; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzad { - public static class: java.lang.Class; - public run(): void; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzae { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzaf { - public static class: java.lang.Class; - public onServiceConnected(param0: globalAndroid.content.ComponentName, param1: globalAndroid.os.IBinder): void; - public onServiceDisconnected(param0: globalAndroid.content.ComponentName): void; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzag { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzah extends com.google.android.gms.internal.play_billing.zzf { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzai { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzaj implements com.android.billingclient.api.AcknowledgePurchaseResponseListener, com.android.billingclient.api.BillingClientStateListener, com.android.billingclient.api.ConsumeResponseListener, com.android.billingclient.api.PurchaseHistoryResponseListener, com.android.billingclient.api.PurchasesResponseListener, com.android.billingclient.api.PurchasesUpdatedListener, com.android.billingclient.api.SkuDetailsResponseListener { - public static class: java.lang.Class; - public onBillingSetupFinished(param0: com.android.billingclient.api.BillingResult): void; - public onQueryPurchasesResponse(param0: com.android.billingclient.api.BillingResult, param1: java.util.List): void; - public static nativeOnAcknowledgePurchaseResponse(param0: number, param1: string, param2: number): void; - public onSkuDetailsResponse(param0: com.android.billingclient.api.BillingResult, param1: java.util.List): void; - public static nativeOnBillingSetupFinished(param0: number, param1: string, param2: number): void; - public static nativeOnPriceChangeConfirmationResult(param0: number, param1: string, param2: number): void; - public onConsumeResponse(param0: com.android.billingclient.api.BillingResult, param1: string): void; - public static nativeOnPurchasesUpdated(param0: number, param1: string, param2: androidNative.Array): void; - public static nativeOnConsumePurchaseResponse(param0: number, param1: string, param2: string, param3: number): void; - public static nativeOnQueryPurchasesResponse(param0: number, param1: string, param2: androidNative.Array, param3: number): void; - public static nativeOnBillingServiceDisconnected(): void; - public static nativeOnSkuDetailsResponse(param0: number, param1: string, param2: androidNative.Array, param3: number): void; - public static nativeOnPurchaseHistoryResponse(param0: number, param1: string, param2: androidNative.Array, param3: number): void; - public onPurchasesUpdated(param0: com.android.billingclient.api.BillingResult, param1: java.util.List): void; - public onBillingServiceDisconnected(): void; - public onAcknowledgePurchaseResponse(param0: com.android.billingclient.api.BillingResult): void; - public onPurchaseHistoryResponse(param0: com.android.billingclient.api.BillingResult, param1: java.util.List): void; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzak { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzal { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzam { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzan { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzao { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzap { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzaq { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzar { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.android.billingclient.api.zzar interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - zza(param0: any /* com.google.android.gms.internal.play_billing.zzfb*/): void; - zzb(param0: any /* com.google.android.gms.internal.play_billing.zzff*/): void; - zzc(param0: any /* com.google.android.gms.internal.play_billing.zzgd*/): void; - }); - public constructor(); - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzas { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzat { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzau { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzav { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzaw extends com.android.billingclient.api.zzar { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzax { - public static class: java.lang.Class; - public apply(param0: any): any; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzay { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzaz { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.android.billingclient.api.zzaz interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - }); - public constructor(); - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzb { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzba { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzbb { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzbc { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzbd { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzbe { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzbf { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzbg { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzbh { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzbi { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzbj { - public static class: java.lang.Class; - public constructor(param0: com.android.billingclient.api.BillingResult, param1: java.util.List); - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzbk { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzbl { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzbm { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzbn { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzbo { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzbp { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzbq { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzbr { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzbs { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzbt { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzbu { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzc { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzd { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.android.billingclient.api.zzd interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - }); - public constructor(); - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zze { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.android.billingclient.api.zze interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - }); - public constructor(); - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzf { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzg { - public static class: java.lang.Class; - public onReceive(param0: globalAndroid.content.Context, param1: globalAndroid.content.Intent): void; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzh { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzi { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzj { - public static class: java.lang.Class; - public call(): any; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzk { - public static class: java.lang.Class; - public call(): any; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzl { - public static class: java.lang.Class; - public run(): void; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzm { - public static class: java.lang.Class; - public call(): any; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzn { - public static class: java.lang.Class; - public run(): void; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzo { - public static class: java.lang.Class; - public run(): void; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzp { - public static class: java.lang.Class; - public call(): any; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzq { - public static class: java.lang.Class; - public run(): void; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzr { - public static class: java.lang.Class; - public run(): void; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzs { - public static class: java.lang.Class; - public call(): any; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzt { - public static class: java.lang.Class; - public call(): any; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzu { - public static class: java.lang.Class; - public run(): void; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzv { - public static class: java.lang.Class; - public call(): any; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzw { - public static class: java.lang.Class; - public run(): void; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzx { - public static class: java.lang.Class; - public run(): void; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzy { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module android { - export module billingclient { - export module api { - export class zzz { - public static class: java.lang.Class; - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zza { - public static class: java.lang.Class; - public static values(): any /* androidNative.Array*/; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzaa extends com.google.android.gms.internal.play_billing.zzu { - public static class: java.lang.Class; - public size(): number; - public get(param0: number): any; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzab extends com.google.android.gms.internal.play_billing.zzu { - public static class: java.lang.Class; - public size(): number; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzac extends com.google.android.gms.internal.play_billing.zzy { - public static class: java.lang.Class; - public contains(param0: any): boolean; - public size(): number; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzad extends com.google.android.gms.internal.play_billing.zzy { - public static class: java.lang.Class; - public contains(param0: any): boolean; - public size(): number; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzae extends com.google.android.gms.internal.play_billing.zzu { - public static class: java.lang.Class; - public size(): number; - public get(param0: number): any; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzaf extends com.google.android.gms.internal.play_billing.zzx { - public static class: java.lang.Class; - public get(param0: any): any; - public size(): number; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzag { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export abstract class zzah { - public static class: java.lang.Class; - public constructor(); - /** @deprecated */ - public remove(): void; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export abstract class zzai extends com.google.android.gms.internal.play_billing.zzah { - public static class: java.lang.Class; - public constructor(); - /** @deprecated */ - public add(param0: any): void; - /** @deprecated */ - public set(param0: any): void; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export abstract class zzaj extends java.lang.Object /* com.google.android.gms.internal.play_billing.zzde*/ { - public static class: java.lang.Class>; - public constructor(); - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export abstract class zzak extends java.lang.Object /* com.google.android.gms.internal.play_billing.zzdf*/ { - public static class: java.lang.Class>; - public constructor(); - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export abstract class zzal implements com.google.android.gms.internal.play_billing.zzcf { - public static class: java.lang.Class; - public remove(param0: number): any; - public set(param0: number, param1: any): any; - public removeAll(param0: java.util.Collection): boolean; - public add(param0: any): boolean; - public hashCode(): number; - public remove(param0: any): boolean; - public add(param0: number, param1: any): void; - public retainAll(param0: java.util.Collection): boolean; - public clear(): void; - public equals(param0: any): boolean; - public addAll(param0: java.util.Collection): boolean; - public addAll(param0: number, param1: java.util.Collection): boolean; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzam { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzan { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzao { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzap extends com.google.android.gms.internal.play_billing.zzal implements com.google.android.gms.internal.play_billing.zzcf, com.google.android.gms.internal.play_billing.zzdm { - public static class: java.lang.Class; - public contains(param0: any): boolean; - public size(): number; - public hashCode(): number; - public indexOf(param0: any): number; - public equals(param0: any): boolean; - public removeRange(param0: number, param1: number): void; - public addAll(param0: java.util.Collection): boolean; - public addAll(param0: number, param1: java.util.Collection): boolean; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzaq { - public static class: java.lang.Class; - public constructor(); - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzar extends com.google.android.gms.internal.play_billing.zzat { - public static class: java.lang.Class; - public hasNext(): boolean; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzas { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export abstract class zzat extends com.google.android.gms.internal.play_billing.zzav { - public static class: java.lang.Class; - public remove(): void; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzau extends com.google.android.gms.internal.play_billing.zzax { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzav { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzav interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - zza(): number; - }); - public constructor(); - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export abstract class zzaw extends com.google.android.gms.internal.play_billing.zzba { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzax extends com.google.android.gms.internal.play_billing.zzaw { - public static class: java.lang.Class; - public equals(param0: any): boolean; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzay { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzaz { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzb { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export abstract class zzba { - public static class: java.lang.Class; - public hashCode(): number; - public toString(): string; - public equals(param0: any): boolean; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzbb { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzbc extends com.google.android.gms.internal.play_billing.zzbe { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzbd { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzbe { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzbf extends com.google.android.gms.internal.play_billing.zzbi { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzbg { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzbh { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export abstract class zzbi extends com.google.android.gms.internal.play_billing.zzaq { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzbj extends com.google.android.gms.internal.play_billing.zzey { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzbk extends com.google.android.gms.internal.play_billing.zzal implements com.google.android.gms.internal.play_billing.zzcf, com.google.android.gms.internal.play_billing.zzdm { - public static class: java.lang.Class; - public contains(param0: any): boolean; - public size(): number; - public hashCode(): number; - public indexOf(param0: any): number; - public equals(param0: any): boolean; - public removeRange(param0: number, param1: number): void; - public addAll(param0: java.util.Collection): boolean; - public addAll(param0: number, param1: java.util.Collection): boolean; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzbl { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzbm { - public static class: java.lang.Class; - public hashCode(): number; - public equals(param0: any): boolean; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzbn { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export abstract class zzbo { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzbp extends com.google.android.gms.internal.play_billing.zzbo { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzbq { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzbr { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzbr interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - zza(): number; - zzb(): any /* com.google.android.gms.internal.play_billing.zzew*/; - zzc(): boolean; - }); - public constructor(); - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzbs { - public static class: java.lang.Class; - public hashCode(): number; - public equals(param0: any): boolean; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzbt { - public static class: java.lang.Class; - public static values(): any /* androidNative.Array*/; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzbu extends com.google.android.gms.internal.play_billing.zzal implements com.google.android.gms.internal.play_billing.zzcf, com.google.android.gms.internal.play_billing.zzdm { - public static class: java.lang.Class; - public contains(param0: any): boolean; - public size(): number; - public hashCode(): number; - public indexOf(param0: any): number; - public equals(param0: any): boolean; - public removeRange(param0: number, param1: number): void; - public addAll(param0: java.util.Collection): boolean; - public addAll(param0: number, param1: java.util.Collection): boolean; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export abstract class zzbv { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzbw extends com.google.android.gms.internal.play_billing.zzdd { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzbx extends java.lang.Object /* com.google.android.gms.internal.play_billing.zzaj*/ { - public static class: java.lang.Class>; - public constructor(); - public constructor(param0: any); - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export abstract class zzby extends com.google.android.gms.internal.play_billing.zzcb implements com.google.android.gms.internal.play_billing.zzdg { - public static class: java.lang.Class; - public constructor(); - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzbz extends com.google.android.gms.internal.play_billing.zzbl { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzc extends com.google.android.gms.internal.play_billing.zzh implements com.google.android.gms.internal.play_billing.zze { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzca { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export abstract class zzcb extends java.lang.Object /* com.google.android.gms.internal.play_billing.zzak*/ { - public static class: java.lang.Class>; - public constructor(); - public hashCode(): number; - public toString(): string; - public equals(param0: any): boolean; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzcc extends com.google.android.gms.internal.play_billing.zzal implements com.google.android.gms.internal.play_billing.zzcf, com.google.android.gms.internal.play_billing.zzdm { - public static class: java.lang.Class; - public contains(param0: any): boolean; - public size(): number; - public hashCode(): number; - public indexOf(param0: any): number; - public equals(param0: any): boolean; - public removeRange(param0: number, param1: number): void; - public addAll(param0: java.util.Collection): boolean; - public addAll(param0: number, param1: java.util.Collection): boolean; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzcd { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzcd interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - }); - public constructor(); - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzce { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzce interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - zza(param0: number): boolean; - }); - public constructor(); - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzcf { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzcf interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - zzd(param0: number): any /* com.google.android.gms.internal.play_billing.zzcf*/; - zzb(): void; - zzc(): boolean; - }); - public constructor(); - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzcg { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzch extends com.google.android.gms.internal.play_billing.zzci { - public static class: java.lang.Class; - public constructor(param0: string); - public constructor(param0: java.io.IOException); - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzci { - public static class: java.lang.Class; - public constructor(param0: string); - public constructor(param0: java.io.IOException); - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzcj { - public static class: java.lang.Class; - public static values(): any /* androidNative.Array*/; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzck extends com.google.android.gms.internal.play_billing.zzcl { - public static class: java.lang.Class; - public hashCode(): number; - public toString(): string; - public equals(param0: any): boolean; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzcl { - public static class: java.lang.Class; - public constructor(); - public hashCode(): number; - public equals(param0: any): boolean; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzcm extends com.google.android.gms.internal.play_billing.zzal implements com.google.android.gms.internal.play_billing.zzcn { - public static class: java.lang.Class; - public constructor(); - public size(): number; - public clear(): void; - public addAll(param0: java.util.Collection): boolean; - public constructor(param0: number); - public addAll(param0: number, param1: java.util.Collection): boolean; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzcn { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzcn interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - zze(): any /* com.google.android.gms.internal.play_billing.zzcn*/; - zzf(param0: number): any; - zzh(): java.util.List; - }); - public constructor(); - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzco { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzcp extends com.google.android.gms.internal.play_billing.zzct { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzcq { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzcr extends com.google.android.gms.internal.play_billing.zzct { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzcs { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export abstract class zzct { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzcu extends com.google.android.gms.internal.play_billing.zzal implements com.google.android.gms.internal.play_billing.zzcf, com.google.android.gms.internal.play_billing.zzdm { - public static class: java.lang.Class; - public contains(param0: any): boolean; - public size(): number; - public hashCode(): number; - public indexOf(param0: any): number; - public equals(param0: any): boolean; - public removeRange(param0: number, param1: number): void; - public addAll(param0: java.util.Collection): boolean; - public addAll(param0: number, param1: java.util.Collection): boolean; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzcv extends com.google.android.gms.internal.play_billing.zzdd { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzcw extends com.google.android.gms.internal.play_billing.zzdd { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzcx extends com.google.android.gms.internal.play_billing.zzdq { - public static class: java.lang.Class; - public constructor(); - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzcy { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzcz { - public static class: java.lang.Class; - public hashCode(): number; - public remove(param0: any): any; - public entrySet(): java.util.Set; - public putAll(param0: java.util.Map): void; - public clear(): void; - public put(param0: any, param1: any): any; - public equals(param0: any): boolean; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export abstract class zzd extends com.google.android.gms.internal.play_billing.zzi implements com.google.android.gms.internal.play_billing.zze { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzda { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzdb { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzdc { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzdc interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - zza(): any /* com.google.android.gms.internal.play_billing.zzdf*/; - zzb(): boolean; - zzc(): number; - }); - public constructor(); - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzdd { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzdd interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - zzb(param0: java.lang.Class): any /* com.google.android.gms.internal.play_billing.zzdc*/; - zzc(param0: java.lang.Class): boolean; - }); - public constructor(); - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzde extends com.google.android.gms.internal.play_billing.zzdg { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzde interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - zze(): any /* com.google.android.gms.internal.play_billing.zzdf*/; - zzf(): any /* com.google.android.gms.internal.play_billing.zzdf*/; - }); - public constructor(); - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzdf extends com.google.android.gms.internal.play_billing.zzdg { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzdf interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - zze(): number; - zzb(): any /* com.google.android.gms.internal.play_billing.zzba*/; - zzk(): any /* com.google.android.gms.internal.play_billing.zzde*/; - zzr(param0: any /* com.google.android.gms.internal.play_billing.zzbi*/): void; - zzf(): any /* com.google.android.gms.internal.play_billing.zzdf*/; - }); - public constructor(); - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzdg { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzdg interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - zzf(): any /* com.google.android.gms.internal.play_billing.zzdf*/; - }); - public constructor(); - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzdh { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzdi extends java.lang.Object /* com.google.android.gms.internal.play_billing.zzdp*/ { - public static class: java.lang.Class>; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzdj extends com.google.android.gms.internal.play_billing.zzdp { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzdk { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzdl { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzdm { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzdm interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - }); - public constructor(); - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzdn { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzdo extends com.google.android.gms.internal.play_billing.zzdc { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzdp extends java.lang.Object { - public static class: java.lang.Class>; - /** - * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzdp interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - zza(param0: any): number; - zzb(param0: any): number; - zze(): any; - zzf(param0: any): void; - zzg(param0: any, param1: any): void; - zzh(param0: any, param1: androidNative.Array, param2: number, param3: number, param4: any /* com.google.android.gms.internal.play_billing.zzan*/): void; - zzi(param0: any, param1: any /* com.google.android.gms.internal.play_billing.zzey*/): void; - zzj(param0: any, param1: any): boolean; - zzk(param0: any): boolean; - }); - public constructor(); - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzdq { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzdq interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - zza(param0: java.lang.Class): any /* com.google.android.gms.internal.play_billing.zzdp*/; - }); - public constructor(); - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzdr { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzds extends com.google.android.gms.internal.play_billing.zzec { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzdt { - public static class: java.lang.Class; - public remove(): void; - public hasNext(): boolean; - public next(): any; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzdu { - public static class: java.lang.Class; - public iterator(): java.util.Iterator; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzdv { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzdw { - public static class: java.lang.Class; - public getValue(): any; - public hashCode(): number; - public toString(): string; - public setValue(param0: any): any; - public equals(param0: any): boolean; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzdx { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzdy { - public static class: java.lang.Class; - public remove(): void; - public hasNext(): boolean; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzdz { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zze { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.google.android.gms.internal.play_billing.zze interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - zza(param0: number, param1: string, param2: string): number; - zzq(param0: number, param1: string, param2: string): number; - zzc(param0: number, param1: string, param2: string, param3: globalAndroid.os.Bundle): number; - zzd(param0: number, param1: string, param2: string, param3: globalAndroid.os.Bundle): globalAndroid.os.Bundle; - zze(param0: number, param1: string, param2: string, param3: globalAndroid.os.Bundle): globalAndroid.os.Bundle; - zzf(param0: number, param1: string, param2: string, param3: string, param4: string): globalAndroid.os.Bundle; - zzg(param0: number, param1: string, param2: string, param3: string, param4: string, param5: globalAndroid.os.Bundle): globalAndroid.os.Bundle; - zzh(param0: number, param1: string, param2: string, param3: string, param4: globalAndroid.os.Bundle): globalAndroid.os.Bundle; - zzi(param0: number, param1: string, param2: string, param3: string): globalAndroid.os.Bundle; - zzj(param0: number, param1: string, param2: string, param3: string, param4: globalAndroid.os.Bundle): globalAndroid.os.Bundle; - zzk(param0: number, param1: string, param2: string, param3: globalAndroid.os.Bundle): globalAndroid.os.Bundle; - zzl(param0: number, param1: string, param2: string, param3: globalAndroid.os.Bundle, param4: globalAndroid.os.Bundle): globalAndroid.os.Bundle; - zzm(param0: number, param1: string, param2: globalAndroid.os.Bundle, param3: any /* com.google.android.gms.internal.play_billing.zzg*/): void; - }); - public constructor(); - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzea { - public static class: java.lang.Class; - public contains(param0: any): boolean; - public size(): number; - public remove(param0: any): boolean; - public clear(): void; - public iterator(): java.util.Iterator; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzeb { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzec { - public static class: java.lang.Class; - public get(param0: any): any; - public size(): number; - public hashCode(): number; - public remove(param0: any): any; - public entrySet(): java.util.Set; - public containsKey(param0: any): boolean; - public clear(): void; - public equals(param0: any): boolean; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzed extends com.google.android.gms.internal.play_billing.zzdc { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzee { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzef { - public static class: java.lang.Class; - public constructor(param0: any /* com.google.android.gms.internal.play_billing.zzdf*/); - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export abstract class zzeg { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzeh { - public static class: java.lang.Class; - public hashCode(): number; - public equals(param0: any): boolean; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzei extends com.google.android.gms.internal.play_billing.zzeg { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzej { - public static class: java.lang.Class; - public previousIndex(): number; - public nextIndex(): number; - public remove(): void; - public hasNext(): boolean; - public hasPrevious(): boolean; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzek { - public static class: java.lang.Class; - public remove(): void; - public hasNext(): boolean; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzel implements com.google.android.gms.internal.play_billing.zzcn { - public static class: java.lang.Class; - public size(): number; - public listIterator(param0: number): java.util.ListIterator; - public constructor(param0: any /* com.google.android.gms.internal.play_billing.zzcn*/); - public iterator(): java.util.Iterator; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzem { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzen extends com.google.android.gms.internal.play_billing.zzep { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzeo extends com.google.android.gms.internal.play_billing.zzep { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export abstract class zzep { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzeq { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzer { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export abstract class zzes { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzet extends com.google.android.gms.internal.play_billing.zzes { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzeu { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzev { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzew { - public static class: java.lang.Class; - public static values(): any /* androidNative.Array*/; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzex { - public static class: java.lang.Class; - public static values(): any /* androidNative.Array*/; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzey { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzey interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - zzb(param0: number, param1: boolean): void; - zzc(param0: number, param1: java.util.List, param2: boolean): void; - zzd(param0: number, param1: any /* com.google.android.gms.internal.play_billing.zzba*/): void; - zze(param0: number, param1: java.util.List): void; - zzf(param0: number, param1: number): void; - zzg(param0: number, param1: java.util.List, param2: boolean): void; - zzh(param0: number): void; - zzi(param0: number, param1: number): void; - zzj(param0: number, param1: java.util.List, param2: boolean): void; - zzk(param0: number, param1: number): void; - zzl(param0: number, param1: java.util.List, param2: boolean): void; - zzm(param0: number, param1: number): void; - zzn(param0: number, param1: java.util.List, param2: boolean): void; - zzo(param0: number, param1: number): void; - zzp(param0: number, param1: java.util.List, param2: boolean): void; - zzq(param0: number, param1: any, param2: any /* com.google.android.gms.internal.play_billing.zzdp*/): void; - zzr(param0: number, param1: number): void; - zzs(param0: number, param1: java.util.List, param2: boolean): void; - zzt(param0: number, param1: number): void; - zzu(param0: number, param1: java.util.List, param2: boolean): void; - zzv(param0: number, param1: any, param2: any /* com.google.android.gms.internal.play_billing.zzdp*/): void; - zzw(param0: number, param1: number): void; - zzx(param0: number, param1: java.util.List, param2: boolean): void; - zzy(param0: number, param1: number): void; - zzz(param0: number, param1: java.util.List, param2: boolean): void; - zzA(param0: number, param1: number): void; - zzB(param0: number, param1: java.util.List, param2: boolean): void; - zzC(param0: number, param1: number): void; - zzD(param0: number, param1: java.util.List, param2: boolean): void; - zzE(param0: number): void; - zzF(param0: number, param1: string): void; - zzG(param0: number, param1: java.util.List): void; - zzH(param0: number, param1: number): void; - zzI(param0: number, param1: java.util.List, param2: boolean): void; - zzJ(param0: number, param1: number): void; - zzK(param0: number, param1: java.util.List, param2: boolean): void; - }); - public constructor(); - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzez { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export abstract class zzf extends com.google.android.gms.internal.play_billing.zzi implements com.google.android.gms.internal.play_billing.zzg { - public static class: java.lang.Class; - public constructor(); - public constructor(param0: string); - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzfa extends com.google.android.gms.internal.play_billing.zzbx implements com.google.android.gms.internal.play_billing.zzdg { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzfb extends com.google.android.gms.internal.play_billing.zzcb implements com.google.android.gms.internal.play_billing.zzdg { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzfc extends com.google.android.gms.internal.play_billing.zzce { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzfd { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzfe extends com.google.android.gms.internal.play_billing.zzbx implements com.google.android.gms.internal.play_billing.zzdg { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzff extends com.google.android.gms.internal.play_billing.zzcb implements com.google.android.gms.internal.play_billing.zzdg { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzfg { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzfh extends com.google.android.gms.internal.play_billing.zzbx implements com.google.android.gms.internal.play_billing.zzdg { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzfi extends com.google.android.gms.internal.play_billing.zzce { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzfj extends com.google.android.gms.internal.play_billing.zzcb implements com.google.android.gms.internal.play_billing.zzdg { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzfk { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzfl extends com.google.android.gms.internal.play_billing.zzbx implements com.google.android.gms.internal.play_billing.zzdg { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzfm extends com.google.android.gms.internal.play_billing.zzcb implements com.google.android.gms.internal.play_billing.zzdg { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzfn extends com.google.android.gms.internal.play_billing.zzcd { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzfo extends com.google.android.gms.internal.play_billing.zzce { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzfp { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzfq { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzfr extends com.google.android.gms.internal.play_billing.zzbx implements com.google.android.gms.internal.play_billing.zzdg { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzfs extends com.google.android.gms.internal.play_billing.zzcb implements com.google.android.gms.internal.play_billing.zzdg { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzft { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzfu extends com.google.android.gms.internal.play_billing.zzbx implements com.google.android.gms.internal.play_billing.zzdg { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzfv extends com.google.android.gms.internal.play_billing.zzce { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzfw extends com.google.android.gms.internal.play_billing.zzcb implements com.google.android.gms.internal.play_billing.zzdg { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzfx { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzfy extends com.google.android.gms.internal.play_billing.zzbx implements com.google.android.gms.internal.play_billing.zzdg { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzfz extends com.google.android.gms.internal.play_billing.zzcb implements com.google.android.gms.internal.play_billing.zzdg { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzg { - public static class: java.lang.Class; - /** - * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzg interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. - */ - public constructor(implementation: { - zza(param0: globalAndroid.os.Bundle): void; - }); - public constructor(); - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzga { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzgb extends com.google.android.gms.internal.play_billing.zzbx implements com.google.android.gms.internal.play_billing.zzdg { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzgc extends com.google.android.gms.internal.play_billing.zzce { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzgd extends com.google.android.gms.internal.play_billing.zzcb implements com.google.android.gms.internal.play_billing.zzdg { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzh { - public static class: java.lang.Class; - public constructor(param0: globalAndroid.os.IBinder, param1: string); - public asBinder(): globalAndroid.os.IBinder; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzi { - public static class: java.lang.Class; - public asBinder(): globalAndroid.os.IBinder; - public constructor(param0: string); - public onTransact(param0: number, param1: globalAndroid.os.Parcel, param2: globalAndroid.os.Parcel, param3: number): boolean; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzj { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzk { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzl extends com.google.android.gms.internal.play_billing.zzk { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzm { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzn { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export abstract class zzo extends com.google.android.gms.internal.play_billing.zzai { - public static class: java.lang.Class; - public constructor(); - public previousIndex(): number; - public previous(): any; - public constructor(param0: number, param1: number); - public nextIndex(): number; - public hasNext(): boolean; - public hasPrevious(): boolean; - public next(): any; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzp { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzq { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export abstract class zzr { - public static class: java.lang.Class; - public contains(param0: any): boolean; - /** @deprecated */ - public addAll(param0: java.util.Collection): boolean; - /** @deprecated */ - public add(param0: any): boolean; - /** @deprecated */ - public remove(param0: any): boolean; - /** @deprecated */ - public clear(): void; - public toArray(): androidNative.Array; - /** @deprecated */ - public removeAll(param0: java.util.Collection): boolean; - public toArray(param0: androidNative.Array): androidNative.Array; - /** @deprecated */ - public retainAll(param0: java.util.Collection): boolean; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzs extends com.google.android.gms.internal.play_billing.zzo { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzt extends com.google.android.gms.internal.play_billing.zzu { - public static class: java.lang.Class; - public size(): number; - public get(param0: number): any; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export abstract class zzu extends com.google.android.gms.internal.play_billing.zzr { - public static class: java.lang.Class; - public contains(param0: any): boolean; - /** @deprecated */ - public addAll(param0: java.util.Collection): boolean; - /** @deprecated */ - public add(param0: any): boolean; - public hashCode(): number; - public lastIndexOf(param0: any): number; - /** @deprecated */ - public addAll(param0: number, param1: java.util.Collection): boolean; - /** @deprecated */ - public remove(param0: any): boolean; - /** @deprecated */ - public remove(param0: number): any; - public indexOf(param0: any): number; - /** @deprecated */ - public add(param0: number, param1: any): void; - public equals(param0: any): boolean; - /** @deprecated */ - public set(param0: number, param1: any): any; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzv { - public static class: java.lang.Class; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzw { - public static class: java.lang.Class; - public constructor(); - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export abstract class zzx { - public static class: java.lang.Class; - public get(param0: any): any; - public hashCode(): number; - public containsKey(param0: any): boolean; - public getOrDefault(param0: any, param1: any): any; - /** @deprecated */ - public put(param0: any, param1: any): any; - /** @deprecated */ - public remove(param0: any): any; - /** @deprecated */ - public clear(): void; - public toString(): string; - /** @deprecated */ - public putAll(param0: java.util.Map): void; - public equals(param0: any): boolean; - public isEmpty(): boolean; - public containsValue(param0: any): boolean; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export abstract class zzy extends com.google.android.gms.internal.play_billing.zzr { - public static class: java.lang.Class; - public hashCode(): number; - public equals(param0: any): boolean; - } - } - } - } - } - } -} - -declare module com { - export module google { - export module android { - export module gms { - export module internal { - export module play_billing { - export class zzz { - public static class: java.lang.Class; - } - } - } - } - } - } +declare module org { + export module nativescript { + export module plugins { + export module payments { + export class Payments { + public static class: java.lang.Class; + public getBilling$payments_release(): com.android.billingclient.api.BillingClient; + + public setOnReadyListener(value: any): void; + public setOnPurchaseUpdateListener(value: any): void; + public isFeatureSupported(feature: org.nativescript.plugins.payments.Payments.Features): boolean; + public fetchProducts(it: androidNative.Array, type: org.nativescript.plugins.payments.Product.Type, $i$f$mapTo: any): void; + public restartConnection(): void; + public constructor(pendingParams: globalAndroid.content.Context); + public fetchPurchases(callback: any): void; + public canMakePayments(): boolean; + public static isSupported(context: globalAndroid.content.Context): boolean; + public purchaseProduct($this$purchaseProduct_u24lambda_u248: globalAndroid.app.Activity, product: org.nativescript.plugins.payments.Product, id: org.nativescript.plugins.payments.Payments.PurchaseOptions): org.nativescript.plugins.payments.Payments.BillingResponse; + public getOnPurchaseUpdateListener(): any; + public getOnReadyListener(): any; + public purchaseProduct(activity: globalAndroid.app.Activity, product: org.nativescript.plugins.payments.Product): org.nativescript.plugins.payments.Payments.BillingResponse; + public setBilling$payments_release(value: com.android.billingclient.api.BillingClient): void; + public static mapResponseCode$payments_release(code: number): org.nativescript.plugins.payments.Payments.BillingResponse; + } + export module Payments { + export class BillingResponse { + public static class: java.lang.Class; + public getMessage(): string; + public constructor(code: number, message: string, resolution: string); + public getCode(): number; + public getResolution(): string; + } + export class Companion { + public static class: java.lang.Class; + public isSupported($this$isSupported_u24lambda_u240: globalAndroid.content.Context): boolean; + public mapResponseCode$payments_release(code: number): org.nativescript.plugins.payments.Payments.BillingResponse; + } + export class Features { + public static class: java.lang.Class; + public static Subscriptions: org.nativescript.plugins.payments.Payments.Features; + public static SubscriptionsUpdate: org.nativescript.plugins.payments.Payments.Features; + public static PriceChangeConfirmation: org.nativescript.plugins.payments.Payments.Features; + public static InAppMessaging: org.nativescript.plugins.payments.Payments.Features; + public static ProductDetails: org.nativescript.plugins.payments.Payments.Features; + public static BillingConfig: org.nativescript.plugins.payments.Payments.Features; + public static AlternativeBillingOnly: org.nativescript.plugins.payments.Payments.Features; + public static ExternalOffer: org.nativescript.plugins.payments.Payments.Features; + public static valueOf(value: string): org.nativescript.plugins.payments.Payments.Features; + public getValue(): string; + public static values(): androidNative.Array; + public static getEntries(): any; + } + export class PurchaseOptions { + public static class: java.lang.Class; + public constructor(); + public getAccountId(): string; + public setAccountId(value: string): void; + public setProfileId(value: string): void; + public getProfileId(): string; + public getSetIsOfferPersonalized(): boolean; + public setSetIsOfferPersonalized(value: boolean): void; + } + } + } + } + } +} + +declare module org { + export module nativescript { + export module plugins { + export module payments { + export class Product { + public static class: java.lang.Class; + public getTitle(): string; + public getProduct(): com.android.billingclient.api.ProductDetails; + public getId(): string; + public getName(): string; + public getType(): org.nativescript.plugins.payments.Product.Type; + public constructor(product: com.android.billingclient.api.ProductDetails); + public getDescription(): string; + public getPriceAmountMicros(): number | null; + public getPriceFormatted(): string | null; + } + export module Product { + export class Type { + public static class: java.lang.Class; + public static InApp: org.nativescript.plugins.payments.Product.Type; + public static Subs: org.nativescript.plugins.payments.Product.Type; + public getToType$payments_release(): string; + public static valueOf(value: string): org.nativescript.plugins.payments.Product.Type; + public static values(): androidNative.Array; + public static getEntries(): any; + public getValue(): number; + } + export module Type { + export class WhenMappings { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module org { + export module nativescript { + export module plugins { + export module payments { + export class Transaction { + public static class: java.lang.Class; + public getOriginalJson(): org.json.JSONObject; + public getProductId(): string; + public getOrderId(): string; + public getOrderDate(): number; + public finish(params: any): void; + public getToken(): string; + public constructor(purchase: com.android.billingclient.api.Purchase, type: org.nativescript.plugins.payments.Product.Type, payments: org.nativescript.plugins.payments.Payments); + public getQuantity(): number; + public isSubscription(): boolean; + public getPurchase(): com.android.billingclient.api.Purchase; + public getSignature(): string; + public getType(): org.nativescript.plugins.payments.Product.Type; + public getState(): org.nativescript.plugins.payments.Transaction.State; + public getDeveloperPayload(): string; + public getOriginalJsonString(): string; + public getProducts(): java.util.List; + } + export module Transaction { + export class State { + public static class: java.lang.Class; + public static Unknown: org.nativescript.plugins.payments.Transaction.State; + public static Purchased: org.nativescript.plugins.payments.Transaction.State; + public static Pending: org.nativescript.plugins.payments.Transaction.State; + public static getEntries(): any; + public static valueOf(value: string): org.nativescript.plugins.payments.Transaction.State; + public static values(): androidNative.Array; + public getValue(): number; + } + } + } + } + } } //Generics information: -//com.google.android.gms.internal.play_billing.zzaj:2 -//com.google.android.gms.internal.play_billing.zzak:2 -//com.google.android.gms.internal.play_billing.zzbx:2 -//com.google.android.gms.internal.play_billing.zzcb:2 -//com.google.android.gms.internal.play_billing.zzdi:1 -//com.google.android.gms.internal.play_billing.zzdp:1 - diff --git a/packages/payments/typings/billingclient.android.d.ts b/packages/payments/typings/billingclient.android.d.ts new file mode 100644 index 0000000..271deaf --- /dev/null +++ b/packages/payments/typings/billingclient.android.d.ts @@ -0,0 +1,7689 @@ +declare module com { + export module android { + export module billingclient { + export class BuildConfig { + public static class: java.lang.Class; + public static APPLICATION_ID: string = 'com.android.billingclient'; + public static VERSION_NAME: string = '8.0.0'; + public constructor(); + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class AccountIdentifiers { + public static class: java.lang.Class; + public getObfuscatedAccountId(): string; + public getObfuscatedProfileId(): string; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class AcknowledgePurchaseParams { + public static class: java.lang.Class; + public static newBuilder(): com.android.billingclient.api.AcknowledgePurchaseParams.Builder; + public getPurchaseToken(): string; + } + export module AcknowledgePurchaseParams { + export class Builder { + public static class: java.lang.Class; + public setPurchaseToken(purchaseToken: string): com.android.billingclient.api.AcknowledgePurchaseParams.Builder; + public build(): com.android.billingclient.api.AcknowledgePurchaseParams; + } + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class AcknowledgePurchaseResponseListener { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.AcknowledgePurchaseResponseListener interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { onAcknowledgePurchaseResponse(param0: com.android.billingclient.api.BillingResult): void }); + public constructor(); + public onAcknowledgePurchaseResponse(param0: com.android.billingclient.api.BillingResult): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class AlternativeBillingOnlyAvailabilityListener { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.AlternativeBillingOnlyAvailabilityListener interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { onAlternativeBillingOnlyAvailabilityResponse(param0: com.android.billingclient.api.BillingResult): void }); + public constructor(); + public onAlternativeBillingOnlyAvailabilityResponse(param0: com.android.billingclient.api.BillingResult): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class AlternativeBillingOnlyInformationDialogListener { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.AlternativeBillingOnlyInformationDialogListener interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { onAlternativeBillingOnlyInformationDialogResponse(param0: com.android.billingclient.api.BillingResult): void }); + public constructor(); + public onAlternativeBillingOnlyInformationDialogResponse(param0: com.android.billingclient.api.BillingResult): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class AlternativeBillingOnlyReportingDetails { + public static class: java.lang.Class; + public getExternalTransactionToken(): string; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class AlternativeBillingOnlyReportingDetailsListener { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.AlternativeBillingOnlyReportingDetailsListener interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { onAlternativeBillingOnlyTokenResponse(param0: com.android.billingclient.api.BillingResult, param1: com.android.billingclient.api.AlternativeBillingOnlyReportingDetails): void }); + public constructor(); + public onAlternativeBillingOnlyTokenResponse(param0: com.android.billingclient.api.BillingResult, param1: com.android.billingclient.api.AlternativeBillingOnlyReportingDetails): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export abstract class BillingClient { + public static class: java.lang.Class; + public isReady(): boolean; + public launchBillingFlow(param0: globalAndroid.app.Activity, param1: com.android.billingclient.api.BillingFlowParams): com.android.billingclient.api.BillingResult; + public endConnection(): void; + public acknowledgePurchase(param0: com.android.billingclient.api.AcknowledgePurchaseParams, param1: com.android.billingclient.api.AcknowledgePurchaseResponseListener): void; + public isExternalOfferAvailableAsync(param0: com.android.billingclient.api.ExternalOfferAvailabilityListener): void; + public showInAppMessages(param0: globalAndroid.app.Activity, param1: com.android.billingclient.api.InAppMessageParams, param2: com.android.billingclient.api.InAppMessageResponseListener): com.android.billingclient.api.BillingResult; + public showAlternativeBillingOnlyInformationDialog(param0: globalAndroid.app.Activity, param1: com.android.billingclient.api.AlternativeBillingOnlyInformationDialogListener): com.android.billingclient.api.BillingResult; + public createAlternativeBillingOnlyReportingDetailsAsync(param0: com.android.billingclient.api.AlternativeBillingOnlyReportingDetailsListener): void; + public static newBuilder(context: globalAndroid.content.Context): com.android.billingclient.api.BillingClient.Builder; + public showExternalOfferInformationDialog(param0: globalAndroid.app.Activity, param1: com.android.billingclient.api.ExternalOfferInformationDialogListener): com.android.billingclient.api.BillingResult; + public getConnectionState(): number; + public isFeatureSupported(param0: string): com.android.billingclient.api.BillingResult; + public startConnection(param0: com.android.billingclient.api.BillingClientStateListener): void; + public constructor(); + public getBillingConfigAsync(param0: com.android.billingclient.api.GetBillingConfigParams, param1: com.android.billingclient.api.BillingConfigResponseListener): void; + public queryPurchasesAsync(param0: com.android.billingclient.api.QueryPurchasesParams, param1: com.android.billingclient.api.PurchasesResponseListener): void; + public queryProductDetailsAsync(param0: com.android.billingclient.api.QueryProductDetailsParams, param1: com.android.billingclient.api.ProductDetailsResponseListener): void; + public isAlternativeBillingOnlyAvailableAsync(param0: com.android.billingclient.api.AlternativeBillingOnlyAvailabilityListener): void; + public createExternalOfferReportingDetailsAsync(param0: com.android.billingclient.api.ExternalOfferReportingDetailsListener): void; + public consumeAsync(param0: com.android.billingclient.api.ConsumeParams, param1: com.android.billingclient.api.ConsumeResponseListener): void; + } + export module BillingClient { + export class BillingResponseCode { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.BillingClient$BillingResponseCode interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: {}); + public constructor(); + public static ITEM_UNAVAILABLE: number = 4; + public static NETWORK_ERROR: number = 12; + public static SERVICE_UNAVAILABLE: number = 2; + public static FEATURE_NOT_SUPPORTED: number = -2; + public static ITEM_NOT_OWNED: number = 8; + public static DEVELOPER_ERROR: number = 5; + public static ITEM_ALREADY_OWNED: number = 7; + public static USER_CANCELED: number = 1; + public static ERROR: number = 6; + public static SERVICE_TIMEOUT: number = -3; + public static OK: number = 0; + public static BILLING_UNAVAILABLE: number = 3; + public static SERVICE_DISCONNECTED: number = -1; + } + export class Builder { + public static class: java.lang.Class; + public build(): com.android.billingclient.api.BillingClient; + public enableExternalOffer(): com.android.billingclient.api.BillingClient.Builder; + public enableUserChoiceBilling(userChoiceBillingListener: com.android.billingclient.api.UserChoiceBillingListener): com.android.billingclient.api.BillingClient.Builder; + public enableAlternativeBillingOnly(): com.android.billingclient.api.BillingClient.Builder; + public enablePendingPurchases(pendingPurchasesParams: com.android.billingclient.api.PendingPurchasesParams): com.android.billingclient.api.BillingClient.Builder; + public setListener(listener: com.android.billingclient.api.PurchasesUpdatedListener): com.android.billingclient.api.BillingClient.Builder; + public enableAutoServiceReconnection(): com.android.billingclient.api.BillingClient.Builder; + } + export class ConnectionState { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.BillingClient$ConnectionState interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: {}); + public constructor(); + public static CONNECTED: number = 2; + public static DISCONNECTED: number = 0; + public static CLOSED: number = 3; + public static CONNECTING: number = 1; + } + export class FeatureType { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.BillingClient$FeatureType interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: {}); + public constructor(); + public static EXTERNAL_OFFER: string = 'kkk'; + public static SUBSCRIPTIONS_UPDATE: string = 'subscriptionsUpdate'; + public static PRICE_CHANGE_CONFIRMATION: string = 'priceChangeConfirmation'; + public static BILLING_CONFIG: string = 'ggg'; + public static ALTERNATIVE_BILLING_ONLY: string = 'jjj'; + public static IN_APP_MESSAGING: string = 'bbb'; + public static PRODUCT_DETAILS: string = 'fff'; + public static SUBSCRIPTIONS: string = 'subscriptions'; + } + export class OnPurchasesUpdatedSubResponseCode { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.BillingClient$OnPurchasesUpdatedSubResponseCode interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: {}); + public constructor(); + public static USER_INELIGIBLE: number = 2; + public static NO_APPLICABLE_SUB_RESPONSE_CODE: number = 0; + public static PAYMENT_DECLINED_DUE_TO_INSUFFICIENT_FUNDS: number = 1; + } + export class ProductType { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.BillingClient$ProductType interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: {}); + public constructor(); + public static SUBS: string = 'subs'; + public static INAPP: string = 'inapp'; + } + export class SkuType { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.BillingClient$SkuType interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: {}); + public constructor(); + public static SUBS: string = 'subs'; + public static INAPP: string = 'inapp'; + } + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class BillingClientImpl extends com.android.billingclient.api.BillingClient { + public static class: java.lang.Class; + public isReady(): boolean; + public createExternalOfferReportingDetailsAsync(listener: com.android.billingclient.api.ExternalOfferReportingDetailsListener): void; + public launchBillingFlow(param0: globalAndroid.app.Activity, param1: com.android.billingclient.api.BillingFlowParams): com.android.billingclient.api.BillingResult; + public showAlternativeBillingOnlyInformationDialog(activity: globalAndroid.app.Activity, listener: com.android.billingclient.api.AlternativeBillingOnlyInformationDialogListener): com.android.billingclient.api.BillingResult; + public endConnection(): void; + public acknowledgePurchase(param0: com.android.billingclient.api.AcknowledgePurchaseParams, param1: com.android.billingclient.api.AcknowledgePurchaseResponseListener): void; + public isExternalOfferAvailableAsync(listener: com.android.billingclient.api.ExternalOfferAvailabilityListener): void; + public showInAppMessages(param0: globalAndroid.app.Activity, param1: com.android.billingclient.api.InAppMessageParams, param2: com.android.billingclient.api.InAppMessageResponseListener): com.android.billingclient.api.BillingResult; + public isAlternativeBillingOnlyAvailableAsync(listener: com.android.billingclient.api.AlternativeBillingOnlyAvailabilityListener): void; + public getConnectionState(): number; + public isFeatureSupported(param0: string): com.android.billingclient.api.BillingResult; + public startConnection(param0: com.android.billingclient.api.BillingClientStateListener): void; + public queryPurchasesAsync(param0: com.android.billingclient.api.QueryPurchasesParams, param1: com.android.billingclient.api.PurchasesResponseListener): void; + public queryProductDetailsAsync(param0: com.android.billingclient.api.QueryProductDetailsParams, param1: com.android.billingclient.api.ProductDetailsResponseListener): void; + public showExternalOfferInformationDialog(activity: globalAndroid.app.Activity, listener: com.android.billingclient.api.ExternalOfferInformationDialogListener): com.android.billingclient.api.BillingResult; + public consumeAsync(param0: com.android.billingclient.api.ConsumeParams, param1: com.android.billingclient.api.ConsumeResponseListener): void; + public createAlternativeBillingOnlyReportingDetailsAsync(listener: com.android.billingclient.api.AlternativeBillingOnlyReportingDetailsListener): void; + public getBillingConfigAsync(listener: com.android.billingclient.api.GetBillingConfigParams, param1: com.android.billingclient.api.BillingConfigResponseListener): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class BillingClientStateListener { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.BillingClientStateListener interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { onBillingServiceDisconnected(): void; onBillingSetupFinished(param0: com.android.billingclient.api.BillingResult): void }); + public constructor(); + public onBillingSetupFinished(param0: com.android.billingclient.api.BillingResult): void; + public onBillingServiceDisconnected(): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class BillingConfig { + public static class: java.lang.Class; + public getCountryCode(): string; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class BillingConfigResponseListener { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.BillingConfigResponseListener interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { onBillingConfigResponse(param0: com.android.billingclient.api.BillingResult, param1: com.android.billingclient.api.BillingConfig): void }); + public constructor(); + public onBillingConfigResponse(param0: com.android.billingclient.api.BillingResult, param1: com.android.billingclient.api.BillingConfig): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class BillingFlowParams { + public static class: java.lang.Class; + public static newBuilder(): com.android.billingclient.api.BillingFlowParams.Builder; + } + export module BillingFlowParams { + export class Builder { + public static class: java.lang.Class; + public setIsOfferPersonalized(isOfferPersonalized: boolean): com.android.billingclient.api.BillingFlowParams.Builder; + public setProductDetailsParamsList(productDetailsParamsList: java.util.List): com.android.billingclient.api.BillingFlowParams.Builder; + public setObfuscatedProfileId(obfuscatedProfileId: string): com.android.billingclient.api.BillingFlowParams.Builder; + public setSubscriptionUpdateParams(subscriptionUpdateParams: com.android.billingclient.api.BillingFlowParams.SubscriptionUpdateParams): com.android.billingclient.api.BillingFlowParams.Builder; + public setObfuscatedAccountId(obfuscatedAccountid: string): com.android.billingclient.api.BillingFlowParams.Builder; + public build(): com.android.billingclient.api.BillingFlowParams; + /** @deprecated */ + public setSkuDetails(skuDetails: com.android.billingclient.api.SkuDetails): com.android.billingclient.api.BillingFlowParams.Builder; + } + export class ProductDetailsParams { + public static class: java.lang.Class; + public static newBuilder(): com.android.billingclient.api.BillingFlowParams.ProductDetailsParams.Builder; + } + export module ProductDetailsParams { + export class Builder { + public static class: java.lang.Class; + public build(): com.android.billingclient.api.BillingFlowParams.ProductDetailsParams; + public setProductDetails(productDetails: com.android.billingclient.api.ProductDetails): com.android.billingclient.api.BillingFlowParams.ProductDetailsParams.Builder; + public setOfferToken(offerToken: string): com.android.billingclient.api.BillingFlowParams.ProductDetailsParams.Builder; + } + } + export class SubscriptionUpdateParams { + public static class: java.lang.Class; + public static newBuilder(): com.android.billingclient.api.BillingFlowParams.SubscriptionUpdateParams.Builder; + } + export module SubscriptionUpdateParams { + export class Builder { + public static class: java.lang.Class; + public build(): com.android.billingclient.api.BillingFlowParams.SubscriptionUpdateParams; + public setOldPurchaseToken(purchaseToken: string): com.android.billingclient.api.BillingFlowParams.SubscriptionUpdateParams.Builder; + public setOriginalExternalTransactionId(externalTransactionId: string): com.android.billingclient.api.BillingFlowParams.SubscriptionUpdateParams.Builder; + public setSubscriptionReplacementMode(subscriptionReplacementMode: number): com.android.billingclient.api.BillingFlowParams.SubscriptionUpdateParams.Builder; + } + export class ReplacementMode { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.BillingFlowParams$SubscriptionUpdateParams$ReplacementMode interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: {}); + public constructor(); + public static WITH_TIME_PRORATION: number = 1; + public static WITHOUT_PRORATION: number = 3; + public static CHARGE_FULL_PRICE: number = 5; + public static DEFERRED: number = 6; + public static UNKNOWN_REPLACEMENT_MODE: number = 0; + public static CHARGE_PRORATED_PRICE: number = 2; + } + } + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class BillingResult { + public static class: java.lang.Class; + public toString(): string; + public getResponseCode(): number; + public constructor(); + public static newBuilder(): com.android.billingclient.api.BillingResult.Builder; + public getOnPurchasesUpdatedSubResponseCode(): number; + public getDebugMessage(): string; + } + export module BillingResult { + export class Builder { + public static class: java.lang.Class; + public setDebugMessage(debugMessage: string): com.android.billingclient.api.BillingResult.Builder; + public build(): com.android.billingclient.api.BillingResult; + public setOnPurchasesUpdatedSubResponseCode(onPurchasesUpdatedSubResponseCode: number): com.android.billingclient.api.BillingResult.Builder; + public setResponseCode(responseCode: number): com.android.billingclient.api.BillingResult.Builder; + } + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class ConsumeParams { + public static class: java.lang.Class; + public static newBuilder(): com.android.billingclient.api.ConsumeParams.Builder; + public getPurchaseToken(): string; + } + export module ConsumeParams { + export class Builder { + public static class: java.lang.Class; + public setPurchaseToken(purchaseToken: string): com.android.billingclient.api.ConsumeParams.Builder; + public build(): com.android.billingclient.api.ConsumeParams; + } + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class ConsumeResponseListener { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.ConsumeResponseListener interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { onConsumeResponse(param0: com.android.billingclient.api.BillingResult, param1: string): void }); + public constructor(); + public onConsumeResponse(param0: com.android.billingclient.api.BillingResult, param1: string): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class ExternalOfferAvailabilityListener { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.ExternalOfferAvailabilityListener interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { onExternalOfferAvailabilityResponse(param0: com.android.billingclient.api.BillingResult): void }); + public constructor(); + public onExternalOfferAvailabilityResponse(param0: com.android.billingclient.api.BillingResult): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class ExternalOfferInformationDialogListener { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.ExternalOfferInformationDialogListener interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { onExternalOfferInformationDialogResponse(param0: com.android.billingclient.api.BillingResult): void }); + public constructor(); + public onExternalOfferInformationDialogResponse(param0: com.android.billingclient.api.BillingResult): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class ExternalOfferReportingDetails { + public static class: java.lang.Class; + public getExternalTransactionToken(): string; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class ExternalOfferReportingDetailsListener { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.ExternalOfferReportingDetailsListener interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { onExternalOfferReportingDetailsResponse(param0: com.android.billingclient.api.BillingResult, param1: com.android.billingclient.api.ExternalOfferReportingDetails): void }); + public constructor(); + public onExternalOfferReportingDetailsResponse(param0: com.android.billingclient.api.BillingResult, param1: com.android.billingclient.api.ExternalOfferReportingDetails): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class GetBillingConfigParams { + public static class: java.lang.Class; + public static newBuilder(): com.android.billingclient.api.GetBillingConfigParams.Builder; + } + export module GetBillingConfigParams { + export class Builder { + public static class: java.lang.Class; + public build(): com.android.billingclient.api.GetBillingConfigParams; + } + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class InAppMessageParams { + public static class: java.lang.Class; + public static newBuilder(): com.android.billingclient.api.InAppMessageParams.Builder; + } + export module InAppMessageParams { + export class Builder { + public static class: java.lang.Class; + public constructor(); + public addAllInAppMessageCategoriesToShow(): com.android.billingclient.api.InAppMessageParams.Builder; + public addInAppMessageCategoryToShow(inAppMessageCategoryId: number): com.android.billingclient.api.InAppMessageParams.Builder; + public build(): com.android.billingclient.api.InAppMessageParams; + } + export class InAppMessageCategoryId { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.InAppMessageParams$InAppMessageCategoryId interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: {}); + public constructor(); + public static TRANSACTIONAL: number = 2; + public static UNKNOWN_IN_APP_MESSAGE_CATEGORY_ID: number = 0; + } + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class InAppMessageResponseListener { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.InAppMessageResponseListener interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { onInAppMessageResponse(param0: com.android.billingclient.api.InAppMessageResult): void }); + public constructor(); + public onInAppMessageResponse(param0: com.android.billingclient.api.InAppMessageResult): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class InAppMessageResult { + public static class: java.lang.Class; + public getResponseCode(): number; + public constructor(param0: number, param1: string); + public getPurchaseToken(): string; + } + export module InAppMessageResult { + export class InAppMessageResponseCode { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.InAppMessageResult$InAppMessageResponseCode interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: {}); + public constructor(); + public static NO_ACTION_NEEDED: number = 0; + public static SUBSCRIPTION_STATUS_UPDATED: number = 1; + } + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class PendingPurchasesParams { + public static class: java.lang.Class; + public static newBuilder(): com.android.billingclient.api.PendingPurchasesParams.Builder; + } + export module PendingPurchasesParams { + export class Builder { + public static class: java.lang.Class; + public enablePrepaidPlans(): com.android.billingclient.api.PendingPurchasesParams.Builder; + public build(): com.android.billingclient.api.PendingPurchasesParams; + public enableOneTimeProducts(): com.android.billingclient.api.PendingPurchasesParams.Builder; + } + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class ProductDetails { + public static class: java.lang.Class; + public getTitle(): string; + public getProductId(): string; + public toString(): string; + public getName(): string; + public getProductType(): string; + public getSubscriptionOfferDetails(): java.util.List; + public hashCode(): number; + public getOneTimePurchaseOfferDetails(): com.android.billingclient.api.ProductDetails.OneTimePurchaseOfferDetails; + public getDescription(): string; + public equals(o: any): boolean; + public getOneTimePurchaseOfferDetailsList(): java.util.List; + } + export module ProductDetails { + export class InstallmentPlanDetails { + public static class: java.lang.Class; + public getSubsequentInstallmentPlanCommitmentPaymentsCount(): number; + public getInstallmentPlanCommitmentPaymentsCount(): number; + } + export class OneTimePurchaseOfferDetails { + public static class: java.lang.Class; + public getOfferToken(): string; + public getLimitedQuantityInfo(): com.android.billingclient.api.ProductDetails.OneTimePurchaseOfferDetails.LimitedQuantityInfo; + public getFormattedPrice(): string; + public getPurchaseOptionId(): string; + public getOfferId(): string; + public getPriceCurrencyCode(): string; + public getRentalDetails(): com.android.billingclient.api.ProductDetails.OneTimePurchaseOfferDetails.RentalDetails; + public getDiscountDisplayInfo(): com.android.billingclient.api.ProductDetails.OneTimePurchaseOfferDetails.DiscountDisplayInfo; + public getValidTimeWindow(): com.android.billingclient.api.ProductDetails.OneTimePurchaseOfferDetails.ValidTimeWindow; + public getFullPriceMicros(): java.lang.Long; + public getOfferTags(): java.util.List; + public getPriceAmountMicros(): number; + } + export module OneTimePurchaseOfferDetails { + export class DiscountDisplayInfo { + public static class: java.lang.Class; + public getDiscountAmount(): com.android.billingclient.api.ProductDetails.OneTimePurchaseOfferDetails.DiscountDisplayInfo.DiscountAmount; + public getPercentageDiscount(): java.lang.Integer; + } + export module DiscountDisplayInfo { + export class DiscountAmount { + public static class: java.lang.Class; + public getDiscountAmountCurrencyCode(): string; + public getDiscountAmountMicros(): number; + public getFormattedDiscountAmount(): string; + } + } + export class LimitedQuantityInfo { + public static class: java.lang.Class; + public getRemainingQuantity(): number; + public getMaximumQuantity(): number; + } + export class RentalDetails { + public static class: java.lang.Class; + public getRentalExpirationPeriod(): string; + public getRentalPeriod(): string; + } + export class ValidTimeWindow { + public static class: java.lang.Class; + public getEndTimeMillis(): java.lang.Long; + public getStartTimeMillis(): java.lang.Long; + } + } + export class PricingPhase { + public static class: java.lang.Class; + public getFormattedPrice(): string; + public getPriceCurrencyCode(): string; + public getRecurrenceMode(): number; + public getPriceAmountMicros(): number; + public getBillingPeriod(): string; + public getBillingCycleCount(): number; + } + export class PricingPhases { + public static class: java.lang.Class; + public getPricingPhaseList(): java.util.List; + } + export class RecurrenceMode { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.ProductDetails$RecurrenceMode interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: {}); + public constructor(); + public static FINITE_RECURRING: number = 2; + public static NON_RECURRING: number = 3; + public static INFINITE_RECURRING: number = 1; + } + export class SubscriptionOfferDetails { + public static class: java.lang.Class; + public getOfferToken(): string; + public getOfferId(): string; + public getPricingPhases(): com.android.billingclient.api.ProductDetails.PricingPhases; + public getOfferTags(): java.util.List; + public getInstallmentPlanDetails(): com.android.billingclient.api.ProductDetails.InstallmentPlanDetails; + public getBasePlanId(): string; + } + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class ProductDetailsResponseListener { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.ProductDetailsResponseListener interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { onProductDetailsResponse(param0: com.android.billingclient.api.BillingResult, param1: com.android.billingclient.api.QueryProductDetailsResult): void }); + public constructor(); + public onProductDetailsResponse(param0: com.android.billingclient.api.BillingResult, param1: com.android.billingclient.api.QueryProductDetailsResult): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class ProxyBillingActivity { + public static class: java.lang.Class; + public constructor(); + public onCreate(savedInstanceState: globalAndroid.os.Bundle): void; + public onDestroy(): void; + public onActivityResult(requestCode: number, resultCode: number, data: globalAndroid.content.Intent): void; + public onSaveInstanceState(outState: globalAndroid.os.Bundle): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class ProxyBillingActivityV2 { + public static class: java.lang.Class; + public onSaveInstanceState(param0: globalAndroid.os.Bundle): void; + public onCreate(param0: globalAndroid.os.Bundle): void; + public constructor(); + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class Purchase { + public static class: java.lang.Class; + public getOrderId(): string; + /** @deprecated */ + public getSkus(): java.util.ArrayList; + public getPurchaseState(): number; + public getPackageName(): string; + public constructor(jsonPurchaseInfo: string, signature: string); + public isAcknowledged(): boolean; + public equals(o: any): boolean; + public getQuantity(): number; + public getPurchaseToken(): string; + public toString(): string; + public getSignature(): string; + public getPurchaseTime(): number; + public getOriginalJson(): string; + public getDeveloperPayload(): string; + public isAutoRenewing(): boolean; + public hashCode(): number; + public getPendingPurchaseUpdate(): com.android.billingclient.api.Purchase.PendingPurchaseUpdate; + public getAccountIdentifiers(): com.android.billingclient.api.AccountIdentifiers; + public getProducts(): java.util.List; + } + export module Purchase { + export class PendingPurchaseUpdate { + public static class: java.lang.Class; + public getPurchaseToken(): string; + public getProducts(): java.util.List; + } + export class PurchaseState { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.Purchase$PurchaseState interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: {}); + public constructor(); + public static PENDING: number = 2; + public static PURCHASED: number = 1; + public static UNSPECIFIED_STATE: number = 0; + } + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class PurchaseHistoryRecord { + public static class: java.lang.Class; + public toString(): string; + public getSignature(): string; + /** @deprecated */ + public getSkus(): java.util.ArrayList; + public getPurchaseTime(): number; + public getOriginalJson(): string; + public constructor(jsonPurchaseInfo: string, signature: string); + public getDeveloperPayload(): string; + public hashCode(): number; + public equals(o: any): boolean; + public getQuantity(): number; + public getPurchaseToken(): string; + public getProducts(): java.util.List; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class PurchaseHistoryResponseListener { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.PurchaseHistoryResponseListener interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { onPurchaseHistoryResponse(param0: com.android.billingclient.api.BillingResult, param1: java.util.List): void }); + public constructor(); + public onPurchaseHistoryResponse(param0: com.android.billingclient.api.BillingResult, param1: java.util.List): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class PurchasesResponseListener { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.PurchasesResponseListener interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { onQueryPurchasesResponse(param0: com.android.billingclient.api.BillingResult, param1: java.util.List): void }); + public constructor(); + public onQueryPurchasesResponse(param0: com.android.billingclient.api.BillingResult, param1: java.util.List): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class PurchasesUpdatedListener { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.PurchasesUpdatedListener interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { onPurchasesUpdated(param0: com.android.billingclient.api.BillingResult, param1: java.util.List): void }); + public constructor(); + public onPurchasesUpdated(param0: com.android.billingclient.api.BillingResult, param1: java.util.List): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class QueryProductDetailsParams { + public static class: java.lang.Class; + public static newBuilder(): com.android.billingclient.api.QueryProductDetailsParams.Builder; + } + export module QueryProductDetailsParams { + export class Builder { + public static class: java.lang.Class; + public setProductList(productList: java.util.List): com.android.billingclient.api.QueryProductDetailsParams.Builder; + public build(): com.android.billingclient.api.QueryProductDetailsParams; + } + export class Product { + public static class: java.lang.Class; + public static newBuilder(): com.android.billingclient.api.QueryProductDetailsParams.Product.Builder; + } + export module Product { + export class Builder { + public static class: java.lang.Class; + public build(): com.android.billingclient.api.QueryProductDetailsParams.Product; + public setProductType(productType: string): com.android.billingclient.api.QueryProductDetailsParams.Product.Builder; + public setProductId(productId: string): com.android.billingclient.api.QueryProductDetailsParams.Product.Builder; + } + } + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class QueryProductDetailsResult { + public static class: java.lang.Class; + public static create(productDetailsList: java.util.List, unfetchedProductList: java.util.List): com.android.billingclient.api.QueryProductDetailsResult; + public getUnfetchedProductList(): java.util.List; + public getProductDetailsList(): java.util.List; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class QueryPurchaseHistoryParams { + public static class: java.lang.Class; + public static newBuilder(): com.android.billingclient.api.QueryPurchaseHistoryParams.Builder; + } + export module QueryPurchaseHistoryParams { + export class Builder { + public static class: java.lang.Class; + public build(): com.android.billingclient.api.QueryPurchaseHistoryParams; + public setProductType(productType: string): com.android.billingclient.api.QueryPurchaseHistoryParams.Builder; + } + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class QueryPurchasesParams { + public static class: java.lang.Class; + public static newBuilder(): com.android.billingclient.api.QueryPurchasesParams.Builder; + } + export module QueryPurchasesParams { + export class Builder { + public static class: java.lang.Class; + public setProductType(productType: string): com.android.billingclient.api.QueryPurchasesParams.Builder; + public build(): com.android.billingclient.api.QueryPurchasesParams; + } + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class SkuDetails { + public static class: java.lang.Class; + public getTitle(): string; + public constructor(jsonSkuDetails: string); + public getPriceCurrencyCode(): string; + public equals(o: any): boolean; + public getIntroductoryPriceCycles(): number; + public toString(): string; + public getIntroductoryPrice(): string; + public getSubscriptionPeriod(): string; + public getPriceAmountMicros(): number; + public getOriginalJson(): string; + public getIntroductoryPricePeriod(): string; + public getSku(): string; + public getIntroductoryPriceAmountMicros(): number; + public getOriginalPriceAmountMicros(): number; + public hashCode(): number; + public getDescription(): string; + public getType(): string; + public getIconUrl(): string; + public getOriginalPrice(): string; + public getPrice(): string; + public getFreeTrialPeriod(): string; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class SkuDetailsParams { + public static class: java.lang.Class; + public getSkusList(): java.util.List; + public constructor(); + public static newBuilder(): com.android.billingclient.api.SkuDetailsParams.Builder; + public getSkuType(): string; + } + export module SkuDetailsParams { + export class Builder { + public static class: java.lang.Class; + public setSkusList(skusList: java.util.List): com.android.billingclient.api.SkuDetailsParams.Builder; + public setType(type: string): com.android.billingclient.api.SkuDetailsParams.Builder; + public build(): com.android.billingclient.api.SkuDetailsParams; + } + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class SkuDetailsResponseListener { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.SkuDetailsResponseListener interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { onSkuDetailsResponse(param0: com.android.billingclient.api.BillingResult, param1: java.util.List): void }); + public constructor(); + public onSkuDetailsResponse(param0: com.android.billingclient.api.BillingResult, param1: java.util.List): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class UnfetchedProduct { + public static class: java.lang.Class; + public getStatusCode(): number; + public getProductId(): string; + public toString(): string; + public static fromJson(jsonString: string): com.android.billingclient.api.UnfetchedProduct; + public getProductType(): string; + public getSerializedDocid(): string; + public hashCode(): number; + public equals(o: any): boolean; + } + export module UnfetchedProduct { + export class StatusCode { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.UnfetchedProduct$StatusCode interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: {}); + public constructor(); + public static NO_ELIGIBLE_OFFER: number = 4; + public static UNKNOWN: number = 0; + public static PRODUCT_NOT_FOUND: number = 3; + public static INVALID_PRODUCT_ID_FORMAT: number = 2; + } + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class UserChoiceBillingListener { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.UserChoiceBillingListener interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { userSelectedAlternativeBilling(param0: com.android.billingclient.api.UserChoiceDetails): void }); + public constructor(); + public userSelectedAlternativeBilling(param0: com.android.billingclient.api.UserChoiceDetails): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class UserChoiceDetails { + public static class: java.lang.Class; + public getExternalTransactionToken(): string; + public getOriginalExternalTransactionId(): string; + public getProducts(): java.util.List; + } + export module UserChoiceDetails { + export class Product { + public static class: java.lang.Class; + public getOfferToken(): string; + public getType(): string; + public hashCode(): number; + public getId(): string; + public equals(o: any): boolean; + public toString(): string; + } + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zza { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzaa { + public static class: java.lang.Class; + public call(): any; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzab { + public static class: java.lang.Class; + public run(): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzac { + public static class: java.lang.Class; + public run(): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzad { + public static class: java.lang.Class; + public call(): any; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzae { + public static class: java.lang.Class; + public run(): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzaf { + public static class: java.lang.Class; + public call(): any; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzag { + public static class: java.lang.Class; + public run(): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzah { + public static class: java.lang.Class; + public call(): any; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzai { + public static class: java.lang.Class; + public run(): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzaj { + public static class: java.lang.Class; + public run(): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzak { + public static class: java.lang.Class; + public call(): any; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzal { + public static class: java.lang.Class; + public call(): any; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzam { + public static class: java.lang.Class; + public run(): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzan { + public static class: java.lang.Class; + public call(): any; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzao { + public static class: java.lang.Class; + public run(): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzap { + public static class: java.lang.Class; + public run(): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzaq { + public static class: java.lang.Class; + public call(): any; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzar { + public static class: java.lang.Class; + public run(): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzas { + public static class: java.lang.Class; + public call(): any; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzat { + public static class: java.lang.Class; + public run(): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzau { + public static class: java.lang.Class; + public call(): any; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzav { + public static class: java.lang.Class; + public newThread(param0: java.lang.Runnable): java.lang.Thread; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzaw { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzax { + public static class: java.lang.Class; + public onReceiveResult(param0: number, param1: globalAndroid.os.Bundle): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzay { + public static class: java.lang.Class; + public onReceiveResult(param0: number, param1: globalAndroid.os.Bundle): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzaz { + public static class: java.lang.Class; + public onReceiveResult(param0: number, param1: globalAndroid.os.Bundle): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzb { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.zzb interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { zza(): void }); + public constructor(); + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzba { + public static class: java.lang.Class; + public run(): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzbb { + public static class: java.lang.Class; + public run(): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzbc extends com.android.billingclient.api.BillingClientStateListener { + public static class: java.lang.Class; + public onBillingSetupFinished(param0: com.android.billingclient.api.BillingResult): void; + public onBillingServiceDisconnected(): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzbd { + public static class: java.lang.Class; + public call(): any; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzbe { + public static class: java.lang.Class; + public run(): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzbf { + public static class: java.lang.Class; + public onServiceConnected(param0: globalAndroid.content.ComponentName, param1: globalAndroid.os.IBinder): void; + public onBindingDied(param0: globalAndroid.content.ComponentName): void; + public onServiceDisconnected(param0: globalAndroid.content.ComponentName): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzbg extends com.google.android.gms.internal.play_billing.zzw { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzbh extends com.google.android.gms.internal.play_billing.zzy { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzbi extends com.google.android.gms.internal.play_billing.zzaa { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzbj extends com.google.android.gms.internal.play_billing.zzac { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzbk extends com.google.android.gms.internal.play_billing.zzae { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzbl extends com.google.android.gms.internal.play_billing.zzag { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzbm extends com.google.android.gms.internal.play_billing.zzai { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzbn extends com.google.android.gms.internal.play_billing.zzan { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzbo { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzbp { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzbq implements com.android.billingclient.api.AcknowledgePurchaseResponseListener, com.android.billingclient.api.BillingClientStateListener, com.android.billingclient.api.ConsumeResponseListener, com.android.billingclient.api.PurchaseHistoryResponseListener, com.android.billingclient.api.PurchasesResponseListener, com.android.billingclient.api.PurchasesUpdatedListener, com.android.billingclient.api.SkuDetailsResponseListener { + public static class: java.lang.Class; + public onBillingSetupFinished(param0: com.android.billingclient.api.BillingResult): void; + public onQueryPurchasesResponse(param0: com.android.billingclient.api.BillingResult, param1: java.util.List): void; + public static nativeOnAcknowledgePurchaseResponse(param0: number, param1: string, param2: number): void; + public onSkuDetailsResponse(param0: com.android.billingclient.api.BillingResult, param1: java.util.List): void; + public static nativeOnBillingSetupFinished(param0: number, param1: string, param2: number): void; + public static nativeOnPriceChangeConfirmationResult(param0: number, param1: string, param2: number): void; + public onConsumeResponse(param0: com.android.billingclient.api.BillingResult, param1: string): void; + public static nativeOnPurchasesUpdated(param0: number, param1: string, param2: androidNative.Array): void; + public static nativeOnConsumePurchaseResponse(param0: number, param1: string, param2: string, param3: number): void; + public static nativeOnQueryPurchasesResponse(param0: number, param1: string, param2: androidNative.Array, param3: number): void; + public static nativeOnBillingServiceDisconnected(): void; + public static nativeOnSkuDetailsResponse(param0: number, param1: string, param2: androidNative.Array, param3: number): void; + public static nativeOnPurchaseHistoryResponse(param0: number, param1: string, param2: androidNative.Array, param3: number): void; + public onPurchasesUpdated(param0: com.android.billingclient.api.BillingResult, param1: java.util.List): void; + public onBillingServiceDisconnected(): void; + public onAcknowledgePurchaseResponse(param0: com.android.billingclient.api.BillingResult): void; + public onPurchaseHistoryResponse(param0: com.android.billingclient.api.BillingResult, param1: java.util.List): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzbr { + public static class: java.lang.Class; + public accept(param0: any): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzbs { + public static class: java.lang.Class; + public run(): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzbt { + public static class: java.lang.Class; + public accept(param0: any): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzbu { + public static class: java.lang.Class; + public run(): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzbv extends com.google.android.gms.internal.play_billing.zzr { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzbw { + public static class: java.lang.Class; + public accept(param0: any): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzbx { + public static class: java.lang.Class; + public run(): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzby { + public static class: java.lang.Class; + public accept(param0: any): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzbz { + public static class: java.lang.Class; + public call(): any; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzc { + public static class: java.lang.Class; + public equals(param0: any): boolean; + public toString(): string; + public hashCode(): number; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzca extends com.google.android.gms.internal.play_billing.zzcs { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzcb extends com.google.android.gms.internal.play_billing.zzav { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzcc { + public static class: java.lang.Class; + public onServiceConnected(param0: globalAndroid.content.ComponentName, param1: globalAndroid.os.IBinder): void; + public onServiceDisconnected(param0: globalAndroid.content.ComponentName): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzcd { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzce extends com.android.billingclient.api.BillingClientImpl { + public static class: java.lang.Class; + public launchBillingFlow(param0: globalAndroid.app.Activity, param1: com.android.billingclient.api.BillingFlowParams): com.android.billingclient.api.BillingResult; + public endConnection(): void; + public startConnection(param0: com.android.billingclient.api.BillingClientStateListener): void; + public acknowledgePurchase(param0: com.android.billingclient.api.AcknowledgePurchaseParams, param1: com.android.billingclient.api.AcknowledgePurchaseResponseListener): void; + public queryProductDetailsAsync(param0: com.android.billingclient.api.QueryProductDetailsParams, param1: com.android.billingclient.api.ProductDetailsResponseListener): void; + public consumeAsync(param0: com.android.billingclient.api.ConsumeParams, param1: com.android.billingclient.api.ConsumeResponseListener): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzcf { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzcg { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzch { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.zzch interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { + ''(): void; + zza(param0: any /* com.google.android.gms.internal.play_billing.zzhx*/): void; + zzb(param0: any /* com.google.android.gms.internal.play_billing.zzhx*/, param1: number): void; + zzc(param0: any /* com.google.android.gms.internal.play_billing.zzhx*/, param1: number, param2: number): void; + zzd(param0: any /* com.google.android.gms.internal.play_billing.zzhx*/, param1: number, param2: boolean): void; + zze(param0: any /* com.google.android.gms.internal.play_billing.zzhx*/, param1: number, param2: number, param3: boolean): void; + zzf(param0: any /* com.google.android.gms.internal.play_billing.zzib*/): void; + zzg(param0: any /* com.google.android.gms.internal.play_billing.zzib*/, param1: number): void; + zzh(param0: any /* com.google.android.gms.internal.play_billing.zzib*/, param1: number, param2: boolean): void; + zzi(param0: any /* com.google.android.gms.internal.play_billing.zzij*/): void; + zzj(param0: any /* com.google.android.gms.internal.play_billing.zzjo*/): void; + zzk(param0: any /* com.google.android.gms.internal.play_billing.zzjs*/): void; + }); + public constructor(); + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzci { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzcj { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzck { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzcl extends com.android.billingclient.api.zzch { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzcm { + public static class: java.lang.Class; + public apply(param0: any): any; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzcn { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzco { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.zzco interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: {}); + public constructor(); + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzcp { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzcq { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzcr { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzcs { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzct { + public static class: java.lang.Class; + public onActivityResult(param0: any): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzcu { + public static class: java.lang.Class; + public onActivityResult(param0: any): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzcv { + public static class: java.lang.Class; + public onActivityResult(param0: any): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzcw { + public static class: java.lang.Class; + public constructor(param0: com.android.billingclient.api.BillingResult, param1: java.util.List); + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzcx { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzcy { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzcz { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzd { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzda { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzdb { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzdc { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zze { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.zze interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: {}); + public constructor(); + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzf { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.zzf interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: {}); + public constructor(); + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzg { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.zzg interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: {}); + public constructor(); + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzh { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.zzh interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: {}); + public constructor(); + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzi { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.zzi interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: {}); + public constructor(); + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzj { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.zzj interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: {}); + public constructor(); + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzk { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.zzk interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: {}); + public constructor(); + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzl { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.zzl interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: {}); + public constructor(); + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzm { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.zzm interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: {}); + public constructor(); + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzn { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.zzn interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: {}); + public constructor(); + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzo { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.zzo interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: {}); + public constructor(); + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzp { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.zzp interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: {}); + public constructor(); + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzq { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.android.billingclient.api.zzq interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: {}); + public constructor(); + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzr { + public static class: java.lang.Class; + public onReceive(param0: globalAndroid.content.Context, param1: globalAndroid.content.Intent): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzs { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzt { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzu extends com.google.android.gms.internal.play_billing.zzr { + public static class: java.lang.Class; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzv { + public static class: java.lang.Class; + public run(): void; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzw { + public static class: java.lang.Class; + public call(): any; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzx { + public static class: java.lang.Class; + public call(): any; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzy { + public static class: java.lang.Class; + public call(): any; + } + } + } + } +} + +declare module com { + export module android { + export module billingclient { + export module api { + export class zzz { + public static class: java.lang.Class; + public run(): void; + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zza { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzaa extends com.google.android.gms.internal.play_billing.zzaq implements com.google.android.gms.internal.play_billing.zzab { + public static class: java.lang.Class; + public constructor(); + public constructor(param0: string); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzab { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzab interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { zza(param0: globalAndroid.os.Bundle): void }); + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzac extends com.google.android.gms.internal.play_billing.zzaq implements com.google.android.gms.internal.play_billing.zzad { + public static class: java.lang.Class; + public constructor(); + public constructor(param0: string); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzad { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzad interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { zza(param0: globalAndroid.os.Bundle): void }); + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzae extends com.google.android.gms.internal.play_billing.zzaq implements com.google.android.gms.internal.play_billing.zzaf { + public static class: java.lang.Class; + public constructor(); + public constructor(param0: string); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzaf { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzaf interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { zza(param0: globalAndroid.os.Bundle): void }); + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzag extends com.google.android.gms.internal.play_billing.zzaq implements com.google.android.gms.internal.play_billing.zzah { + public static class: java.lang.Class; + public constructor(); + public constructor(param0: string); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzah { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzah interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { zza(param0: globalAndroid.os.Bundle): void }); + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzai extends com.google.android.gms.internal.play_billing.zzaq implements com.google.android.gms.internal.play_billing.zzaj { + public static class: java.lang.Class; + public constructor(); + public constructor(param0: string); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzaj { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzaj interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { zza(param0: globalAndroid.os.Bundle): void }); + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzak extends com.google.android.gms.internal.play_billing.zzap implements com.google.android.gms.internal.play_billing.zzam { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzal extends com.google.android.gms.internal.play_billing.zzaq implements com.google.android.gms.internal.play_billing.zzam { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzam { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzam interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { + zza(param0: number, param1: string, param2: string): number; + zzw(param0: number, param1: string, param2: string): number; + zzc(param0: number, param1: string, param2: string, param3: globalAndroid.os.Bundle): number; + zzd(param0: number, param1: string, param2: string, param3: globalAndroid.os.Bundle): globalAndroid.os.Bundle; + zze(param0: number, param1: string, param2: string, param3: globalAndroid.os.Bundle): globalAndroid.os.Bundle; + zzf(param0: number, param1: string, param2: string, param3: string, param4: string): globalAndroid.os.Bundle; + zzg(param0: number, param1: string, param2: string, param3: string, param4: string, param5: globalAndroid.os.Bundle): globalAndroid.os.Bundle; + zzh(param0: number, param1: string, param2: string, param3: string): globalAndroid.os.Bundle; + zzi(param0: number, param1: string, param2: string, param3: string, param4: globalAndroid.os.Bundle): globalAndroid.os.Bundle; + zzj(param0: number, param1: string, param2: string, param3: globalAndroid.os.Bundle, param4: globalAndroid.os.Bundle): globalAndroid.os.Bundle; + zzk(param0: number, param1: string, param2: globalAndroid.os.Bundle, param3: any /* com.google.android.gms.internal.play_billing.zzx*/): void; + zzl(param0: number, param1: string, param2: globalAndroid.os.Bundle, param3: any /* com.google.android.gms.internal.play_billing.zzz*/): void; + zzm(param0: number, param1: string, param2: globalAndroid.os.Bundle, param3: any /* com.google.android.gms.internal.play_billing.zzab*/): void; + zzn(param0: number, param1: string, param2: globalAndroid.os.Bundle, param3: any /* com.google.android.gms.internal.play_billing.zzad*/): void; + zzo(param0: number, param1: string, param2: globalAndroid.os.Bundle, param3: any /* com.google.android.gms.internal.play_billing.zzaf*/): void; + zzp(param0: number, param1: string, param2: globalAndroid.os.Bundle, param3: any /* com.google.android.gms.internal.play_billing.zzah*/): void; + zzq(param0: number, param1: string, param2: globalAndroid.os.Bundle, param3: any /* com.google.android.gms.internal.play_billing.zzaj*/): void; + zzr(param0: number, param1: string, param2: globalAndroid.os.Bundle, param3: any /* com.google.android.gms.internal.play_billing.zzao*/): void; + }); + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzan extends com.google.android.gms.internal.play_billing.zzaq implements com.google.android.gms.internal.play_billing.zzao { + public static class: java.lang.Class; + public constructor(); + public constructor(param0: string); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzao { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzao interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { zza(param0: globalAndroid.os.Bundle): void }); + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzap { + public static class: java.lang.Class; + public constructor(param0: globalAndroid.os.IBinder, param1: string); + public asBinder(): globalAndroid.os.IBinder; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzaq { + public static class: java.lang.Class; + public asBinder(): globalAndroid.os.IBinder; + public constructor(param0: string); + public onTransact(param0: number, param1: globalAndroid.os.Parcel, param2: globalAndroid.os.Parcel, param3: number): boolean; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzar { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzas extends com.google.android.gms.internal.play_billing.zzap implements com.google.android.gms.internal.play_billing.zzau { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzat extends com.google.android.gms.internal.play_billing.zzaq implements com.google.android.gms.internal.play_billing.zzau { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzau { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzau interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { zza(param0: string, param1: string, param2: any /* com.google.android.gms.internal.play_billing.zzaw*/): void }); + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzav extends com.google.android.gms.internal.play_billing.zzaq implements com.google.android.gms.internal.play_billing.zzaw { + public static class: java.lang.Class; + public constructor(); + public constructor(param0: string); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzaw { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzaw interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { zza(param0: number): void }); + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzax extends com.google.android.gms.internal.play_billing.zzbl { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzay extends com.google.android.gms.internal.play_billing.zzbl { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzaz { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzb { + public static class: java.lang.Class; + public static values(): any /* androidNative.Array*/; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzba { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzbb { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzbc { + public static class: java.lang.Class; + public toString(): string; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzbd { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzbe { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzbf extends com.google.android.gms.internal.play_billing.zzba { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzbg { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzbh { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzbi { + public static class: java.lang.Class; + public toString(): string; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzbj { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzbk extends com.google.android.gms.internal.play_billing.zzbl { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzbl { + public static class: java.lang.Class; + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzbm { + public static class: java.lang.Class; + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzbn extends com.google.android.gms.internal.play_billing.zzci { + public static class: java.lang.Class; + public constructor(); + public previousIndex(): number; + public previous(): any; + public constructor(param0: number, param1: number); + public nextIndex(): number; + public hasNext(): boolean; + public hasPrevious(): boolean; + public next(): any; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzbo { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzbp { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzbq { + public static class: java.lang.Class; + public contains(param0: any): boolean; + /** @deprecated */ + public addAll(param0: java.util.Collection): boolean; + /** @deprecated */ + public add(param0: any): boolean; + /** @deprecated */ + public remove(param0: any): boolean; + public spliterator(): java.util.Spliterator; + /** @deprecated */ + public clear(): void; + public toArray(): androidNative.Array; + /** @deprecated */ + public removeAll(param0: java.util.Collection): boolean; + public toArray(param0: androidNative.Array): androidNative.Array; + /** @deprecated */ + public retainAll(param0: java.util.Collection): boolean; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzbr extends com.google.android.gms.internal.play_billing.zzbn { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzbs extends com.google.android.gms.internal.play_billing.zzbt { + public static class: java.lang.Class; + public size(): number; + public get(param0: number): any; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzbt extends com.google.android.gms.internal.play_billing.zzbq { + public static class: java.lang.Class; + public contains(param0: any): boolean; + /** @deprecated */ + public addAll(param0: java.util.Collection): boolean; + /** @deprecated */ + public add(param0: any): boolean; + public hashCode(): number; + public lastIndexOf(param0: any): number; + /** @deprecated */ + public addAll(param0: number, param1: java.util.Collection): boolean; + /** @deprecated */ + public remove(param0: any): boolean; + /** @deprecated */ + public remove(param0: number): any; + public indexOf(param0: any): number; + /** @deprecated */ + public add(param0: number, param1: any): void; + public equals(param0: any): boolean; + /** @deprecated */ + public set(param0: number, param1: any): any; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzbu { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzbv { + public static class: java.lang.Class; + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzbw { + public static class: java.lang.Class; + public get(param0: any): any; + public hashCode(): number; + public containsKey(param0: any): boolean; + public getOrDefault(param0: any, param1: any): any; + /** @deprecated */ + public put(param0: any, param1: any): any; + /** @deprecated */ + public remove(param0: any): any; + /** @deprecated */ + public clear(): void; + public toString(): string; + /** @deprecated */ + public putAll(param0: java.util.Map): void; + public equals(param0: any): boolean; + public isEmpty(): boolean; + public containsValue(param0: any): boolean; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzbx extends com.google.android.gms.internal.play_billing.zzbq { + public static class: java.lang.Class; + public hashCode(): number; + public equals(param0: any): boolean; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzby { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzbz { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzc { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzca extends com.google.android.gms.internal.play_billing.zzbt { + public static class: java.lang.Class; + public size(): number; + public get(param0: number): any; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzcb extends com.google.android.gms.internal.play_billing.zzbt { + public static class: java.lang.Class; + public size(): number; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzcc extends com.google.android.gms.internal.play_billing.zzbx { + public static class: java.lang.Class; + public contains(param0: any): boolean; + public size(): number; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzcd extends com.google.android.gms.internal.play_billing.zzbx { + public static class: java.lang.Class; + public contains(param0: any): boolean; + public size(): number; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzce extends com.google.android.gms.internal.play_billing.zzbt { + public static class: java.lang.Class; + public size(): number; + public get(param0: number): any; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzcf extends com.google.android.gms.internal.play_billing.zzbw { + public static class: java.lang.Class; + public get(param0: any): any; + public size(): number; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzcg { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzch { + public static class: java.lang.Class; + public constructor(); + /** @deprecated */ + public remove(): void; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzci extends com.google.android.gms.internal.play_billing.zzch { + public static class: java.lang.Class; + public constructor(); + /** @deprecated */ + public add(param0: any): void; + /** @deprecated */ + public set(param0: any): void; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzcj extends java.lang.Object /* com.google.android.gms.internal.play_billing.zzck*/ { + public static class: java.lang.Class>; + public get(): any; + public constructor(); + public cancel(param0: boolean): boolean; + public get(param0: number, param1: java.util.concurrent.TimeUnit): any; + public isCancelled(): boolean; + public isDone(): boolean; + public toString(): string; + } + export module zzcj { + export class zza { + public static class: java.lang.Class; + } + export class zzb extends java.lang.Runnable { + public static class: java.lang.Class>; + public run(): void; + } + export class zzc { + public static class: java.lang.Class; + } + export class zzd { + public static class: java.lang.Class; + } + export class zze extends java.lang.Object /* com.google.android.gms.internal.play_billing.zzcz*/ { + public static class: java.lang.Class>; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzcj$zze interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { zzb(param0: java.lang.Runnable, param1: java.util.concurrent.Executor): void }); + public constructor(); + } + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzck extends java.lang.Object /* com.google.android.gms.internal.play_billing.zzdf*/ implements any /* com.google.android.gms.internal.play_billing.zzcz*/ { + public static class: java.lang.Class>; + } + export module zzck { + export abstract class zza { + public static class: java.lang.Class; + } + export class zzb extends com.google.android.gms.internal.play_billing.zzck.zza { + public static class: java.lang.Class; + } + export class zzc extends com.google.android.gms.internal.play_billing.zzck.zza { + public static class: java.lang.Class; + } + export class zzd extends com.google.android.gms.internal.play_billing.zzck.zza { + public static class: java.lang.Class; + } + export class zze { + public static class: java.lang.Class; + } + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzcl { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzcm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzcn { + public static class: java.lang.Class; + public run(): any; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzco { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzcp { + public static class: java.lang.Class; + public execute(param0: java.lang.Runnable): void; + public static values(): any /* androidNative.Array*/; + public toString(): string; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzcq extends com.google.android.gms.internal.play_billing.zzcr implements com.google.android.gms.internal.play_billing.zzcj.zze { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzcr extends com.google.android.gms.internal.play_billing.zzcv { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzcs { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzcs interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { zza(param0: java.lang.Throwable): void; zzb(param0: any): void }); + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzct { + public static class: java.lang.Class; + public toString(): string; + public run(): void; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzcu extends com.google.android.gms.internal.play_billing.zzcw { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzcv extends com.google.android.gms.internal.play_billing.zzcj { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzcw { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzcx extends com.google.android.gms.internal.play_billing.zzcz { + public static class: java.lang.Class; + public get(): any; + public cancel(param0: boolean): boolean; + public get(param0: number, param1: java.util.concurrent.TimeUnit): any; + public isCancelled(): boolean; + public isDone(): boolean; + public toString(): string; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzcy { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzcz extends java.util.concurrent.Future { + public static class: java.lang.Class>; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzcz interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { zzb(param0: java.lang.Runnable, param1: java.util.concurrent.Executor): void }); + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzd { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzda { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzdb { + public static class: java.lang.Class; + public run(): void; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzdc { + public static class: java.lang.Class; + public fillInStackTrace(): java.lang.Throwable; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzdd { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzde extends com.google.android.gms.internal.play_billing.zzcq { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzdf { + public static class: java.lang.Class; + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzdg { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzdh extends com.google.android.gms.internal.play_billing.zzfe implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzdi extends com.google.android.gms.internal.play_billing.zzfi implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzdj extends com.google.android.gms.internal.play_billing.zzfe implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzdk extends com.google.android.gms.internal.play_billing.zzfi implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzdl { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzdm extends com.google.android.gms.internal.play_billing.zzfe implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzdn extends com.google.android.gms.internal.play_billing.zzfi implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzdo { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzdp extends com.google.android.gms.internal.play_billing.zzfl { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzdq { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzdr extends java.lang.Object /* com.google.android.gms.internal.play_billing.zzgk*/ { + public static class: java.lang.Class>; + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzds extends java.lang.Object /* com.google.android.gms.internal.play_billing.zzgl*/ { + public static class: java.lang.Class>; + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzdt extends com.google.android.gms.internal.play_billing.zzgl { + public static class: java.lang.Class; + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzdu implements com.google.android.gms.internal.play_billing.zzfn { + public static class: java.lang.Class; + public remove(param0: number): any; + public set(param0: number, param1: any): any; + public removeAll(param0: java.util.Collection): boolean; + public add(param0: any): boolean; + public hashCode(): number; + public remove(param0: any): boolean; + public add(param0: number, param1: any): void; + public retainAll(param0: java.util.Collection): boolean; + public clear(): void; + public equals(param0: any): boolean; + public addAll(param0: java.util.Collection): boolean; + public addAll(param0: number, param1: java.util.Collection): boolean; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzdv { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzdw { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzdx { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzdy extends com.google.android.gms.internal.play_billing.zzdu implements com.google.android.gms.internal.play_billing.zzfn { + public static class: java.lang.Class; + public contains(param0: any): boolean; + public size(): number; + public hashCode(): number; + public indexOf(param0: any): number; + public equals(param0: any): boolean; + public removeRange(param0: number, param1: number): void; + public addAll(param0: java.util.Collection): boolean; + public addAll(param0: number, param1: java.util.Collection): boolean; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzdz { + public static class: java.lang.Class; + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zze { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzea extends com.google.android.gms.internal.play_billing.zzeb { + public static class: java.lang.Class; + public hasNext(): boolean; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzeb extends com.google.android.gms.internal.play_billing.zzed { + public static class: java.lang.Class; + public remove(): void; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzec extends com.google.android.gms.internal.play_billing.zzeg { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzed { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzed interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { zza(): number }); + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzee { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzef extends com.google.android.gms.internal.play_billing.zzei { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzeg extends com.google.android.gms.internal.play_billing.zzef { + public static class: java.lang.Class; + public equals(param0: any): boolean; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzeh { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzei { + public static class: java.lang.Class; + public hashCode(): number; + public toString(): string; + public equals(param0: any): boolean; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzej extends com.google.android.gms.internal.play_billing.zzel { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzek { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzel { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzem extends com.google.android.gms.internal.play_billing.zzep { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzen { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzeo { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzep extends com.google.android.gms.internal.play_billing.zzdz { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzeq extends com.google.android.gms.internal.play_billing.zzhu { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzer extends com.google.android.gms.internal.play_billing.zzdu implements com.google.android.gms.internal.play_billing.zzfn { + public static class: java.lang.Class; + public contains(param0: any): boolean; + public size(): number; + public hashCode(): number; + public indexOf(param0: any): number; + public equals(param0: any): boolean; + public removeRange(param0: number, param1: number): void; + public addAll(param0: java.util.Collection): boolean; + public addAll(param0: number, param1: java.util.Collection): boolean; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzes { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzet { + public static class: java.lang.Class; + public hashCode(): number; + public equals(param0: any): boolean; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzeu { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzev { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzew extends com.google.android.gms.internal.play_billing.zzev { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzex { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzey { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzey interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { zza(): number; zzb(): any /* com.google.android.gms.internal.play_billing.zzhs*/; zzc(): any /* com.google.android.gms.internal.play_billing.zzht*/; zzd(): boolean; zze(): boolean }); + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzez { + public static class: java.lang.Class; + public hashCode(): number; + public equals(param0: any): boolean; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzf { + public static class: java.lang.Class; + public fillInStackTrace(): java.lang.Throwable; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzfa { + public static class: java.lang.Class; + public static values(): any /* androidNative.Array*/; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzfb extends com.google.android.gms.internal.play_billing.zzdu implements com.google.android.gms.internal.play_billing.zzfn { + public static class: java.lang.Class; + public contains(param0: any): boolean; + public size(): number; + public hashCode(): number; + public indexOf(param0: any): number; + public equals(param0: any): boolean; + public removeRange(param0: number, param1: number): void; + public addAll(param0: java.util.Collection): boolean; + public addAll(param0: number, param1: java.util.Collection): boolean; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzfc { + public static class: java.lang.Class; + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzfd extends com.google.android.gms.internal.play_billing.zzgj { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzfe extends java.lang.Object /* com.google.android.gms.internal.play_billing.zzdr*/ { + public static class: java.lang.Class>; + public constructor(); + public constructor(param0: any); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzff extends com.google.android.gms.internal.play_billing.zzfi implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzfg extends com.google.android.gms.internal.play_billing.zzey { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzfh extends com.google.android.gms.internal.play_billing.zzes { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzfi extends java.lang.Object /* com.google.android.gms.internal.play_billing.zzds*/ { + public static class: java.lang.Class>; + public constructor(); + public hashCode(): number; + public toString(): string; + public equals(param0: any): boolean; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzfj extends com.google.android.gms.internal.play_billing.zzdu implements com.google.android.gms.internal.play_billing.zzfm { + public static class: java.lang.Class; + public contains(param0: any): boolean; + public size(): number; + public hashCode(): number; + public indexOf(param0: any): number; + public equals(param0: any): boolean; + public removeRange(param0: number, param1: number): void; + public addAll(param0: java.util.Collection): boolean; + public addAll(param0: number, param1: java.util.Collection): boolean; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzfk { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzfk interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { zza(): number }); + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzfl { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzfl interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { zza(param0: number): boolean }); + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzfm extends com.google.android.gms.internal.play_billing.zzfn { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzfm interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { zzd(param0: number): any /* com.google.android.gms.internal.play_billing.zzfn*/; zzb(): void; zzc(): boolean }); + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzfn { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzfn interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { zzd(param0: number): any /* com.google.android.gms.internal.play_billing.zzfn*/; zzb(): void; zzc(): boolean }); + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzfo { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzfp extends com.google.android.gms.internal.play_billing.zzfq { + public static class: java.lang.Class; + public constructor(param0: string); + public constructor(param0: java.io.IOException); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzfq { + public static class: java.lang.Class; + public constructor(param0: string); + public constructor(param0: java.io.IOException); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzfr { + public static class: java.lang.Class; + public static values(): any /* androidNative.Array*/; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzfs { + public static class: java.lang.Class; + public getValue(): any; + public getKey(): any; + public setValue(param0: any): any; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzft { + public static class: java.lang.Class; + public remove(): void; + public hasNext(): boolean; + public constructor(param0: java.util.Iterator); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzfu { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzfv extends com.google.android.gms.internal.play_billing.zzfw { + public static class: java.lang.Class; + public hashCode(): number; + public toString(): string; + public equals(param0: any): boolean; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzfw { + public static class: java.lang.Class; + public constructor(); + public hashCode(): number; + public equals(param0: any): boolean; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzfx { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzfx interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { zza(): any }); + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzfy { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzfz { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzg { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzga extends com.google.android.gms.internal.play_billing.zzdu implements com.google.android.gms.internal.play_billing.zzfn { + public static class: java.lang.Class; + public contains(param0: any): boolean; + public size(): number; + public hashCode(): number; + public indexOf(param0: any): number; + public equals(param0: any): boolean; + public removeRange(param0: number, param1: number): void; + public addAll(param0: java.util.Collection): boolean; + public addAll(param0: number, param1: java.util.Collection): boolean; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzgb extends com.google.android.gms.internal.play_billing.zzgj { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzgc extends com.google.android.gms.internal.play_billing.zzgj { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzgd extends com.google.android.gms.internal.play_billing.zzgw { + public static class: java.lang.Class; + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzge { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzgf { + public static class: java.lang.Class; + public hashCode(): number; + public remove(param0: any): any; + public entrySet(): java.util.Set; + public putAll(param0: java.util.Map): void; + public clear(): void; + public put(param0: any, param1: any): any; + public equals(param0: any): boolean; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzgg { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzgh { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzgi { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzgi interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { zza(): any /* com.google.android.gms.internal.play_billing.zzgl*/; zzb(): boolean; zzc(): number }); + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzgj { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzgj interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { zzb(param0: java.lang.Class): any /* com.google.android.gms.internal.play_billing.zzgi*/; zzc(param0: java.lang.Class): boolean }); + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzgk extends com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzgk interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { zzg(): any /* com.google.android.gms.internal.play_billing.zzgl*/; zzh(): any /* com.google.android.gms.internal.play_billing.zzgl*/; zzk(): boolean }); + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzgl extends com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzgl interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { zzj(): number; zzf(): any /* com.google.android.gms.internal.play_billing.zzei*/; zzK(): any /* com.google.android.gms.internal.play_billing.zzgk*/; zzL(param0: any /* com.google.android.gms.internal.play_billing.zzep*/): void; zzh(): any /* com.google.android.gms.internal.play_billing.zzgl*/; zzk(): boolean }); + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzgm { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzgm interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { zzh(): any /* com.google.android.gms.internal.play_billing.zzgl*/; zzk(): boolean }); + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzgn { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzgo extends java.lang.Object /* com.google.android.gms.internal.play_billing.zzgv*/ { + public static class: java.lang.Class>; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzgp extends com.google.android.gms.internal.play_billing.zzgv { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzgq { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzgr { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzgs { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzgt extends com.google.android.gms.internal.play_billing.zzdu { + public static class: java.lang.Class; + public remove(param0: number): any; + public set(param0: number, param1: any): any; + public size(): number; + public add(param0: any): boolean; + public remove(param0: any): boolean; + public add(param0: number, param1: any): void; + public get(param0: number): any; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzgu extends com.google.android.gms.internal.play_billing.zzgi { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzgv extends java.lang.Object { + public static class: java.lang.Class>; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzgv interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { zza(param0: any): number; zzb(param0: any): number; zze(): any; zzf(param0: any): void; zzg(param0: any, param1: any): void; zzh(param0: any, param1: androidNative.Array, param2: number, param3: number, param4: any /* com.google.android.gms.internal.play_billing.zzdw*/): void; zzi(param0: any, param1: any /* com.google.android.gms.internal.play_billing.zzhu*/): void; zzj(param0: any, param1: any): boolean; zzk(param0: any): boolean }); + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzgw { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzgw interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { zza(param0: java.lang.Class): any /* com.google.android.gms.internal.play_billing.zzgv*/ }); + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzgx { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzgy extends com.google.android.gms.internal.play_billing.zzhd { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzgz { + public static class: java.lang.Class; + public getValue(): any; + public hashCode(): number; + public toString(): string; + public setValue(param0: any): any; + public equals(param0: any): boolean; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzh { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzha { + public static class: java.lang.Class; + public remove(): void; + public hasNext(): boolean; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzhb { + public static class: java.lang.Class; + public contains(param0: any): boolean; + public size(): number; + public remove(param0: any): boolean; + public clear(): void; + public iterator(): java.util.Iterator; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzhc { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzhd { + public static class: java.lang.Class; + public get(param0: any): any; + public size(): number; + public hashCode(): number; + public remove(param0: any): any; + public entrySet(): java.util.Set; + public containsKey(param0: any): boolean; + public clear(): void; + public equals(param0: any): boolean; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzhe extends com.google.android.gms.internal.play_billing.zzgi { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzhf { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzhg { + public static class: java.lang.Class; + public constructor(param0: any /* com.google.android.gms.internal.play_billing.zzgl*/); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzhh { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzhi { + public static class: java.lang.Class; + public hashCode(): number; + public equals(param0: any): boolean; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzhj extends com.google.android.gms.internal.play_billing.zzhh { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzhk { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzhl extends com.google.android.gms.internal.play_billing.zzhn { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzhm extends com.google.android.gms.internal.play_billing.zzhn { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzhn { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzho { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzhp { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzhq { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzhr { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzhs { + public static class: java.lang.Class; + public static values(): any /* androidNative.Array*/; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzht { + public static class: java.lang.Class; + public static values(): any /* androidNative.Array*/; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzhu { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzhu interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { + zzb(param0: number, param1: boolean): void; + zzc(param0: number, param1: java.util.List, param2: boolean): void; + zzd(param0: number, param1: any /* com.google.android.gms.internal.play_billing.zzei*/): void; + zze(param0: number, param1: java.util.List): void; + zzf(param0: number, param1: number): void; + zzg(param0: number, param1: java.util.List, param2: boolean): void; + zzh(param0: number): void; + zzi(param0: number, param1: number): void; + zzj(param0: number, param1: java.util.List, param2: boolean): void; + zzk(param0: number, param1: number): void; + zzl(param0: number, param1: java.util.List, param2: boolean): void; + zzm(param0: number, param1: number): void; + zzn(param0: number, param1: java.util.List, param2: boolean): void; + zzo(param0: number, param1: number): void; + zzp(param0: number, param1: java.util.List, param2: boolean): void; + zzq(param0: number, param1: any, param2: any /* com.google.android.gms.internal.play_billing.zzgv*/): void; + zzr(param0: number, param1: number): void; + zzs(param0: number, param1: java.util.List, param2: boolean): void; + zzt(param0: number, param1: number): void; + zzu(param0: number, param1: java.util.List, param2: boolean): void; + zzv(param0: number, param1: any, param2: any /* com.google.android.gms.internal.play_billing.zzgv*/): void; + zzw(param0: number, param1: any): void; + zzx(param0: number, param1: number): void; + zzy(param0: number, param1: java.util.List, param2: boolean): void; + zzz(param0: number, param1: number): void; + zzA(param0: number, param1: java.util.List, param2: boolean): void; + zzB(param0: number, param1: number): void; + zzC(param0: number, param1: java.util.List, param2: boolean): void; + zzD(param0: number, param1: number): void; + zzE(param0: number, param1: java.util.List, param2: boolean): void; + zzF(param0: number): void; + zzG(param0: number, param1: string): void; + zzH(param0: number, param1: java.util.List): void; + zzI(param0: number, param1: number): void; + zzJ(param0: number, param1: java.util.List, param2: boolean): void; + zzK(param0: number, param1: number): void; + zzL(param0: number, param1: java.util.List, param2: boolean): void; + }); + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzhv extends com.google.android.gms.internal.play_billing.zzfe implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzhw { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzhx extends com.google.android.gms.internal.play_billing.zzfi implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzhy extends com.google.android.gms.internal.play_billing.zzfl { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzhz extends com.google.android.gms.internal.play_billing.zzfe implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzi { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzia { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzib extends com.google.android.gms.internal.play_billing.zzfi implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzic extends com.google.android.gms.internal.play_billing.zzfe implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzid extends com.google.android.gms.internal.play_billing.zzfl { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzie implements com.google.android.gms.internal.play_billing.zzfk { + public static class: java.lang.Class; + public static values(): any /* androidNative.Array*/; + public toString(): string; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzif { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzig extends com.google.android.gms.internal.play_billing.zzfi implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzih extends com.google.android.gms.internal.play_billing.zzfe implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzii { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzij extends com.google.android.gms.internal.play_billing.zzfi implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzik extends com.google.android.gms.internal.play_billing.zzfl { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzil implements com.google.android.gms.internal.play_billing.zzfk { + public static class: java.lang.Class; + public static values(): any /* androidNative.Array*/; + public toString(): string; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzim extends com.google.android.gms.internal.play_billing.zzfe implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzin extends com.google.android.gms.internal.play_billing.zzfl { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzio { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzip extends com.google.android.gms.internal.play_billing.zzfi implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zziq extends com.google.android.gms.internal.play_billing.zzfe implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzir { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzis extends com.google.android.gms.internal.play_billing.zzfi implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzit extends com.google.android.gms.internal.play_billing.zzfe implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zziu { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zziv extends com.google.android.gms.internal.play_billing.zzfi implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zziw extends com.google.android.gms.internal.play_billing.zzfe implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzix extends com.google.android.gms.internal.play_billing.zzfl { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zziy { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zziz extends com.google.android.gms.internal.play_billing.zzfi implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzj extends com.google.android.gms.internal.play_billing.zzd { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzja extends com.google.android.gms.internal.play_billing.zzfe implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzjb extends com.google.android.gms.internal.play_billing.zzfe implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzjc extends com.google.android.gms.internal.play_billing.zzfl { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzjd extends com.google.android.gms.internal.play_billing.zzfi implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzje { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzjf extends com.google.android.gms.internal.play_billing.zzfi implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzjg extends com.google.android.gms.internal.play_billing.zzfe implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzjh { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzji extends com.google.android.gms.internal.play_billing.zzfi implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzjj extends com.google.android.gms.internal.play_billing.zzfe implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzjk { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzjl extends com.google.android.gms.internal.play_billing.zzfi implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzjm extends com.google.android.gms.internal.play_billing.zzfe implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzjn { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzjo extends com.google.android.gms.internal.play_billing.zzfi implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzjp extends com.google.android.gms.internal.play_billing.zzfe implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzjq extends com.google.android.gms.internal.play_billing.zzfl { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzjr { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzjs extends com.google.android.gms.internal.play_billing.zzfi implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzjt extends com.google.android.gms.internal.play_billing.zzfe implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzju { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzjv extends com.google.android.gms.internal.play_billing.zzfi implements com.google.android.gms.internal.play_billing.zzgm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzk { + public static class: java.lang.Class; + public run(): void; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzl extends com.google.android.gms.internal.play_billing.zzd { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzm { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzn { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzo extends com.google.android.gms.internal.play_billing.zzcz { + public static class: java.lang.Class; + public get(): any; + public constructor(); + public cancel(param0: boolean): boolean; + public get(param0: number, param1: java.util.concurrent.TimeUnit): any; + public isCancelled(): boolean; + public isDone(): boolean; + public toString(): string; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzp { + public static class: java.lang.Class; + public finalize(): void; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzq { + public static class: java.lang.Class; + public fillInStackTrace(): java.lang.Throwable; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzr { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzr interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { zza(param0: any /* com.google.android.gms.internal.play_billing.zzp*/): any }); + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzs extends com.google.android.gms.internal.play_billing.zzo { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzt extends com.google.android.gms.internal.play_billing.zzcz { + public static class: java.lang.Class; + public get(): any; + public cancel(param0: boolean): boolean; + public get(param0: number, param1: java.util.concurrent.TimeUnit): any; + public isCancelled(): boolean; + public isDone(): boolean; + public toString(): string; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzu { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzv extends com.google.android.gms.internal.play_billing.zzo { + public static class: java.lang.Class; + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzw extends com.google.android.gms.internal.play_billing.zzaq implements com.google.android.gms.internal.play_billing.zzx { + public static class: java.lang.Class; + public constructor(); + public constructor(param0: string); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzx { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzx interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { zza(param0: globalAndroid.os.Bundle): void }); + public constructor(); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export abstract class zzy extends com.google.android.gms.internal.play_billing.zzaq implements com.google.android.gms.internal.play_billing.zzz { + public static class: java.lang.Class; + public constructor(); + public constructor(param0: string); + } + } + } + } + } + } +} + +declare module com { + export module google { + export module android { + export module gms { + export module internal { + export module play_billing { + export class zzz { + public static class: java.lang.Class; + /** + * Constructs a new instance of the com.google.android.gms.internal.play_billing.zzz interface with the provided implementation. An empty constructor exists calling super() when extending the interface class. + */ + public constructor(implementation: { zza(param0: globalAndroid.os.Bundle): void }); + public constructor(); + } + } + } + } + } + } +} + +//Generics information: +//com.google.android.gms.internal.play_billing.zzcj:1 +//com.google.android.gms.internal.play_billing.zzcj.zzb:1 +//com.google.android.gms.internal.play_billing.zzcj.zze:1 +//com.google.android.gms.internal.play_billing.zzck:1 +//com.google.android.gms.internal.play_billing.zzcz:1 +//com.google.android.gms.internal.play_billing.zzdr:2 +//com.google.android.gms.internal.play_billing.zzds:2 +//com.google.android.gms.internal.play_billing.zzfe:2 +//com.google.android.gms.internal.play_billing.zzfi:2 +//com.google.android.gms.internal.play_billing.zzgo:1 +//com.google.android.gms.internal.play_billing.zzgv:1 diff --git a/packages/payments/typings/objc!NSCPayments.d.ts b/packages/payments/typings/objc!NSCPayments.d.ts new file mode 100644 index 0000000..5fd5876 --- /dev/null +++ b/packages/payments/typings/objc!NSCPayments.d.ts @@ -0,0 +1,149 @@ +declare class NSCPayments extends NSObject { + static alloc(): NSCPayments; // inherited from NSObject + + static isSupported(): boolean; + + static new(): NSCPayments; // inherited from NSObject + + isRestoring: boolean; + + pendingTasks: NSArray; + + previousPurcahses: NSArray; + + transactionUpdateListener: (p1: NSCTransaction) => void; + + updatesListener: any; + + readonly version: NSCPaymentsStoreKitVersion; + + canMakePayments(): boolean; + + fetchProducts(identifiers: NSArray | string[], callback: (p1: NSArray, p2: NSError) => void): void; + + fetchPurchases(callback: (p1: NSArray, p2: NSCPaymentsResponse) => void): void; + + purchaseProduct(product: NSCProduct, confirmIn: UIViewController, callback: (p1: NSCPaymentsResponse) => void): void; +} + +declare class NSCPaymentsResponse extends NSObject { + static alloc(): NSCPaymentsResponse; // inherited from NSObject + + static new(): NSCPaymentsResponse; // inherited from NSObject + + readonly code: NSCPaymentsResponseFailure; + + readonly message: string; + + readonly resolution: string; + + constructor(o: { code: NSCPaymentsResponseFailure; message: string; resolution: string }); + + initWithCodeMessageResolution(code: NSCPaymentsResponseFailure, message: string, resolution: string): this; +} + +declare const enum NSCPaymentsResponseFailure { + ProductUnavailable = 0, + + DeveloperUsage = 1, + + ProductAlreadyOwned = 2, + + ProductNotOwned = 3, + + UserCancelled = 4, + + NetworkAvailability = 5, + + BillingAvailability = 6, + + Unspecified = 7, + + PurchaseNotAllowed = 8, + + DeferredPayment = 9, + + Error = 10, +} + +declare const enum NSCPaymentsStoreKitVersion { + V1 = 0, + + V2 = 1, +} + +declare class NSCProduct extends NSObject { + static alloc(): NSCProduct; // inherited from NSObject + + static new(): NSCProduct; // inherited from NSObject + + readonly displayName: string; + + readonly id: string; + + readonly isFamilyShareable: boolean; + + readonly price: number; + + readonly priceCurrencyCode: string; + + readonly priceFormatted: string; + + readonly product: any; + + readonly productIdentifier: string; + + readonly receiptToken: string; + + readonly v1: SKProduct; + + readonly type: string; + + readonly version: NSCPaymentsStoreKitVersion; + + constructor(o: { product: any }); + + initWithProduct(product: any, version: NSCPaymentsStoreKitVersion): this; +} + +declare class NSCTransaction extends NSObject { + static alloc(): NSCTransaction; // inherited from NSObject + + static new(): NSCTransaction; // inherited from NSObject + + readonly error: NSError; + + errorValue: NSError; + + readonly orderId: string; + + readonly productId: string; + + readonly quantity: number; + + readonly orderDate: Date?; + + readonly receipt: string; + + readonly state: NSCTransactionState; + + transaction: any; + + readonly v1: SKPaymentTransaction; + + readonly version: NSCPaymentsStoreKitVersion; + + constructor(o: { transaction: any }); + + finish(callback: (p1: NSCPaymentsResponse) => void): void; + + initWithTransaction(transaction: any, version: NSCPaymentsStoreKitVersion): this; +} + +declare const enum NSCTransactionState { + Unknown = 0, + + Purchased = 1, + + Pending = 2, +} From 084b582e582d4d21ecee70bfd9d04799669a8344 Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Tue, 12 Aug 2025 14:15:19 -0400 Subject: [PATCH 02/34] chore(payments): clean up --- packages/payments/common.ts | 267 ----------------------------- packages/payments/index.android.ts | 6 +- packages/payments/index.ios.ts | 6 +- 3 files changed, 7 insertions(+), 272 deletions(-) delete mode 100644 packages/payments/common.ts diff --git a/packages/payments/common.ts b/packages/payments/common.ts deleted file mode 100644 index 36cae8c..0000000 --- a/packages/payments/common.ts +++ /dev/null @@ -1,267 +0,0 @@ -import { Utils } from '@nativescript/core'; -import { ConnectableObservable, Observable, ReplaySubject } from 'rxjs'; -import { publish } from 'rxjs/operators'; -import { Failure } from './failure'; -import { Item } from './item'; -import { Order } from './order'; - -export function toMainThread() { - return (source: Observable) => - new Observable((observer) => - source.subscribe({ - next: (x) => Utils.executeOnMainThread(() => observer.next(x)), - error: (err) => Utils.executeOnMainThread(() => observer.error(err)), - complete: () => Utils.executeOnMainThread(() => observer.complete()), - }) - ); -} - -export namespace PaymentEvent { - export enum Context { - CONNECTING_STORE = 'CONNECTING_STORE', - RETRIEVING_ITEMS = 'RETRIEVING_ITEMS', - PROCESSING_ORDER = 'PROCESSING_ORDER', - FINALIZING_ORDER = 'FINALIZING_ORDER', - RESTORING_ORDERS = 'RESTORING_ORDERS', - } - - export enum Result { - STARTED = 'STARTED', - PENDING = 'PENDING', - SUCCESS = 'SUCCESS', - FAILURE = 'FAILURE', - } - - type IPayload = Failure | Item | Order | Array | Array | number | null; - - interface IEvent { - context: Context; - result: Result; - payload: IPayload; - } - - /** - * Connecting Store Events - */ - export namespace ConnectingStore { - interface IConnectingStoreEvent extends IEvent { - context: Context.CONNECTING_STORE; - payload: null | Failure; - } - - export interface IStarted extends IConnectingStoreEvent { - result: Result.STARTED; - payload: null; - } - - export interface IPending extends IConnectingStoreEvent { - result: Result.PENDING; - payload: null; - } - - export interface ISuccess extends IConnectingStoreEvent { - result: Result.SUCCESS; - payload: null; - } - - export interface IFailure extends IConnectingStoreEvent { - result: Result.FAILURE; - payload: Failure; - } - } - - export type ConnectingStore = ConnectingStore.IStarted | ConnectingStore.IPending | ConnectingStore.ISuccess | ConnectingStore.IFailure; - - /** - * Retrieving Items Events - */ - export namespace RetrievingItems { - interface IRetrievingItemsEvent extends IEvent { - context: Context.RETRIEVING_ITEMS; - payload: Array | Array | Failure; - } - - export interface IStarted extends IRetrievingItemsEvent { - result: Result.STARTED; - payload: Array; - } - - export interface IPending extends IRetrievingItemsEvent { - result: Result.PENDING; - payload: Array; - } - - export interface ISuccess extends IRetrievingItemsEvent { - result: Result.SUCCESS; - payload: Array; - } - - export interface IFailure extends IRetrievingItemsEvent { - result: Result.FAILURE; - payload: Failure; - } - } - - export type RetrievingItems = RetrievingItems.IStarted | RetrievingItems.IPending | RetrievingItems.ISuccess | RetrievingItems.IFailure; - - /** - * Processing Order Events - */ - export namespace ProcessingOrder { - interface IProcessingOrderEvent extends IEvent { - context: Context.PROCESSING_ORDER; - payload: Item | number | Order | Failure; - } - - export interface IStarted extends IProcessingOrderEvent { - result: Result.STARTED; - payload: Item; - } - - export interface IPending extends IProcessingOrderEvent { - result: Result.PENDING; - payload: number; - } - - export interface ISuccess extends IProcessingOrderEvent { - result: Result.SUCCESS; - payload: Order; - } - - export interface IFailure extends IProcessingOrderEvent { - result: Result.FAILURE; - payload: Failure; - } - } - - export type ProcessingOrder = ProcessingOrder.IStarted | ProcessingOrder.IPending | ProcessingOrder.ISuccess | ProcessingOrder.IFailure; - - /** - * Finalizing Order Events - */ - export namespace FinalizingOrder { - interface IFinalizingOrderEvent extends IEvent { - context: Context.FINALIZING_ORDER; - payload: Order | Failure; - } - - export interface IStarted extends IFinalizingOrderEvent { - result: Result.STARTED; - payload: Order; - } - - export interface IPending extends IFinalizingOrderEvent { - result: Result.PENDING; - payload: Order; - } - - export interface ISuccess extends IFinalizingOrderEvent { - result: Result.SUCCESS; - payload: Order; - } - - export interface IFailure extends IFinalizingOrderEvent { - result: Result.FAILURE; - payload: Failure; - } - } - - export type FinalizingOrder = FinalizingOrder.IStarted | FinalizingOrder.IPending | FinalizingOrder.ISuccess | FinalizingOrder.IFailure; - - /** - * Restoring Orders Events - */ - export namespace RestoringOrders { - interface IRestoringOrdersEvent extends IEvent { - context: Context.RESTORING_ORDERS; - payload: null | Order | Failure; - } - - export interface IStarted extends IRestoringOrdersEvent { - result: Result.STARTED; - payload: null; - } - - export interface IPending extends IRestoringOrdersEvent { - result: Result.PENDING; - payload: Order; - } - - export interface ISuccess extends IRestoringOrdersEvent { - result: Result.SUCCESS; - payload: null; - } - - export interface IFailure extends IRestoringOrdersEvent { - result: Result.FAILURE; - payload: Failure; - } - } - - export type RestoringOrders = RestoringOrders.IStarted | RestoringOrders.IPending | RestoringOrders.ISuccess | RestoringOrders.IFailure; - - export type Type = ConnectingStore | RetrievingItems | ProcessingOrder | FinalizingOrder | RestoringOrders; -} - -// TODO publishReplay and regular Subject instead? -/** - * @private DO NOT USE! - */ -export const _payments$: ReplaySubject = new ReplaySubject(128); - -/** - * ConnectableObservable to receive results and events - * @deprecated - Use paymentEvents instead. - */ -export const payments$: ConnectableObservable = >_payments$.pipe(publish()); - -/** - * ConnectableObservable to receive results and events - */ -export const paymentEvents = payments$; - -export interface BuyItemOptions { - /** - * A string that associates the payment transaction with a user on your own service. - */ - accountUserName?: string; - android?: { - /** - * Specifies an optional obfuscated string that is uniquely associated with the user's account in your app. - */ - obfuscatedAccountId?: string; - - /** - * Specifies an optional obfuscated string that is uniquely associated with the user's profile in your app. - */ - obfuscatedProfileId?: string; - }; - ios?: { - /** - * A string that identifies a product that can be purchased from within your app. - */ - productIdentifier?: string; - - /** - * A Boolean value that produces an “ask to buy” flow for this payment in the sandbox. - */ - simulatesAskToBuyInSandbox?: boolean; - - /** - * The number of items the user wants to purchase. - */ - quantity?: number; - }; -} - -// const _storeConnecting$: Subject = new Subject(); -// const _itemsRetrieving$: Subject = new Subject(); -// const _orderProcessing$: Subject = new Subject(); -// const _orderFinalizing$: Subject = new Subject(); -// const _ordersRestoring$: Subject = new Subject(); -// -// export const storeConnecting$: Observable = _storeConnecting$.asObservable(); -// export const itemsRetrieving$: Observable = _itemsRetrieving$.asObservable(); -// export const orderProcessing$: Observable = _orderProcessing$.asObservable(); -// export const orderFinalizing$: Observable = _orderFinalizing$.asObservable(); -// export const ordersRestoring$: Observable = _ordersRestoring$.asObservable(); diff --git a/packages/payments/index.android.ts b/packages/payments/index.android.ts index f905a60..d60d1ab 100644 --- a/packages/payments/index.android.ts +++ b/packages/payments/index.android.ts @@ -98,10 +98,12 @@ export class Transaction { toJSON() { return { - json: this.json, + orderId: this.orderId, + productId: this.productId, + orderDate: this.orderDate, + receiptToken: this.receiptToken, signature: this.signature, quantity: this.quantity, - orderId: this.orderId, state: this.state, }; } diff --git a/packages/payments/index.ios.ts b/packages/payments/index.ios.ts index aeea951..b13c3d6 100644 --- a/packages/payments/index.ios.ts +++ b/packages/payments/index.ios.ts @@ -1,7 +1,5 @@ import { Utils } from '@nativescript/core'; -export { PaymentEvent, paymentEvents, payments$, toMainThread } from './common'; - export class PaymentError extends Error { private nativeError: NSCPaymentsResponse; constructor(message: string, nativeError?: any) { @@ -95,10 +93,12 @@ export class Transaction { toJSON() { return { + orderId: this.orderId, + productId: this.productId, + orderDate: this.orderDate, receiptToken: this.receiptToken, signature: this.signature, quantity: this.quantity, - orderId: this.orderId, state: this.state, }; } From 3687e900cb91aba550ed703eb418655a5a81937e Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Tue, 12 Aug 2025 14:15:34 -0400 Subject: [PATCH 03/34] chore(payments): bump From 50a75a44dc00297163336d73e84a007d66f16974 Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Tue, 12 Aug 2025 16:07:01 -0400 Subject: [PATCH 04/34] fix(payments): purchase options --- packages/payments/index.android.ts | 22 ++++++++- packages/payments/index.d.ts | 15 ++++++ packages/payments/index.ios.ts | 23 ++++++++- .../platforms/ios/src/NSCPayment.swift | 47 +++++++++++++++++-- .../payments/typings/objc!NSCPayments.d.ts | 13 ++++- 5 files changed, 110 insertions(+), 10 deletions(-) diff --git a/packages/payments/index.android.ts b/packages/payments/index.android.ts index d60d1ab..5d17116 100644 --- a/packages/payments/index.android.ts +++ b/packages/payments/index.android.ts @@ -1,4 +1,5 @@ import { Utils } from '@nativescript/core'; +import type { PurchaseOptions } from '.'; declare const kotlin: any; export class PaymentError extends Error { @@ -269,9 +270,26 @@ export class Payment { }); } - purchaseProduct(product: Product): Promise { + purchaseProduct(product: Product, options: PurchaseOptions | null | undefined = null): Promise { return new Promise((resolve, reject) => { - const response = this.native.purchaseProduct(Utils.android.getCurrentActivity(), product.native); + const opts = new org.nativescript.plugins.payments.Payments.PurchaseOptions(); + if (options && typeof options === 'object') { + if ('accountId' in options) { + opts.setAccountId(options.accountId); + } + if (options.android && typeof options.android === 'object') { + if ('accountId' in options.android) { + opts.setAccountId(options.android.accountId); + } + if ('profileId' in options.android) { + opts.setProfileId(options.android.profileId); + } + if ('isOfferPersonalized' in options.android) { + opts.setSetIsOfferPersonalized(options.android.isOfferPersonalized); + } + } + } + const response = this.native.purchaseProduct(Utils.android.getCurrentActivity(), product.native, opts); const code = response.getCode(); if (code === 0) { resolve(); diff --git a/packages/payments/index.d.ts b/packages/payments/index.d.ts index 73a9505..33aadf8 100644 --- a/packages/payments/index.d.ts +++ b/packages/payments/index.d.ts @@ -1,8 +1,23 @@ +export interface PurchaseOptions { + accountId?: string; + android?: { + accountId?: string; + profileId?: string; + isOfferPersonalized?: boolean; + }; + ios?: { + quantity?: number; + simulatesAskToBuyInSandbox?: boolean; + accountId?: any /* NSUUID */; + }; +} + export class Payment { onReady?: () => void; onPurchaseUpdate?: (purchases: Array, error: Error | null) => void; fetchProducts(itemIds: Array, type: 'inapp' | 'subs'): Promise>; purchaseProduct(product: Product): Promise; + purchaseProduct(product: Product, options: PurchaseOptions | null | undefined): Promise; fetchPurchases(): Promise>; static isSupported(): boolean; diff --git a/packages/payments/index.ios.ts b/packages/payments/index.ios.ts index b13c3d6..ec10758 100644 --- a/packages/payments/index.ios.ts +++ b/packages/payments/index.ios.ts @@ -1,4 +1,5 @@ import { Utils } from '@nativescript/core'; +import type { PurchaseOptions } from '.'; export class PaymentError extends Error { private nativeError: NSCPaymentsResponse; @@ -234,9 +235,27 @@ export class Payment { }); } - purchaseProduct(product: Product): Promise { + purchaseProduct(product: Product, options?: PurchaseOptions | null | undefined): Promise { return new Promise((resolve, reject) => { - const response = this.native.purchaseProduct(product.native, Utils.ios.getVisibleViewController(Utils.ios.getRootViewController()), (response) => { + const opts: NSCPurchaseOptions = NSCPurchaseOptions.new(); + if (options && typeof options === 'object') { + if (options.accountId) { + opts.accountId = options.accountId; + } + if (options.ios && typeof options.ios === 'object') { + if ('quantity' in options.ios) { + opts.quantity = options.ios.quantity; + } + if ('simulatesAskToBuyInSandbox' in options.ios) { + opts.simulatesAskToBuyInSandbox = options.ios.simulatesAskToBuyInSandbox; + } + + if ('accountId' in options.ios && options.ios.accountId instanceof NSUUID) { + opts.accountUUID = options.ios.accountId; + } + } + } + this.native.purchaseProduct(product.native, Utils.ios.getVisibleViewController(Utils.ios.getRootViewController()), opts, (response) => { if (response) { reject(new PaymentError(response.message, response)); } diff --git a/packages/payments/platforms/ios/src/NSCPayment.swift b/packages/payments/platforms/ios/src/NSCPayment.swift index dd8ac91..c9da7ce 100644 --- a/packages/payments/platforms/ios/src/NSCPayment.swift +++ b/packages/payments/platforms/ios/src/NSCPayment.swift @@ -431,6 +431,15 @@ public class NSCPaymentsResponse: NSObject { } } +@objc(NSCPurchaseOptions) +@objcMembers +public class NSCPurchaseOptions: NSObject { + public var accountId: String? + public var accountUUID: UUID? + public var quantity: Int = 1 + public var simulatesAskToBuyInSandbox: Bool = false +} + @objc(NSCPayments) @objcMembers public class NSCPayments: NSObject { @@ -585,25 +594,53 @@ public class NSCPayments: NSObject { } } - public func purchaseProduct(_ product: NSCProduct, _ confirmIn: UIViewController, _ callback: @escaping (NSCPaymentsResponse?)->Void){ + public func purchaseProduct(_ product: NSCProduct, _ confirmIn: UIViewController, _ options: NSCPurchaseOptions?, _ callback: @escaping (NSCPaymentsResponse?)->Void){ switch(version){ case .v1: - let payment = SKPayment(product: product.v1!) + let payment = SKMutablePayment(product: product.v1!) + if let options = options { + if let accountId = options.accountId { + payment.applicationUsername = accountId + } + payment.quantity = options.quantity + payment.simulatesAskToBuyInSandbox = options.simulatesAskToBuyInSandbox + } + + SKPaymentQueue.default().add(payment) break case .v2: Task { do { if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { + var opts: Set = [] + + if let options = options { + var id: UUID? = nil + if let accountId = options.accountId { + id = UUID(uuidString: accountId) + } + if let accountUUID = options.accountUUID { + id = accountUUID + } + if let id = id { + opts.insert(.appAccountToken(id)) + } + + opts.insert(.quantity(options.quantity)) + opts.insert(.simulatesAskToBuyInSandbox(options.simulatesAskToBuyInSandbox)) + + } + var result: Product.PurchaseResult if #available(iOS 18.2, *) { if let scene = await confirmIn.view.window?.windowScene { - result = try await product.v2!.purchase(confirmIn: scene) + result = try await product.v2!.purchase(confirmIn: scene, options: opts) }else { - result = try await product.v2!.purchase() + result = try await product.v2!.purchase(options: opts) } }else { - result = try await product.v2!.purchase() + result = try await product.v2!.purchase(options: opts) } switch result { diff --git a/packages/payments/typings/objc!NSCPayments.d.ts b/packages/payments/typings/objc!NSCPayments.d.ts index 5fd5876..b86ccf1 100644 --- a/packages/payments/typings/objc!NSCPayments.d.ts +++ b/packages/payments/typings/objc!NSCPayments.d.ts @@ -23,7 +23,7 @@ declare class NSCPayments extends NSObject { fetchPurchases(callback: (p1: NSArray, p2: NSCPaymentsResponse) => void): void; - purchaseProduct(product: NSCProduct, confirmIn: UIViewController, callback: (p1: NSCPaymentsResponse) => void): void; + purchaseProduct(product: NSCProduct, confirmIn: UIViewController, options: NSCPurchaseOptions, callback: (p1: NSCPaymentsResponse) => void): void; } declare class NSCPaymentsResponse extends NSObject { @@ -106,6 +106,17 @@ declare class NSCProduct extends NSObject { initWithProduct(product: any, version: NSCPaymentsStoreKitVersion): this; } +declare class NSCPurchaseOptions extends NSObject { + static alloc(): NSCPurchaseOptions; // inherited from NSObject + + static new(): NSCPurchaseOptions; // inherited from NSObject + + accountId: string; + accountUUID: NSUUID; + quantity: number; + simulatesAskToBuyInSandbox: Bool = false; +} + declare class NSCTransaction extends NSObject { static alloc(): NSCTransaction; // inherited from NSObject From 3b5f1cde5593e724adbfe4461178d2f5f29e3d19 Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Tue, 12 Aug 2025 16:07:16 -0400 Subject: [PATCH 05/34] chore(payments): bump --- packages/payments/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/payments/package.json b/packages/payments/package.json index d2bb0b0..6db4e1d 100644 --- a/packages/payments/package.json +++ b/packages/payments/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/payments", - "version": "4.0.0-alpha.0", + "version": "4.0.0-alpha.1", "description": "In-App Purchase and Subscriptions for NativeScript", "main": "index", "typings": "index.d.ts", From f9e3ffd8f51fbc11900ec194e1bb340c7badb95f Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Tue, 12 Aug 2025 17:05:37 -0400 Subject: [PATCH 06/34] fix(payment): isReady --- .../java/org/nativescript/plugins/payments/Payments.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Payments.kt b/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Payments.kt index ca67708..64a0892 100644 --- a/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Payments.kt +++ b/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Payments.kt @@ -102,10 +102,10 @@ class Payments(context: Context) { override fun onBillingSetupFinished(p0: BillingResult) { isSetup = p0.responseCode == BillingClient.BillingResponseCode.OK if (!this@Payments.isReady) { + this@Payments.isReady = true onReadyListener?.let { it() } - this@Payments.isReady = true } } }) @@ -122,10 +122,10 @@ class Payments(context: Context) { override fun onBillingSetupFinished(p0: BillingResult) { isSetup = p0.responseCode == BillingClient.BillingResponseCode.OK if (!this@Payments.isReady) { + this@Payments.isReady = true onReadyListener?.let { it() } - this@Payments.isReady = true } } }) From e57a3eae37f5ca63f6b03107bcceed9be5a950e0 Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Tue, 12 Aug 2025 17:07:07 -0400 Subject: [PATCH 07/34] fix(payment): clone --- packages/payments/index.android.ts | 3 +++ packages/payments/index.ios.ts | 3 +++ 2 files changed, 6 insertions(+) diff --git a/packages/payments/index.android.ts b/packages/payments/index.android.ts index 5d17116..a74180f 100644 --- a/packages/payments/index.android.ts +++ b/packages/payments/index.android.ts @@ -158,7 +158,10 @@ export class Product { name: this.name, description: this.description, title: this.title, + localizedTitle: this.localizedTitle, type: this.type, + priceFormatted: this.priceFormatted, + priceAmountMicros: this.priceAmountMicros, }; } } diff --git a/packages/payments/index.ios.ts b/packages/payments/index.ios.ts index ec10758..f4fea11 100644 --- a/packages/payments/index.ios.ts +++ b/packages/payments/index.ios.ts @@ -154,6 +154,9 @@ export class Product { description: this.description, title: this.title, type: this.type, + localizedTitle: this.localizedTitle, + priceFormatted: this.priceFormatted, + priceAmountMicros: this.priceAmountMicros, }; } } From fd73943da3a457cbe7bcd20c23ee95ad1fa73e74 Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Tue, 12 Aug 2025 17:07:43 -0400 Subject: [PATCH 08/34] chore(payments): bump --- packages/payments/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/payments/package.json b/packages/payments/package.json index 6db4e1d..c2dcb9b 100644 --- a/packages/payments/package.json +++ b/packages/payments/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/payments", - "version": "4.0.0-alpha.1", + "version": "4.0.0-alpha.2", "description": "In-App Purchase and Subscriptions for NativeScript", "main": "index", "typings": "index.d.ts", From b0c9a7074d78d420913faec1eecc03f826f4e079 Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Tue, 12 Aug 2025 18:13:22 -0400 Subject: [PATCH 09/34] feat(payments): Transaction type --- packages/payments/index.android.ts | 26 +++++++++- packages/payments/index.d.ts | 6 ++- packages/payments/index.ios.ts | 9 ++++ .../platforms/ios/src/NSCPayment.swift | 51 ++++++++++++++++--- packages/payments/typings/android.d.ts | 1 + .../payments/typings/objc!NSCPayments.d.ts | 2 + 6 files changed, 84 insertions(+), 11 deletions(-) diff --git a/packages/payments/index.android.ts b/packages/payments/index.android.ts index a74180f..f3b319f 100644 --- a/packages/payments/index.android.ts +++ b/packages/payments/index.android.ts @@ -70,6 +70,10 @@ export class Transaction { return new Date(this.native.getOrderDate()); } + get isAcknowledged(): boolean { + return this.native.isAcknowledged(); + } + get state(): 'pending' | 'purchased' | 'unknown' { switch (this.native.getState()) { case org.nativescript.plugins.payments.Transaction.State.Pending: @@ -81,6 +85,17 @@ export class Transaction { } } + get type(): 'inapp' | 'subs' | 'unknown' { + switch (this.native.getType()) { + case org.nativescript.plugins.payments.Product.Type.InApp: + return 'inapp'; + case org.nativescript.plugins.payments.Product.Type.Subs: + return 'subs'; + default: + return 'unknown'; + } + } + finish() { return new Promise((resolve, reject) => { this.native.finish( @@ -140,8 +155,15 @@ export class Product { return this.native.getProduct().getTitle(); } - get type(): 'inapp' | 'subs' { - return this.native.getType().getToType$payments_release() as 'inapp' | 'subs'; + get type(): 'inapp' | 'subs' | 'unknown' { + switch (this.native.getType()) { + case org.nativescript.plugins.payments.Product.Type.InApp: + return 'inapp'; + case org.nativescript.plugins.payments.Product.Type.Subs: + return 'subs'; + default: + return 'unknown'; + } } get priceFormatted(): string | null { diff --git a/packages/payments/index.d.ts b/packages/payments/index.d.ts index 33aadf8..9d37d62 100644 --- a/packages/payments/index.d.ts +++ b/packages/payments/index.d.ts @@ -42,6 +42,10 @@ export class Transaction { readonly state: 'pending' | 'purchased' | 'unknown'; + readonly isAcknowledged: boolean; + + readonly type: 'inapp' | 'subs' | 'unknown'; + finish(): Promise; } @@ -56,7 +60,7 @@ export class Product { readonly localizedTitle: string; - readonly type: 'inapp' | 'subs'; + readonly type: 'inapp' | 'subs' | 'unknown'; readonly priceFormatted: string | null; diff --git a/packages/payments/index.ios.ts b/packages/payments/index.ios.ts index f4fea11..2fb0db7 100644 --- a/packages/payments/index.ios.ts +++ b/packages/payments/index.ios.ts @@ -69,6 +69,10 @@ export class Transaction { return this.native.orderDate; } + get isAcknowledged(): boolean { + return this.state === 'purchased'; + } + get state(): 'pending' | 'purchased' | 'unknown' { switch (this.native.state) { case NSCTransactionState.Pending: @@ -80,6 +84,10 @@ export class Transaction { } } + get type(): 'inapp' | 'subs' | 'unknown' { + return this.native.type as never; + } + finish() { return new Promise((resolve, reject) => { this.native.finish((response) => { @@ -101,6 +109,7 @@ export class Transaction { signature: this.signature, quantity: this.quantity, state: this.state, + type: this.type, }; } } diff --git a/packages/payments/platforms/ios/src/NSCPayment.swift b/packages/payments/platforms/ios/src/NSCPayment.swift index c9da7ce..12ffea8 100644 --- a/packages/payments/platforms/ios/src/NSCPayment.swift +++ b/packages/payments/platforms/ios/src/NSCPayment.swift @@ -181,6 +181,22 @@ public class NSCTransaction: NSObject { return nil } + internal var productType = "unknown" + public var type: String { + if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { + if(version == .v2){ + switch(v2!.productType){ + case .autoRenewable, .nonRenewable: + return "sub" + default: + return "inapp" + } + } + } + + return productType + } + public func finish(_ callback: @escaping (NSCPaymentsResponse?) -> Void) { if version == .v2 && version.storeKit2Available { Task { @@ -483,11 +499,15 @@ public class NSCPayments: NSObject { func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { if(payments.isRestoring){ for transaction in transactions where transaction.transactionState == .restored { - payments.previousPurcahses.append(NSCTransaction(transaction: transaction, .v1)) + let value = NSCTransaction(transaction: transaction, .v1) + value.productType = payments.productsTypeCache[transaction.payment.productIdentifier] ?? "unknown" + payments.previousPurcahses.append(value) } }else { for transaction in transactions { - payments.transactionUpdateListener?(NSCTransaction(transaction: transaction, .v1)) + let value = NSCTransaction(transaction: transaction, .v1) + value.productType = payments.productsTypeCache[transaction.payment.productIdentifier] ?? "unknown" + payments.transactionUpdateListener?(value) } } } @@ -544,7 +564,7 @@ public class NSCPayments: NSObject { public func canMakePayments() -> Bool { return NSCPayments.isSupported() } - + private var productsTypeCache: [String: String] = [:] public func fetchProducts(_ identifiers: [String], _ callback: @escaping ([NSCProduct], Error?) -> Void) { switch(version){ case .v1: @@ -554,15 +574,31 @@ public class NSCPayments: NSObject { class SKProductsRequestDelegateImpl: NSObject, SKProductsRequestDelegate { let callback: ([NSCProduct], Error?) -> Void let version: NSCPaymentsStoreKitVersion - init(_ cb: @escaping ([NSCProduct], Error?) -> Void, _ storeVerion: NSCPaymentsStoreKitVersion){ + let payments: NSCPayments + init(_ cb: @escaping ([NSCProduct], Error?) -> Void, _ storeVerion: NSCPaymentsStoreKitVersion, _ payment: NSCPayments){ version = storeVerion callback = cb + payments = payment super .init() } func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) { - let products = response.products.map {NSCProduct(product: $0, version)} + let products = response.products.map { + + payments.productsTypeCache[$0.productIdentifier] = if #available(iOS 11.2, macOS 10.13.2, tvOS 11.2, watchOS 6.2, *){ + if($0.subscriptionPeriod != nil){ + "sub" + }else { + "inapp" + } + }else { + "unknown" + } + + + return NSCProduct(product: $0, version) + } callback( products, nil) } @@ -570,7 +606,7 @@ public class NSCPayments: NSObject { callback([], error) } } - return SKProductsRequestDelegateImpl(callback, version) + return SKProductsRequestDelegateImpl(callback, version, self) }() request.delegate = delegate @@ -652,7 +688,7 @@ public class NSCPayments: NSObject { ) break case .verified(let transaction): - transactionUpdateListener?(NSCTransaction(transaction: transaction, .v2)) + // transactionUpdateListener?(NSCTransaction(transaction: transaction, .v2)) callback(nil) break } @@ -664,7 +700,6 @@ public class NSCPayments: NSObject { break } - } }catch { callback( diff --git a/packages/payments/typings/android.d.ts b/packages/payments/typings/android.d.ts index cee3471..c3d050a 100644 --- a/packages/payments/typings/android.d.ts +++ b/packages/payments/typings/android.d.ts @@ -126,6 +126,7 @@ declare module org { public getDeveloperPayload(): string; public getOriginalJsonString(): string; public getProducts(): java.util.List; + public isAcknowledged(): boolean; } export module Transaction { export class State { diff --git a/packages/payments/typings/objc!NSCPayments.d.ts b/packages/payments/typings/objc!NSCPayments.d.ts index b86ccf1..cb80c2f 100644 --- a/packages/payments/typings/objc!NSCPayments.d.ts +++ b/packages/payments/typings/objc!NSCPayments.d.ts @@ -144,6 +144,8 @@ declare class NSCTransaction extends NSObject { readonly version: NSCPaymentsStoreKitVersion; + readonly type: string; + constructor(o: { transaction: any }); finish(callback: (p1: NSCPaymentsResponse) => void): void; From 4479e7312143e1961ddb0d3eabeaa12efafd2463 Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Tue, 12 Aug 2025 18:14:43 -0400 Subject: [PATCH 10/34] chore(payment): bump --- packages/payments/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/payments/package.json b/packages/payments/package.json index c2dcb9b..4cdb347 100644 --- a/packages/payments/package.json +++ b/packages/payments/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/payments", - "version": "4.0.0-alpha.2", + "version": "4.0.0-alpha.3", "description": "In-App Purchase and Subscriptions for NativeScript", "main": "index", "typings": "index.d.ts", From 665eed376cd76806a24ebaacef5a5cbda80445db Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Tue, 12 Aug 2025 18:17:16 -0400 Subject: [PATCH 11/34] fix(payments): isAcknowledged --- packages/payments/index.android.ts | 2 ++ packages/payments/index.ios.ts | 1 + 2 files changed, 3 insertions(+) diff --git a/packages/payments/index.android.ts b/packages/payments/index.android.ts index f3b319f..82d69ad 100644 --- a/packages/payments/index.android.ts +++ b/packages/payments/index.android.ts @@ -121,6 +121,8 @@ export class Transaction { signature: this.signature, quantity: this.quantity, state: this.state, + isAcknowledged: this.isAcknowledged, + type: this.type, }; } } diff --git a/packages/payments/index.ios.ts b/packages/payments/index.ios.ts index 2fb0db7..7501cf0 100644 --- a/packages/payments/index.ios.ts +++ b/packages/payments/index.ios.ts @@ -109,6 +109,7 @@ export class Transaction { signature: this.signature, quantity: this.quantity, state: this.state, + isAcknowledged: this.isAcknowledged, type: this.type, }; } From 5be4a1d7b8789830ba1e82b5134778d4eb0cfd2c Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Tue, 12 Aug 2025 18:17:33 -0400 Subject: [PATCH 12/34] chore(payment): bump --- packages/payments/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/payments/package.json b/packages/payments/package.json index 4cdb347..ed029d4 100644 --- a/packages/payments/package.json +++ b/packages/payments/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/payments", - "version": "4.0.0-alpha.3", + "version": "4.0.0-alpha.4", "description": "In-App Purchase and Subscriptions for NativeScript", "main": "index", "typings": "index.d.ts", From a48b638772df4e7ffb8f11649b13238c45e8524a Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Wed, 13 Aug 2025 03:59:26 -0400 Subject: [PATCH 13/34] feat(payments): isExpired, expirationDate, isRevoked & revocationDate --- packages/payments/index.android.ts | 10 + packages/payments/index.d.ts | 12 ++ packages/payments/index.ios.ts | 22 ++- packages/payments/package.json | 2 +- .../plugins/payments/Transaction.kt | 185 ++++++++++-------- packages/payments/platforms/ios/Podfile | 2 + .../platforms/ios/src/NSCPayment.swift | 147 +++++++++++--- packages/payments/typings/android.d.ts | 3 +- .../payments/typings/objc!NSCPayments.d.ts | 33 +++- 9 files changed, 295 insertions(+), 121 deletions(-) create mode 100644 packages/payments/platforms/ios/Podfile diff --git a/packages/payments/index.android.ts b/packages/payments/index.android.ts index 82d69ad..130807b 100644 --- a/packages/payments/index.android.ts +++ b/packages/payments/index.android.ts @@ -74,6 +74,10 @@ export class Transaction { return this.native.isAcknowledged(); } + get isAutoRenewing(): boolean { + return this.native.isAutoRenewing(); + } + get state(): 'pending' | 'purchased' | 'unknown' { switch (this.native.getState()) { case org.nativescript.plugins.payments.Transaction.State.Pending: @@ -96,6 +100,10 @@ export class Transaction { } } + get isExpired(): boolean { + return this.native.isExpired(); + } + finish() { return new Promise((resolve, reject) => { this.native.finish( @@ -123,6 +131,8 @@ export class Transaction { state: this.state, isAcknowledged: this.isAcknowledged, type: this.type, + isExpired: this.isExpired, + isAutoRenewing: this.isAutoRenewing, }; } } diff --git a/packages/payments/index.d.ts b/packages/payments/index.d.ts index 9d37d62..a1ac03d 100644 --- a/packages/payments/index.d.ts +++ b/packages/payments/index.d.ts @@ -46,6 +46,18 @@ export class Transaction { readonly type: 'inapp' | 'subs' | 'unknown'; + readonly isAcknowledged: boolean; + + readonly isExpired: boolean; + + readonly expirationDate: Date; + + readonly isRevoked: boolean; + + readonly revocationDate: Date; + + readonly isAutoRenewing: boolean; + finish(): Promise; } diff --git a/packages/payments/index.ios.ts b/packages/payments/index.ios.ts index 7501cf0..0dd3042 100644 --- a/packages/payments/index.ios.ts +++ b/packages/payments/index.ios.ts @@ -84,10 +84,26 @@ export class Transaction { } } - get type(): 'inapp' | 'subs' | 'unknown' { + get type(): 'inapp' | 'subs`' | 'unknown' { return this.native.type as never; } + get isExpired(): boolean { + return this.native.isExpired; + } + + get expirationDate(): Date { + return this.native.expirationDate; + } + + get isRevoked(): boolean { + return this.native.isRevoked; + } + + get revocationDate(): Date { + return this.native.revocationDate; + } + finish() { return new Promise((resolve, reject) => { this.native.finish((response) => { @@ -111,6 +127,10 @@ export class Transaction { state: this.state, isAcknowledged: this.isAcknowledged, type: this.type, + isExpired: this.isExpired, + expirationDate: this.expirationDate, + isRevoked: this.isRevoked, + revocationDate: this.revocationDate, }; } } diff --git a/packages/payments/package.json b/packages/payments/package.json index ed029d4..1173bb4 100644 --- a/packages/payments/package.json +++ b/packages/payments/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/payments", - "version": "4.0.0-alpha.4", + "version": "4.0.0-alpha.6", "description": "In-App Purchase and Subscriptions for NativeScript", "main": "index", "typings": "index.d.ts", diff --git a/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Transaction.kt b/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Transaction.kt index 99b5129..dc1aca9 100644 --- a/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Transaction.kt +++ b/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Transaction.kt @@ -8,108 +8,121 @@ import org.json.JSONObject class Transaction(val purchase: Purchase, val type: Product.Type, private val payments: Payments) { - enum class State(val value: Int) { - Unknown(-1), Purchased(1), Pending(2) - } - - val orderId: String? - get() { - return purchase.orderId + enum class State(val value: Int) { + Unknown(-1), Purchased(1), Pending(2) } - val productId: String? - get() { - return purchase.products.first() - } + val orderId: String? + get() { + return purchase.orderId + } - val orderDate: Long - get() { - return purchase.purchaseTime - } + val productId: String? + get() { + return purchase.products.first() + } - val isSubscription: Boolean - get() { - return purchase.isAutoRenewing - } + val isAcknowledged: Boolean + get() { + return purchase.isAcknowledged + } - val products: List - get() { - return purchase.products - } + val orderDate: Long + get() { + return purchase.purchaseTime + } - val quantity: Int - get() { - return purchase.quantity - } + val isAutoRenewing: Boolean + get() { + return purchase.isAutoRenewing + } - val token: String - get() { - return purchase.purchaseToken - } + val isExpired: Boolean + get() { + if (type == Product.Type.Subs) { + return !purchase.isAutoRenewing + } + return false + } - val signature: String - get() { - return purchase.signature - } + val products: List + get() { + return purchase.products + } - val state: State - get() { - return when (purchase.purchaseState) { - Purchase.PurchaseState.PURCHASED -> State.Purchased - Purchase.PurchaseState.PENDING -> State.Pending - else -> State.Unknown - } - } + val quantity: Int + get() { + return purchase.quantity + } - val developerPayload: String - get() { - return purchase.developerPayload - } + val token: String + get() { + return purchase.purchaseToken + } - val originalJsonString: String - get() { - return purchase.originalJson - } + val signature: String + get() { + return purchase.signature + } - private var json: JSONObject? = null - val originalJson: JSONObject - get() { - if (json == null) { - try { - json = JSONObject(purchase.originalJson) - } catch (_: Exception) { + val state: State + get() { + return when (purchase.purchaseState) { + Purchase.PurchaseState.PURCHASED -> State.Purchased + Purchase.PurchaseState.PENDING -> State.Pending + else -> State.Unknown + } } - } - return json ?: JSONObject() - } - fun finish(callback: (Payments.BillingResponse?) -> Unit) { - if (purchase.isAutoRenewing) { - if (purchase.isAcknowledged) { - callback(null) - return - } - val params = AcknowledgePurchaseParams.newBuilder() - .setPurchaseToken(purchase.purchaseToken) - .build() - payments.billing.acknowledgePurchase(params) { p0 -> - if (p0.responseCode == BillingClient.BillingResponseCode.OK) { - callback(null) - } else { - callback(Payments.mapResponseCode(p0.responseCode)) + val developerPayload: String + get() { + return purchase.developerPayload + } + + val originalJsonString: String + get() { + return purchase.originalJson } - } - } else { - val params = ConsumeParams.newBuilder() - .setPurchaseToken(purchase.purchaseToken) - .build() - payments.billing.consumeAsync(params) { p0, p1 -> - if (p0.responseCode == BillingClient.BillingResponseCode.OK) { - callback(null) + + private var json: JSONObject? = null + val originalJson: JSONObject + get() { + if (json == null) { + try { + json = JSONObject(purchase.originalJson) + } catch (_: Exception) { + } + } + return json ?: JSONObject() + } + + fun finish(callback: (Payments.BillingResponse?) -> Unit) { + if (purchase.isAutoRenewing) { + if (purchase.isAcknowledged) { + callback(null) + return + } + val params = AcknowledgePurchaseParams.newBuilder() + .setPurchaseToken(purchase.purchaseToken) + .build() + payments.billing.acknowledgePurchase(params) { p0 -> + if (p0.responseCode == BillingClient.BillingResponseCode.OK) { + callback(null) + } else { + callback(Payments.mapResponseCode(p0.responseCode)) + } + } } else { - callback(Payments.mapResponseCode(p0.responseCode)) + val params = ConsumeParams.newBuilder() + .setPurchaseToken(purchase.purchaseToken) + .build() + payments.billing.consumeAsync(params) { p0, p1 -> + if (p0.responseCode == BillingClient.BillingResponseCode.OK) { + callback(null) + } else { + callback(Payments.mapResponseCode(p0.responseCode)) + } + } } - } } - } } diff --git a/packages/payments/platforms/ios/Podfile b/packages/payments/platforms/ios/Podfile new file mode 100644 index 0000000..3e56775 --- /dev/null +++ b/packages/payments/platforms/ios/Podfile @@ -0,0 +1,2 @@ +platform :ios, '12.0' +pod 'TPInAppReceipt' \ No newline at end of file diff --git a/packages/payments/platforms/ios/src/NSCPayment.swift b/packages/payments/platforms/ios/src/NSCPayment.swift index 12ffea8..c6da9f4 100644 --- a/packages/payments/platforms/ios/src/NSCPayment.swift +++ b/packages/payments/platforms/ios/src/NSCPayment.swift @@ -7,7 +7,7 @@ // import UIKit import StoreKit - +import TPInAppReceipt @objc(NSCPaymentsStoreKitVersion) public enum NSCPaymentsStoreKitVersion: Int32, RawRepresentable { @@ -197,6 +197,73 @@ public class NSCTransaction: NSObject { return productType } + internal var revocationDateV1: Date? = nil + + var revocationDate: Date? { + get { + if version == .v2 && version.storeKit2Available { + if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { + return v2!.revocationDate + } + }else if version == .v1 { + return self.revocationDateV1 + } + return nil + } + } + + var isRevoked: Bool { + get { + var revocationDate: Date? = nil + if version == .v2 && version.storeKit2Available { + if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { + revocationDate = v2!.revocationDate + } + }else if version == .v1 { + revocationDate = self.revocationDateV1 + } + + if let revoked = revocationDate { + return revoked >= Date() + } + return false + } + } + + internal var expirationDateV1: Date? = nil + + var expirationDate: Date? { + get { + if version == .v2 && version.storeKit2Available { + if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { + return v2!.expirationDate + } + }else if version == .v1 { + return self.expirationDateV1 + } + return nil + } + } + + var isExpired: Bool { + get { + var expirationDate: Date? = nil + if version == .v2 && version.storeKit2Available { + if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { + expirationDate = v2!.expirationDate + } + }else { + expirationDate = expirationDateV1 + } + + if let expiration = expirationDate { + return expiration >= Date() + } + + return false + } + } + public func finish(_ callback: @escaping (NSCPaymentsResponse?) -> Void) { if version == .v2 && version.storeKit2Available { Task { @@ -465,7 +532,7 @@ public class NSCPayments: NSObject { public var transactionUpdateListener: ((NSCTransaction) -> Void)? internal var isRestoring = false internal var fetchingPurchases: [([NSCTransaction]?, NSCPaymentsResponse?) -> Void] = [] - internal var previousPurcahses: [NSCTransaction] = [] + internal var previousPurchases: [NSCTransaction] = [] public override init() { if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { version = .v2 @@ -497,16 +564,63 @@ public class NSCPayments: NSObject { } func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { + var receipt: InAppReceipt? = nil + do { + receipt = try InAppReceipt.localReceipt() + }catch {} if(payments.isRestoring){ for transaction in transactions where transaction.transactionState == .restored { let value = NSCTransaction(transaction: transaction, .v1) - value.productType = payments.productsTypeCache[transaction.payment.productIdentifier] ?? "unknown" - payments.previousPurcahses.append(value) + + if let receipt = receipt { + let purchaseInfo = receipt.activeAutoRenewableSubscriptionPurchases + .filter({ $0.transactionIdentifier == transaction.transactionIdentifier }) + .first + if let purchaseInfo = purchaseInfo { + value.expirationDateV1 = purchaseInfo.subscriptionExpirationDate + value.revocationDateV1 = purchaseInfo.cancellationDate + value.productType = switch(purchaseInfo.productType){ + case .unknown: + "unknown" + case .nonConsumable: + "inapp" + case .consumable: + "inapp" + case .nonRenewingSubscription: + "subs" + case .autoRenewableSubscription: + "subs" + } + } + } + payments.previousPurchases.append(value) } }else { for transaction in transactions { let value = NSCTransaction(transaction: transaction, .v1) - value.productType = payments.productsTypeCache[transaction.payment.productIdentifier] ?? "unknown" + if let receipt = receipt { + let purchaseInfo = receipt.activeAutoRenewableSubscriptionPurchases + .filter({ $0.transactionIdentifier == transaction.transactionIdentifier }) + .first + if let purchaseInfo = purchaseInfo { + value.expirationDateV1 = purchaseInfo.subscriptionExpirationDate + value.revocationDateV1 = purchaseInfo.cancellationDate + value.productType = switch(purchaseInfo.productType){ + case .unknown: + "unknown" + case .nonConsumable: + "inapp" + case .consumable: + "inapp" + case .nonRenewingSubscription: + "subs" + case .autoRenewableSubscription: + "subs" + } + } + } + + payments.transactionUpdateListener?(value) } } @@ -527,11 +641,11 @@ public class NSCPayments: NSObject { func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) { if(payments.isRestoring){ for callback in payments.fetchingPurchases { - callback(payments.previousPurcahses, nil) + callback(payments.previousPurchases, nil) } payments.fetchingPurchases.removeAll() - payments.previousPurcahses.removeAll() + payments.previousPurchases.removeAll() payments.isRestoring = false } } @@ -564,7 +678,6 @@ public class NSCPayments: NSObject { public func canMakePayments() -> Bool { return NSCPayments.isSupported() } - private var productsTypeCache: [String: String] = [:] public func fetchProducts(_ identifiers: [String], _ callback: @escaping ([NSCProduct], Error?) -> Void) { switch(version){ case .v1: @@ -586,17 +699,6 @@ public class NSCPayments: NSObject { func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) { let products = response.products.map { - payments.productsTypeCache[$0.productIdentifier] = if #available(iOS 11.2, macOS 10.13.2, tvOS 11.2, watchOS 6.2, *){ - if($0.subscriptionPeriod != nil){ - "sub" - }else { - "inapp" - } - }else { - "unknown" - } - - return NSCProduct(product: $0, version) } callback( products, nil) @@ -641,7 +743,7 @@ public class NSCPayments: NSObject { payment.quantity = options.quantity payment.simulatesAskToBuyInSandbox = options.simulatesAskToBuyInSandbox } - + SKPaymentQueue.default().add(payment) break @@ -650,7 +752,7 @@ public class NSCPayments: NSObject { do { if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { var opts: Set = [] - + if let options = options { var id: UUID? = nil if let accountId = options.accountId { @@ -687,8 +789,7 @@ public class NSCPayments: NSObject { NSCPaymentsResponse(code: .Error, message: "Usage error: \(verificationError.localizedDescription)", resolution: "") ) break - case .verified(let transaction): - // transactionUpdateListener?(NSCTransaction(transaction: transaction, .v2)) + case .verified(_): callback(nil) break } diff --git a/packages/payments/typings/android.d.ts b/packages/payments/typings/android.d.ts index c3d050a..6df7df9 100644 --- a/packages/payments/typings/android.d.ts +++ b/packages/payments/typings/android.d.ts @@ -118,7 +118,7 @@ declare module org { public getToken(): string; public constructor(purchase: com.android.billingclient.api.Purchase, type: org.nativescript.plugins.payments.Product.Type, payments: org.nativescript.plugins.payments.Payments); public getQuantity(): number; - public isSubscription(): boolean; + public isAutoRenewing(): boolean; public getPurchase(): com.android.billingclient.api.Purchase; public getSignature(): string; public getType(): org.nativescript.plugins.payments.Product.Type; @@ -127,6 +127,7 @@ declare module org { public getOriginalJsonString(): string; public getProducts(): java.util.List; public isAcknowledged(): boolean; + public isExpired(): boolean; } export module Transaction { export class State { diff --git a/packages/payments/typings/objc!NSCPayments.d.ts b/packages/payments/typings/objc!NSCPayments.d.ts index cb80c2f..3ce5398 100644 --- a/packages/payments/typings/objc!NSCPayments.d.ts +++ b/packages/payments/typings/objc!NSCPayments.d.ts @@ -9,7 +9,7 @@ declare class NSCPayments extends NSObject { pendingTasks: NSArray; - previousPurcahses: NSArray; + previousPurchases: NSArray; transactionUpdateListener: (p1: NSCTransaction) => void; @@ -95,10 +95,10 @@ declare class NSCProduct extends NSObject { readonly receiptToken: string; - readonly v1: SKProduct; - readonly type: string; + readonly v1: SKProduct; + readonly version: NSCPaymentsStoreKitVersion; constructor(o: { product: any }); @@ -112,9 +112,12 @@ declare class NSCPurchaseOptions extends NSObject { static new(): NSCPurchaseOptions; // inherited from NSObject accountId: string; + accountUUID: NSUUID; + quantity: number; - simulatesAskToBuyInSandbox: Bool = false; + + simulatesAskToBuyInSandbox: boolean; } declare class NSCTransaction extends NSObject { @@ -126,26 +129,38 @@ declare class NSCTransaction extends NSObject { errorValue: NSError; + readonly expirationDate: Date; + + expirationDateV1: Date; + + readonly isExpired: boolean; + + readonly isRevoked: boolean; + + readonly orderDate: Date; + readonly orderId: string; readonly productId: string; - readonly quantity: number; - - readonly orderDate: Date?; + productType: string; readonly receipt: string; + readonly revocationDate: Date; + + revocationDateV1: Date; + readonly state: NSCTransactionState; transaction: any; + readonly type: string; + readonly v1: SKPaymentTransaction; readonly version: NSCPaymentsStoreKitVersion; - readonly type: string; - constructor(o: { transaction: any }); finish(callback: (p1: NSCPaymentsResponse) => void): void; From 0f3ad784d17f2e96f99248cfd5cba9f007a20ebb Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Wed, 13 Aug 2025 04:21:02 -0400 Subject: [PATCH 14/34] fix(payments): purchaseProduct --- packages/payments/index.android.ts | 31 +- packages/payments/index.d.ts | 4 + packages/payments/index.ios.ts | 8 +- packages/payments/package.json | 2 +- .../nativescript/plugins/payments/Payments.kt | 725 +++++++++--------- packages/payments/typings/android.d.ts | 57 +- 6 files changed, 440 insertions(+), 387 deletions(-) diff --git a/packages/payments/index.android.ts b/packages/payments/index.android.ts index 130807b..8c8e4e4 100644 --- a/packages/payments/index.android.ts +++ b/packages/payments/index.android.ts @@ -247,8 +247,12 @@ export class Payment { return this.native.canMakePayments(); } - restartConnection() { - this.native.restartConnection(); + connect() { + this.native.connect(); + } + + disconnect() { + this.native.disconnect(); } fetchProducts(productIdentifiers: string[], type: 'subs' | 'inapp') { @@ -326,13 +330,22 @@ export class Payment { } } } - const response = this.native.purchaseProduct(Utils.android.getCurrentActivity(), product.native, opts); - const code = response.getCode(); - if (code === 0) { - resolve(); - } else { - reject(new PaymentError(response.getMessage(), response)); - } + + this.native.purchaseProduct( + Utils.android.getCurrentActivity(), + product.native, + opts, + new kotlin.jvm.functions.Function1({ + invoke(response: org.nativescript.plugins.payments.Payments.BillingResponse): void { + const code = response.getCode(); + if (code === 0) { + resolve(); + } else { + reject(new PaymentError(response.getMessage(), response)); + } + }, + }), + ); }); } } diff --git a/packages/payments/index.d.ts b/packages/payments/index.d.ts index a1ac03d..d84b971 100644 --- a/packages/payments/index.d.ts +++ b/packages/payments/index.d.ts @@ -23,6 +23,10 @@ export class Payment { static isSupported(): boolean; canMakePayments(): boolean; + + connect(): void; + + disconnect(): void; } export class Transaction { diff --git a/packages/payments/index.ios.ts b/packages/payments/index.ios.ts index 0dd3042..fd7ff4f 100644 --- a/packages/payments/index.ios.ts +++ b/packages/payments/index.ios.ts @@ -221,8 +221,12 @@ export class Payment { return this.native.canMakePayments(); } - restartConnection() { - // noop + connect() { + // no-op for iOS + } + + disconnect() { + // no-op for iOS } fetchProducts(productIdentifiers: string[], type: 'subs' | 'inapp') { diff --git a/packages/payments/package.json b/packages/payments/package.json index 1173bb4..7a3c617 100644 --- a/packages/payments/package.json +++ b/packages/payments/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/payments", - "version": "4.0.0-alpha.6", + "version": "4.0.0-alpha.7", "description": "In-App Purchase and Subscriptions for NativeScript", "main": "index", "typings": "index.d.ts", diff --git a/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Payments.kt b/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Payments.kt index 64a0892..2aa6ee2 100644 --- a/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Payments.kt +++ b/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Payments.kt @@ -10,6 +10,7 @@ import com.android.billingclient.api.BillingClientStateListener import com.android.billingclient.api.BillingFlowParams import com.android.billingclient.api.BillingResult import com.android.billingclient.api.PendingPurchasesParams +import com.android.billingclient.api.PurchasesUpdatedListener import com.android.billingclient.api.QueryProductDetailsParams import com.android.billingclient.api.QueryPurchasesParams import org.json.JSONObject @@ -17,129 +18,129 @@ import java.util.concurrent.CountDownLatch import java.util.concurrent.Executors class Payments(context: Context) { - private var isReady = false - private var isSetup = false - internal var billing = BillingClient.newBuilder(context).apply { - val pendingParams = PendingPurchasesParams.newBuilder() - .enablePrepaidPlans() - .enablePrepaidPlans() - .enableOneTimeProducts() - .build() - enablePendingPurchases(pendingParams) - enableAutoServiceReconnection() - setListener { response, purchases -> - { - if (response.responseCode == BillingClient.BillingResponseCode.OK && purchases != null) { - val value = purchases.map { - val json = JSONObject(it.originalJson) - Transaction( - it, if (json.optBoolean("autoRenewing", false)) { - Product.Type.Subs - } else { - Product.Type.InApp - }, this@Payments - ) - } - onPurchaseUpdateListener?.let { - it(value, null) - } - } else { - onPurchaseUpdateListener?.let { - it(null, mapResponseCode(response.responseCode)) - } - } - } + private var isReady = false + private var isSetup = false + private val purchaseListener = PurchasesUpdatedListener { response, purchases -> + { + if (response.responseCode == BillingClient.BillingResponseCode.OK && purchases != null) { + val value = purchases.map { + val json = JSONObject(it.originalJson) + Transaction( + it, if (json.optBoolean("autoRenewing", false)) { + Product.Type.Subs + } else { + Product.Type.InApp + }, this@Payments + ) + } + onPurchaseUpdateListener?.let { + it(value, null) } - }.build() - - private val executor = Executors.newCachedThreadPool() - - var onReadyListener: (() -> Unit)? = null - - var onPurchaseUpdateListener: ((List?, BillingResponse?) -> Unit)? = null - - class BillingResponse( - val code: Int, - val message: String, - val resolution: String, - val subCode: Int = Int.MAX_VALUE - ) - - enum class Features(val value: String) { - Subscriptions(BillingClient.FeatureType.SUBSCRIPTIONS), - SubscriptionsUpdate(BillingClient.FeatureType.SUBSCRIPTIONS_UPDATE), - PriceChangeConfirmation(BillingClient.FeatureType.PRICE_CHANGE_CONFIRMATION), - InAppMessaging(BillingClient.FeatureType.IN_APP_MESSAGING), - ProductDetails(BillingClient.FeatureType.PRODUCT_DETAILS), - BillingConfig(BillingClient.FeatureType.BILLING_CONFIG), - AlternativeBillingOnly(BillingClient.FeatureType.ALTERNATIVE_BILLING_ONLY), - ExternalOffer(BillingClient.FeatureType.EXTERNAL_OFFER), + } else { + onPurchaseUpdateListener?.let { + it(null, mapResponseCode(response.responseCode)) + } + } + } + } + internal var billing = BillingClient.newBuilder(context).apply { + val pendingParams = PendingPurchasesParams.newBuilder() + .enablePrepaidPlans() + .enableOneTimeProducts() + .build() + enablePendingPurchases(pendingParams) + enableAutoServiceReconnection() + setListener(purchaseListener) + }.build() + + private val executor = Executors.newCachedThreadPool() + + var onReadyListener: (() -> Unit)? = null + + var onPurchaseUpdateListener: ((List?, BillingResponse?) -> Unit)? = null + + class BillingResponse( + val code: Int, + val message: String, + val resolution: String, + val subCode: Int = Int.MAX_VALUE + ) + + enum class Features(val value: String) { + Subscriptions(BillingClient.FeatureType.SUBSCRIPTIONS), + SubscriptionsUpdate(BillingClient.FeatureType.SUBSCRIPTIONS_UPDATE), + PriceChangeConfirmation(BillingClient.FeatureType.PRICE_CHANGE_CONFIRMATION), + InAppMessaging(BillingClient.FeatureType.IN_APP_MESSAGING), + ProductDetails(BillingClient.FeatureType.PRODUCT_DETAILS), + BillingConfig(BillingClient.FeatureType.BILLING_CONFIG), + AlternativeBillingOnly(BillingClient.FeatureType.ALTERNATIVE_BILLING_ONLY), + ExternalOffer(BillingClient.FeatureType.EXTERNAL_OFFER), + } + + class PurchaseOptions { + enum class ReplacementMode(val value: Int) { + Unknown(0), + WithTimeProration(1), + ChargeProratedPrice(2), + WithoutProration(3), + ChargeFullPrice(5), + Deferred(6); } - class PurchaseOptions { - enum class ReplacementMode(val value: Int) { - Unknown(0), - WithTimeProration(1), - ChargeProratedPrice(2), - WithoutProration(3), - ChargeFullPrice(5), - Deferred(6); + var profileId: String? = null + var accountId: String? = null + var setIsOfferPersonalized = false + var subscriptionUpdateToken: String? = null + var subscriptionUpdateReplacementMode: ReplacementMode? = null + } + + init { + billing.startConnection(object : BillingClientStateListener { + override fun onBillingServiceDisconnected() { + this@Payments.isReady = false + } + + override fun onBillingSetupFinished(p0: BillingResult) { + isSetup = p0.responseCode == BillingClient.BillingResponseCode.OK + if (!this@Payments.isReady) { + this@Payments.isReady = true + onReadyListener?.let { + it() + } } + } + }) + } - var profileId: String? = null - var accountId: String? = null - var setIsOfferPersonalized = false - var subscriptionUpdateToken: String? = null - var subscriptionUpdateReplacementMode: ReplacementMode? = null - } - - init { + fun connect() { + when (billing.connectionState) { + BillingClient.ConnectionState.DISCONNECTED, BillingClient.ConnectionState.CLOSED -> { billing.startConnection(object : BillingClientStateListener { - override fun onBillingServiceDisconnected() { - this@Payments.isReady = false - } - - override fun onBillingSetupFinished(p0: BillingResult) { - isSetup = p0.responseCode == BillingClient.BillingResponseCode.OK - if (!this@Payments.isReady) { - this@Payments.isReady = true - onReadyListener?.let { - it() - } - } + override fun onBillingServiceDisconnected() { + this@Payments.isReady = false + } + + override fun onBillingSetupFinished(p0: BillingResult) { + isSetup = p0.responseCode == BillingClient.BillingResponseCode.OK + if (!this@Payments.isReady) { + this@Payments.isReady = true + onReadyListener?.let { + it() + } } + } }) - } + } - fun connect() { - when (billing.connectionState) { - BillingClient.ConnectionState.DISCONNECTED, BillingClient.ConnectionState.CLOSED -> { - billing.startConnection(object : BillingClientStateListener { - override fun onBillingServiceDisconnected() { - this@Payments.isReady = false - } - - override fun onBillingSetupFinished(p0: BillingResult) { - isSetup = p0.responseCode == BillingClient.BillingResponseCode.OK - if (!this@Payments.isReady) { - this@Payments.isReady = true - onReadyListener?.let { - it() - } - } - } - }) - } - - else -> {} - } + else -> {} } + } - fun disconnect() { - billing.endConnection() - } + fun disconnect() { + billing.endConnection() + } - fun showInAppMessaging(activity: Activity) { + fun showInAppMessaging(activity: Activity) { // val params = InAppMessageParams.newBuilder() // .apply { // addInAppMessageCategoryToShow(InAppMessageParams.InAppMessageCategoryId.TRANSACTIONAL) @@ -150,271 +151,277 @@ class Payments(context: Context) { // // } // }) - } + } - fun canMakePayments(): Boolean { - return isReady && billing.isReady - } + fun canMakePayments(): Boolean { + return isReady && billing.isReady + } - fun isFeatureSupported(feature: Features): Boolean { - if (!billing.isReady) { - return false - } - return billing.isFeatureSupported(feature.value).responseCode == BillingClient.BillingResponseCode.OK + fun isFeatureSupported(feature: Features): Boolean { + if (!billing.isReady) { + return false } - - fun fetchProducts( - identifiers: Array, - type: Product.Type, - callback: (List?, BillingResponse?) -> Unit - ) { - val products = identifiers.map { - QueryProductDetailsParams.Product.newBuilder() - .setProductType(type.toType) - .setProductId(it) - .build() - } - val params = QueryProductDetailsParams.newBuilder() - .setProductList(products) - .build() - - billing.queryProductDetailsAsync(params) { p0, p1 -> - if (p0.responseCode == BillingClient.BillingResponseCode.OK) { - val products = p1.productDetailsList.map { - Product(it) - } - callback(products, null) - } else { - callback(null, mapResponseCode(p0.responseCode)) - } + return billing.isFeatureSupported(feature.value).responseCode == BillingClient.BillingResponseCode.OK + } + + fun fetchProducts( + identifiers: Array, + type: Product.Type, + callback: (List?, BillingResponse?) -> Unit + ) { + val products = identifiers.map { + QueryProductDetailsParams.Product.newBuilder() + .setProductType(type.toType) + .setProductId(it) + .build() + } + val params = QueryProductDetailsParams.newBuilder() + .setProductList(products) + .build() + + billing.queryProductDetailsAsync(params) { p0, p1 -> + if (p0.responseCode == BillingClient.BillingResponseCode.OK) { + val products = p1.productDetailsList.map { + Product(it) } + callback(products, null) + } else { + callback(null, mapResponseCode(p0.responseCode)) + } } - - - @JvmOverloads - fun purchaseProduct( - activity: Activity, - product: Product, - options: PurchaseOptions? = null - ): BillingResponse { - val param = BillingFlowParams.ProductDetailsParams.newBuilder() - .apply { - setProductDetails(product.product) - if (product.type == Product.Type.Subs) { - product.product.subscriptionOfferDetails?.first()?.let { - setOfferToken(it.offerToken) - } - } - } - .build() - - val flow = BillingFlowParams.newBuilder() - .apply { - options?.let { - setIsOfferPersonalized(it.setIsOfferPersonalized) - it.profileId?.let { id -> - setObfuscatedProfileId(id) - } - - it.accountId?.let { id -> - setObfuscatedAccountId(id) - } - - it.subscriptionUpdateToken?.let { token -> - val params = BillingFlowParams.SubscriptionUpdateParams.newBuilder() - .apply { - it.subscriptionUpdateReplacementMode?.let { mode -> - setSubscriptionReplacementMode(mode.value) - } - } - .setOldPurchaseToken(token) - .build() - - setSubscriptionUpdateParams(params) - } - } - setProductDetailsParamsList(listOf(param)) - } - .build() - - val response = billing.launchBillingFlow(activity, flow) - - if (response.responseCode != BillingClient.BillingResponseCode.OK) { - return when (response.onPurchasesUpdatedSubResponseCode) { - BillingClient.OnPurchasesUpdatedSubResponseCode.PAYMENT_DECLINED_DUE_TO_INSUFFICIENT_FUNDS -> { - BillingResponse( - Int.MAX_VALUE, - "The payment was declined due to insufficient funds.", - "The user must either add funds/increase limits or retry the transaction with a different payment method", - response.onPurchasesUpdatedSubResponseCode - ) - } - - BillingClient.OnPurchasesUpdatedSubResponseCode.USER_INELIGIBLE -> { - BillingResponse( - Int.MAX_VALUE, - "the user does not currently meet offer eligibility requirements.", - "This offer isn’t available in your region or for your account type.”", - response.onPurchasesUpdatedSubResponseCode - ) + } + + + @JvmOverloads + fun purchaseProduct( + activity: Activity, + product: Product, + options: PurchaseOptions? = null, + callback: (BillingResponse?) -> Unit + ) { + val param = BillingFlowParams.ProductDetailsParams.newBuilder() + .apply { + setProductDetails(product.product) + if (product.type == Product.Type.Subs) { + product.product.subscriptionOfferDetails?.first()?.let { + setOfferToken(it.offerToken) + } + } + } + .build() + + val flow = BillingFlowParams.newBuilder() + .apply { + options?.let { + setIsOfferPersonalized(it.setIsOfferPersonalized) + it.profileId?.let { id -> + setObfuscatedProfileId(id) + } + + it.accountId?.let { id -> + setObfuscatedAccountId(id) + } + + it.subscriptionUpdateToken?.let { token -> + val params = BillingFlowParams.SubscriptionUpdateParams.newBuilder() + .apply { + it.subscriptionUpdateReplacementMode?.let { mode -> + setSubscriptionReplacementMode(mode.value) } + } + .setOldPurchaseToken(token) + .build() - else -> { - if (enableDebug) { - Log.d( - "JS", - "mapSubResponseCode ${response.onPurchasesUpdatedSubResponseCode}" - ) - } - BillingResponse(Int.MAX_VALUE, "", "", Int.MAX_VALUE) - } + setSubscriptionUpdateParams(params) + } + } + setProductDetailsParamsList(listOf(param)) + } + .build() + + val response = billing.launchBillingFlow(activity, flow) + + executor.execute { + if (response.responseCode != BillingClient.BillingResponseCode.OK) { + val res = when (response.onPurchasesUpdatedSubResponseCode) { + BillingClient.OnPurchasesUpdatedSubResponseCode.PAYMENT_DECLINED_DUE_TO_INSUFFICIENT_FUNDS -> { + BillingResponse( + Int.MAX_VALUE, + "The payment was declined due to insufficient funds.", + "The user must either add funds/increase limits or retry the transaction with a different payment method", + response.onPurchasesUpdatedSubResponseCode + ) + } + + BillingClient.OnPurchasesUpdatedSubResponseCode.USER_INELIGIBLE -> { + BillingResponse( + Int.MAX_VALUE, + "the user does not currently meet offer eligibility requirements.", + "This offer isn’t available in your region or for your account type.”", + response.onPurchasesUpdatedSubResponseCode + ) + } + + else -> { + if (enableDebug) { + Log.d( + "JS", + "mapSubResponseCode ${response.onPurchasesUpdatedSubResponseCode}" + ) } + BillingResponse(Int.MAX_VALUE, "", "", Int.MAX_VALUE) + } } - return mapResponseCode(response.responseCode) - } + callback(res) + return@execute + } - fun fetchPurchases(callback: (List?, BillingResponse?) -> Unit) { - executor.execute { - val inapp = QueryPurchasesParams.newBuilder() - .setProductType(BillingClient.ProductType.INAPP) - .build() - val subs = QueryPurchasesParams.newBuilder() - .setProductType(BillingClient.ProductType.SUBS) - .build() - val ret = arrayOf>(mutableListOf(), mutableListOf()) - val error = arrayOfNulls(1) - val lock = CountDownLatch(2) - billing.queryPurchasesAsync(inapp) { p0, p1 -> - if (p0.responseCode == BillingClient.BillingResponseCode.OK) { - p1.forEach { purchase -> - purchase?.let { - ret[0].add(Transaction(it, Product.Type.InApp, this)) - } - } - } else { - error[0] = mapResponseCode(p0.responseCode) - } - lock.countDown() - } - - billing.queryPurchasesAsync(subs) { p0, p1 -> - if (p0.responseCode == BillingClient.BillingResponseCode.OK) { - p1.forEach { purchase -> - purchase?.let { - ret[1].add(Transaction(it, Product.Type.Subs, this)) - } - } - } else { - error[0] = mapResponseCode(p0.responseCode) - } - lock.countDown() + callback(null) + } + } + + fun fetchPurchases(callback: (List?, BillingResponse?) -> Unit) { + executor.execute { + val inapp = QueryPurchasesParams.newBuilder() + .setProductType(BillingClient.ProductType.INAPP) + .build() + val subs = QueryPurchasesParams.newBuilder() + .setProductType(BillingClient.ProductType.SUBS) + .build() + val ret = arrayOf>(mutableListOf(), mutableListOf()) + val error = arrayOfNulls(1) + val lock = CountDownLatch(2) + billing.queryPurchasesAsync(inapp) { p0, p1 -> + if (p0.responseCode == BillingClient.BillingResponseCode.OK) { + p1.forEach { purchase -> + purchase?.let { + ret[0].add(Transaction(it, Product.Type.InApp, this)) } - - try { - lock.await() - ret[0].addAll(ret[1]) - callback( - ret[0], null - ) - } catch (_: Exception) { - callback(null, error[0]) + } + } else { + error[0] = mapResponseCode(p0.responseCode) + } + lock.countDown() + } + + billing.queryPurchasesAsync(subs) { p0, p1 -> + if (p0.responseCode == BillingClient.BillingResponseCode.OK) { + p1.forEach { purchase -> + purchase?.let { + ret[1].add(Transaction(it, Product.Type.Subs, this)) } + } + } else { + error[0] = mapResponseCode(p0.responseCode) } + lock.countDown() + } + + try { + lock.await() + ret[0].addAll(ret[1]) + callback( + ret[0], null + ) + } catch (_: Exception) { + callback(null, error[0]) + } } - - companion object { - @JvmStatic - var enableDebug = false - - @JvmStatic - internal fun mapResponseCode(code: Int): BillingResponse { - return when (code) { - BillingClient.BillingResponseCode.OK -> BillingResponse(code, "OK", "") - - BillingClient.BillingResponseCode.BILLING_UNAVAILABLE -> BillingResponse( - code, - "A user billing error occurred during processing.", - "Automatic retries are unlikely to help in this case. However, a manual retry can help if the user addresses the condition that caused the issue." - ) - - BillingClient.BillingResponseCode.NETWORK_ERROR -> BillingResponse( - code, - "A network error occurred during the operation.", - "" - ) - - BillingClient.BillingResponseCode.USER_CANCELED -> BillingResponse( - code, - "The user has clicked out of the billing flow UI.", - "This is informational only and can fail gracefully." - ) - - BillingClient.BillingResponseCode.ITEM_UNAVAILABLE -> BillingResponse( - code, - "The requested product is not available for purchase.", - "Make sure your app refreshes the product details via queryProductDetailsAsync as recommended." - ) - - BillingClient.BillingResponseCode.DEVELOPER_ERROR -> BillingResponse( - code, - "Error resulting from incorrect usage of the API.", - "Make sure that you are correctly using the different Play Billing Library calls. Also, check the debug message for more info about the error." - ) - - BillingClient.BillingResponseCode.FEATURE_NOT_SUPPORTED -> BillingResponse( - code, - "The requested feature is not supported by the Play Store on the current device.", - "Use isFeatureSupported() to check feature support before making the call to the Play Billing Library." - ) - - BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED -> BillingResponse( - code, - "The purchase failed because the item is already owned.", - "To avoid this error happening when the cause is not a cache issue, don't offer a product for purchase when the user already owns it." - ) - - BillingClient.BillingResponseCode.ITEM_NOT_OWNED -> BillingResponse( - code, - "Requested action on the item failed since it is not owned by the user.", - "When the error is received because of a cache issue, the error triggers Google Play’s cache to get updated with the latest data from Play’s backend." - ) - - BillingClient.BillingResponseCode.SERVICE_UNAVAILABLE -> BillingResponse( - code, - "The service is currently unavailable.", - "This is usually a transient issue. Retry the request using either either a simple or exponential backoff strategy, depending on which action returned the error." - ) - - BillingClient.BillingResponseCode.SERVICE_DISCONNECTED -> BillingResponse( - code, - "The app is not connected to the Play Store service via the Google Play Billing Library.", - "To attempt recovery from SERVICE_DISCONNECTED , your client app should try to re-establish the connection using .restartConnection." - ) - - BillingClient.BillingResponseCode.ERROR -> BillingResponse( - code, - "Fatal error during the API action.", - "Sometimes internal Google Play problems that lead to ERROR are transient, and a retry with an exponential backoff can be implemented for mitigation. When users are in session, a simple retry is preferable." - ) - - else -> { - if (enableDebug) { - Log.d("JS", "mapResponseCode $code") - } - return BillingResponse(Int.MAX_VALUE, "", "") - } - } + } + + companion object { + @JvmStatic + var enableDebug = false + + @JvmStatic + internal fun mapResponseCode(code: Int): BillingResponse { + return when (code) { + BillingClient.BillingResponseCode.OK -> BillingResponse(code, "OK", "") + + BillingClient.BillingResponseCode.BILLING_UNAVAILABLE -> BillingResponse( + code, + "A user billing error occurred during processing.", + "Automatic retries are unlikely to help in this case. However, a manual retry can help if the user addresses the condition that caused the issue." + ) + + BillingClient.BillingResponseCode.NETWORK_ERROR -> BillingResponse( + code, + "A network error occurred during the operation.", + "" + ) + + BillingClient.BillingResponseCode.USER_CANCELED -> BillingResponse( + code, + "The user has clicked out of the billing flow UI.", + "This is informational only and can fail gracefully." + ) + + BillingClient.BillingResponseCode.ITEM_UNAVAILABLE -> BillingResponse( + code, + "The requested product is not available for purchase.", + "Make sure your app refreshes the product details via queryProductDetailsAsync as recommended." + ) + + BillingClient.BillingResponseCode.DEVELOPER_ERROR -> BillingResponse( + code, + "Error resulting from incorrect usage of the API.", + "Make sure that you are correctly using the different Play Billing Library calls. Also, check the debug message for more info about the error." + ) + + BillingClient.BillingResponseCode.FEATURE_NOT_SUPPORTED -> BillingResponse( + code, + "The requested feature is not supported by the Play Store on the current device.", + "Use isFeatureSupported() to check feature support before making the call to the Play Billing Library." + ) + + BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED -> BillingResponse( + code, + "The purchase failed because the item is already owned.", + "To avoid this error happening when the cause is not a cache issue, don't offer a product for purchase when the user already owns it." + ) + + BillingClient.BillingResponseCode.ITEM_NOT_OWNED -> BillingResponse( + code, + "Requested action on the item failed since it is not owned by the user.", + "When the error is received because of a cache issue, the error triggers Google Play’s cache to get updated with the latest data from Play’s backend." + ) + + BillingClient.BillingResponseCode.SERVICE_UNAVAILABLE -> BillingResponse( + code, + "The service is currently unavailable.", + "This is usually a transient issue. Retry the request using either either a simple or exponential backoff strategy, depending on which action returned the error." + ) + + BillingClient.BillingResponseCode.SERVICE_DISCONNECTED -> BillingResponse( + code, + "The app is not connected to the Play Store service via the Google Play Billing Library.", + "To attempt recovery from SERVICE_DISCONNECTED , your client app should try to re-establish the connection using .restartConnection." + ) + + BillingClient.BillingResponseCode.ERROR -> BillingResponse( + code, + "Fatal error during the API action.", + "Sometimes internal Google Play problems that lead to ERROR are transient, and a retry with an exponential backoff can be implemented for mitigation. When users are in session, a simple retry is preferable." + ) + + else -> { + if (enableDebug) { + Log.d("JS", "mapResponseCode $code") + } + return BillingResponse(Int.MAX_VALUE, "", "") } + } + } - @JvmStatic - fun isSupported(context: Context): Boolean { - val playStoreIntent = Intent(Intent.ACTION_VIEW).apply { - data = Uri.parse("market://details?id=${context.packageName}") - setPackage("com.android.vending") - } - return playStoreIntent.resolveActivity(context.packageManager) != null - } + @JvmStatic + fun isSupported(context: Context): Boolean { + val playStoreIntent = Intent(Intent.ACTION_VIEW).apply { + data = Uri.parse("market://details?id=${context.packageName}") + setPackage("com.android.vending") + } + return playStoreIntent.resolveActivity(context.packageManager) != null } + } } diff --git a/packages/payments/typings/android.d.ts b/packages/payments/typings/android.d.ts index 6df7df9..74017b7 100644 --- a/packages/payments/typings/android.d.ts +++ b/packages/payments/typings/android.d.ts @@ -4,36 +4,42 @@ declare module org { export module payments { export class Payments { public static class: java.lang.Class; + public showInAppMessaging(activity: globalAndroid.app.Activity): void; public getBilling$payments_release(): com.android.billingclient.api.BillingClient; - - public setOnReadyListener(value: any): void; public setOnPurchaseUpdateListener(value: any): void; public isFeatureSupported(feature: org.nativescript.plugins.payments.Payments.Features): boolean; - public fetchProducts(it: androidNative.Array, type: org.nativescript.plugins.payments.Product.Type, $i$f$mapTo: any): void; - public restartConnection(): void; + public purchaseProduct(it: globalAndroid.app.Activity, product: org.nativescript.plugins.payments.Product, opts: org.nativescript.plugins.payments.Payments.PurchaseOptions, callback: any): void; + public static getEnableDebug(): boolean; + public fetchProducts(it: androidNative.Array, item$iv$iv: org.nativescript.plugins.payments.Product.Type, $i$f$mapTo: any): void; public constructor(pendingParams: globalAndroid.content.Context); + public purchaseProduct(activity: globalAndroid.app.Activity, product: org.nativescript.plugins.payments.Product, callback: any): void; public fetchPurchases(callback: any): void; public canMakePayments(): boolean; public static isSupported(context: globalAndroid.content.Context): boolean; - public purchaseProduct($this$purchaseProduct_u24lambda_u248: globalAndroid.app.Activity, product: org.nativescript.plugins.payments.Product, id: org.nativescript.plugins.payments.Payments.PurchaseOptions): org.nativescript.plugins.payments.Payments.BillingResponse; - public getOnPurchaseUpdateListener(): any; + public static setEnableDebug(value: boolean): void; + public connect(): void; public getOnReadyListener(): any; - public purchaseProduct(activity: globalAndroid.app.Activity, product: org.nativescript.plugins.payments.Product): org.nativescript.plugins.payments.Payments.BillingResponse; + public setOnReadyListener(value: any): void; + public getOnPurchaseUpdateListener(): any; public setBilling$payments_release(value: com.android.billingclient.api.BillingClient): void; + public disconnect(): void; public static mapResponseCode$payments_release(code: number): org.nativescript.plugins.payments.Payments.BillingResponse; } export module Payments { export class BillingResponse { public static class: java.lang.Class; public getMessage(): string; - public constructor(code: number, message: string, resolution: string); + public constructor(code: number, message: string, resolution: string, subCode: number); public getCode(): number; public getResolution(): string; + public getSubCode(): number; } export class Companion { public static class: java.lang.Class; public isSupported($this$isSupported_u24lambda_u240: globalAndroid.content.Context): boolean; + public getEnableDebug(): boolean; public mapResponseCode$payments_release(code: number): org.nativescript.plugins.payments.Payments.BillingResponse; + public setEnableDebug(value: boolean): void; } export class Features { public static class: java.lang.Class; @@ -52,14 +58,33 @@ declare module org { } export class PurchaseOptions { public static class: java.lang.Class; + public getSubscriptionUpdateReplacementMode(): org.nativescript.plugins.payments.Payments.PurchaseOptions.ReplacementMode; public constructor(); public getAccountId(): string; public setAccountId(value: string): void; + public setSubscriptionUpdateToken(value: string): void; + public setSubscriptionUpdateReplacementMode(value: org.nativescript.plugins.payments.Payments.PurchaseOptions.ReplacementMode): void; + public getSubscriptionUpdateToken(): string; public setProfileId(value: string): void; public getProfileId(): string; public getSetIsOfferPersonalized(): boolean; public setSetIsOfferPersonalized(value: boolean): void; } + export module PurchaseOptions { + export class ReplacementMode { + public static class: java.lang.Class; + public static Unknown: org.nativescript.plugins.payments.Payments.PurchaseOptions.ReplacementMode; + public static WithTimeProration: org.nativescript.plugins.payments.Payments.PurchaseOptions.ReplacementMode; + public static ChargeProratedPrice: org.nativescript.plugins.payments.Payments.PurchaseOptions.ReplacementMode; + public static WithoutProration: org.nativescript.plugins.payments.Payments.PurchaseOptions.ReplacementMode; + public static ChargeFullPrice: org.nativescript.plugins.payments.Payments.PurchaseOptions.ReplacementMode; + public static Deferred: org.nativescript.plugins.payments.Payments.PurchaseOptions.ReplacementMode; + public static values(): androidNative.Array; + public static valueOf(value: string): org.nativescript.plugins.payments.Payments.PurchaseOptions.ReplacementMode; + public static getEntries(): any; + public getValue(): number; + } + } } } } @@ -78,9 +103,9 @@ declare module org { public getName(): string; public getType(): org.nativescript.plugins.payments.Product.Type; public constructor(product: com.android.billingclient.api.ProductDetails); + public getPriceAmountMicros(): java.lang.Long; + public getPriceFormatted(): string; public getDescription(): string; - public getPriceAmountMicros(): number | null; - public getPriceFormatted(): string | null; } export module Product { export class Type { @@ -110,24 +135,24 @@ declare module org { export module payments { export class Transaction { public static class: java.lang.Class; - public getOriginalJson(): org.json.JSONObject; - public getProductId(): string; public getOrderId(): string; - public getOrderDate(): number; + public getOriginalJson(): org.json.JSONObject; public finish(params: any): void; + public isExpired(): boolean; public getToken(): string; + public isAcknowledged(): boolean; public constructor(purchase: com.android.billingclient.api.Purchase, type: org.nativescript.plugins.payments.Product.Type, payments: org.nativescript.plugins.payments.Payments); public getQuantity(): number; - public isAutoRenewing(): boolean; + public getOrderDate(): number; public getPurchase(): com.android.billingclient.api.Purchase; + public getProductId(): string; public getSignature(): string; public getType(): org.nativescript.plugins.payments.Product.Type; + public isAutoRenewing(): boolean; public getState(): org.nativescript.plugins.payments.Transaction.State; public getDeveloperPayload(): string; public getOriginalJsonString(): string; public getProducts(): java.util.List; - public isAcknowledged(): boolean; - public isExpired(): boolean; } export module Transaction { export class State { From d4998e5b3097f50317c5cedcb7d895dcbb506f73 Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Wed, 13 Aug 2025 04:23:52 -0400 Subject: [PATCH 15/34] fix(payments): priceAmountMicros --- packages/payments/index.android.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/payments/index.android.ts b/packages/payments/index.android.ts index 8c8e4e4..418b1f3 100644 --- a/packages/payments/index.android.ts +++ b/packages/payments/index.android.ts @@ -183,7 +183,7 @@ export class Product { } get priceAmountMicros(): number | null { - return this.native.getPriceAmountMicros(); + return this.native.getPriceAmountMicros()?.longValue?.() ?? null; } toJSON() { From cc1b646e890f8e6060c2296787d4007cc9a7a014 Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Wed, 13 Aug 2025 04:27:51 -0400 Subject: [PATCH 16/34] fix(payments): purchase flow --- packages/payments/index.android.ts | 12 ++++++++---- packages/payments/package.json | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/payments/index.android.ts b/packages/payments/index.android.ts index 418b1f3..d65c668 100644 --- a/packages/payments/index.android.ts +++ b/packages/payments/index.android.ts @@ -337,11 +337,15 @@ export class Payment { opts, new kotlin.jvm.functions.Function1({ invoke(response: org.nativescript.plugins.payments.Payments.BillingResponse): void { - const code = response.getCode(); - if (code === 0) { - resolve(); + if (response) { + const code = response.getCode(); + if (code === 0) { + resolve(); + } else { + reject(new PaymentError(response.getMessage(), response)); + } } else { - reject(new PaymentError(response.getMessage(), response)); + resolve(); } }, }), diff --git a/packages/payments/package.json b/packages/payments/package.json index 7a3c617..c7dadf7 100644 --- a/packages/payments/package.json +++ b/packages/payments/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/payments", - "version": "4.0.0-alpha.7", + "version": "4.0.0-alpha.8", "description": "In-App Purchase and Subscriptions for NativeScript", "main": "index", "typings": "index.d.ts", From 6b6a57ed50593c193d1ea9add658041a2d227a43 Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Wed, 13 Aug 2025 05:03:19 -0400 Subject: [PATCH 17/34] fix(payment): purchase update listener --- packages/payments/package.json | 2 +- .../nativescript/plugins/payments/Payments.kt | 55 +++++++++---------- 2 files changed, 28 insertions(+), 29 deletions(-) diff --git a/packages/payments/package.json b/packages/payments/package.json index c7dadf7..79e2cc9 100644 --- a/packages/payments/package.json +++ b/packages/payments/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/payments", - "version": "4.0.0-alpha.8", + "version": "4.0.0-alpha.9", "description": "In-App Purchase and Subscriptions for NativeScript", "main": "index", "typings": "index.d.ts", diff --git a/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Payments.kt b/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Payments.kt index 2aa6ee2..da0b2b0 100644 --- a/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Payments.kt +++ b/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Payments.kt @@ -21,37 +21,36 @@ class Payments(context: Context) { private var isReady = false private var isSetup = false private val purchaseListener = PurchasesUpdatedListener { response, purchases -> - { - if (response.responseCode == BillingClient.BillingResponseCode.OK && purchases != null) { - val value = purchases.map { - val json = JSONObject(it.originalJson) - Transaction( - it, if (json.optBoolean("autoRenewing", false)) { - Product.Type.Subs - } else { - Product.Type.InApp - }, this@Payments - ) - } - onPurchaseUpdateListener?.let { - it(value, null) - } - } else { - onPurchaseUpdateListener?.let { - it(null, mapResponseCode(response.responseCode)) - } + if (response.responseCode == BillingClient.BillingResponseCode.OK && purchases != null) { + val value = purchases.map { + val json = JSONObject(it.originalJson) + Transaction( + it, if (json.optBoolean("autoRenewing", false)) { + Product.Type.Subs + } else { + Product.Type.InApp + }, this@Payments + ) + } + onPurchaseUpdateListener?.let { + it(value, null) + } + } else { + onPurchaseUpdateListener?.let { + it(null, mapResponseCode(response.responseCode)) } } } - internal var billing = BillingClient.newBuilder(context).apply { - val pendingParams = PendingPurchasesParams.newBuilder() - .enablePrepaidPlans() - .enableOneTimeProducts() - .build() - enablePendingPurchases(pendingParams) - enableAutoServiceReconnection() - setListener(purchaseListener) - }.build() + internal var billing = BillingClient.newBuilder(context) + .enablePendingPurchases( + PendingPurchasesParams.newBuilder() + .enablePrepaidPlans() + .enableOneTimeProducts() + .build() + ) + .enableAutoServiceReconnection() + .setListener(purchaseListener) + .build() private val executor = Executors.newCachedThreadPool() From 93c6ceeb2f79d8c3e4e21ea1e0d0e70a3836c954 Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Wed, 13 Aug 2025 06:22:55 -0400 Subject: [PATCH 18/34] feat(payments): use string for response.code --- packages/payments/index.android.ts | 9 +---- packages/payments/index.d.ts | 8 ++++ packages/payments/index.ios.ts | 8 +--- .../nativescript/plugins/payments/Payments.kt | 40 ++++++++++++++++++- .../platforms/ios/src/NSCPayment.swift | 31 ++++++++++++++ packages/payments/typings/android.d.ts | 1 + .../payments/typings/objc!NSCPayments.d.ts | 2 + 7 files changed, 85 insertions(+), 14 deletions(-) diff --git a/packages/payments/index.android.ts b/packages/payments/index.android.ts index d65c668..e13f0f3 100644 --- a/packages/payments/index.android.ts +++ b/packages/payments/index.android.ts @@ -9,14 +9,9 @@ export class PaymentError extends Error { this.nativeError = nativeError; } - get code(): number { - return this.nativeError?.getCode() ?? Number.MAX_SAFE_INTEGER; + get code(): string { + return this.nativeError.getRaw(); } - - get subCode(): number { - return this.nativeError?.getSubCode() ?? Number.MAX_SAFE_INTEGER; - } - get native(): any { return this.nativeError; } diff --git a/packages/payments/index.d.ts b/packages/payments/index.d.ts index d84b971..b39bb17 100644 --- a/packages/payments/index.d.ts +++ b/packages/payments/index.d.ts @@ -1,3 +1,11 @@ +export type FailureTypes = 'DEFERRED_PAYMENT' | 'PURCHASE_NOT_ALLOWED' | 'PRODUCT_UNAVAILABLE' | 'DEVELOPER_USAGE' | 'PRODUCT_ALREADY_OWNED' | 'PRODUCT_NOT_OWNED' | 'USER_CANCELLED' | 'NETWORK_AVAILABILITY' | 'BILLING_AVAILABILITY' | 'UNSPECIFIED' | 'SERVICE_DISCONNECTED' | 'SERVICE_TIMEOUT' | 'SERVICE_UNAVAILABLE' | 'FEATURE_NOT_SUPPORTED' | 'ERROR' | 'USER_INELIGIBLE' | 'INSUFFICIENT_FUNDS'; + +export class PaymentError extends Error { + readonly code: FailureTypes; + readonly native: any; + readonly resolution: string; +} + export interface PurchaseOptions { accountId?: string; android?: { diff --git a/packages/payments/index.ios.ts b/packages/payments/index.ios.ts index fd7ff4f..64fc2a9 100644 --- a/packages/payments/index.ios.ts +++ b/packages/payments/index.ios.ts @@ -8,12 +8,8 @@ export class PaymentError extends Error { this.nativeError = nativeError; } - get code(): number { - return this.nativeError?.code ?? Number.MAX_SAFE_INTEGER; - } - - get subCode(): number { - return Number.MAX_SAFE_INTEGER; + get code(): string { + return this.nativeError.raw ?? 'UNSPECIFIED'; } get native(): any { diff --git a/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Payments.kt b/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Payments.kt index da0b2b0..16eac5f 100644 --- a/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Payments.kt +++ b/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Payments.kt @@ -63,7 +63,45 @@ class Payments(context: Context) { val message: String, val resolution: String, val subCode: Int = Int.MAX_VALUE - ) + ) { + val raw: String + get() { + if (subCode == BillingClient.OnPurchasesUpdatedSubResponseCode.USER_INELIGIBLE) { + return "USER_INELIGIBLE" + } else if (subCode == BillingClient.OnPurchasesUpdatedSubResponseCode.PAYMENT_DECLINED_DUE_TO_INSUFFICIENT_FUNDS) { + return "INSUFFICIENT_FUNDS" + } + + return when (code) { + BillingClient.BillingResponseCode.OK -> "OK" + + BillingClient.BillingResponseCode.BILLING_UNAVAILABLE -> "NETWORK_ERROR" + + BillingClient.BillingResponseCode.NETWORK_ERROR -> "NETWORK_ERROR" + + BillingClient.BillingResponseCode.USER_CANCELED -> "USER_CANCELED" + + BillingClient.BillingResponseCode.ITEM_UNAVAILABLE -> "ITEM_UNAVAILABLE" + + BillingClient.BillingResponseCode.DEVELOPER_ERROR -> "DEVELOPER_ERROR" + + BillingClient.BillingResponseCode.FEATURE_NOT_SUPPORTED -> "FEATURE_NOT_SUPPORTED" + + BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED -> "ITEM_ALREADY_OWNED" + + BillingClient.BillingResponseCode.ITEM_NOT_OWNED -> "ITEM_NOT_OWNED" + + BillingClient.BillingResponseCode.SERVICE_UNAVAILABLE -> "SERVICE_UNAVAILABLE" + + BillingClient.BillingResponseCode.SERVICE_DISCONNECTED -> "SERVICE_DISCONNECTED" + + BillingClient.BillingResponseCode.SERVICE_TIMEOUT -> "SERVICE_TIMEOUT" + + BillingClient.BillingResponseCode.ERROR -> "ERROR" + else -> "UNSPECIFIED" + } + } + } enum class Features(val value: String) { Subscriptions(BillingClient.FeatureType.SUBSCRIPTIONS), diff --git a/packages/payments/platforms/ios/src/NSCPayment.swift b/packages/payments/platforms/ios/src/NSCPayment.swift index c6da9f4..d1fc665 100644 --- a/packages/payments/platforms/ios/src/NSCPayment.swift +++ b/packages/payments/platforms/ios/src/NSCPayment.swift @@ -494,6 +494,33 @@ public enum NSCPaymentsResponseFailure: Int32, RawRepresentable { return 10 } } + + var stringValue: String { + switch self { + case .ProductUnavailable: + return "PRODUCT_UNAVAILABLE" + case .DeveloperUsage: + return "DEVELOPER_USAGE" + case .ProductAlreadyOwned: + return "PRODUCT_ALREADY_OWNED" + case .ProductNotOwned: + return "PRODUCT_NOT_OWNED" + case .UserCancelled: + return "USER_CANCELLED" + case .NetworkAvailability: + return "NETWORK_AVAILABILITY" + case .BillingAvailability: + return "BILLING_AVAILABILITY" + case .Unspecified: + return "UNSPECIFIED" + case .PurchaseNotAllowed: + return "PURCHASE_NOT_ALLOWED" + case .DeferredPayment: + return "DEFERRED_PAYMENT" + case .Error: + return "ERROR" + } + } } @objc(NSCPaymentsResponse) @@ -512,6 +539,10 @@ public class NSCPaymentsResponse: NSObject { self.message = message self.resolution = resolution } + + public var raw: String { + return code.stringValue + } } @objc(NSCPurchaseOptions) diff --git a/packages/payments/typings/android.d.ts b/packages/payments/typings/android.d.ts index 74017b7..ad8e9c4 100644 --- a/packages/payments/typings/android.d.ts +++ b/packages/payments/typings/android.d.ts @@ -33,6 +33,7 @@ declare module org { public getCode(): number; public getResolution(): string; public getSubCode(): number; + public getRaw(): string; } export class Companion { public static class: java.lang.Class; diff --git a/packages/payments/typings/objc!NSCPayments.d.ts b/packages/payments/typings/objc!NSCPayments.d.ts index 3ce5398..4990ce5 100644 --- a/packages/payments/typings/objc!NSCPayments.d.ts +++ b/packages/payments/typings/objc!NSCPayments.d.ts @@ -33,6 +33,8 @@ declare class NSCPaymentsResponse extends NSObject { readonly code: NSCPaymentsResponseFailure; + readonly raw: string; + readonly message: string; readonly resolution: string; From bcd40ce6e7c5b981f5f9135576a961c1e25cec25 Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Wed, 13 Aug 2025 06:23:36 -0400 Subject: [PATCH 19/34] chore(payments): bump --- packages/payments/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/payments/package.json b/packages/payments/package.json index 79e2cc9..e3a56f8 100644 --- a/packages/payments/package.json +++ b/packages/payments/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/payments", - "version": "4.0.0-alpha.9", + "version": "4.0.0-alpha.10", "description": "In-App Purchase and Subscriptions for NativeScript", "main": "index", "typings": "index.d.ts", From b7b48cdac6b2014a781d32b8725c1b7d05db0e0c Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Wed, 13 Aug 2025 23:44:22 -0400 Subject: [PATCH 20/34] fix(payments): onPurchase error handling --- packages/payments/index.ios.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/payments/index.ios.ts b/packages/payments/index.ios.ts index 64fc2a9..da915e9 100644 --- a/packages/payments/index.ios.ts +++ b/packages/payments/index.ios.ts @@ -196,10 +196,10 @@ export class Payment { this.native.transactionUpdateListener = (transaction) => { if (this.onPurchaseUpdate) { if (transaction.error) { - this.onPurchaseUpdate([Transaction.fromNative(transaction)], null); - } else { const error = NSCPaymentsResponse.alloc().initWithCodeMessageResolution(NSCPaymentsResponseFailure.Error, `Usage error: ${transaction.error.localizedDescription}`, ''); this.onPurchaseUpdate([], new PaymentError(transaction.error.localizedDescription, error)); + } else { + this.onPurchaseUpdate([Transaction.fromNative(transaction)], null); } } }; From 3f97b8383b1c6563f53b3c4913b909fae0ccbbff Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Wed, 13 Aug 2025 23:44:38 -0400 Subject: [PATCH 21/34] chore(payments): bump --- packages/payments/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/payments/package.json b/packages/payments/package.json index e3a56f8..1c40bcc 100644 --- a/packages/payments/package.json +++ b/packages/payments/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/payments", - "version": "4.0.0-alpha.10", + "version": "4.0.0-alpha.11", "description": "In-App Purchase and Subscriptions for NativeScript", "main": "index", "typings": "index.d.ts", From 57231dac4b685f92daf69985755185fa6c52c287 Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Thu, 14 Aug 2025 12:38:15 -0400 Subject: [PATCH 22/34] feat(payments): show storekit version used --- packages/payments/index.d.ts | 12 ++---------- packages/payments/index.ios.ts | 12 ++++++++++++ packages/payments/package.json | 2 +- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/packages/payments/index.d.ts b/packages/payments/index.d.ts index b39bb17..3919df1 100644 --- a/packages/payments/index.d.ts +++ b/packages/payments/index.d.ts @@ -70,6 +70,8 @@ export class Transaction { readonly isAutoRenewing: boolean; + readonly version: 'v1' | 'v2' | undefined; // iOS store version; + finish(): Promise; } @@ -90,13 +92,3 @@ export class Product { readonly priceAmountMicros: number | null; } - -export class Transaction { - native: org.nativescript.plugins.payments.Transaction; - readonly json: any; - readonly signature: string; - readonly quantity: number; - readonly orderId: string; - readonly state: 'pending' | 'purchased' | 'unknown'; - finish(): Promise; -} diff --git a/packages/payments/index.ios.ts b/packages/payments/index.ios.ts index da915e9..8f13a3d 100644 --- a/packages/payments/index.ios.ts +++ b/packages/payments/index.ios.ts @@ -100,6 +100,17 @@ export class Transaction { return this.native.revocationDate; } + get version(): 'v1' | 'v2' { + switch (this.native.version) { + case NSCPaymentsStoreKitVersion.V1: + return 'v1'; + case NSCPaymentsStoreKitVersion.V2: + return 'v2'; + default: + return 'v1'; + } + } + finish() { return new Promise((resolve, reject) => { this.native.finish((response) => { @@ -127,6 +138,7 @@ export class Transaction { expirationDate: this.expirationDate, isRevoked: this.isRevoked, revocationDate: this.revocationDate, + version: this.version, }; } } diff --git a/packages/payments/package.json b/packages/payments/package.json index 1c40bcc..61a9ac0 100644 --- a/packages/payments/package.json +++ b/packages/payments/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/payments", - "version": "4.0.0-alpha.11", + "version": "4.0.0-alpha.13", "description": "In-App Purchase and Subscriptions for NativeScript", "main": "index", "typings": "index.d.ts", From df68216a00102365f790682d6f6bdd6d7be756b3 Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Thu, 14 Aug 2025 12:53:38 -0400 Subject: [PATCH 23/34] fix(payments): iOS receipt storekit v1 --- packages/payments/package.json | 2 +- .../payments/platforms/ios/src/NSCPayment.swift | 16 ++++------------ 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/packages/payments/package.json b/packages/payments/package.json index 61a9ac0..1a98177 100644 --- a/packages/payments/package.json +++ b/packages/payments/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/payments", - "version": "4.0.0-alpha.13", + "version": "4.0.0-alpha.14", "description": "In-App Purchase and Subscriptions for NativeScript", "main": "index", "typings": "index.d.ts", diff --git a/packages/payments/platforms/ios/src/NSCPayment.swift b/packages/payments/platforms/ios/src/NSCPayment.swift index d1fc665..f0876ad 100644 --- a/packages/payments/platforms/ios/src/NSCPayment.swift +++ b/packages/payments/platforms/ios/src/NSCPayment.swift @@ -155,6 +155,7 @@ public class NSCTransaction: NSObject { } } + internal var receiptV1: String? = nil var receipt: String? { get { if version == .v2 && version.storeKit2Available { @@ -162,7 +163,7 @@ public class NSCTransaction: NSObject { return String(data:v2!.jsonRepresentation, encoding: .utf8) } } - return nil + return receiptV1 } } @@ -304,17 +305,6 @@ public class NSCProduct: NSObject { self.version = version } - public var receiptToken: String? { - if let url = Bundle.main.appStoreReceiptURL { - do { - return try Data(contentsOf: url).base64EncodedString() - }catch { - return nil - } - } - return nil - } - @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) internal var v2: Product? { if version.storeKit2Available { @@ -604,6 +594,7 @@ public class NSCPayments: NSObject { let value = NSCTransaction(transaction: transaction, .v1) if let receipt = receipt { + value.receiptV1 = receipt.base64 let purchaseInfo = receipt.activeAutoRenewableSubscriptionPurchases .filter({ $0.transactionIdentifier == transaction.transactionIdentifier }) .first @@ -630,6 +621,7 @@ public class NSCPayments: NSObject { for transaction in transactions { let value = NSCTransaction(transaction: transaction, .v1) if let receipt = receipt { + value.receiptV1 = receipt.base64 let purchaseInfo = receipt.activeAutoRenewableSubscriptionPurchases .filter({ $0.transactionIdentifier == transaction.transactionIdentifier }) .first From 2225b1f75c047dc930301d4221078264c483c35d Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Thu, 14 Aug 2025 17:42:21 -0400 Subject: [PATCH 24/34] fix(payments): isExpired & isRevoked --- packages/payments/package.json | 2 +- packages/payments/platforms/ios/src/NSCPayment.swift | 4 ++-- packages/payments/typings/objc!NSCPayments.d.ts | 2 -- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/payments/package.json b/packages/payments/package.json index 1a98177..c76d6e9 100644 --- a/packages/payments/package.json +++ b/packages/payments/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/payments", - "version": "4.0.0-alpha.14", + "version": "4.0.0-alpha.15", "description": "In-App Purchase and Subscriptions for NativeScript", "main": "index", "typings": "index.d.ts", diff --git a/packages/payments/platforms/ios/src/NSCPayment.swift b/packages/payments/platforms/ios/src/NSCPayment.swift index f0876ad..765a76b 100644 --- a/packages/payments/platforms/ios/src/NSCPayment.swift +++ b/packages/payments/platforms/ios/src/NSCPayment.swift @@ -225,7 +225,7 @@ public class NSCTransaction: NSObject { } if let revoked = revocationDate { - return revoked >= Date() + return revoked <= Date() } return false } @@ -258,7 +258,7 @@ public class NSCTransaction: NSObject { } if let expiration = expirationDate { - return expiration >= Date() + return expiration <= Date() } return false diff --git a/packages/payments/typings/objc!NSCPayments.d.ts b/packages/payments/typings/objc!NSCPayments.d.ts index 4990ce5..045c7ca 100644 --- a/packages/payments/typings/objc!NSCPayments.d.ts +++ b/packages/payments/typings/objc!NSCPayments.d.ts @@ -95,8 +95,6 @@ declare class NSCProduct extends NSObject { readonly productIdentifier: string; - readonly receiptToken: string; - readonly type: string; readonly v1: SKProduct; From f1651a24fa3dc570f0ca8977426b8423000026e3 Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Fri, 15 Aug 2025 02:44:38 -0400 Subject: [PATCH 25/34] feat(payments): showSubscriptionsManagement --- apps/demo/src/plugin-demos/payments.ts | 2 +- packages/payments/index.android.ts | 16 + packages/payments/index.d.ts | 16 +- packages/payments/index.ios.ts | 53 +- packages/payments/package.json | 2 +- .../nativescript/plugins/payments/Payments.kt | 774 +++++++++--------- .../platforms/ios/src/NSCPayment.swift | 145 +++- packages/payments/typings/android.d.ts | 24 +- .../payments/typings/objc!NSCPayments.d.ts | 132 +-- 9 files changed, 655 insertions(+), 509 deletions(-) diff --git a/apps/demo/src/plugin-demos/payments.ts b/apps/demo/src/plugin-demos/payments.ts index 610467f..6c99684 100644 --- a/apps/demo/src/plugin-demos/payments.ts +++ b/apps/demo/src/plugin-demos/payments.ts @@ -95,7 +95,7 @@ export class DemoModel extends Observable { if (transaction.state === 'pending') { transaction.finish(); } else if (transaction.state === 'purchased') { - console.log(`🟢 Purchase Update: ${JSON.stringify(transaction.json)} 🟢`); + console.log(`🟢 Purchase Update: ${JSON.stringify(transaction.receiptToken)} 🟢`); } }); } diff --git a/packages/payments/index.android.ts b/packages/payments/index.android.ts index e13f0f3..5b663a2 100644 --- a/packages/payments/index.android.ts +++ b/packages/payments/index.android.ts @@ -250,6 +250,22 @@ export class Payment { this.native.disconnect(); } + showSubscriptionsManagement(options?: { + android?: { + packageName?: string; + productId?: string; + }; + ios?: { + subscriptionGroupID?: string; + }; + }) { + return new Promise((resolve, reject) => { + const packageName = options?.android?.packageName ?? null; + org.nativescript.plugins.payments.Payments.showManageSubscriptions(Utils.android.getCurrentActivity() || Utils.android.getApplicationContext(), packageName, options?.android?.productId ?? null); + resolve(); + }); + } + fetchProducts(productIdentifiers: string[], type: 'subs' | 'inapp') { const items = Array.create(java.lang.String, productIdentifiers.length); for (let i = 0; i < productIdentifiers.length; i++) { diff --git a/packages/payments/index.d.ts b/packages/payments/index.d.ts index 3919df1..80bc330 100644 --- a/packages/payments/index.d.ts +++ b/packages/payments/index.d.ts @@ -23,6 +23,7 @@ export interface PurchaseOptions { export class Payment { onReady?: () => void; onPurchaseUpdate?: (purchases: Array, error: Error | null) => void; + onIncomingPromotion?: (product: Product) => void; fetchProducts(itemIds: Array, type: 'inapp' | 'subs'): Promise>; purchaseProduct(product: Product): Promise; purchaseProduct(product: Product, options: PurchaseOptions | null | undefined): Promise; @@ -35,10 +36,21 @@ export class Payment { connect(): void; disconnect(): void; + + showSubscriptionsManagement(options?: { + android?: { + packageName?: string; + productId?: string; + }; + ios?: { + subscriptionGroupID?: string; + }; + }): Promise; + showSubscriptionsManagement(): Promise; } export class Transaction { - readonly native: org.nativescript.plugins.payments.Transaction | NSCTransaction; + readonly native: org.nativescript.plugins.payments.Transaction | NSCPaymentsTransaction; readonly receiptToken: string; @@ -76,7 +88,7 @@ export class Transaction { } export class Product { - readonly native: org.nativescript.plugins.payments.Product | NSCProduct; + readonly native: org.nativescript.plugins.payments.Product | NSCPaymentsProduct; readonly id: string; readonly name: string; diff --git a/packages/payments/index.ios.ts b/packages/payments/index.ios.ts index 8f13a3d..fcb1ad4 100644 --- a/packages/payments/index.ios.ts +++ b/packages/payments/index.ios.ts @@ -29,13 +29,13 @@ export class PaymentError extends Error { } export class Transaction { - readonly native: NSCTransaction; - constructor(native: NSCTransaction) { + readonly native: NSCPaymentsTransaction; + constructor(native: NSCPaymentsTransaction) { this.native = native; } - static fromNative(native: NSCTransaction): Transaction { - if (native instanceof NSCTransaction) { + static fromNative(native: NSCPaymentsTransaction): Transaction { + if (native instanceof NSCPaymentsTransaction) { return new Transaction(native); } return null; @@ -66,14 +66,14 @@ export class Transaction { } get isAcknowledged(): boolean { - return this.state === 'purchased'; + return this.native.isAcknowledged; } get state(): 'pending' | 'purchased' | 'unknown' { switch (this.native.state) { - case NSCTransactionState.Pending: + case NSCPaymentsTransactionState.Pending: return 'pending'; - case NSCTransactionState.Purchased: + case NSCPaymentsTransactionState.Purchased: return 'purchased'; default: return 'unknown'; @@ -144,13 +144,13 @@ export class Transaction { } export class Product { - readonly native: NSCProduct; - constructor(native: NSCProduct) { + readonly native: NSCPaymentsProduct; + constructor(native: NSCPaymentsProduct) { this.native = native; } - static fromNative(native: NSCProduct): Product { - if (native instanceof NSCProduct) { + static fromNative(native: NSCPaymentsProduct): Product { + if (native instanceof NSCPaymentsProduct) { return new Product(native); } return null; @@ -203,6 +203,8 @@ export class Payment { readonly native: NSCPayments; onReady?: () => void; onPurchaseUpdate?: (purchases: Array, error: Error | null) => void; + onIncomingPromotion?: (product: Product) => void; + constructor() { this.native = NSCPayments.new(); this.native.transactionUpdateListener = (transaction) => { @@ -215,6 +217,13 @@ export class Payment { } } }; + this.native.incomingPromotionListener = (product) => { + if (this.onIncomingPromotion) { + this.onIncomingPromotion(Product.fromNative(product)); + return true; + } + return false; + }; setTimeout(() => { this.onReady(); @@ -237,6 +246,26 @@ export class Payment { // no-op for iOS } + showSubscriptionsManagement(options?: { + android?: { + packageName?: string; + productId?: string; + }; + ios?: { + subscriptionGroupID?: string; + }; + }) { + return new Promise((resolve, reject) => { + NSCPayments.showManageSubscriptions(Utils.ios.getVisibleViewController(Utils.ios.getRootViewController()), options?.ios?.subscriptionGroupID ?? null, (result) => { + if (result) { + reject(new Error(result)); + } else { + resolve(); + } + }); + }); + } + fetchProducts(productIdentifiers: string[], type: 'subs' | 'inapp') { return new Promise((resolve, reject) => { if (type !== 'subs' && type !== 'inapp') { @@ -282,7 +311,7 @@ export class Payment { purchaseProduct(product: Product, options?: PurchaseOptions | null | undefined): Promise { return new Promise((resolve, reject) => { - const opts: NSCPurchaseOptions = NSCPurchaseOptions.new(); + const opts = NSCPaymentsPurchaseOptions.new(); if (options && typeof options === 'object') { if (options.accountId) { opts.accountId = options.accountId; diff --git a/packages/payments/package.json b/packages/payments/package.json index c76d6e9..1e7d8c8 100644 --- a/packages/payments/package.json +++ b/packages/payments/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/payments", - "version": "4.0.0-alpha.15", + "version": "4.0.0-alpha.17", "description": "In-App Purchase and Subscriptions for NativeScript", "main": "index", "typings": "index.d.ts", diff --git a/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Payments.kt b/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Payments.kt index 16eac5f..061a87a 100644 --- a/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Payments.kt +++ b/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Payments.kt @@ -18,166 +18,156 @@ import java.util.concurrent.CountDownLatch import java.util.concurrent.Executors class Payments(context: Context) { - private var isReady = false - private var isSetup = false - private val purchaseListener = PurchasesUpdatedListener { response, purchases -> - if (response.responseCode == BillingClient.BillingResponseCode.OK && purchases != null) { - val value = purchases.map { - val json = JSONObject(it.originalJson) - Transaction( - it, if (json.optBoolean("autoRenewing", false)) { - Product.Type.Subs - } else { - Product.Type.InApp - }, this@Payments - ) - } - onPurchaseUpdateListener?.let { - it(value, null) - } - } else { - onPurchaseUpdateListener?.let { - it(null, mapResponseCode(response.responseCode)) - } - } - } - internal var billing = BillingClient.newBuilder(context) - .enablePendingPurchases( - PendingPurchasesParams.newBuilder() - .enablePrepaidPlans() - .enableOneTimeProducts() - .build() - ) - .enableAutoServiceReconnection() - .setListener(purchaseListener) - .build() - - private val executor = Executors.newCachedThreadPool() - - var onReadyListener: (() -> Unit)? = null - - var onPurchaseUpdateListener: ((List?, BillingResponse?) -> Unit)? = null - - class BillingResponse( - val code: Int, - val message: String, - val resolution: String, - val subCode: Int = Int.MAX_VALUE - ) { - val raw: String - get() { - if (subCode == BillingClient.OnPurchasesUpdatedSubResponseCode.USER_INELIGIBLE) { - return "USER_INELIGIBLE" - } else if (subCode == BillingClient.OnPurchasesUpdatedSubResponseCode.PAYMENT_DECLINED_DUE_TO_INSUFFICIENT_FUNDS) { - return "INSUFFICIENT_FUNDS" + private var isReady = false + private var isSetup = false + private val purchaseListener = PurchasesUpdatedListener { response, purchases -> + if (response.responseCode == BillingClient.BillingResponseCode.OK && purchases != null) { + val value = purchases.map { + val json = JSONObject(it.originalJson) + Transaction( + it, if (json.optBoolean("autoRenewing", false)) { + Product.Type.Subs + } else { + Product.Type.InApp + }, this@Payments + ) + } + onPurchaseUpdateListener?.let { + it(value, null) + } + } else { + onPurchaseUpdateListener?.let { + it(null, mapResponseCode(response.responseCode)) + } } + } + internal var billing = BillingClient.newBuilder(context).enablePendingPurchases( + PendingPurchasesParams.newBuilder().enablePrepaidPlans().enableOneTimeProducts().build() + ).enableAutoServiceReconnection().setListener(purchaseListener).build() + + private val executor = Executors.newCachedThreadPool() - return when (code) { - BillingClient.BillingResponseCode.OK -> "OK" + var onReadyListener: (() -> Unit)? = null - BillingClient.BillingResponseCode.BILLING_UNAVAILABLE -> "NETWORK_ERROR" + var onPurchaseUpdateListener: ((List?, BillingResponse?) -> Unit)? = null - BillingClient.BillingResponseCode.NETWORK_ERROR -> "NETWORK_ERROR" + class BillingResponse( + val code: Int, val message: String, val resolution: String, val subCode: Int = Int.MAX_VALUE + ) { + val raw: String + get() { + if (subCode == BillingClient.OnPurchasesUpdatedSubResponseCode.USER_INELIGIBLE) { + return "USER_INELIGIBLE" + } else if (subCode == BillingClient.OnPurchasesUpdatedSubResponseCode.PAYMENT_DECLINED_DUE_TO_INSUFFICIENT_FUNDS) { + return "INSUFFICIENT_FUNDS" + } - BillingClient.BillingResponseCode.USER_CANCELED -> "USER_CANCELED" + return when (code) { + BillingClient.BillingResponseCode.OK -> "OK" - BillingClient.BillingResponseCode.ITEM_UNAVAILABLE -> "ITEM_UNAVAILABLE" + BillingClient.BillingResponseCode.BILLING_UNAVAILABLE -> "NETWORK_ERROR" - BillingClient.BillingResponseCode.DEVELOPER_ERROR -> "DEVELOPER_ERROR" + BillingClient.BillingResponseCode.NETWORK_ERROR -> "NETWORK_ERROR" - BillingClient.BillingResponseCode.FEATURE_NOT_SUPPORTED -> "FEATURE_NOT_SUPPORTED" + BillingClient.BillingResponseCode.USER_CANCELED -> "USER_CANCELED" - BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED -> "ITEM_ALREADY_OWNED" + BillingClient.BillingResponseCode.ITEM_UNAVAILABLE -> "ITEM_UNAVAILABLE" - BillingClient.BillingResponseCode.ITEM_NOT_OWNED -> "ITEM_NOT_OWNED" + BillingClient.BillingResponseCode.DEVELOPER_ERROR -> "DEVELOPER_ERROR" - BillingClient.BillingResponseCode.SERVICE_UNAVAILABLE -> "SERVICE_UNAVAILABLE" + BillingClient.BillingResponseCode.FEATURE_NOT_SUPPORTED -> "FEATURE_NOT_SUPPORTED" - BillingClient.BillingResponseCode.SERVICE_DISCONNECTED -> "SERVICE_DISCONNECTED" + BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED -> "ITEM_ALREADY_OWNED" - BillingClient.BillingResponseCode.SERVICE_TIMEOUT -> "SERVICE_TIMEOUT" + BillingClient.BillingResponseCode.ITEM_NOT_OWNED -> "ITEM_NOT_OWNED" - BillingClient.BillingResponseCode.ERROR -> "ERROR" - else -> "UNSPECIFIED" - } - } - } - - enum class Features(val value: String) { - Subscriptions(BillingClient.FeatureType.SUBSCRIPTIONS), - SubscriptionsUpdate(BillingClient.FeatureType.SUBSCRIPTIONS_UPDATE), - PriceChangeConfirmation(BillingClient.FeatureType.PRICE_CHANGE_CONFIRMATION), - InAppMessaging(BillingClient.FeatureType.IN_APP_MESSAGING), - ProductDetails(BillingClient.FeatureType.PRODUCT_DETAILS), - BillingConfig(BillingClient.FeatureType.BILLING_CONFIG), - AlternativeBillingOnly(BillingClient.FeatureType.ALTERNATIVE_BILLING_ONLY), - ExternalOffer(BillingClient.FeatureType.EXTERNAL_OFFER), - } - - class PurchaseOptions { - enum class ReplacementMode(val value: Int) { - Unknown(0), - WithTimeProration(1), - ChargeProratedPrice(2), - WithoutProration(3), - ChargeFullPrice(5), - Deferred(6); + BillingClient.BillingResponseCode.SERVICE_UNAVAILABLE -> "SERVICE_UNAVAILABLE" + + BillingClient.BillingResponseCode.SERVICE_DISCONNECTED -> "SERVICE_DISCONNECTED" + + BillingClient.BillingResponseCode.SERVICE_TIMEOUT -> "SERVICE_TIMEOUT" + + BillingClient.BillingResponseCode.ERROR -> "ERROR" + else -> "UNSPECIFIED" + } + } } - var profileId: String? = null - var accountId: String? = null - var setIsOfferPersonalized = false - var subscriptionUpdateToken: String? = null - var subscriptionUpdateReplacementMode: ReplacementMode? = null - } - - init { - billing.startConnection(object : BillingClientStateListener { - override fun onBillingServiceDisconnected() { - this@Payments.isReady = false - } - - override fun onBillingSetupFinished(p0: BillingResult) { - isSetup = p0.responseCode == BillingClient.BillingResponseCode.OK - if (!this@Payments.isReady) { - this@Payments.isReady = true - onReadyListener?.let { - it() - } + enum class Features(val value: String) { + Subscriptions(BillingClient.FeatureType.SUBSCRIPTIONS), SubscriptionsUpdate(BillingClient.FeatureType.SUBSCRIPTIONS_UPDATE), PriceChangeConfirmation( + BillingClient.FeatureType.PRICE_CHANGE_CONFIRMATION + ), + InAppMessaging(BillingClient.FeatureType.IN_APP_MESSAGING), ProductDetails(BillingClient.FeatureType.PRODUCT_DETAILS), BillingConfig( + BillingClient.FeatureType.BILLING_CONFIG + ), + AlternativeBillingOnly(BillingClient.FeatureType.ALTERNATIVE_BILLING_ONLY), ExternalOffer( + BillingClient.FeatureType.EXTERNAL_OFFER + ), + } + + class PurchaseOptions { + enum class ReplacementMode(val value: Int) { + Unknown(0), WithTimeProration(1), ChargeProratedPrice(2), WithoutProration(3), ChargeFullPrice( + 5 + ), + Deferred(6); } - } - }) - } - fun connect() { - when (billing.connectionState) { - BillingClient.ConnectionState.DISCONNECTED, BillingClient.ConnectionState.CLOSED -> { + var profileId: String? = null + var accountId: String? = null + var setIsOfferPersonalized = false + var subscriptionUpdateToken: String? = null + var subscriptionUpdateReplacementMode: ReplacementMode? = null + } + + init { billing.startConnection(object : BillingClientStateListener { - override fun onBillingServiceDisconnected() { - this@Payments.isReady = false - } - - override fun onBillingSetupFinished(p0: BillingResult) { - isSetup = p0.responseCode == BillingClient.BillingResponseCode.OK - if (!this@Payments.isReady) { - this@Payments.isReady = true - onReadyListener?.let { - it() - } + override fun onBillingServiceDisconnected() { + this@Payments.isReady = false + } + + override fun onBillingSetupFinished(p0: BillingResult) { + isSetup = p0.responseCode == BillingClient.BillingResponseCode.OK + if (!this@Payments.isReady) { + this@Payments.isReady = true + onReadyListener?.let { + it() + } + } } - } }) - } + } + - else -> {} + fun connect() { + when (billing.connectionState) { + BillingClient.ConnectionState.DISCONNECTED, BillingClient.ConnectionState.CLOSED -> { + billing.startConnection(object : BillingClientStateListener { + override fun onBillingServiceDisconnected() { + this@Payments.isReady = false + } + + override fun onBillingSetupFinished(p0: BillingResult) { + isSetup = p0.responseCode == BillingClient.BillingResponseCode.OK + if (!this@Payments.isReady) { + this@Payments.isReady = true + onReadyListener?.let { + it() + } + } + } + }) + } + + else -> {} + } } - } - fun disconnect() { - billing.endConnection() - } + fun disconnect() { + billing.endConnection() + } - fun showInAppMessaging(activity: Activity) { + fun showInAppMessaging(activity: Activity) { // val params = InAppMessageParams.newBuilder() // .apply { // addInAppMessageCategoryToShow(InAppMessageParams.InAppMessageCategoryId.TRANSACTIONAL) @@ -188,277 +178,283 @@ class Payments(context: Context) { // // } // }) - } - - fun canMakePayments(): Boolean { - return isReady && billing.isReady - } - - fun isFeatureSupported(feature: Features): Boolean { - if (!billing.isReady) { - return false } - return billing.isFeatureSupported(feature.value).responseCode == BillingClient.BillingResponseCode.OK - } - - fun fetchProducts( - identifiers: Array, - type: Product.Type, - callback: (List?, BillingResponse?) -> Unit - ) { - val products = identifiers.map { - QueryProductDetailsParams.Product.newBuilder() - .setProductType(type.toType) - .setProductId(it) - .build() + + fun canMakePayments(): Boolean { + return isReady && billing.isReady } - val params = QueryProductDetailsParams.newBuilder() - .setProductList(products) - .build() - - billing.queryProductDetailsAsync(params) { p0, p1 -> - if (p0.responseCode == BillingClient.BillingResponseCode.OK) { - val products = p1.productDetailsList.map { - Product(it) + + fun isFeatureSupported(feature: Features): Boolean { + if (!billing.isReady) { + return false } - callback(products, null) - } else { - callback(null, mapResponseCode(p0.responseCode)) - } + return billing.isFeatureSupported(feature.value).responseCode == BillingClient.BillingResponseCode.OK } - } - - - @JvmOverloads - fun purchaseProduct( - activity: Activity, - product: Product, - options: PurchaseOptions? = null, - callback: (BillingResponse?) -> Unit - ) { - val param = BillingFlowParams.ProductDetailsParams.newBuilder() - .apply { - setProductDetails(product.product) - if (product.type == Product.Type.Subs) { - product.product.subscriptionOfferDetails?.first()?.let { - setOfferToken(it.offerToken) - } - } - } - .build() - - val flow = BillingFlowParams.newBuilder() - .apply { - options?.let { - setIsOfferPersonalized(it.setIsOfferPersonalized) - it.profileId?.let { id -> - setObfuscatedProfileId(id) - } - - it.accountId?.let { id -> - setObfuscatedAccountId(id) - } - - it.subscriptionUpdateToken?.let { token -> - val params = BillingFlowParams.SubscriptionUpdateParams.newBuilder() - .apply { - it.subscriptionUpdateReplacementMode?.let { mode -> - setSubscriptionReplacementMode(mode.value) - } - } - .setOldPurchaseToken(token) - .build() - setSubscriptionUpdateParams(params) - } + fun fetchProducts( + identifiers: Array, + type: Product.Type, + callback: (List?, BillingResponse?) -> Unit + ) { + val products = identifiers.map { + QueryProductDetailsParams.Product.newBuilder().setProductType(type.toType) + .setProductId(it) + .build() } - setProductDetailsParamsList(listOf(param)) - } - .build() - - val response = billing.launchBillingFlow(activity, flow) - - executor.execute { - if (response.responseCode != BillingClient.BillingResponseCode.OK) { - val res = when (response.onPurchasesUpdatedSubResponseCode) { - BillingClient.OnPurchasesUpdatedSubResponseCode.PAYMENT_DECLINED_DUE_TO_INSUFFICIENT_FUNDS -> { - BillingResponse( - Int.MAX_VALUE, - "The payment was declined due to insufficient funds.", - "The user must either add funds/increase limits or retry the transaction with a different payment method", - response.onPurchasesUpdatedSubResponseCode - ) - } - - BillingClient.OnPurchasesUpdatedSubResponseCode.USER_INELIGIBLE -> { - BillingResponse( - Int.MAX_VALUE, - "the user does not currently meet offer eligibility requirements.", - "This offer isn’t available in your region or for your account type.”", - response.onPurchasesUpdatedSubResponseCode - ) - } - - else -> { - if (enableDebug) { - Log.d( - "JS", - "mapSubResponseCode ${response.onPurchasesUpdatedSubResponseCode}" - ) + val params = QueryProductDetailsParams.newBuilder().setProductList(products).build() + + billing.queryProductDetailsAsync(params) { p0, p1 -> + if (p0.responseCode == BillingClient.BillingResponseCode.OK) { + val products = p1.productDetailsList.map { + Product(it) + } + callback(products, null) + } else { + callback(null, mapResponseCode(p0.responseCode)) } - BillingResponse(Int.MAX_VALUE, "", "", Int.MAX_VALUE) - } } + } - callback(res) - return@execute - } - callback(null) - } - } - - fun fetchPurchases(callback: (List?, BillingResponse?) -> Unit) { - executor.execute { - val inapp = QueryPurchasesParams.newBuilder() - .setProductType(BillingClient.ProductType.INAPP) - .build() - val subs = QueryPurchasesParams.newBuilder() - .setProductType(BillingClient.ProductType.SUBS) - .build() - val ret = arrayOf>(mutableListOf(), mutableListOf()) - val error = arrayOfNulls(1) - val lock = CountDownLatch(2) - billing.queryPurchasesAsync(inapp) { p0, p1 -> - if (p0.responseCode == BillingClient.BillingResponseCode.OK) { - p1.forEach { purchase -> - purchase?.let { - ret[0].add(Transaction(it, Product.Type.InApp, this)) + @JvmOverloads + fun purchaseProduct( + activity: Activity, + product: Product, + options: PurchaseOptions? = null, + callback: (BillingResponse?) -> Unit + ) { + val param = BillingFlowParams.ProductDetailsParams.newBuilder().apply { + setProductDetails(product.product) + if (product.type == Product.Type.Subs) { + product.product.subscriptionOfferDetails?.first()?.let { + setOfferToken(it.offerToken) + } } - } - } else { - error[0] = mapResponseCode(p0.responseCode) - } - lock.countDown() - } - - billing.queryPurchasesAsync(subs) { p0, p1 -> - if (p0.responseCode == BillingClient.BillingResponseCode.OK) { - p1.forEach { purchase -> - purchase?.let { - ret[1].add(Transaction(it, Product.Type.Subs, this)) + }.build() + + val flow = BillingFlowParams.newBuilder().apply { + options?.let { + setIsOfferPersonalized(it.setIsOfferPersonalized) + it.profileId?.let { id -> + setObfuscatedProfileId(id) + } + + it.accountId?.let { id -> + setObfuscatedAccountId(id) + } + + it.subscriptionUpdateToken?.let { token -> + val params = BillingFlowParams.SubscriptionUpdateParams.newBuilder().apply { + it.subscriptionUpdateReplacementMode?.let { mode -> + setSubscriptionReplacementMode(mode.value) + } + }.setOldPurchaseToken(token).build() + + setSubscriptionUpdateParams(params) + } } - } - } else { - error[0] = mapResponseCode(p0.responseCode) + setProductDetailsParamsList(listOf(param)) + }.build() + + val response = billing.launchBillingFlow(activity, flow) + + executor.execute { + if (response.responseCode != BillingClient.BillingResponseCode.OK) { + val res = when (response.onPurchasesUpdatedSubResponseCode) { + BillingClient.OnPurchasesUpdatedSubResponseCode.PAYMENT_DECLINED_DUE_TO_INSUFFICIENT_FUNDS -> { + BillingResponse( + Int.MAX_VALUE, + "The payment was declined due to insufficient funds.", + "The user must either add funds/increase limits or retry the transaction with a different payment method", + response.onPurchasesUpdatedSubResponseCode + ) + } + + BillingClient.OnPurchasesUpdatedSubResponseCode.USER_INELIGIBLE -> { + BillingResponse( + Int.MAX_VALUE, + "the user does not currently meet offer eligibility requirements.", + "This offer isn’t available in your region or for your account type.”", + response.onPurchasesUpdatedSubResponseCode + ) + } + + else -> { + if (enableDebug) { + Log.d( + "JS", + "mapSubResponseCode ${response.onPurchasesUpdatedSubResponseCode}" + ) + } + BillingResponse(Int.MAX_VALUE, "", "", Int.MAX_VALUE) + } + } + + callback(res) + return@execute + } + + callback(null) } - lock.countDown() - } - - try { - lock.await() - ret[0].addAll(ret[1]) - callback( - ret[0], null - ) - } catch (_: Exception) { - callback(null, error[0]) - } } - } - - companion object { - @JvmStatic - var enableDebug = false - - @JvmStatic - internal fun mapResponseCode(code: Int): BillingResponse { - return when (code) { - BillingClient.BillingResponseCode.OK -> BillingResponse(code, "OK", "") - - BillingClient.BillingResponseCode.BILLING_UNAVAILABLE -> BillingResponse( - code, - "A user billing error occurred during processing.", - "Automatic retries are unlikely to help in this case. However, a manual retry can help if the user addresses the condition that caused the issue." - ) - - BillingClient.BillingResponseCode.NETWORK_ERROR -> BillingResponse( - code, - "A network error occurred during the operation.", - "" - ) - - BillingClient.BillingResponseCode.USER_CANCELED -> BillingResponse( - code, - "The user has clicked out of the billing flow UI.", - "This is informational only and can fail gracefully." - ) - - BillingClient.BillingResponseCode.ITEM_UNAVAILABLE -> BillingResponse( - code, - "The requested product is not available for purchase.", - "Make sure your app refreshes the product details via queryProductDetailsAsync as recommended." - ) - - BillingClient.BillingResponseCode.DEVELOPER_ERROR -> BillingResponse( - code, - "Error resulting from incorrect usage of the API.", - "Make sure that you are correctly using the different Play Billing Library calls. Also, check the debug message for more info about the error." - ) - - BillingClient.BillingResponseCode.FEATURE_NOT_SUPPORTED -> BillingResponse( - code, - "The requested feature is not supported by the Play Store on the current device.", - "Use isFeatureSupported() to check feature support before making the call to the Play Billing Library." - ) - - BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED -> BillingResponse( - code, - "The purchase failed because the item is already owned.", - "To avoid this error happening when the cause is not a cache issue, don't offer a product for purchase when the user already owns it." - ) - - BillingClient.BillingResponseCode.ITEM_NOT_OWNED -> BillingResponse( - code, - "Requested action on the item failed since it is not owned by the user.", - "When the error is received because of a cache issue, the error triggers Google Play’s cache to get updated with the latest data from Play’s backend." - ) - - BillingClient.BillingResponseCode.SERVICE_UNAVAILABLE -> BillingResponse( - code, - "The service is currently unavailable.", - "This is usually a transient issue. Retry the request using either either a simple or exponential backoff strategy, depending on which action returned the error." - ) - - BillingClient.BillingResponseCode.SERVICE_DISCONNECTED -> BillingResponse( - code, - "The app is not connected to the Play Store service via the Google Play Billing Library.", - "To attempt recovery from SERVICE_DISCONNECTED , your client app should try to re-establish the connection using .restartConnection." - ) - - BillingClient.BillingResponseCode.ERROR -> BillingResponse( - code, - "Fatal error during the API action.", - "Sometimes internal Google Play problems that lead to ERROR are transient, and a retry with an exponential backoff can be implemented for mitigation. When users are in session, a simple retry is preferable." - ) - - else -> { - if (enableDebug) { - Log.d("JS", "mapResponseCode $code") - } - return BillingResponse(Int.MAX_VALUE, "", "") + + fun fetchPurchases(callback: (List?, BillingResponse?) -> Unit) { + executor.execute { + val inapp = + QueryPurchasesParams.newBuilder().setProductType(BillingClient.ProductType.INAPP) + .build() + val subs = + QueryPurchasesParams.newBuilder().setProductType(BillingClient.ProductType.SUBS) + .build() + val ret = arrayOf>(mutableListOf(), mutableListOf()) + val error = arrayOfNulls(1) + val lock = CountDownLatch(2) + billing.queryPurchasesAsync(inapp) { p0, p1 -> + if (p0.responseCode == BillingClient.BillingResponseCode.OK) { + p1.forEach { purchase -> + purchase?.let { + ret[0].add(Transaction(it, Product.Type.InApp, this)) + } + } + } else { + error[0] = mapResponseCode(p0.responseCode) + } + lock.countDown() + } + + billing.queryPurchasesAsync(subs) { p0, p1 -> + if (p0.responseCode == BillingClient.BillingResponseCode.OK) { + p1.forEach { purchase -> + purchase?.let { + ret[1].add(Transaction(it, Product.Type.Subs, this)) + } + } + } else { + error[0] = mapResponseCode(p0.responseCode) + } + lock.countDown() + } + + try { + lock.await() + ret[0].addAll(ret[1]) + callback( + ret[0], null + ) + } catch (_: Exception) { + callback(null, error[0]) + } } - } } - @JvmStatic - fun isSupported(context: Context): Boolean { - val playStoreIntent = Intent(Intent.ACTION_VIEW).apply { - data = Uri.parse("market://details?id=${context.packageName}") - setPackage("com.android.vending") - } - return playStoreIntent.resolveActivity(context.packageManager) != null + companion object { + @JvmStatic + var enableDebug = false + + @JvmStatic + internal fun mapResponseCode(code: Int): BillingResponse { + return when (code) { + BillingClient.BillingResponseCode.OK -> BillingResponse(code, "OK", "") + + BillingClient.BillingResponseCode.BILLING_UNAVAILABLE -> BillingResponse( + code, + "A user billing error occurred during processing.", + "Automatic retries are unlikely to help in this case. However, a manual retry can help if the user addresses the condition that caused the issue." + ) + + BillingClient.BillingResponseCode.NETWORK_ERROR -> BillingResponse( + code, "A network error occurred during the operation.", "" + ) + + BillingClient.BillingResponseCode.USER_CANCELED -> BillingResponse( + code, + "The user has clicked out of the billing flow UI.", + "This is informational only and can fail gracefully." + ) + + BillingClient.BillingResponseCode.ITEM_UNAVAILABLE -> BillingResponse( + code, + "The requested product is not available for purchase.", + "Make sure your app refreshes the product details via queryProductDetailsAsync as recommended." + ) + + BillingClient.BillingResponseCode.DEVELOPER_ERROR -> BillingResponse( + code, + "Error resulting from incorrect usage of the API.", + "Make sure that you are correctly using the different Play Billing Library calls. Also, check the debug message for more info about the error." + ) + + BillingClient.BillingResponseCode.FEATURE_NOT_SUPPORTED -> BillingResponse( + code, + "The requested feature is not supported by the Play Store on the current device.", + "Use isFeatureSupported() to check feature support before making the call to the Play Billing Library." + ) + + BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED -> BillingResponse( + code, + "The purchase failed because the item is already owned.", + "To avoid this error happening when the cause is not a cache issue, don't offer a product for purchase when the user already owns it." + ) + + BillingClient.BillingResponseCode.ITEM_NOT_OWNED -> BillingResponse( + code, + "Requested action on the item failed since it is not owned by the user.", + "When the error is received because of a cache issue, the error triggers Google Play’s cache to get updated with the latest data from Play’s backend." + ) + + BillingClient.BillingResponseCode.SERVICE_UNAVAILABLE -> BillingResponse( + code, + "The service is currently unavailable.", + "This is usually a transient issue. Retry the request using either either a simple or exponential backoff strategy, depending on which action returned the error." + ) + + BillingClient.BillingResponseCode.SERVICE_DISCONNECTED -> BillingResponse( + code, + "The app is not connected to the Play Store service via the Google Play Billing Library.", + "To attempt recovery from SERVICE_DISCONNECTED , your client app should try to re-establish the connection using .restartConnection." + ) + + BillingClient.BillingResponseCode.ERROR -> BillingResponse( + code, + "Fatal error during the API action.", + "Sometimes internal Google Play problems that lead to ERROR are transient, and a retry with an exponential backoff can be implemented for mitigation. When users are in session, a simple retry is preferable." + ) + + else -> { + if (enableDebug) { + Log.d("JS", "mapResponseCode $code") + } + return BillingResponse(Int.MAX_VALUE, "", "") + } + } + } + + @JvmStatic + fun isSupported(context: Context): Boolean { + val playStoreIntent = Intent(Intent.ACTION_VIEW).apply { + data = Uri.parse("market://details?id=${context.packageName}") + setPackage("com.android.vending") + } + return playStoreIntent.resolveActivity(context.packageManager) != null + } + + + @JvmOverloads + @JvmStatic + fun showManageSubscriptions( + context: Context, + packageName: String? = null, + productId: String? = null + ) { + var url = "https://play.google.com/store/account/subscriptions" + productId?.let { id -> + url = "$url?sku=$id&package=${packageName ?: context.packageName}" + } + val uri = Uri.parse(url) + val intent = Intent(Intent.ACTION_VIEW, uri) + intent.setPackage("com.android.vending") + context.startActivity(intent) + } } - } } diff --git a/packages/payments/platforms/ios/src/NSCPayment.swift b/packages/payments/platforms/ios/src/NSCPayment.swift index 765a76b..adfa100 100644 --- a/packages/payments/platforms/ios/src/NSCPayment.swift +++ b/packages/payments/platforms/ios/src/NSCPayment.swift @@ -46,8 +46,8 @@ public enum NSCPaymentsStoreKitVersion: Int32, RawRepresentable { } -@objc(NSCTransactionState) -public enum NSCTransactionState: Int32, RawRepresentable { +@objc(NSCPaymentsTransactionState) +public enum NSCPaymentsTransactionState: Int32, RawRepresentable { case unknown case purchased case pending @@ -80,9 +80,9 @@ public enum NSCTransactionState: Int32, RawRepresentable { } } -@objc(NSCTransaction) +@objc(NSCPaymentsTransaction) @objcMembers -public class NSCTransaction: NSObject { +public class NSCPaymentsTransaction: NSObject { public let version: NSCPaymentsStoreKitVersion internal var transaction: Any init(transaction: Any, _ version : NSCPaymentsStoreKitVersion) { @@ -90,6 +90,8 @@ public class NSCTransaction: NSObject { self.transaction = transaction } + public internal(set) var isAcknowledged: Bool = false + public var orderId: String? { if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { return "\(v2!.id)" @@ -124,7 +126,7 @@ public class NSCTransaction: NSObject { } } - var state: NSCTransactionState { + var state: NSCPaymentsTransactionState { get { if(version == .v2 && version.storeKit2Available){ if #available(iOS 15.0, *) { @@ -282,6 +284,7 @@ public class NSCTransaction: NSObject { case .verified(let t): if(t.id == v2!.id){ self.transaction = transaction + self.isAcknowledged = true callback(nil) break } @@ -291,15 +294,19 @@ public class NSCTransaction: NSObject { } } else { SKPaymentQueue.default().finishTransaction(v1!) + isAcknowledged = true } } } -@objc(NSCProduct) +@objc(NSCPaymentsProduct) @objcMembers -public class NSCProduct: NSObject { +public class NSCPaymentsProduct: NSObject { public let version: NSCPaymentsStoreKitVersion + public internal(set) var isPromoted: Bool = false + internal var promotedPayment: SKPayment? = nil internal let product: Any + internal var promotedOffer: Any? init(product: Any, _ version : NSCPaymentsStoreKitVersion) { self.product = product self.version = version @@ -535,9 +542,9 @@ public class NSCPaymentsResponse: NSObject { } } -@objc(NSCPurchaseOptions) +@objc(NSCPaymentsPurchaseOptions) @objcMembers -public class NSCPurchaseOptions: NSObject { +public class NSCPaymentsPurchaseOptions: NSObject { public var accountId: String? public var accountUUID: UUID? public var quantity: Int = 1 @@ -548,26 +555,33 @@ public class NSCPurchaseOptions: NSObject { @objcMembers public class NSCPayments: NSObject { internal var updatesListener: AnyObject? + internal var promotionListener: AnyObject? internal var pendingTasks: [AnyObject] = [] public let version: NSCPaymentsStoreKitVersion - public var transactionUpdateListener: ((NSCTransaction) -> Void)? + public var transactionUpdateListener: ((NSCPaymentsTransaction) -> Void)? + public var incomingPromotionListener: ((NSCPaymentsProduct) -> Bool)? internal var isRestoring = false - internal var fetchingPurchases: [([NSCTransaction]?, NSCPaymentsResponse?) -> Void] = [] - internal var previousPurchases: [NSCTransaction] = [] + internal var fetchingPurchases: [([NSCPaymentsTransaction]?, NSCPaymentsResponse?) -> Void] = [] + internal var previousPurchases: [NSCPaymentsTransaction] = [] + private var emittedUpdate: Set = [] public override init() { if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { version = .v2 super.init() - updatesListener = Task(priority: .background) { + updatesListener = Task.detached(priority: .background) { for await transaction in Transaction.updates { switch transaction { case .unverified(let transaction, let error): - let ret = NSCTransaction(transaction: transaction, .v2) + let ret = NSCPaymentsTransaction(transaction: transaction, .v2) ret.errorValue = error - transactionUpdateListener?(ret) + self.transactionUpdateListener?(ret) break case .verified(let transaction): - transactionUpdateListener?(NSCTransaction(transaction: transaction, .v2)) + if(self.emittedUpdate.contains(transaction.id)){ + self.emittedUpdate.remove(transaction.id) + continue + } + self.transactionUpdateListener?(NSCPaymentsTransaction(transaction: transaction, .v2)) break } } @@ -591,8 +605,8 @@ public class NSCPayments: NSObject { }catch {} if(payments.isRestoring){ for transaction in transactions where transaction.transactionState == .restored { - let value = NSCTransaction(transaction: transaction, .v1) - + let value = NSCPaymentsTransaction(transaction: transaction, .v1) + value.isAcknowledged = true if let receipt = receipt { value.receiptV1 = receipt.base64 let purchaseInfo = receipt.activeAutoRenewableSubscriptionPurchases @@ -619,7 +633,7 @@ public class NSCPayments: NSObject { } }else { for transaction in transactions { - let value = NSCTransaction(transaction: transaction, .v1) + let value = NSCPaymentsTransaction(transaction: transaction, .v1) if let receipt = receipt { value.receiptV1 = receipt.base64 let purchaseInfo = receipt.activeAutoRenewableSubscriptionPurchases @@ -642,16 +656,12 @@ public class NSCPayments: NSObject { } } } - - payments.transactionUpdateListener?(value) } } } - func paymentQueue(_ queue: SKPaymentQueue, removedTransactions transactions: [SKPaymentTransaction]) { - - } + func paymentQueue(_ queue: SKPaymentQueue, removedTransactions transactions: [SKPaymentTransaction]) { } func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: Error) { if(payments.isRestoring){ @@ -673,7 +683,20 @@ public class NSCPayments: NSObject { } } - func paymentQueue(shouldAddStorePayment payment: SKPayment, forTransaction transaction: SKPaymentTransaction) -> Bool { + func paymentQueue(_ queue: SKPaymentQueue, shouldAddStorePayment payment: SKPayment, for product: SKProduct) -> Bool { + if #available(iOS 16.4, *) { + if(payments.version == .v2){ + return true + } + } + + if let listener = payments.incomingPromotionListener { + let product = NSCPaymentsProduct(product: product, .v1) + product.isPromoted = true + product.promotedPayment = payment + return listener(product) + } + return true } } @@ -683,6 +706,21 @@ public class NSCPayments: NSObject { updatesListener = instance } + if #available(iOS 16.4, *) { + if(version == .v2){ + promotionListener = Task(priority: .background) { + for await intent in PurchaseIntent.intents { + let product = NSCPaymentsProduct(product: intent.product, .v2) + product.isPromoted = true + if #available(iOS 18.0, *) { + product.promotedOffer = intent.offer + } + let _ = self.incomingPromotionListener?(product) + } + } as AnyObject + } + } + } deinit { @@ -701,17 +739,17 @@ public class NSCPayments: NSObject { public func canMakePayments() -> Bool { return NSCPayments.isSupported() } - public func fetchProducts(_ identifiers: [String], _ callback: @escaping ([NSCProduct], Error?) -> Void) { + public func fetchProducts(_ identifiers: [String], _ callback: @escaping ([NSCPaymentsProduct], Error?) -> Void) { switch(version){ case .v1: let request = SKProductsRequest(productIdentifiers: Set(identifiers)) let delegate: SKProductsRequestDelegate = { class SKProductsRequestDelegateImpl: NSObject, SKProductsRequestDelegate { - let callback: ([NSCProduct], Error?) -> Void + let callback: ([NSCPaymentsProduct], Error?) -> Void let version: NSCPaymentsStoreKitVersion let payments: NSCPayments - init(_ cb: @escaping ([NSCProduct], Error?) -> Void, _ storeVerion: NSCPaymentsStoreKitVersion, _ payment: NSCPayments){ + init(_ cb: @escaping ([NSCPaymentsProduct], Error?) -> Void, _ storeVerion: NSCPaymentsStoreKitVersion, _ payment: NSCPayments){ version = storeVerion callback = cb payments = payment @@ -722,7 +760,7 @@ public class NSCPayments: NSObject { func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) { let products = response.products.map { - return NSCProduct(product: $0, version) + return NSCPaymentsProduct(product: $0, version) } callback( products, nil) } @@ -744,7 +782,7 @@ public class NSCPayments: NSObject { do { let products = try await Product.products(for: Set(identifiers)) - let ret = products.map {NSCProduct(product: $0, version)} + let ret = products.map {NSCPaymentsProduct(product: $0, version)} callback(ret,nil) }catch { callback([], error) @@ -755,10 +793,16 @@ public class NSCPayments: NSObject { } } - public func purchaseProduct(_ product: NSCProduct, _ confirmIn: UIViewController, _ options: NSCPurchaseOptions?, _ callback: @escaping (NSCPaymentsResponse?)->Void){ + public func purchaseProduct(_ product: NSCPaymentsProduct, _ confirmIn: UIViewController, _ options: NSCPaymentsPurchaseOptions?, _ callback: @escaping (NSCPaymentsResponse?)->Void){ switch(version){ case .v1: - let payment = SKMutablePayment(product: product.v1!) + + let payment = if(product.isPromoted){ + product.promotedPayment!.mutableCopy() as! SKMutablePayment + }else { + SKMutablePayment(product: product.v1!) + } + if let options = options { if let accountId = options.accountId { payment.applicationUsername = accountId @@ -767,7 +811,6 @@ public class NSCPayments: NSObject { payment.simulatesAskToBuyInSandbox = options.simulatesAskToBuyInSandbox } - SKPaymentQueue.default().add(payment) break case .v2: @@ -812,8 +855,11 @@ public class NSCPayments: NSObject { NSCPaymentsResponse(code: .Error, message: "Usage error: \(verificationError.localizedDescription)", resolution: "") ) break - case .verified(_): + case .verified(let transaction): callback(nil) + let ret = NSCPaymentsTransaction(transaction: transaction, .v2) + self.emittedUpdate.insert(transaction.id) + transactionUpdateListener?(ret) break } case .userCancelled: @@ -837,13 +883,13 @@ public class NSCPayments: NSObject { // return error + transaction ? - public func fetchPurchases(_ callback: @escaping ([NSCTransaction]?, NSCPaymentsResponse?) -> Void){ + public func fetchPurchases(_ callback: @escaping ([NSCPaymentsTransaction]?, NSCPaymentsResponse?) -> Void){ if(version == .v2 && version.storeKit2Available){ if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *){ Task(priority: .background) { do { try await AppStore.sync() - var purchases: [NSCTransaction] = [] + var purchases: [NSCPaymentsTransaction] = [] var hasError: Bool = false for await transaction in Transaction.currentEntitlements { switch transaction { @@ -852,7 +898,7 @@ public class NSCPayments: NSObject { hasError = true return case .verified(let transaction): - purchases.append(NSCTransaction(transaction: transaction, .v2)) + purchases.append(NSCPaymentsTransaction(transaction: transaction, .v2)) break } } @@ -883,4 +929,29 @@ public class NSCPayments: NSObject { return SKPaymentQueue.canMakePayments() } } + + public static func showManageSubscriptions(_ showIn: UIViewController, _ subscriptionGroupID: String? = nil, _ callback: @escaping (String?) -> Void){ + if #available(iOS 15.0, *) { + Task { + if let scene = await showIn.view.window?.windowScene { + if let id = subscriptionGroupID { + if #available(iOS 17.0, *) { + try await AppStore.showManageSubscriptions(in: scene, subscriptionGroupID: id) + } else { + try await AppStore.showManageSubscriptions(in: scene) + } + }else { + try await AppStore.showManageSubscriptions(in: scene) + } + }else { + callback("Invalid view controller") + } + + } + }else { + UIApplication.shared.open(URL(string: "https://apps.apple.com/account/subscriptions")!, options: [:]) {_ in + callback(nil) + } + } + } } diff --git a/packages/payments/typings/android.d.ts b/packages/payments/typings/android.d.ts index ad8e9c4..a0f2b06 100644 --- a/packages/payments/typings/android.d.ts +++ b/packages/payments/typings/android.d.ts @@ -5,42 +5,48 @@ declare module org { export class Payments { public static class: java.lang.Class; public showInAppMessaging(activity: globalAndroid.app.Activity): void; - public getBilling$payments_release(): com.android.billingclient.api.BillingClient; public setOnPurchaseUpdateListener(value: any): void; public isFeatureSupported(feature: org.nativescript.plugins.payments.Payments.Features): boolean; - public purchaseProduct(it: globalAndroid.app.Activity, product: org.nativescript.plugins.payments.Product, opts: org.nativescript.plugins.payments.Payments.PurchaseOptions, callback: any): void; + public static showManageSubscriptions(context: globalAndroid.content.Context, packageName: string): void; public static getEnableDebug(): boolean; - public fetchProducts(it: androidNative.Array, item$iv$iv: org.nativescript.plugins.payments.Product.Type, $i$f$mapTo: any): void; - public constructor(pendingParams: globalAndroid.content.Context); - public purchaseProduct(activity: globalAndroid.app.Activity, product: org.nativescript.plugins.payments.Product, callback: any): void; + public static showManageSubscriptions(context: globalAndroid.content.Context): void; public fetchPurchases(callback: any): void; public canMakePayments(): boolean; - public static isSupported(context: globalAndroid.content.Context): boolean; public static setEnableDebug(value: boolean): void; public connect(): void; - public getOnReadyListener(): any; public setOnReadyListener(value: any): void; public getOnPurchaseUpdateListener(): any; - public setBilling$payments_release(value: com.android.billingclient.api.BillingClient): void; public disconnect(): void; public static mapResponseCode$payments_release(code: number): org.nativescript.plugins.payments.Payments.BillingResponse; + public getBilling$payments_release(): com.android.billingclient.api.BillingClient; + public fetchProducts(it: androidNative.Array, item$iv$iv: org.nativescript.plugins.payments.Product.Type, $i$f$mapTo: any): void; + public static showManageSubscriptions(context: globalAndroid.content.Context, packageName: string, productId: string): void; + public purchaseProduct(activity: globalAndroid.app.Activity, product: org.nativescript.plugins.payments.Product, callback: any): void; + public static isSupported(context: globalAndroid.content.Context): boolean; + public getOnReadyListener(): any; + public constructor(context: globalAndroid.content.Context); + public purchaseProduct(it: globalAndroid.app.Activity, product: org.nativescript.plugins.payments.Product, $this$purchaseProduct_u24lambda_u2422: org.nativescript.plugins.payments.Payments.PurchaseOptions, callback: any): void; + public setBilling$payments_release(value: com.android.billingclient.api.BillingClient): void; } export module Payments { export class BillingResponse { public static class: java.lang.Class; public getMessage(): string; public constructor(code: number, message: string, resolution: string, subCode: number); + public getRaw(): string; public getCode(): number; public getResolution(): string; public getSubCode(): number; - public getRaw(): string; } export class Companion { public static class: java.lang.Class; public isSupported($this$isSupported_u24lambda_u240: globalAndroid.content.Context): boolean; + public showManageSubscriptions(context: globalAndroid.content.Context): void; + public showManageSubscriptions(id: globalAndroid.content.Context, url: string, uri: string): void; public getEnableDebug(): boolean; public mapResponseCode$payments_release(code: number): org.nativescript.plugins.payments.Payments.BillingResponse; public setEnableDebug(value: boolean): void; + public showManageSubscriptions(context: globalAndroid.content.Context, packageName: string): void; } export class Features { public static class: java.lang.Class; diff --git a/packages/payments/typings/objc!NSCPayments.d.ts b/packages/payments/typings/objc!NSCPayments.d.ts index 045c7ca..e847214 100644 --- a/packages/payments/typings/objc!NSCPayments.d.ts +++ b/packages/payments/typings/objc!NSCPayments.d.ts @@ -5,13 +5,19 @@ declare class NSCPayments extends NSObject { static new(): NSCPayments; // inherited from NSObject + static showManageSubscriptions(showIn: UIViewController, subscriptionGroupID: string, callback: (p1: string) => void): void; + + incomingPromotionListener: (p1: NSCPaymentsProduct) => boolean; + isRestoring: boolean; pendingTasks: NSArray; - previousPurchases: NSArray; + previousPurchases: NSArray; + + promotionListener: any; - transactionUpdateListener: (p1: NSCTransaction) => void; + transactionUpdateListener: (p1: NSCPaymentsTransaction) => void; updatesListener: any; @@ -19,11 +25,63 @@ declare class NSCPayments extends NSObject { canMakePayments(): boolean; - fetchProducts(identifiers: NSArray | string[], callback: (p1: NSArray, p2: NSError) => void): void; + fetchProducts(identifiers: NSArray | string[], callback: (p1: NSArray, p2: NSError) => void): void; + + fetchPurchases(callback: (p1: NSArray, p2: NSCPaymentsResponse) => void): void; + + purchaseProduct(product: NSCPaymentsProduct, confirmIn: UIViewController, options: NSCPaymentsPurchaseOptions, callback: (p1: NSCPaymentsResponse) => void): void; +} + +declare class NSCPaymentsProduct extends NSObject { + static alloc(): NSCPaymentsProduct; // inherited from NSObject + + static new(): NSCPaymentsProduct; // inherited from NSObject + + readonly displayName: string; + + readonly id: string; + + readonly isFamilyShareable: boolean; + + isPromoted: boolean; + + readonly price: number; + + readonly priceCurrencyCode: string; + + readonly priceFormatted: string; + + readonly product: any; + + readonly productIdentifier: string; + + promotedOffer: any; + + promotedPayment: SKPayment; + + readonly type: string; + + readonly v1: SKProduct; + + readonly version: NSCPaymentsStoreKitVersion; - fetchPurchases(callback: (p1: NSArray, p2: NSCPaymentsResponse) => void): void; + constructor(o: { product: any }); - purchaseProduct(product: NSCProduct, confirmIn: UIViewController, options: NSCPurchaseOptions, callback: (p1: NSCPaymentsResponse) => void): void; + initWithProduct(product: any, version: NSCPaymentsStoreKitVersion): this; +} + +declare class NSCPaymentsPurchaseOptions extends NSObject { + static alloc(): NSCPaymentsPurchaseOptions; // inherited from NSObject + + static new(): NSCPaymentsPurchaseOptions; // inherited from NSObject + + accountId: string; + + accountUUID: NSUUID; + + quantity: number; + + simulatesAskToBuyInSandbox: boolean; } declare class NSCPaymentsResponse extends NSObject { @@ -33,10 +91,10 @@ declare class NSCPaymentsResponse extends NSObject { readonly code: NSCPaymentsResponseFailure; - readonly raw: string; - readonly message: string; + readonly raw: string; + readonly resolution: string; constructor(o: { code: NSCPaymentsResponseFailure; message: string; resolution: string }); @@ -74,56 +132,10 @@ declare const enum NSCPaymentsStoreKitVersion { V2 = 1, } -declare class NSCProduct extends NSObject { - static alloc(): NSCProduct; // inherited from NSObject - - static new(): NSCProduct; // inherited from NSObject - - readonly displayName: string; - - readonly id: string; - - readonly isFamilyShareable: boolean; - - readonly price: number; - - readonly priceCurrencyCode: string; - - readonly priceFormatted: string; - - readonly product: any; - - readonly productIdentifier: string; - - readonly type: string; - - readonly v1: SKProduct; - - readonly version: NSCPaymentsStoreKitVersion; - - constructor(o: { product: any }); - - initWithProduct(product: any, version: NSCPaymentsStoreKitVersion): this; -} - -declare class NSCPurchaseOptions extends NSObject { - static alloc(): NSCPurchaseOptions; // inherited from NSObject - - static new(): NSCPurchaseOptions; // inherited from NSObject +declare class NSCPaymentsTransaction extends NSObject { + static alloc(): NSCPaymentsTransaction; // inherited from NSObject - accountId: string; - - accountUUID: NSUUID; - - quantity: number; - - simulatesAskToBuyInSandbox: boolean; -} - -declare class NSCTransaction extends NSObject { - static alloc(): NSCTransaction; // inherited from NSObject - - static new(): NSCTransaction; // inherited from NSObject + static new(): NSCPaymentsTransaction; // inherited from NSObject readonly error: NSError; @@ -133,6 +145,8 @@ declare class NSCTransaction extends NSObject { expirationDateV1: Date; + readonly isAcknowledged: boolean; + readonly isExpired: boolean; readonly isRevoked: boolean; @@ -147,11 +161,13 @@ declare class NSCTransaction extends NSObject { readonly receipt: string; + receiptV1: string; + readonly revocationDate: Date; revocationDateV1: Date; - readonly state: NSCTransactionState; + readonly state: NSCPaymentsTransactionState; transaction: any; @@ -168,7 +184,7 @@ declare class NSCTransaction extends NSObject { initWithTransaction(transaction: any, version: NSCPaymentsStoreKitVersion): this; } -declare const enum NSCTransactionState { +declare const enum NSCPaymentsTransactionState { Unknown = 0, Purchased = 1, From f7a783f6d9f01bab49aeaa81e95d3052d5957685 Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Fri, 15 Aug 2025 02:54:38 -0400 Subject: [PATCH 26/34] fix(payments): purchase & restore state --- packages/payments/platforms/ios/src/NSCPayment.swift | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/payments/platforms/ios/src/NSCPayment.swift b/packages/payments/platforms/ios/src/NSCPayment.swift index adfa100..eec26f3 100644 --- a/packages/payments/platforms/ios/src/NSCPayment.swift +++ b/packages/payments/platforms/ios/src/NSCPayment.swift @@ -838,11 +838,7 @@ public class NSCPayments: NSObject { var result: Product.PurchaseResult if #available(iOS 18.2, *) { - if let scene = await confirmIn.view.window?.windowScene { - result = try await product.v2!.purchase(confirmIn: scene, options: opts) - }else { - result = try await product.v2!.purchase(options: opts) - } + result = try await product.v2!.purchase(confirmIn: confirmIn, options: opts) }else { result = try await product.v2!.purchase(options: opts) } @@ -898,7 +894,9 @@ public class NSCPayments: NSObject { hasError = true return case .verified(let transaction): - purchases.append(NSCPaymentsTransaction(transaction: transaction, .v2)) + let restored = NSCPaymentsTransaction(transaction: transaction, .v2) + restored.isAcknowledged = true + purchases.append(restored) break } } From 7e9adfb426644508ea4cd9ee6edc8e97cbdf6adc Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Fri, 15 Aug 2025 02:55:18 -0400 Subject: [PATCH 27/34] chore(payments): bump --- packages/payments/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/payments/package.json b/packages/payments/package.json index 1e7d8c8..ef7abce 100644 --- a/packages/payments/package.json +++ b/packages/payments/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/payments", - "version": "4.0.0-alpha.17", + "version": "4.0.0-alpha.18", "description": "In-App Purchase and Subscriptions for NativeScript", "main": "index", "typings": "index.d.ts", From 3196aff502957b1381d6876c58abd72b3640ddc1 Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Fri, 15 Aug 2025 04:04:50 -0400 Subject: [PATCH 28/34] feat(payments): forceStoreV1Receipt --- packages/payments/index.d.ts | 2 ++ packages/payments/index.ios.ts | 8 +++++ packages/payments/package.json | 2 +- .../platforms/ios/src/NSCPayment.swift | 36 ++++++++++++++++--- .../payments/typings/objc!NSCPayments.d.ts | 2 ++ 5 files changed, 45 insertions(+), 5 deletions(-) diff --git a/packages/payments/index.d.ts b/packages/payments/index.d.ts index 80bc330..3fb4998 100644 --- a/packages/payments/index.d.ts +++ b/packages/payments/index.d.ts @@ -31,6 +31,8 @@ export class Payment { static isSupported(): boolean; + forceStoreV1Receipt: boolean; // iOS only allows forcing the use of V1 receipts + canMakePayments(): boolean; connect(): void; diff --git a/packages/payments/index.ios.ts b/packages/payments/index.ios.ts index fcb1ad4..519225f 100644 --- a/packages/payments/index.ios.ts +++ b/packages/payments/index.ios.ts @@ -234,6 +234,14 @@ export class Payment { return NSCPayments.isSupported(); } + get forceStoreV1Receipt(): boolean { + return this.native.alwaysStoreV1Receipt; + } + + set forceStoreV1Receipt(value: boolean) { + this.native.alwaysStoreV1Receipt = value; + } + canMakePayments(): boolean { return this.native.canMakePayments(); } diff --git a/packages/payments/package.json b/packages/payments/package.json index ef7abce..8a4bd96 100644 --- a/packages/payments/package.json +++ b/packages/payments/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/payments", - "version": "4.0.0-alpha.18", + "version": "4.0.0-alpha.19", "description": "In-App Purchase and Subscriptions for NativeScript", "main": "index", "typings": "index.d.ts", diff --git a/packages/payments/platforms/ios/src/NSCPayment.swift b/packages/payments/platforms/ios/src/NSCPayment.swift index eec26f3..6015f5e 100644 --- a/packages/payments/platforms/ios/src/NSCPayment.swift +++ b/packages/payments/platforms/ios/src/NSCPayment.swift @@ -157,10 +157,14 @@ public class NSCPaymentsTransaction: NSObject { } } - internal var receiptV1: String? = nil + fileprivate var receiptV1: String? = nil var receipt: String? { get { if version == .v2 && version.storeKit2Available { + // always + if(receiptV1 != nil){ + return receiptV1 + } if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { return String(data:v2!.jsonRepresentation, encoding: .utf8) } @@ -200,7 +204,7 @@ public class NSCPaymentsTransaction: NSObject { return productType } - internal var revocationDateV1: Date? = nil + fileprivate var revocationDateV1: Date? = nil var revocationDate: Date? { get { @@ -233,7 +237,7 @@ public class NSCPaymentsTransaction: NSObject { } } - internal var expirationDateV1: Date? = nil + fileprivate var expirationDateV1: Date? = nil var expirationDate: Date? { get { @@ -564,6 +568,7 @@ public class NSCPayments: NSObject { internal var fetchingPurchases: [([NSCPaymentsTransaction]?, NSCPaymentsResponse?) -> Void] = [] internal var previousPurchases: [NSCPaymentsTransaction] = [] private var emittedUpdate: Set = [] + var alwaysStoreV1Receipt: Bool = false public override init() { if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { version = .v2 @@ -574,6 +579,14 @@ public class NSCPayments: NSObject { case .unverified(let transaction, let error): let ret = NSCPaymentsTransaction(transaction: transaction, .v2) ret.errorValue = error + + if(self.alwaysStoreV1Receipt){ + do { + let receipt = try InAppReceipt.localReceipt() + ret.receiptV1 = receipt.base64 + }catch {} + } + self.transactionUpdateListener?(ret) break case .verified(let transaction): @@ -581,7 +594,14 @@ public class NSCPayments: NSObject { self.emittedUpdate.remove(transaction.id) continue } - self.transactionUpdateListener?(NSCPaymentsTransaction(transaction: transaction, .v2)) + let ret = NSCPaymentsTransaction(transaction: transaction, .v2) + if(self.alwaysStoreV1Receipt){ + do { + let receipt = try InAppReceipt.localReceipt() + ret.receiptV1 = receipt.base64 + }catch {} + } + self.transactionUpdateListener?(ret) break } } @@ -896,6 +916,14 @@ public class NSCPayments: NSObject { case .verified(let transaction): let restored = NSCPaymentsTransaction(transaction: transaction, .v2) restored.isAcknowledged = true + + if(self.alwaysStoreV1Receipt){ + do { + let receipt = try InAppReceipt.localReceipt() + restored.receiptV1 = receipt.base64 + }catch {} + } + purchases.append(restored) break } diff --git a/packages/payments/typings/objc!NSCPayments.d.ts b/packages/payments/typings/objc!NSCPayments.d.ts index e847214..764a977 100644 --- a/packages/payments/typings/objc!NSCPayments.d.ts +++ b/packages/payments/typings/objc!NSCPayments.d.ts @@ -9,6 +9,8 @@ declare class NSCPayments extends NSObject { incomingPromotionListener: (p1: NSCPaymentsProduct) => boolean; + alwaysStoreV1Receipt: boolean; + isRestoring: boolean; pendingTasks: NSArray; From ca44f0b27784da2379a2e599c7aefa0e3f8ce1da Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Fri, 15 Aug 2025 04:16:14 -0400 Subject: [PATCH 29/34] fix(payments): v1 store --- packages/payments/package.json | 2 +- packages/payments/platforms/ios/src/NSCPayment.swift | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/payments/package.json b/packages/payments/package.json index 8a4bd96..19fe9b0 100644 --- a/packages/payments/package.json +++ b/packages/payments/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/payments", - "version": "4.0.0-alpha.19", + "version": "4.0.0-alpha.20", "description": "In-App Purchase and Subscriptions for NativeScript", "main": "index", "typings": "index.d.ts", diff --git a/packages/payments/platforms/ios/src/NSCPayment.swift b/packages/payments/platforms/ios/src/NSCPayment.swift index 6015f5e..e6cae78 100644 --- a/packages/payments/platforms/ios/src/NSCPayment.swift +++ b/packages/payments/platforms/ios/src/NSCPayment.swift @@ -874,6 +874,14 @@ public class NSCPayments: NSObject { case .verified(let transaction): callback(nil) let ret = NSCPaymentsTransaction(transaction: transaction, .v2) + + if(self.alwaysStoreV1Receipt){ + do { + let receipt = try InAppReceipt.localReceipt() + ret.receiptV1 = receipt.base64 + }catch {} + } + self.emittedUpdate.insert(transaction.id) transactionUpdateListener?(ret) break From 11c587ecddfec3bd1ff45d33a243992120a22682 Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Fri, 15 Aug 2025 05:23:43 -0400 Subject: [PATCH 30/34] fix(payments): callback execution --- packages/payments/package.json | 2 +- .../platforms/ios/src/NSCPayment.swift | 125 +++++++++++++----- 2 files changed, 93 insertions(+), 34 deletions(-) diff --git a/packages/payments/package.json b/packages/payments/package.json index 19fe9b0..f5f1d54 100644 --- a/packages/payments/package.json +++ b/packages/payments/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/payments", - "version": "4.0.0-alpha.20", + "version": "4.0.0-alpha.22", "description": "In-App Purchase and Subscriptions for NativeScript", "main": "index", "typings": "index.d.ts", diff --git a/packages/payments/platforms/ios/src/NSCPayment.swift b/packages/payments/platforms/ios/src/NSCPayment.swift index e6cae78..17902fd 100644 --- a/packages/payments/platforms/ios/src/NSCPayment.swift +++ b/packages/payments/platforms/ios/src/NSCPayment.swift @@ -569,7 +569,19 @@ public class NSCPayments: NSObject { internal var previousPurchases: [NSCPaymentsTransaction] = [] private var emittedUpdate: Set = [] var alwaysStoreV1Receipt: Bool = false + + + private static func executeInLoop(_ runloop: CFRunLoop?, _ function: @escaping() -> Void){ + if let runloop = runloop { + CFRunLoopPerformBlock(runloop, CFRunLoopMode.defaultMode.rawValue) { + function() + } + }else { + function() + } + } public override init() { + let runloop = CFRunLoopGetCurrent() if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { version = .v2 super.init() @@ -587,7 +599,10 @@ public class NSCPayments: NSObject { }catch {} } - self.transactionUpdateListener?(ret) + NSCPayments.executeInLoop(runloop, { + self.transactionUpdateListener?(ret) + }) + break case .verified(let transaction): if(self.emittedUpdate.contains(transaction.id)){ @@ -601,7 +616,10 @@ public class NSCPayments: NSObject { ret.receiptV1 = receipt.base64 }catch {} } - self.transactionUpdateListener?(ret) + + NSCPayments.executeInLoop(runloop, { + self.transactionUpdateListener?(ret) + }) break } } @@ -612,9 +630,10 @@ public class NSCPayments: NSObject { let instance: SKPaymentTransactionObserver = { class TransactionObserver: NSObject, SKPaymentTransactionObserver { var payments: NSCPayments - - init(payments instance : NSCPayments) { + var runloop: CFRunLoop? + init(payments instance: NSCPayments, runloop runLoop: CFRunLoop?) { payments = instance + runloop = runLoop super.init() } @@ -676,7 +695,11 @@ public class NSCPayments: NSObject { } } } - payments.transactionUpdateListener?(value) + + NSCPayments.executeInLoop(runloop, { + self.payments.transactionUpdateListener?(value) + }) + } } } @@ -685,17 +708,21 @@ public class NSCPayments: NSObject { func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: Error) { if(payments.isRestoring){ - for callback in payments.fetchingPurchases { - callback(nil,NSCPaymentsResponse(code: .Error, message: "Usage error: \(error.localizedDescription)", resolution: "")) - } + NSCPayments.executeInLoop(runloop, { + for callback in self.payments.fetchingPurchases { + callback(nil,NSCPaymentsResponse(code: .Error, message: "Usage error: \(error.localizedDescription)", resolution: "")) + } + }) } } func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) { if(payments.isRestoring){ - for callback in payments.fetchingPurchases { - callback(payments.previousPurchases, nil) - } + NSCPayments.executeInLoop(runloop, { + for callback in self.payments.fetchingPurchases { + callback(self.payments.previousPurchases, nil) + } + }) payments.fetchingPurchases.removeAll() payments.previousPurchases.removeAll() @@ -720,7 +747,7 @@ public class NSCPayments: NSObject { return true } } - return TransactionObserver(payments: self) + return TransactionObserver(payments: self, runloop: runloop) }() SKPaymentQueue.default().add(instance) updatesListener = instance @@ -735,7 +762,13 @@ public class NSCPayments: NSObject { if #available(iOS 18.0, *) { product.promotedOffer = intent.offer } - let _ = self.incomingPromotionListener?(product) + if let incomingPromotionListener = incomingPromotionListener { + NSCPayments.executeInLoop(runloop, { + let _ = self.incomingPromotionListener?(product) + + }) + } + } } as AnyObject } @@ -760,6 +793,7 @@ public class NSCPayments: NSObject { return NSCPayments.isSupported() } public func fetchProducts(_ identifiers: [String], _ callback: @escaping ([NSCPaymentsProduct], Error?) -> Void) { + let runloop = CFRunLoopGetCurrent() switch(version){ case .v1: let request = SKProductsRequest(productIdentifiers: Set(identifiers)) @@ -769,27 +803,32 @@ public class NSCPayments: NSObject { let callback: ([NSCPaymentsProduct], Error?) -> Void let version: NSCPaymentsStoreKitVersion let payments: NSCPayments - init(_ cb: @escaping ([NSCPaymentsProduct], Error?) -> Void, _ storeVerion: NSCPaymentsStoreKitVersion, _ payment: NSCPayments){ + let runloop: CFRunLoop? + init(_ cb: @escaping ([NSCPaymentsProduct], Error?) -> Void, _ storeVerion: NSCPaymentsStoreKitVersion, _ payment: NSCPayments, _ runLoop: CFRunLoop?){ version = storeVerion callback = cb payments = payment + runloop = runLoop super .init() } func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) { let products = response.products.map { - return NSCPaymentsProduct(product: $0, version) } - callback( products, nil) + NSCPayments.executeInLoop(runloop, { + self.callback( products, nil) + }) } func request(_ request: SKRequest, didFailWithError error: Error) { - callback([], error) + NSCPayments.executeInLoop(runloop, { + self.callback([], error) + }) } } - return SKProductsRequestDelegateImpl(callback, version, self) + return SKProductsRequestDelegateImpl(callback, version, self, runloop) }() request.delegate = delegate @@ -834,6 +873,7 @@ public class NSCPayments: NSObject { SKPaymentQueue.default().add(payment) break case .v2: + let runloop = CFRunLoopGetCurrent() Task { do { if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { @@ -867,9 +907,11 @@ public class NSCPayments: NSObject { case .success(let success): switch(success){ case .unverified(_, let verificationError): - callback( - NSCPaymentsResponse(code: .Error, message: "Usage error: \(verificationError.localizedDescription)", resolution: "") - ) + NSCPayments.executeInLoop(runloop) { + callback( + NSCPaymentsResponse(code: .Error, message: "Usage error: \(verificationError.localizedDescription)", resolution: "") + ) + } break case .verified(let transaction): callback(nil) @@ -883,22 +925,30 @@ public class NSCPayments: NSObject { } self.emittedUpdate.insert(transaction.id) - transactionUpdateListener?(ret) + NSCPayments.executeInLoop(runloop) { + self.transactionUpdateListener?(ret) + } break } case .userCancelled: - callback(NSCPaymentsResponse(code: .UserCancelled, message: "Indicates that the user cancelled a payment request.", resolution: "")) + NSCPayments.executeInLoop(runloop) { + callback(NSCPaymentsResponse(code: .UserCancelled, message: "Indicates that the user cancelled a payment request.", resolution: "")) + } break case .pending: - callback(NSCPaymentsResponse(code: .DeferredPayment, message: "Indicated that is in the queue, but its final status is pending external action such as Ask to Buy.", resolution: "")) + NSCPayments.executeInLoop(runloop) { + callback(NSCPaymentsResponse(code: .DeferredPayment, message: "Indicated that is in the queue, but its final status is pending external action such as Ask to Buy.", resolution: "")) + } break } } }catch { - callback( - NSCPaymentsResponse(code: .Error, message: "Usage error: \(error.localizedDescription)", resolution: "") - ) + NSCPayments.executeInLoop(runloop) { + callback( + NSCPaymentsResponse(code: .Error, message: "Usage error: \(error.localizedDescription)", resolution: "") + ) + } } } break @@ -909,6 +959,7 @@ public class NSCPayments: NSObject { // return error + transaction ? public func fetchPurchases(_ callback: @escaping ([NSCPaymentsTransaction]?, NSCPaymentsResponse?) -> Void){ if(version == .v2 && version.storeKit2Available){ + let runloop = CFRunLoopGetCurrent() if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *){ Task(priority: .background) { do { @@ -918,7 +969,9 @@ public class NSCPayments: NSObject { for await transaction in Transaction.currentEntitlements { switch transaction { case .unverified(_, let error): - callback(nil,NSCPaymentsResponse(code: .Error, message: "Usage error: \(error.localizedDescription)", resolution: "")) + NSCPayments.executeInLoop(runloop) { + callback(nil,NSCPaymentsResponse(code: .Error, message: "Usage error: \(error.localizedDescription)", resolution: "")) + } hasError = true return case .verified(let transaction): @@ -931,19 +984,23 @@ public class NSCPayments: NSObject { restored.receiptV1 = receipt.base64 }catch {} } - + purchases.append(restored) break } } if(!hasError){ - callback(purchases, nil) + NSCPayments.executeInLoop(runloop) { + callback(purchases, nil) + } } }catch { - callback(nil, NSCPaymentsResponse(code: .Error, message: "Usage error: \(error.localizedDescription)", resolution: "") - ) + NSCPayments.executeInLoop(runloop) { + callback(nil, NSCPaymentsResponse(code: .Error, message: "Usage error: \(error.localizedDescription)", resolution: "") + ) + } } } } @@ -971,16 +1028,18 @@ public class NSCPayments: NSObject { if let id = subscriptionGroupID { if #available(iOS 17.0, *) { try await AppStore.showManageSubscriptions(in: scene, subscriptionGroupID: id) + callback(nil) } else { try await AppStore.showManageSubscriptions(in: scene) + callback(nil) } }else { try await AppStore.showManageSubscriptions(in: scene) + callback(nil) } }else { callback("Invalid view controller") } - } }else { UIApplication.shared.open(URL(string: "https://apps.apple.com/account/subscriptions")!, options: [:]) {_ in From 9e40efde1c676ed5aa3247754e941572b23ded74 Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Fri, 15 Aug 2025 16:42:58 -0400 Subject: [PATCH 31/34] fix(payments): callback execute --- packages/payments/package.json | 2 +- .../platforms/ios/src/NSCPayment.swift | 101 +++++++++++++----- 2 files changed, 73 insertions(+), 30 deletions(-) diff --git a/packages/payments/package.json b/packages/payments/package.json index f5f1d54..ce38b60 100644 --- a/packages/payments/package.json +++ b/packages/payments/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/payments", - "version": "4.0.0-alpha.22", + "version": "4.0.0-alpha.23", "description": "In-App Purchase and Subscriptions for NativeScript", "main": "index", "typings": "index.d.ts", diff --git a/packages/payments/platforms/ios/src/NSCPayment.swift b/packages/payments/platforms/ios/src/NSCPayment.swift index 17902fd..a2233d5 100644 --- a/packages/payments/platforms/ios/src/NSCPayment.swift +++ b/packages/payments/platforms/ios/src/NSCPayment.swift @@ -273,32 +273,52 @@ public class NSCPaymentsTransaction: NSObject { public func finish(_ callback: @escaping (NSCPaymentsResponse?) -> Void) { if version == .v2 && version.storeKit2Available { - Task { + let runloop = CFRunLoopGetCurrent() + Task.detached { if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { - await v2!.finish() + await self.v2!.finish() + var isAcknowledged = false + var updateTransaction: Transaction? + var hasError: Error? for await complete in Transaction.all { switch complete { case .unverified(let t, let error): - if(t.id == v2!.id){ - self.errorValue = error - callback(NSCPaymentsResponse(code: .Error, message: "Usage error: \(error.localizedDescription)", resolution: "")) - break + if(t.id == self.v2!.id){ + hasError = error + updateTransaction = t } break case .verified(let t): - if(t.id == v2!.id){ - self.transaction = transaction - self.isAcknowledged = true - callback(nil) - break + if(t.id == self.v2!.id){ + updateTransaction = t + isAcknowledged = true } + break + } + } + + if let error = hasError { + self.errorValue = error + if let updateTransaction = updateTransaction { + self.transaction = updateTransaction + } + NSCPayments.executeInLoop(runloop) { + callback(NSCPaymentsResponse(code: .Error, message: "Usage error: \(error.localizedDescription)", resolution: "")) } + }else { + self.isAcknowledged = isAcknowledged + if let updateTransaction = updateTransaction { + self.transaction = updateTransaction + } + + callback(nil) } } } } else { SKPaymentQueue.default().finishTransaction(v1!) isAcknowledged = true + callback(nil) } } } @@ -571,11 +591,12 @@ public class NSCPayments: NSObject { var alwaysStoreV1Receipt: Bool = false - private static func executeInLoop(_ runloop: CFRunLoop?, _ function: @escaping() -> Void){ + fileprivate static func executeInLoop(_ runloop: CFRunLoop?, _ function: @escaping() -> Void){ if let runloop = runloop { CFRunLoopPerformBlock(runloop, CFRunLoopMode.defaultMode.rawValue) { function() } + CFRunLoopWakeUp(runloop) }else { function() } @@ -585,7 +606,7 @@ public class NSCPayments: NSObject { if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { version = .v2 super.init() - updatesListener = Task.detached(priority: .background) { + updatesListener = Task.detached { for await transaction in Transaction.updates { switch transaction { case .unverified(let transaction, let error): @@ -755,16 +776,16 @@ public class NSCPayments: NSObject { if #available(iOS 16.4, *) { if(version == .v2){ - promotionListener = Task(priority: .background) { + promotionListener = Task.detached(priority: .background) { for await intent in PurchaseIntent.intents { let product = NSCPaymentsProduct(product: intent.product, .v2) product.isPromoted = true if #available(iOS 18.0, *) { product.promotedOffer = intent.offer } - if let incomingPromotionListener = incomingPromotionListener { + if let incomingPromotionListener = self.incomingPromotionListener { NSCPayments.executeInLoop(runloop, { - let _ = self.incomingPromotionListener?(product) + let _ = incomingPromotionListener(product) }) } @@ -837,14 +858,17 @@ public class NSCPayments: NSObject { break case .v2: if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { - Task { + Task.detached { do { - let products = try await Product.products(for: Set(identifiers)) - let ret = products.map {NSCPaymentsProduct(product: $0, version)} - callback(ret,nil) + let ret = products.map {NSCPaymentsProduct(product: $0, self.version)} + NSCPayments.executeInLoop(runloop, { + callback(ret,nil) + }) }catch { - callback([], error) + NSCPayments.executeInLoop(runloop, { + callback([], error) + }) } } } @@ -853,6 +877,7 @@ public class NSCPayments: NSObject { } public func purchaseProduct(_ product: NSCPaymentsProduct, _ confirmIn: UIViewController, _ options: NSCPaymentsPurchaseOptions?, _ callback: @escaping (NSCPaymentsResponse?)->Void){ + let runloop = CFRunLoopGetCurrent() switch(version){ case .v1: @@ -873,7 +898,6 @@ public class NSCPayments: NSObject { SKPaymentQueue.default().add(payment) break case .v2: - let runloop = CFRunLoopGetCurrent() Task { do { if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { @@ -897,7 +921,15 @@ public class NSCPayments: NSObject { } var result: Product.PurchaseResult - if #available(iOS 18.2, *) { + + + if #available(iOS 17.0, *) { + if let window = await confirmIn.view.window, let windowScene = await window.windowScene { + result = try await product.v2!.purchase(confirmIn: windowScene, options: opts) + }else { + result = try await product.v2!.purchase(options: opts) + } + } else if #available(iOS 18.2, *) { result = try await product.v2!.purchase(confirmIn: confirmIn, options: opts) }else { result = try await product.v2!.purchase(options: opts) @@ -914,7 +946,9 @@ public class NSCPayments: NSObject { } break case .verified(let transaction): - callback(nil) + NSCPayments.executeInLoop(runloop) { + callback(nil) + } let ret = NSCPaymentsTransaction(transaction: transaction, .v2) if(self.alwaysStoreV1Receipt){ @@ -961,7 +995,7 @@ public class NSCPayments: NSObject { if(version == .v2 && version.storeKit2Available){ let runloop = CFRunLoopGetCurrent() if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *){ - Task(priority: .background) { + Task.detached { do { try await AppStore.sync() var purchases: [NSCPaymentsTransaction] = [] @@ -1023,22 +1057,31 @@ public class NSCPayments: NSObject { public static func showManageSubscriptions(_ showIn: UIViewController, _ subscriptionGroupID: String? = nil, _ callback: @escaping (String?) -> Void){ if #available(iOS 15.0, *) { + let runloop = CFRunLoopGetCurrent() Task { if let scene = await showIn.view.window?.windowScene { if let id = subscriptionGroupID { if #available(iOS 17.0, *) { try await AppStore.showManageSubscriptions(in: scene, subscriptionGroupID: id) - callback(nil) + NSCPayments.executeInLoop(runloop) { + callback(nil) + } } else { try await AppStore.showManageSubscriptions(in: scene) - callback(nil) + NSCPayments.executeInLoop(runloop) { + callback(nil) + } } }else { try await AppStore.showManageSubscriptions(in: scene) - callback(nil) + NSCPayments.executeInLoop(runloop) { + callback(nil) + } } }else { - callback("Invalid view controller") + NSCPayments.executeInLoop(runloop) { + callback("Invalid view controller") + } } } }else { From 1d21459f1b428cfcc4b081bb4b40a40bc3aed3b7 Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Mon, 18 Aug 2025 10:40:40 -0400 Subject: [PATCH 32/34] fix(payments): set alwaysStoreV1Receipt visibility as public --- packages/payments/package.json | 2 +- packages/payments/platforms/ios/src/NSCPayment.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/payments/package.json b/packages/payments/package.json index ce38b60..71c961d 100644 --- a/packages/payments/package.json +++ b/packages/payments/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/payments", - "version": "4.0.0-alpha.23", + "version": "4.0.0-alpha.24", "description": "In-App Purchase and Subscriptions for NativeScript", "main": "index", "typings": "index.d.ts", diff --git a/packages/payments/platforms/ios/src/NSCPayment.swift b/packages/payments/platforms/ios/src/NSCPayment.swift index a2233d5..ea2521a 100644 --- a/packages/payments/platforms/ios/src/NSCPayment.swift +++ b/packages/payments/platforms/ios/src/NSCPayment.swift @@ -588,7 +588,7 @@ public class NSCPayments: NSObject { internal var fetchingPurchases: [([NSCPaymentsTransaction]?, NSCPaymentsResponse?) -> Void] = [] internal var previousPurchases: [NSCPaymentsTransaction] = [] private var emittedUpdate: Set = [] - var alwaysStoreV1Receipt: Bool = false + public var alwaysStoreV1Receipt: Bool = false fileprivate static func executeInLoop(_ runloop: CFRunLoop?, _ function: @escaping() -> Void){ From 092cbac3a3fad1647d26730a8d8f34db369c3938 Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Tue, 19 Aug 2025 10:41:47 -0400 Subject: [PATCH 33/34] fix(payments): first purchase not returning v1 receipt --- packages/payments/package.json | 2 +- .../platforms/ios/src/NSCPayment.swift | 119 ++++++++++++------ 2 files changed, 84 insertions(+), 37 deletions(-) diff --git a/packages/payments/package.json b/packages/payments/package.json index 71c961d..01d9222 100644 --- a/packages/payments/package.json +++ b/packages/payments/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/payments", - "version": "4.0.0-alpha.24", + "version": "4.0.0-alpha.25", "description": "In-App Purchase and Subscriptions for NativeScript", "main": "index", "typings": "index.d.ts", diff --git a/packages/payments/platforms/ios/src/NSCPayment.swift b/packages/payments/platforms/ios/src/NSCPayment.swift index ea2521a..0315cbe 100644 --- a/packages/payments/platforms/ios/src/NSCPayment.swift +++ b/packages/payments/platforms/ios/src/NSCPayment.swift @@ -83,12 +83,22 @@ public enum NSCPaymentsTransactionState: Int32, RawRepresentable { @objc(NSCPaymentsTransaction) @objcMembers public class NSCPaymentsTransaction: NSObject { - public let version: NSCPaymentsStoreKitVersion + internal let version_: NSCPaymentsStoreKitVersion internal var transaction: Any - init(transaction: Any, _ version : NSCPaymentsStoreKitVersion) { - self.version = version +internal var payments: NSCPayments + init(transaction: Any, _ version : NSCPaymentsStoreKitVersion, _ payments: NSCPayments) { + self.version_ = version self.transaction = transaction + self.payments = payments } + + +public var version: NSCPaymentsStoreKitVersion { + if(payments.alwaysStoreV1Receipt){ + return .v1 + } + return version_ +} public internal(set) var isAcknowledged: Bool = false @@ -117,7 +127,7 @@ public class NSCPaymentsTransaction: NSObject { internal var errorValue: Error? = nil var error: Error? { get { - switch(version){ + switch(version_){ case .v1: return v1!.error case .v2: @@ -128,7 +138,7 @@ public class NSCPaymentsTransaction: NSObject { var state: NSCPaymentsTransactionState { get { - if(version == .v2 && version.storeKit2Available){ + if(version_ == .v2 && version_.storeKit2Available){ if #available(iOS 15.0, *) { switch v2!.revocationReason { case .some: @@ -160,11 +170,10 @@ public class NSCPaymentsTransaction: NSObject { fileprivate var receiptV1: String? = nil var receipt: String? { get { - if version == .v2 && version.storeKit2Available { - // always - if(receiptV1 != nil){ - return receiptV1 - } + if version_ == .v2 && version_.storeKit2Available { + if(payments.alwaysStoreV1Receipt){ + return receiptV1 + } if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { return String(data:v2!.jsonRepresentation, encoding: .utf8) } @@ -175,14 +184,14 @@ public class NSCPaymentsTransaction: NSObject { @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) internal var v2: Transaction? { - if version.storeKit2Available { + if version_.storeKit2Available { return transaction as? Transaction } return nil } internal var v1: SKPaymentTransaction? { - if version == .v1 { + if version_ == .v1 { return transaction as? SKPaymentTransaction } return nil @@ -191,7 +200,7 @@ public class NSCPaymentsTransaction: NSObject { internal var productType = "unknown" public var type: String { if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { - if(version == .v2){ + if(version_ == .v2){ switch(v2!.productType){ case .autoRenewable, .nonRenewable: return "sub" @@ -208,11 +217,11 @@ public class NSCPaymentsTransaction: NSObject { var revocationDate: Date? { get { - if version == .v2 && version.storeKit2Available { + if version_ == .v2 && version_.storeKit2Available { if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { return v2!.revocationDate } - }else if version == .v1 { + }else if version_ == .v1 { return self.revocationDateV1 } return nil @@ -222,11 +231,11 @@ public class NSCPaymentsTransaction: NSObject { var isRevoked: Bool { get { var revocationDate: Date? = nil - if version == .v2 && version.storeKit2Available { + if version_ == .v2 && version_.storeKit2Available { if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { revocationDate = v2!.revocationDate } - }else if version == .v1 { + }else if version_ == .v1 { revocationDate = self.revocationDateV1 } @@ -241,11 +250,11 @@ public class NSCPaymentsTransaction: NSObject { var expirationDate: Date? { get { - if version == .v2 && version.storeKit2Available { + if version_ == .v2 && version_.storeKit2Available { if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { return v2!.expirationDate } - }else if version == .v1 { + }else if version_ == .v1 { return self.expirationDateV1 } return nil @@ -255,7 +264,7 @@ public class NSCPaymentsTransaction: NSObject { var isExpired: Bool { get { var expirationDate: Date? = nil - if version == .v2 && version.storeKit2Available { + if version_ == .v2 && version_.storeKit2Available { if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { expirationDate = v2!.expirationDate } @@ -272,7 +281,7 @@ public class NSCPaymentsTransaction: NSObject { } public func finish(_ callback: @escaping (NSCPaymentsResponse?) -> Void) { - if version == .v2 && version.storeKit2Available { + if version_ == .v2 && version_.storeKit2Available { let runloop = CFRunLoopGetCurrent() Task.detached { if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { @@ -326,7 +335,7 @@ public class NSCPaymentsTransaction: NSObject { @objc(NSCPaymentsProduct) @objcMembers public class NSCPaymentsProduct: NSObject { - public let version: NSCPaymentsStoreKitVersion +internal let version: NSCPaymentsStoreKitVersion public internal(set) var isPromoted: Bool = false internal var promotedPayment: SKPayment? = nil internal let product: Any @@ -335,6 +344,7 @@ public class NSCPaymentsProduct: NSObject { self.product = product self.version = version } + @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) internal var v2: Product? { @@ -601,6 +611,42 @@ public class NSCPayments: NSObject { function() } } + + static var localReceiptQueue: [CheckedContinuation] = [] + @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) + private static func getLocalReceipt() async throws -> InAppReceipt { + try await withCheckedThrowingContinuation { continuation in + do { + let receipt = try InAppReceipt.localReceipt() + continuation.resume(returning: receipt) + } catch { + + InAppReceipt.refresh { refreshError in + if refreshError != nil { + localReceiptQueue.append(continuation) + return + } + + do { + let receipt = try InAppReceipt.localReceipt() + continuation.resume(returning: receipt) + var removing: [Int] = [] + for (i, callback) in localReceiptQueue.enumerated() { + callback.resume(returning: receipt) + removing.append(i) + } + for i in removing { + localReceiptQueue.remove(at: i) + } + } catch { + continuation.resume(throwing: error) + } + } + } + } + } + + public override init() { let runloop = CFRunLoopGetCurrent() if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) { @@ -610,12 +656,12 @@ public class NSCPayments: NSObject { for await transaction in Transaction.updates { switch transaction { case .unverified(let transaction, let error): - let ret = NSCPaymentsTransaction(transaction: transaction, .v2) + let ret = NSCPaymentsTransaction(transaction: transaction, .v2, self) ret.errorValue = error if(self.alwaysStoreV1Receipt){ do { - let receipt = try InAppReceipt.localReceipt() + let receipt = try await NSCPayments.getLocalReceipt() ret.receiptV1 = receipt.base64 }catch {} } @@ -630,10 +676,10 @@ public class NSCPayments: NSObject { self.emittedUpdate.remove(transaction.id) continue } - let ret = NSCPaymentsTransaction(transaction: transaction, .v2) + let ret = NSCPaymentsTransaction(transaction: transaction, .v2, self) if(self.alwaysStoreV1Receipt){ do { - let receipt = try InAppReceipt.localReceipt() + let receipt = try await NSCPayments.getLocalReceipt() ret.receiptV1 = receipt.base64 }catch {} } @@ -665,7 +711,7 @@ public class NSCPayments: NSObject { }catch {} if(payments.isRestoring){ for transaction in transactions where transaction.transactionState == .restored { - let value = NSCPaymentsTransaction(transaction: transaction, .v1) + let value = NSCPaymentsTransaction(transaction: transaction, .v1, payments) value.isAcknowledged = true if let receipt = receipt { value.receiptV1 = receipt.base64 @@ -693,7 +739,7 @@ public class NSCPayments: NSObject { } }else { for transaction in transactions { - let value = NSCPaymentsTransaction(transaction: transaction, .v1) + let value = NSCPaymentsTransaction(transaction: transaction, .v1, payments) if let receipt = receipt { value.receiptV1 = receipt.base64 let purchaseInfo = receipt.activeAutoRenewableSubscriptionPurchases @@ -786,7 +832,6 @@ public class NSCPayments: NSObject { if let incomingPromotionListener = self.incomingPromotionListener { NSCPayments.executeInLoop(runloop, { let _ = incomingPromotionListener(product) - }) } @@ -949,19 +994,21 @@ public class NSCPayments: NSObject { NSCPayments.executeInLoop(runloop) { callback(nil) } - let ret = NSCPaymentsTransaction(transaction: transaction, .v2) + let ret = NSCPaymentsTransaction(transaction: transaction, .v2, self) if(self.alwaysStoreV1Receipt){ do { - let receipt = try InAppReceipt.localReceipt() + let receipt = try await NSCPayments.getLocalReceipt() ret.receiptV1 = receipt.base64 }catch {} } self.emittedUpdate.insert(transaction.id) - NSCPayments.executeInLoop(runloop) { - self.transactionUpdateListener?(ret) - } + // sleep 100ms + try await Task.sleep(nanoseconds: 100_000_000) + NSCPayments.executeInLoop(runloop) { + self.transactionUpdateListener?(ret) + } break } case .userCancelled: @@ -1009,12 +1056,12 @@ public class NSCPayments: NSObject { hasError = true return case .verified(let transaction): - let restored = NSCPaymentsTransaction(transaction: transaction, .v2) + let restored = NSCPaymentsTransaction(transaction: transaction, .v2, self) restored.isAcknowledged = true if(self.alwaysStoreV1Receipt){ do { - let receipt = try InAppReceipt.localReceipt() + let receipt = try await NSCPayments.getLocalReceipt() restored.receiptV1 = receipt.base64 }catch {} } From 5f87f453285233da4c16b4117a73432a26979526 Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Tue, 19 Aug 2025 10:59:29 -0400 Subject: [PATCH 34/34] feat(payments): allow optional consume for non subs --- packages/payments/index.android.ts | 3 +- packages/payments/index.d.ts | 2 +- .../plugins/payments/Transaction.kt | 211 ++++++++++-------- packages/payments/typings/android.d.ts | 2 +- 4 files changed, 117 insertions(+), 101 deletions(-) diff --git a/packages/payments/index.android.ts b/packages/payments/index.android.ts index 5b663a2..5e29c4c 100644 --- a/packages/payments/index.android.ts +++ b/packages/payments/index.android.ts @@ -99,9 +99,10 @@ export class Transaction { return this.native.isExpired(); } - finish() { + finish(options?: { consume?: boolean }): Promise { return new Promise((resolve, reject) => { this.native.finish( + options?.consume ?? false, new kotlin.jvm.functions.Function1({ invoke(response): void { if (response) { diff --git a/packages/payments/index.d.ts b/packages/payments/index.d.ts index 3fb4998..cd7260f 100644 --- a/packages/payments/index.d.ts +++ b/packages/payments/index.d.ts @@ -86,7 +86,7 @@ export class Transaction { readonly version: 'v1' | 'v2' | undefined; // iOS store version; - finish(): Promise; + finish(options?: { consume?: boolean }): Promise; } export class Product { diff --git a/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Transaction.kt b/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Transaction.kt index dc1aca9..bec503c 100644 --- a/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Transaction.kt +++ b/packages/payments/platforms/android/java/org/nativescript/plugins/payments/Transaction.kt @@ -8,121 +8,136 @@ import org.json.JSONObject class Transaction(val purchase: Purchase, val type: Product.Type, private val payments: Payments) { - enum class State(val value: Int) { - Unknown(-1), Purchased(1), Pending(2) - } + enum class State(val value: Int) { + Unknown(-1), Purchased(1), Pending(2) + } - val orderId: String? - get() { - return purchase.orderId - } + val orderId: String? + get() { + return purchase.orderId + } - val productId: String? - get() { - return purchase.products.first() - } + val productId: String? + get() { + return purchase.products.first() + } - val isAcknowledged: Boolean - get() { - return purchase.isAcknowledged - } + val isAcknowledged: Boolean + get() { + return purchase.isAcknowledged + } - val orderDate: Long - get() { - return purchase.purchaseTime - } + val orderDate: Long + get() { + return purchase.purchaseTime + } - val isAutoRenewing: Boolean - get() { - return purchase.isAutoRenewing - } + val isAutoRenewing: Boolean + get() { + return purchase.isAutoRenewing + } - val isExpired: Boolean - get() { - if (type == Product.Type.Subs) { - return !purchase.isAutoRenewing - } - return false - } + val isExpired: Boolean + get() { + if (type == Product.Type.Subs) { + return !purchase.isAutoRenewing + } + return false + } - val products: List - get() { - return purchase.products - } + val products: List + get() { + return purchase.products + } - val quantity: Int - get() { - return purchase.quantity - } + val quantity: Int + get() { + return purchase.quantity + } - val token: String - get() { - return purchase.purchaseToken - } + val token: String + get() { + return purchase.purchaseToken + } - val signature: String - get() { - return purchase.signature - } + val signature: String + get() { + return purchase.signature + } - val state: State - get() { - return when (purchase.purchaseState) { - Purchase.PurchaseState.PURCHASED -> State.Purchased - Purchase.PurchaseState.PENDING -> State.Pending - else -> State.Unknown - } - } + val state: State + get() { + return when (purchase.purchaseState) { + Purchase.PurchaseState.PURCHASED -> State.Purchased + Purchase.PurchaseState.PENDING -> State.Pending + else -> State.Unknown + } + } - val developerPayload: String - get() { - return purchase.developerPayload - } + val developerPayload: String + get() { + return purchase.developerPayload + } - val originalJsonString: String - get() { - return purchase.originalJson - } + val originalJsonString: String + get() { + return purchase.originalJson + } - private var json: JSONObject? = null - val originalJson: JSONObject - get() { - if (json == null) { - try { - json = JSONObject(purchase.originalJson) - } catch (_: Exception) { - } - } - return json ?: JSONObject() + private var json: JSONObject? = null + val originalJson: JSONObject + get() { + if (json == null) { + try { + json = JSONObject(purchase.originalJson) + } catch (_: Exception) { } + } + return json ?: JSONObject() + } - fun finish(callback: (Payments.BillingResponse?) -> Unit) { - if (purchase.isAutoRenewing) { - if (purchase.isAcknowledged) { - callback(null) - return - } - val params = AcknowledgePurchaseParams.newBuilder() - .setPurchaseToken(purchase.purchaseToken) - .build() - payments.billing.acknowledgePurchase(params) { p0 -> - if (p0.responseCode == BillingClient.BillingResponseCode.OK) { - callback(null) - } else { - callback(Payments.mapResponseCode(p0.responseCode)) - } - } + fun finish(consume: Boolean, callback: (Payments.BillingResponse?) -> Unit) { + if (purchase.isAcknowledged) { + callback(null) + return + } + if (purchase.isAutoRenewing) { + val params = AcknowledgePurchaseParams.newBuilder() + .setPurchaseToken(purchase.purchaseToken) + .build() + payments.billing.acknowledgePurchase(params) { p0 -> + if (p0.responseCode == BillingClient.BillingResponseCode.OK) { + callback(null) } else { - val params = ConsumeParams.newBuilder() - .setPurchaseToken(purchase.purchaseToken) - .build() - payments.billing.consumeAsync(params) { p0, p1 -> - if (p0.responseCode == BillingClient.BillingResponseCode.OK) { - callback(null) - } else { - callback(Payments.mapResponseCode(p0.responseCode)) - } - } + callback(Payments.mapResponseCode(p0.responseCode)) + } + } + + } else { + if (consume) { + val params = ConsumeParams.newBuilder() + .setPurchaseToken(purchase.purchaseToken) + .build() + + payments.billing.consumeAsync(params) { p0, p1 -> + if (p0.responseCode == BillingClient.BillingResponseCode.OK) { + callback(null) + } else { + callback(Payments.mapResponseCode(p0.responseCode)) + } + } + } else { + val params = AcknowledgePurchaseParams.newBuilder() + .setPurchaseToken(purchase.purchaseToken) + .build() + payments.billing.acknowledgePurchase(params) { p0 -> + if (p0.responseCode == BillingClient.BillingResponseCode.OK) { + callback(null) + } else { + callback(Payments.mapResponseCode(p0.responseCode)) + } } + } } + } } diff --git a/packages/payments/typings/android.d.ts b/packages/payments/typings/android.d.ts index a0f2b06..a2c13aa 100644 --- a/packages/payments/typings/android.d.ts +++ b/packages/payments/typings/android.d.ts @@ -144,7 +144,7 @@ declare module org { public static class: java.lang.Class; public getOrderId(): string; public getOriginalJson(): org.json.JSONObject; - public finish(params: any): void; + public finish(consume: boolean, params: any): void; public isExpired(): boolean; public getToken(): string; public isAcknowledged(): boolean;