@Override public void setup(StoreSetupListener listener) { Objects.requireNonNull(listener, "listener"); SKPaymentQueue.getDefaultQueue().addTransactionObserver(paymentObserver); listener.onSuccess(); }
@Override public boolean isAvailable() { return SKPaymentQueue.canMakePayments(); }
@Override public void finish() { SKPaymentQueue.getDefaultQueue().finishTransaction(skTransaction); }
@Override public void dispose() { SKPaymentQueue.getDefaultQueue().removeTransactionObserver(paymentObserver); productsRequest = null; }
@Override public void purchaseRestore () { log(LOGTYPELOG, "Restoring purchases..."); // Clear previously restored transactions. restoredTransactions.clear(); // Start the restore flow. SKPaymentQueue.getDefaultQueue().restoreCompletedTransactions(); }
@Override public void didReceiveResponse (SKProductsRequest request, SKProductsResponse response) { // Received the registered products from AppStore. products = response.getProducts(); if (products.size() == 1) { // Create a SKPayment from the product and start purchase flow SKProduct product = products.get(0); log(LOGTYPELOG, "Product info received/purchasing product " + product.getProductIdentifier() + " ..."); SKPayment payment = new SKPayment(product); SKPaymentQueue.getDefaultQueue().addPayment(payment); } else { // wrong product count returned String errorMessage = "Error purchasing product (wrong product info count returned: " + products.size() + ")!"; log(LOGTYPEERROR, errorMessage); observer.handlePurchaseError(new RuntimeException(errorMessage)); } }
@Override public void didReceiveResponse (SKProductsRequest request, SKProductsResponse response) { // Received the registered products from AppStore. products = response.getProducts(); log(LOGTYPELOG, "Products successfully received!"); final SKPaymentQueue defaultQueue = SKPaymentQueue.getDefaultQueue(); // Create and register our apple transaction observer. appleObserver = new AppleTransactionObserver(); defaultQueue.addTransactionObserver(appleObserver); defaultQueue.addStrongRef(appleObserver); log(LOGTYPELOG, "Purchase observer successfully installed!"); // notify of success... observer.handleInstall(); // complete unfinished transactions final NSArray<SKPaymentTransaction> transactions = defaultQueue.getTransactions(); log(LOGTYPELOG, "There are " + transactions.size() + " unfinished transactions. Try to finish..."); appleObserver.updatedTransactions(defaultQueue, transactions); }
@Override public void dispose () { if (appleObserver != null) { // Remove and null our apple transaction observer. SKPaymentQueue defaultQueue = SKPaymentQueue.getDefaultQueue(); defaultQueue.removeTransactionObserver(appleObserver); defaultQueue.removeStrongRef(appleObserver); appleObserver = null; productsRequest = null; products = null; restoredTransactions.clear(); observer = null; config = null; log(LOGTYPELOG, "Disposed purchase manager!"); } }
@Override public void purchaseProduct(Product product) { Util.requireNonNull(product, "product"); if (requestedProducts == null) { BillingError error = new BillingError(ErrorType.PRODUCTS_NOT_REQUESTED, "Product data not requested! Need to call requestProductData() first."); for (BillingObserver observer : billingObservers) { observer.onPurchaseError(null, error); } return; } String id = product.getIdentifier(getType()); if (!requestedProducts.containsKey(id)) { BillingError error = new BillingError(ErrorType.UNKNOWN_PRODUCT_IDENTIFIER, "Product identifier cannot be found for this store!"); for (BillingObserver observer : billingObservers) { observer.onPurchaseError(null, error); } return; } SKPayment payment = new SKPayment(requestedProducts.get(id)); SKPaymentQueue.getDefaultQueue().addPayment(payment); }
@Override public void restoreTransactions() { if (restoringTransactions) { BillingError error = new BillingError(ErrorType.ALREADY_RESTORING, "Already restoring transactions!"); for (BillingObserver observer : billingObservers) { observer.onRestoreError(error); } return; } restoringTransactions = true; SKPaymentQueue.getDefaultQueue().restoreCompletedTransactions(); }
@Override public void didFail (SKRequest request, NSError error) { // Receipt refresh request failed. Let's just continue. log(LOGTYPEERROR, "Receipt fetching failed: " + error.toString()); log(LOGTYPELOG, "Transaction was completed: " + getOriginalTxID(transaction)); observer.handlePurchase(t); // Finish transaction. SKPaymentQueue.getDefaultQueue().finishTransaction(transaction); } });
@Override public void purchase (String identifier) { // Find the SKProduct for this identifier. String identifierForStore = config.getOffer(identifier).getIdentifierForStore(PurchaseManagerConfig.STORE_NAME_IOS_APPLE); SKProduct product = getProductByStoreIdentifier(identifierForStore); if (product == null) { // Product with this identifier not found: load product info first and try to purchase again log(LOGTYPELOG, "Requesting product info for " + identifierForStore); Set<String> identifierForStoreSet = new HashSet<String>(1); identifierForStoreSet.add(identifierForStore); productsRequest = new SKProductsRequest(identifierForStoreSet); productsRequest.setDelegate(new AppleProductsDelegatePurchase()); productsRequest.start(); } else { // Create a SKPayment from the product and start purchase flow log(LOGTYPELOG, "Purchasing product " + identifier + " ..."); SKPayment payment = new SKPayment(product); SKPaymentQueue.getDefaultQueue().addPayment(payment); } }
/** * @param autoFetchInformation is not used, because without product information on ios it's not possible to fill * {@link Transaction} object on successful purchase **/ @Override public void install (PurchaseObserver observer, PurchaseManagerConfig config, boolean autoFetchInformation) { this.observer = observer; this.config = config; log(LOGTYPELOG, "Installing purchase observer..."); // Check if the device is configured for purchases. if (SKPaymentQueue.canMakePayments()) { // Create string set from offer identifiers. int size = config.getOfferCount(); Set<String> productIdentifiers = new HashSet<String>(size); for (int i = 0; i < size; i++) { productIdentifiers.add(config.getOffer(i).getIdentifierForStore(PurchaseManagerConfig.STORE_NAME_IOS_APPLE)); } // Request configured offers/products. log(LOGTYPELOG, "Requesting products..."); productsRequest = new SKProductsRequest(productIdentifiers); productsRequest.setDelegate(new IosFetchProductsAndInstallDelegate()); productsRequest.start(); } else { log(LOGTYPEERROR, "Error setting up in-app-billing: Device not configured for purchases!"); observer.handleInstallError(new RuntimeException( "Error installing purchase observer: Device not configured for purchases!")); } }
@Override public void didFinish (SKRequest r) { // Receipt refresh request finished. if (r.equals(request)) { NSURL receiptURL = NSBundle.getMainBundle().getAppStoreReceiptURL(); NSData receipt = NSData.read(receiptURL); String encodedReceipt = receipt.toBase64EncodedString(NSDataBase64EncodingOptions.None); // FIXME: parse out actual receipt for this IAP purchase: t.setTransactionDataSignature(encodedReceipt); log(LOGTYPELOG, "Receipt was fetched!"); } else { log(LOGTYPEERROR, "Receipt fetching failed: Request doesn't equal initial request!"); } log(LOGTYPELOG, "Transaction was completed: " + getOriginalTxID(transaction)); observer.handlePurchase(t); // Finish transaction. SKPaymentQueue.getDefaultQueue().finishTransaction(transaction); }
SKPaymentQueue.getDefaultQueue().finishTransaction(transaction); SKPaymentQueue.getDefaultQueue().finishTransaction(transaction); SKPaymentQueue.getDefaultQueue().finishTransaction(transaction); break; case Restored: SKPaymentQueue.getDefaultQueue().finishTransaction(transaction);