Hi!
Has anybody ever implemented IAP in Windows 10/8.1 game?
It’s not a big deal of information over the Internet about this issue
Hi!
Has anybody ever implemented IAP in Windows 10/8.1 game?
It’s not a big deal of information over the Internet about this issue
Use the following code but make sure you call it on ui thread otherwise it will crash
create_task(APP::RequestProductPurchaseAsync(productId)).then([this ,productId](task<PurchaseResults^> currentTask)
{
try
{
PurchaseResults^ results = currentTask.get();
switch (results->Status)
{
case ProductPurchaseStatus::Succeeded:
{
GrantFeatureLocally(productId, results->TransactionId);
FulfillProduct1(productId, results->TransactionId);
}
break;
case ProductPurchaseStatus::NotFulfilled:
if (!IsLocallyFulfilled(results->TransactionId))
{
GrantFeatureLocally(productId,results->TransactionId);
}
FulfillProduct1(productId, results->TransactionId);
break;
case ProductPurchaseStatus::NotPurchased:
{
NotifyUser("Product 1 was not purchased.");
}
break;
}
}
catch (Platform::Exception^ exception)
{
NotifyUser("Unable to buy Product 1.");
}
});
}
}
Thank you very much!
I have discovered something like this too. But how to call it from the UI thread?
I did a hack on this one … i used a timer to call it since timer runs on ui thread …the timer call a method that calls the IAP … I m sure someone here knows the real way to do it but if it works it works lol
auto timer = ref new Windows::UI::Xaml::DispatcherTimer();
TimeSpan ts;
ts.Duration = 500;
timer->Interval = ts;
timer->Start();
Ok, so I’ve done something like this:
using namespace WinInApp;
InAppManager::InAppManager() {
// init here
CCLOG("Creating InApp Manager...");
}
void InAppManager::LoadInAppPurchaseProxyFile()
{
CCLOG("Loading proxy file...");
}
void InAppManager::InAppPurchaseRefreshScenario()
{
}
void InAppManager::StartTimerAndRegisterHandler() {
CCLOG("Start timer");
auto timer = ref new Windows::UI::Xaml::DispatcherTimer();
TimeSpan ts;
ts.Duration = 5000;
timer->Interval = ts;
timer->Start();
auto registrationtoken = timer->Tick += ref new EventHandler<Object^>(this, &InAppManager::OnTick);
CCLOG("Timer setup ok.");
}
void InAppManager::OnTick(Object^ sender, Object^ e) {
// do something on each tick here ...
CCLOG("Tick...");
}
Than first time I tried to call
auto m_pInapp = ref new WinInApp::InAppManager();
m_pInapp->StartTimerAndRegisterHandler();
from the scene where my game runs.
It just stuck on this: auto timer = ref new Windows::UI::Xaml::DispatcherTimer();
Just showstop, doing nothing, no crash, just not going any further.
After I placed it to the App.xaml.cpp it just crashes after message “Timer setup ok.” and never goes to OnTick method.
Can you please reveal a bit more about your hack?
I did it this way …
Hope the hack code helps
// setup in App App::OnLaunched
auto timer = ref new Windows::UI::Xaml::DispatcherTimer();
TimeSpan ts;
ts.Duration = 500;
timer->Interval = ts;
timer->Start();
auto registrationtoken = timer->Tick += ref new EventHandler<Object^>(this, &App::OnTick);
///
consumedTransactionIds = ref new Platform::Collections::Vector<Platform::Guid>();
LoadInAppPurchaseConsumablesProxyFile();
the onTick Method in App class
void App::OnTick(Object^ sender, Object^ e) {
// do something on each tick here …
if (InAppPurhase::getInstance()->ready())
{
Platform::String^ productId = stringToPlatformString(InAppPurhase::getInstance()->getPurchaseItemName());
//jkbujauto productName = "Gold";
create_task(APP::RequestProductPurchaseAsync(productId)).then([this ,productId](task<PurchaseResults^> currentTask)
{
try
{
PurchaseResults^ results = currentTask.get();
switch (results->Status)
{
case ProductPurchaseStatus::Succeeded:
{
GrantFeatureLocally(productId, results->TransactionId);
FulfillProduct1(productId, results->TransactionId);
InAppPurhase::getInstance()->onResults(true);
}
break;
case ProductPurchaseStatus::NotFulfilled:
//if (!IsLocallyFulfilled(results->TransactionId))
{
GrantFeatureLocally(productId,results->TransactionId);
InAppPurhase::getInstance()->onResults(true);
}
FulfillProduct1(productId, results->TransactionId);
break;
case ProductPurchaseStatus::NotPurchased:
{
NotifyUser("Product 1 was not purchased.");
InAppPurhase::getInstance()->onResults(false);
}
break;
}
}
catch (Platform::Exception^ exception)
{
NotifyUser("Unable to buy Product 1.");
InAppPurhase::getInstance()->onResults(false);
}
});
}
}
Thanks! Looks like it works now.
How do you switch to real purchases instead of CurrentAppSimulator? You still need to load info, but not from the xlm-file, right?
As I understand you leave something like this:
eventRegistrationToken = (CurrentAppSimulator::LicenseInformation->LicenseChanged += ref new LicenseChangedEventHandler(this, &InAppPurchase::InAppPurchaseRefreshScenario));
create_task(CurrentApp::LoadListingInformationAsync()).then([this](task<ListingInformation^> currentTask)
{
try
{
ListingInformation^ listing = currentTask.get();
auto product1 = listing->ProductListings->Lookup("product1");
auto product2 = listing->ProductListings->Lookup("product2");
}
catch(Platform::Exception^ exception)
{
rootPage->NotifyUser("LoadListingInformationAsync API call failed", NotifyType::ErrorMessage);
}
});
Yea you load from the store when its live . just replace CurrentAppSimulator with App and leave out the load xml .
create_task(CurrentApp::LoadListingInformationAsync()).then([this](task<ListingInformation^> currentTask)
{
try
{
ListingInformation^ listing = currentTask.get();
}
}
Following code will execute task in UI thread without timer hack:
Windows::ApplicationModel::Core::CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
Windows::UI::Core::CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([this] {
create_task(Store::CurrentAppSimulator::RequestProductPurchaseAsync("product1")).then([this](task<Store::PurchaseResults^> currentTask) {
...
});
}));
Also you can use UI and GL thread helper methods from this pull request: https://github.com/cocos2d/cocos2d-x/pull/18067
To run transaction inside UI thread:
cocos2d::GLViewImpl::sharedOpenGLView()->RunOnUIThread(ref new Windows::UI::Core::DispatchedHandler([this] {
...
}));
To complete transaction callback inside GL thread:
cocos2d::GLViewImpl::sharedOpenGLView()->RunOnGLThread(ref new Windows::UI::Core::DispatchedHandler([this] {
...
}));