UNPKG

@nativescript/payments

Version:

In-App Purchase and Subscriptions for NativeScript

329 lines 13.7 kB
import { 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 _productRequest; let _productRequestDelegate; let _paymentTransactionObserver; export function init() { 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() { if (_paymentTransactionObserver) { SKPaymentQueue.defaultQueue().removeTransactionObserver(_paymentTransactionObserver); } _paymentTransactionObserver = null; } export function fetchSubscriptions(itemIds) { fetchItems(itemIds); } export function fetchItems(itemIds) { _payments$.next({ context: PaymentEvent.Context.RETRIEVING_ITEMS, result: PaymentEvent.Result.STARTED, payload: itemIds, }); const productIds = NSMutableSet.alloc().init(); itemIds.forEach((value) => 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, }); } export function startSubscription(item, options) { buyItem(item, options); } export function buyItem(item, buyItemOptions) { 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, }); } } else { console.error(new Error('SKPaymentQueue.defaultQueue().transactions missing.')); } } export function finalizeOrder(order) { _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), }); } } else { _payments$.next({ context: PaymentEvent.Context.FINALIZING_ORDER, result: PaymentEvent.Result.FAILURE, payload: new Failure(999), }); } } export function restoreOrders() { _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), }); } } export function canMakePayments() { // TODO ? return SKPaymentQueue.canMakePayments(); } var SKProductRequestDelegateImpl = /** @class */ (function (_super) { __extends(SKProductRequestDelegateImpl, _super); function SKProductRequestDelegateImpl() { return _super !== null && _super.apply(this, arguments) || this; } SKProductRequestDelegateImpl.prototype.productsRequestDidReceiveResponse = function (request, response) { var products = response.products; // log the invalid IDs if any if (response.invalidProductIdentifiers.count >= 1) { console.log('Invalid product identifiers: ' + JSON.stringify(response.invalidProductIdentifiers.componentsJoinedByString(', '))); } var result = []; var count = products.count; for (var i = 0; i < count; i++) { result.push(new Item(products.objectAtIndex(i))); } _payments$.next({ context: PaymentEvent.Context.RETRIEVING_ITEMS, result: PaymentEvent.Result.SUCCESS, payload: result, }); this._cleanup(); }; SKProductRequestDelegateImpl.prototype.requestDidFailWithError = function (request, error) { _payments$.next({ context: PaymentEvent.Context.RETRIEVING_ITEMS, result: PaymentEvent.Result.FAILURE, payload: new Failure(error.code), }); this._cleanup(); }; SKProductRequestDelegateImpl.prototype._cleanup = function () { _productRequestDelegate = null; _productRequest = null; }; SKProductRequestDelegateImpl.ObjCProtocols = [SKProductsRequestDelegate]; return SKProductRequestDelegateImpl; }(NSObject)); var SKPaymentTransactionObserverImpl = /** @class */ (function (_super) { __extends(SKPaymentTransactionObserverImpl, _super); function SKPaymentTransactionObserverImpl() { return _super !== null && _super.apply(this, arguments) || this; } SKPaymentTransactionObserverImpl.prototype.paymentQueueUpdatedTransactions = function (queue, transactions) { _transactionHandler(queue, transactions); }; SKPaymentTransactionObserverImpl.prototype.paymentQueueRestoreCompletedTransactionsFinished = function (queue) { _payments$.next({ context: PaymentEvent.Context.RESTORING_ORDERS, result: PaymentEvent.Result.SUCCESS, payload: null, }); }; SKPaymentTransactionObserverImpl.prototype.paymentQueueRestoreCompletedTransactionsFailedWithError = function (queue, error) { _payments$.next({ context: PaymentEvent.Context.RESTORING_ORDERS, result: PaymentEvent.Result.FAILURE, payload: new Failure(error.code), }); }; SKPaymentTransactionObserverImpl.prototype.paymentQueueRemovedTransactions = function (queue, transactions) { if (transactions && transactions.count) { for (var i = 0; i < transactions.count; i++) { var transaction = transactions.objectAtIndex(i); if (transaction.transactionState === SKPaymentTransactionState.Purchased) { _payments$.next({ context: PaymentEvent.Context.FINALIZING_ORDER, result: PaymentEvent.Result.SUCCESS, payload: new Order(transaction), }); } } } _payments$.next({ context: PaymentEvent.Context.PROCESSING_ORDER, result: PaymentEvent.Result.PENDING, payload: queue.transactions ? queue.transactions.count : 0, }); }; SKPaymentTransactionObserverImpl.prototype.paymentQueueShouldAddStorePaymentForProduct = function (queue, payment, product) { return true; }; SKPaymentTransactionObserverImpl.prototype.paymentQueueUpdatedDownloads = function (queue, downloads) { console.log('paymentQueueUpdatedDownloads called. Not implemented.'); }; SKPaymentTransactionObserverImpl.ObjCProtocols = [SKPaymentTransactionObserver]; return SKPaymentTransactionObserverImpl; }(NSObject)); function _transactionHandler(queue, transactions) { _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 = transactions.objectAtIndex(i); switch (transaction.transactionState) { case 1 /* SKPaymentTransactionState.Purchased */: _payments$.next({ context: PaymentEvent.Context.PROCESSING_ORDER, result: PaymentEvent.Result.SUCCESS, payload: new Order(transaction), }); break; case 2 /* 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 3 /* 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 0 /* SKPaymentTransactionState.Purchasing */: case 4 /* SKPaymentTransactionState.Deferred */: // TODO ? break; default: console.error(new Error('Missing or unknown transaction state.')); break; } } } _payments$.next({ context: PaymentEvent.Context.PROCESSING_ORDER, result: PaymentEvent.Result.PENDING, payload: queue.transactions ? queue.transactions.count : 0, }); } //# sourceMappingURL=index.ios.js.map