Closed trumpet2012 closed 8 years ago
Windows 10 isn't supported (at least it hasn't been tested by any maintainer here). But it seems it's almost working, good news 👍
Did you find how to retrieve the transaction ID from...? It has to be around when whoever calls approved
.
@dkarzon Any thoughts?
Yeah it does seem to almost work for consumable products in Windows 10. For durable products however it does not get as far. They fail immediately in the subscribe function. I will submit another issue for this.
The transaction ID does appear in the JSON information that gets passed to our server when it validates the order. So at some point the ID is known.
I thought I had it working with Windows 10 :/ It may have just been an 8.1 app running on Win10. Do you know what version of the plugin you are using? Also some sample code for us to double check? I don't think it will be a huge amount of work to fix, I'll see if what I can do when I get some time.
Here are the versions we are running for the relevant libraries and the plugin:
Below is the service we are using to interface with the plugin.
function StoreService($log, $window, $q, $http, $ionicPlatform, Anvil, APPLICATION_SETTINGS) {
var product_registration = $q.defer();
var purchasable_products = [];
// TODO: Register callback with refresh to handle product restores.
// Don't use the store until the plugins are ready.
var store_promise = $ionicPlatform.ready().then(function () {
$window.store.verbosity = $window.store.DEBUG;
$window.store.validator = function(product, callback) {
/**
* This mirrors how the billing plugin (see {@link store._validator}) handles the request, except it uses
* the http service instead of an ajax call. This is done so that token authentication will be performed.
* The plugin uses this function to validate the purchase is legitimate. Anvil will validate the purchase
* with the store.
*
* See https://docs.angularjs.org/api/ng/service/$http for details about the http service response object.
*
* Response data (response.data) is expected to be in the format:
* {
* "ok": true|false,
* "data": { ... }
* }
*
* The data object can contain either an error code (i.e. if subscription is expired), or an error object.
*
* Billing plugin documentation:
* https://github.com/j3k0/cordova-plugin-purchase/blob/master/doc/api.md#-storevalidator
*/
$http({
url: APPLICATION_SETTINGS.ANVIL_API_URL + '/v1/billing/validate/',
method: 'POST',
data: product,
headers: {'Content-Type': 'application/json;charset=UTF-8'}
}).then(
function(response) {
var data = response.data;
callback(data && data.ok, data.data);
},
function(response) {
callback(false, 'Error ' + response.status + ': ' + response.data);
}
);
};
return $window.store;
});
function init_products(products) {
console.log("product init", products);
return store_promise.then(function (store) {
store.error(function (error) {
console.log("Error for store:", e.code, e.message);
});
// resolve product_registration if no products exist or once the first product is registered.
if (products.length == 0) {
$log.warn('StoreService: No products.');
product_registration.resolve();
return;
}
// convert product list to the right format and add them to the store
var PRODUCT_TYPE_MAP = {
'consumable': store.CONSUMABLE,
'non consumable': store.NON_CONSUMABLE,
'paid subscription': store.PAID_SUBSCRIPTION,
'free subscription': store.FREE_SUBSCRIPTION,
'non renewing subscription': store.NON_RENEWING_SUBSCRIPTION
};
console.log("products to be registered", products);
angular.forEach(products, function (prod) {
try {
store.register({
id: prod.product_id,
type: PRODUCT_TYPE_MAP[prod.product_type]
});
} catch (e) {
$log.error("StoreService: Couldn't register product: ", prod, e);
}
});
// This is only used when testing windows phone IAP
$window.store.sandbox = APPLICATION_SETTINGS.WINDOWS_SANDBOX_IAP;
// The docs label this as an expensive call so avoid using it extensively.
$window.store.refresh();
});
}
// Register all products with the store plugin
store_promise.then(function (store) {
Anvil.Product.query().then(
init_products,
null,
init_products
);
});
// Initialize the store state machine.
store_promise.then(function (store) {
// The when("product") filter will match all products purchased.
/* Update the list of purchasable products as they get registered with the store or OWNED */
store.when("product").updated(function (product) {
for (var i = purchasable_products.length - 1; i >= 0; i--) {
if (purchasable_products[i].id == product.id) {
purchasable_products.splice(i, 1);
}
}
console.log("product updated: ", product);
if (product.canPurchase) {
console.log("pushing to list", product);
purchasable_products.push(product);
}
product_registration.resolve();
});
/* Customer has approved the purchase. Anvil should verify with the play store */
store.when("product").approved(function (product) {
product.verify();
});
/* Anvil has verified the purchase. Notify the app everything checks out. */
store.when("product").verified(function (product) {
product.finish();
});
/* Purchase successful. Grant access */
store.when("product").finished(function (product) {
//TODO: grant access
console.log("Finished purchasing product!", product);
})
});
/* Return the list if any of the products have been registered successfully. */
var get_products = product_registration.promise.then(function () {
console.log("Got products", purchasable_products);
return purchasable_products;
});
/* Place an order with the store. Callbacks walk the product through the order cycle.
* The product life cycle is here:
* https://github.com/j3k0/cordova-plugin-purchase/blob/master/doc/api.md#life-cycle */
var place_order = function (product) {
return store_promise.then(
function (store) {
console.log("Placing order: ", store, product);
store.order(product);
},
function (error, arg1, arg2) {
console.log("Error placing order: ",product, error, arg1, arg2);
}
);
};
return {
get_products: get_products,
place_order: place_order
}
}
Hi,
I am having trouble completing a purchase. When trying to buy a consumable product for the first time through the windows store I am receiving the following error:
It is able to trigger the windows buy modal and then goes through the process of validating the order with our server. It then reaches the finished state, before it throws the error.
Could this issue be simply because we are targeting windows 10 instead of 8.1?
I was digging around trying to find where this was being thrown and possibly why. I think the consumePurchase is being called in
src/js/platforms/plugin-bridge.js
here:The only argument it passes is the product ID, while in the
consumePurchase
method insrc/windows/InAppPurchaseProxy.js
expects there to be two arguments passed. With the second argument expected to be the transaction ID.The transaction ID missing would fit with the error since windows expects this value to be a GUID (https://msdn.microsoft.com/en-us/windows/uwp/monetize/enable-consumable-in-app-product-purchases).
Here is the full log of the offending transaction:
Thanks!