cordova-plugin-purchase
Advanced tools
Comparing version 13.9.0 to 13.10.0
{ | ||
"name": "cordova-plugin-purchase", | ||
"version": "13.9.0", | ||
"version": "13.10.0", | ||
"description": "Cordova Purchase plugin for iOS, Android, Windows (AppStore, Play, UWP)", | ||
@@ -5,0 +5,0 @@ "cordova": { |
# Release Notes - Cordova Plugin Purchase | ||
## 13.9 | ||
## 13.10.0 | ||
### 13.9.0 | ||
#### (googleplay) Add "isConsumed" to consumed transactions | ||
Local Google Play transaction now contain `isConsumed`, which is the same as `isAcknowledged`, but only set for consumable products. | ||
#### Make it easier to debug callback calls | ||
It's now possible to add a name to callbacks registered with "store.when()" | ||
When callbacks are triggered, the reason is logged to the console. | ||
#### Prevent instanciating CdvPurchase.store twice | ||
So when ionic packages the plugin with the app code, no double instanciations of the plugin is performed. | ||
## 13.9.0 | ||
#### (appstore) store.restorePurchases() return potential errors | ||
@@ -8,0 +22,0 @@ |
@@ -95,3 +95,3 @@ namespace CdvPurchase { | ||
} | ||
}); | ||
}, 'appStoreDiscountEligibilityDeterminer_listening'); | ||
@@ -112,3 +112,3 @@ const determiner = (_appStoreReceipt: AppleAppStore.ApplicationReceipt, requests: AppleAppStore.DiscountEligibilityRequest[], callback: (response: boolean[]) => void) => { | ||
this.log.debug("Waiting for receipt"); | ||
this.store.when().verified(onVerified); | ||
this.store.when().verified(onVerified, 'appStoreDiscountEligibilityDeterminer_waiting'); | ||
} | ||
@@ -115,0 +115,0 @@ |
@@ -54,3 +54,3 @@ namespace CdvPurchase | ||
this.log.debug('triggering receiptsReady()'); | ||
this.delegate.receiptsReadyCallbacks.trigger(); | ||
this.delegate.receiptsReadyCallbacks.trigger(undefined, 'adapterListener_setSupportedPlatforms'); | ||
} | ||
@@ -77,3 +77,3 @@ } | ||
this.log.debug('triggering receiptsReady()'); | ||
this.delegate.receiptsReadyCallbacks.trigger(); | ||
this.delegate.receiptsReadyCallbacks.trigger(undefined, 'adapterListener_receiptsReady'); | ||
} | ||
@@ -87,3 +87,3 @@ } | ||
productsUpdated(platform: Platform, products: Product[]): void { | ||
products.forEach(product => this.delegate.updatedCallbacks.trigger(product)); | ||
products.forEach(product => this.delegate.updatedCallbacks.trigger(product, 'adapterListener_productsUpdated')); | ||
} | ||
@@ -102,4 +102,5 @@ | ||
const now = +new Date(); | ||
this.log.debug("receiptsUpdated: " + JSON.stringify(receipts)); | ||
receipts.forEach(receipt => { | ||
this.delegate.updatedReceiptCallbacks.trigger(receipt); | ||
this.delegate.updatedReceiptCallbacks.trigger(receipt, 'adapterListener_receiptsUpdated'); | ||
receipt.transactions.forEach(transaction => { | ||
@@ -111,5 +112,5 @@ const transactionToken = StoreAdapterListener.makeTransactionToken(transaction); | ||
if (transaction.state === TransactionState.APPROVED) { | ||
// prevent calling approved twice in a very short period (5 seconds). | ||
if ((this.lastCallTimeForState[tokenWithState] | 0) < now - 5000) { | ||
this.delegate.approvedCallbacks.trigger(transaction); | ||
// prevent calling approved twice in a very short period (60 seconds). | ||
if ((this.lastCallTimeForState[tokenWithState] | 0) < now - 60000) { | ||
this.delegate.approvedCallbacks.trigger(transaction, 'adapterListener_receiptsUpdated_approved'); | ||
this.lastCallTimeForState[tokenWithState] = now; | ||
@@ -120,7 +121,7 @@ } | ||
if (transaction.state === TransactionState.FINISHED) { | ||
this.delegate.finishedCallbacks.trigger(transaction); | ||
this.delegate.finishedCallbacks.trigger(transaction, 'adapterListener_receiptsUpdated_finished'); | ||
this.lastCallTimeForState[tokenWithState] = now; | ||
} | ||
else if (transaction.state === TransactionState.PENDING) { | ||
this.delegate.pendingCallbacks.trigger(transaction); | ||
this.delegate.pendingCallbacks.trigger(transaction, 'adapterListener_receiptsUpdated_pending'); | ||
this.lastCallTimeForState[tokenWithState] = now; | ||
@@ -127,0 +128,0 @@ } |
@@ -17,3 +17,3 @@ namespace CdvPurchase { | ||
/** List of registered callbacks */ | ||
callbacks: Callback<T>[] = []; | ||
callbacks: { callback: Callback<T>, callbackName?: string }[] = []; | ||
@@ -42,3 +42,3 @@ /** If true, newly registered callbacks will be called immediately when the event was already triggered. | ||
/** Add a callback to the list */ | ||
push(callback: Callback<T>) { | ||
push(callback: Callback<T>, callbackName?: string) { | ||
if (this.finalStateMode && this.numTriggers > 0) { | ||
@@ -50,7 +50,7 @@ callback(this.lastTriggerArgument!); | ||
for (const existing of this.callbacks) { | ||
if (existing === callback) { | ||
if (existing.callback === callback) { | ||
throw new Error('REGISTERING THE SAME CALLBACK TWICE? This is indicative of a bug in your integration.'); | ||
} | ||
} | ||
this.callbacks.push(callback); | ||
this.callbacks.push({ callback, callbackName }); | ||
} | ||
@@ -60,3 +60,3 @@ } | ||
/** Call all registered callbacks with the given value */ | ||
trigger(value: T): void { | ||
trigger(value: T, reason: string): void { | ||
this.lastTriggerArgument = value; | ||
@@ -70,3 +70,3 @@ this.numTriggers++; | ||
callbacks.forEach(callback => { | ||
Utils.safeCall(this.logger, this.className, callback, value); | ||
Utils.safeCall(this.logger, this.className, callback.callback, value, callback.callbackName, reason); | ||
}); | ||
@@ -77,3 +77,3 @@ } | ||
remove(callback: Callback<T>): void { | ||
this.callbacks = this.callbacks.filter(el => el !== callback); | ||
this.callbacks = this.callbacks.filter(el => el.callback !== callback); | ||
} | ||
@@ -80,0 +80,0 @@ } |
@@ -30,5 +30,5 @@ namespace CdvPurchase { | ||
/** Calls the ready callbacks */ | ||
trigger(): void { | ||
trigger(reason: string): void { | ||
this.isReady = true; | ||
this.readyCallbacks.forEach(cb => Utils.safeCall(this.logger, 'ready()', cb, undefined)); | ||
this.readyCallbacks.forEach(cb => Utils.safeCall(this.logger, 'ready()', cb, undefined, undefined, reason)); | ||
this.readyCallbacks = []; | ||
@@ -35,0 +35,0 @@ } |
@@ -38,3 +38,3 @@ namespace CdvPurchase | ||
}, 0); | ||
}); | ||
}, 'receiptsMonitor_callReceiptsVerified'); | ||
} | ||
@@ -55,4 +55,4 @@ | ||
this.controller.when() | ||
.verified(check) | ||
.unverified(check) | ||
.verified(check, 'receiptsMonitor_check') | ||
.unverified(check, 'receiptsMonitor_check') | ||
.receiptsReady(() => { | ||
@@ -70,3 +70,3 @@ this.log.debug('receiptsReady...'); | ||
}, 10000); | ||
}); | ||
}, 'receiptsMonitor_setup'); | ||
} | ||
@@ -73,0 +73,0 @@ } |
@@ -40,4 +40,4 @@ namespace CdvPurchase { | ||
when | ||
.approved(transaction => this.callOnChange(transaction)) | ||
.finished(transaction => this.callOnChange(transaction)); | ||
.approved(transaction => this.callOnChange(transaction), 'transactionStateMonitors_callOnChange') | ||
.finished(transaction => this.callOnChange(transaction), 'transactionStateMonitors_callOnChange'); | ||
} | ||
@@ -44,0 +44,0 @@ |
@@ -188,3 +188,3 @@ /// <reference path="../../types.ts" /> | ||
/** Insert or update a transaction in the pseudo receipt */ | ||
/** Insert or update a transaction in the pseudo receipt, based on data collected from the native side */ | ||
private async upsertTransaction(productId: string, transactionId: string, state: TransactionState): Promise<SKTransaction> { | ||
@@ -191,0 +191,0 @@ return new Promise(resolve => { |
@@ -18,3 +18,3 @@ /// <reference path="../../receipt.ts" /> | ||
static toState(state: Bridge.PurchaseState, isAcknowledged: boolean): TransactionState { | ||
static toState(state: Bridge.PurchaseState, isAcknowledged: boolean, isConsumed: boolean): TransactionState { | ||
switch(state) { | ||
@@ -24,6 +24,8 @@ case Bridge.PurchaseState.PENDING: | ||
case Bridge.PurchaseState.PURCHASED: | ||
// if (isAcknowledged) | ||
// return TransactionState.FINISHED; (this prevents receipt validation...) | ||
// else | ||
return TransactionState.APPROVED; | ||
// Note: we still want to validate acknowledged non-consumables and subscriptions, | ||
// so we don't return APPROVED | ||
if (isConsumed) | ||
return TransactionState.FINISHED; | ||
else | ||
return TransactionState.APPROVED; | ||
case Bridge.PurchaseState.UNSPECIFIED_STATE: | ||
@@ -43,6 +45,7 @@ return TransactionState.UNKNOWN_STATE; | ||
if (purchase.purchaseTime) this.purchaseDate = new Date(purchase.purchaseTime); | ||
this.isPending = (purchase.getPurchaseState === Bridge.PurchaseState.PENDING); | ||
this.isPending = (purchase.getPurchaseState === Bridge.PurchaseState.PENDING) | ||
if (typeof purchase.acknowledged !== 'undefined') this.isAcknowledged = purchase.acknowledged; | ||
if (typeof purchase.consumed !== 'undefined') this.isConsumed = purchase.consumed; | ||
if (typeof purchase.autoRenewing !== 'undefined') this.renewalIntent = purchase.autoRenewing ? RenewalIntent.RENEW : RenewalIntent.LAPSE; | ||
this.state = Transaction.toState(purchase.getPurchaseState, purchase.acknowledged); | ||
this.state = Transaction.toState(purchase.getPurchaseState, this.isAcknowledged ?? false, this.isConsumed ?? false); | ||
} | ||
@@ -273,2 +276,3 @@ } | ||
purchase.acknowledged = true; // consumed is the equivalent of acknowledged for consumables | ||
purchase.consumed = true; | ||
this.onPurchasesUpdated([purchase]); | ||
@@ -275,0 +279,0 @@ } |
@@ -110,2 +110,5 @@ /* | ||
/** Whether the purchase has been consumed */ | ||
consumed?: boolean; | ||
/** One of BridgePurchaseState indicating the state of the purchase. */ | ||
@@ -112,0 +115,0 @@ getPurchaseState: PurchaseState; |
@@ -35,3 +35,3 @@ /// <reference path="types.ts" /> | ||
*/ | ||
export const PLUGIN_VERSION = '13.9.0'; | ||
export const PLUGIN_VERSION = '13.10.0'; | ||
@@ -214,3 +214,3 @@ /** | ||
when: this.when.bind(this), | ||
receiptsVerified: () => { store.receiptsVerifiedCallbacks.trigger(); }, | ||
receiptsVerified: () => { store.receiptsVerifiedCallbacks.trigger(undefined, 'receipts_monitor_controller'); }, | ||
log: this.log, | ||
@@ -252,3 +252,3 @@ }).launch(); | ||
errors.forEach(error => { | ||
store.errorCallbacks.trigger(error); | ||
store.errorCallbacks.trigger(error, 'register_error'); | ||
this.log.error(error); | ||
@@ -290,3 +290,3 @@ }); | ||
ret.then(() => { | ||
this._readyCallbacks.trigger(); | ||
this._readyCallbacks.trigger('initialize_promise_resolved'); | ||
this.listener.setSupportedPlatforms(this.adapters.list.filter(a => a.isSupported).map(a => a.id)); | ||
@@ -331,3 +331,3 @@ }); | ||
products?.forEach(p => { | ||
if (p instanceof Product) this.updatedCallbacks.trigger(p); | ||
if (p instanceof Product) this.updatedCallbacks.trigger(p, 'update_has_loaded_products'); | ||
}); | ||
@@ -358,13 +358,13 @@ } | ||
const ret: When = { | ||
productUpdated: (cb: Callback<Product>) => (this.updatedCallbacks.push(cb), ret), | ||
receiptUpdated: (cb: Callback<Receipt>) => (this.updatedReceiptsCallbacks.push(cb), ret), | ||
updated: (cb: Callback<Product | Receipt>) => (this.updatedCallbacks.push(cb), this.updatedReceiptsCallbacks.push(cb), ret), | ||
productUpdated: (cb: Callback<Product>, callbackName?: string) => (this.updatedCallbacks.push(cb, callbackName), ret), | ||
receiptUpdated: (cb: Callback<Receipt>, callbackName?: string) => (this.updatedReceiptsCallbacks.push(cb, callbackName), ret), | ||
updated: (cb: Callback<Product | Receipt>, callbackName?: string) => (this.updatedCallbacks.push(cb, callbackName), this.updatedReceiptsCallbacks.push(cb, callbackName), ret), | ||
// owned: (cb: Callback<Product>) => (this.ownedCallbacks.push(cb), ret), | ||
approved: (cb: Callback<Transaction>) => (this.approvedCallbacks.push(cb), ret), | ||
pending: (cb: Callback<Transaction>) => (this.pendingCallbacks.push(cb), ret), | ||
finished: (cb: Callback<Transaction>) => (this.finishedCallbacks.push(cb), ret), | ||
verified: (cb: Callback<VerifiedReceipt>) => (this.verifiedCallbacks.push(cb), ret), | ||
unverified: (cb: Callback<UnverifiedReceipt>) => (this.unverifiedCallbacks.push(cb), ret), | ||
receiptsReady: (cb: Callback<void>) => (this.receiptsReadyCallbacks.push(cb), ret), | ||
receiptsVerified: (cb: Callback<void>) => (this.receiptsVerifiedCallbacks.push(cb), ret), | ||
approved: (cb: Callback<Transaction>, callbackName?: string) => (this.approvedCallbacks.push(cb, callbackName), ret), | ||
pending: (cb: Callback<Transaction>, callbackName?: string) => (this.pendingCallbacks.push(cb, callbackName), ret), | ||
finished: (cb: Callback<Transaction>, callbackName?: string) => (this.finishedCallbacks.push(cb, callbackName), ret), | ||
verified: (cb: Callback<VerifiedReceipt>, callbackName?: string) => (this.verifiedCallbacks.push(cb, callbackName), ret), | ||
unverified: (cb: Callback<UnverifiedReceipt>, callbackName?: string) => (this.unverifiedCallbacks.push(cb, callbackName), ret), | ||
receiptsReady: (cb: Callback<void>, callbackName?: string) => (this.receiptsReadyCallbacks.push(cb, callbackName), ret), | ||
receiptsVerified: (cb: Callback<void>, callbackName?: string) => (this.receiptsVerifiedCallbacks.push(cb, callbackName), ret), | ||
}; | ||
@@ -405,6 +405,6 @@ return ret; | ||
*/ | ||
monitor(transaction: Transaction, onChange: Callback<TransactionState>): TransactionMonitor { | ||
monitor(transaction: Transaction, onChange: Callback<TransactionState>, callbackName: string): TransactionMonitor { | ||
return this.transactionStateMonitors.start( | ||
transaction, | ||
Utils.safeCallback(this.log, 'monitor()', onChange)); | ||
Utils.safeCallback(this.log, 'monitor()', onChange, callbackName, 'transactionStateMonitors_stateChanged')); | ||
} | ||
@@ -575,3 +575,3 @@ | ||
} | ||
const monitor = this.monitor(result, onStateChange); | ||
const monitor = this.monitor(result, onStateChange, 'requestPayment_onStateChange'); | ||
} | ||
@@ -709,3 +709,3 @@ }); | ||
triggerError(error: IError) { | ||
this.errorCallbacks.trigger(error); | ||
this.errorCallbacks.trigger(error, 'triggerError'); | ||
} | ||
@@ -745,17 +745,10 @@ | ||
console.log('Create CdvPurchase...'); | ||
/* | ||
if (window.CdvPurchase) { | ||
Object.assign(window.CdvPurchase, CdvPurchase, { store: window.CdvPurchase.store }); | ||
const oldStore = window.CdvPurchase?.store; | ||
window.CdvPurchase = CdvPurchase; | ||
if (oldStore) { | ||
window.CdvPurchase.store = oldStore; | ||
} | ||
else { | ||
window.CdvPurchase = CdvPurchase; | ||
} | ||
if (!window.CdvPurchase.store) { | ||
window.CdvPurchase.store = new CdvPurchase.Store(); | ||
// Let's maximize backward compatibility | ||
Object.assign(window.CdvPurchase.store, CdvPurchase.LogLevel, CdvPurchase.ProductType, CdvPurchase.ErrorCode, CdvPurchase.Platform); | ||
} | ||
*/ | ||
window.CdvPurchase = CdvPurchase; | ||
window.CdvPurchase.store = new CdvPurchase.Store(); | ||
// Let's maximize backward compatibility | ||
@@ -762,0 +755,0 @@ Object.assign(window.CdvPurchase.store, CdvPurchase.LogLevel, CdvPurchase.ProductType, CdvPurchase.ErrorCode, CdvPurchase.Platform); |
@@ -285,9 +285,9 @@ /// <reference path="store.ts" /> | ||
*/ | ||
updated(cb: Callback<Product | Receipt>): When; | ||
updated(cb: Callback<Product | Receipt>, callbackName?: string): When; | ||
/** Register a function called when a receipt is updated. */ | ||
receiptUpdated(cb: Callback<Receipt>): When; | ||
receiptUpdated(cb: Callback<Receipt>, callbackName?: string): When; | ||
/** Register a function called when a product is updated. */ | ||
productUpdated(cb: Callback<Product>): When; | ||
productUpdated(cb: Callback<Product>, callbackName?: string): When; | ||
@@ -298,15 +298,15 @@ // /** Register a function called when a product is owned. */ | ||
/** Register a function called when transaction is approved. */ | ||
approved(cb: Callback<Transaction>): When; | ||
approved(cb: Callback<Transaction>, callbackName?: string): When; | ||
/** Register a function called when transaction is pending. */ | ||
pending(cb: Callback<Transaction>): When; | ||
pending(cb: Callback<Transaction>, callbackName?: string): When; | ||
/** Register a function called when a transaction is finished. */ | ||
finished(cb: Callback<Transaction>): When; | ||
finished(cb: Callback<Transaction>, callbackName?: string): When; | ||
/** Register a function called when a receipt is verified. */ | ||
verified(cb: Callback<VerifiedReceipt>): When; | ||
verified(cb: Callback<VerifiedReceipt>, callbackName?: string): When; | ||
/** Register a function called when a receipt failed validation. */ | ||
unverified(cb: Callback<UnverifiedReceipt>): When; | ||
unverified(cb: Callback<UnverifiedReceipt>, callbackName?: string): When; | ||
@@ -323,3 +323,3 @@ /** | ||
*/ | ||
receiptsReady(cb: Callback<void>): When; | ||
receiptsReady(cb: Callback<void>, callbackName?: string): When; | ||
@@ -331,3 +331,3 @@ /** | ||
*/ | ||
receiptsVerified(cb: Callback<void>): When; | ||
receiptsVerified(cb: Callback<void>, callbackName?: string): When; | ||
} | ||
@@ -334,0 +334,0 @@ |
@@ -11,5 +11,5 @@ namespace CdvPurchase { | ||
*/ | ||
export function safeCallback<T>(logger: Logger, className: string, callback: Callback<T>): Callback<T> { | ||
export function safeCallback<T>(logger: Logger, className: string, callback: Callback<T>, callbackName: string | undefined, reason: string): Callback<T> { | ||
return function (value: T) { | ||
safeCall(logger, className, callback, value); | ||
safeCall(logger, className, callback, value, callbackName, reason); | ||
} | ||
@@ -26,11 +26,13 @@ } | ||
*/ | ||
export function safeCall<T>(logger: Logger, className: string, callback: Callback<T>, value: T): void { | ||
const callbackName = callback.name || ('#' + md5(callback.toString())); | ||
export function safeCall<T>(logger: Logger, className: string, callback: Callback<T>, value: T, callbackName: string | undefined, reason: string): void { | ||
if (!callbackName) { | ||
callbackName = callback.name || ('#' + md5(callback.toString())); | ||
} | ||
setTimeout(() => { | ||
try { | ||
logger.debug(`Calling callback: type=${className} name=${callbackName}`); | ||
logger.debug(`Calling callback: type=${className} name=${callbackName} reason=${reason}`); | ||
callback(value); | ||
} | ||
catch (error) { | ||
logger.error(`Error in callback: type=${className} name=${callbackName}`); | ||
logger.error(`Error in callback: type=${className} name=${callbackName} reason=${reason}`); | ||
logger.debug(callback.toString()); | ||
@@ -37,0 +39,0 @@ const errorAsError = error as Error; |
@@ -124,3 +124,3 @@ namespace CdvPurchase { | ||
const vr = this.addVerifiedReceipt(receipt, payload.data); | ||
this.controller.verifiedCallbacks.trigger(vr); | ||
this.controller.verifiedCallbacks.trigger(vr, 'payload_ok'); | ||
// this.verifiedCallbacks.trigger(data.receipt); | ||
@@ -137,10 +137,10 @@ } | ||
}); | ||
this.controller.verifiedCallbacks.trigger(vr); | ||
this.controller.verifiedCallbacks.trigger(vr, 'payload_expired'); | ||
} | ||
else { | ||
this.controller.unverifiedCallbacks.trigger({receipt, payload}); | ||
this.controller.unverifiedCallbacks.trigger({receipt, payload}, 'no_verified_receipt'); | ||
} | ||
} | ||
else { | ||
this.controller.unverifiedCallbacks.trigger({receipt, payload}); | ||
this.controller.unverifiedCallbacks.trigger({receipt, payload}, 'validator_error'); | ||
} | ||
@@ -154,3 +154,3 @@ } | ||
message: (err as Error).message, | ||
}}); | ||
}}, 'validator_exception'); | ||
} | ||
@@ -157,0 +157,0 @@ }; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
1344745
24983