// ------------------------------------------------------------- public string ShowCheckoutWindowAsync( PaddleProductID productID, CheckoutOptions options, bool openInBrowser, bool isDialog) { ScTask task = new ScTask(); PaddleProduct product = Paddle_GetProduct(productID); product.Refresh((success) => { #if kUseThreads // do on another thread i_threadData.i_currentWindowType = (PaddleWindowType)PaddleWindowType.Checkout; i_threadData.i_currentProduct = product; i_threadData.i_checkoutOptions = options; i_threadData.i_openInBrowser = openInBrowser; i_threadData.i_isDialog = isDialog; StartWindowThread(); #else // do it on this thread Paddle.Instance.ShowCheckoutWindowForProduct(product, options, openInBrowser, isDialog); #endif }); return(task.await_result()); }
//------------------------------------------------------------------- private string Activate(string jsonCmd) { string jsonResult = ""; JObject cmdObject = JObject.Parse(jsonCmd); PaddleProductID prodID = cmdObject.Value <PaddleProductID>(kPaddleCmdKey_SKU); string emailStr = cmdObject.Value <string>(kPaddleCmdKey_EMAIL); string snStr = cmdObject.Value <string>(kPaddleCmdKey_SERIAL_NUMBER); PaddleProduct product = Paddle_GetProduct(prodID); ScTask task = new ScTask(); product.ActivateWithEmail(emailStr, snStr, (PaddleSDK.Product.VerificationState verifyState, string resultStr) => { ActivationState state = ConvertState_VerifyToActivate(verifyState); CJsonResult jResult = new CJsonResult { successB = state == ActivationState.Activated, resultI = Convert.ToInt32(state), errStr = resultStr }; task.set_result(CreateJsonResult(jResult)); }); jsonResult = task.await_result(); return(jsonResult); }
private string Deactivate(string jsonCmd) { string jsonResult = ""; JObject cmdObject = JObject.Parse(jsonCmd); PaddleProductID prodID = cmdObject.Value <PaddleProductID>(kPaddleCmdKey_SKU); PaddleProduct product = Paddle_GetProduct(prodID); ScTask task = new ScTask(); product.Deactivate( (bool stateB, string resultStr) => { CJsonResult jResult = new CJsonResult { successB = stateB, resultI = Convert.ToInt32(stateB), errStr = resultStr }; task.set_result(CreateJsonResult(jResult)); }); jsonResult = task.await_result(); return(jsonResult); }
// ------------------------------------------------------------- // validate means verify private string Validate(string jsonCmd) { string jsonResult; JObject cmdObject = JObject.Parse(jsonCmd); PaddleProductID prodID = cmdObject.Value <PaddleProductID>(kPaddleCmdKey_SKU); PaddleProduct product = Paddle_GetProduct(prodID); if (!product.Activated) { VerificationState state; if (product.TrialDaysRemaining > 0) { state = VerificationState.Verified; } else { state = VerificationState.NoActivation; } CJsonResult jResult = new CJsonResult { successB = state == VerificationState.Verified, resultI = Convert.ToInt32(state) }; jsonResult = CreateJsonResult(jResult); } else { DateTime lastSuccessDateT = product.LastSuccessfulVerifiedDate; TimeSpan spanSinceSuccessT = DateTime.Now - lastSuccessDateT; double hoursSinceSuccessT = spanSinceSuccessT.TotalHours; // Verify the activation only if it's been a while. if (hoursSinceSuccessT < 1) { CJsonResult jResult = new CJsonResult { successB = true, resultI = Convert.ToInt32(VerificationState.Verified) }; // No need to verify. The product is activated. All's well. jsonResult = CreateJsonResult(jResult); } else { ScTask task = new ScTask(); product.VerifyActivation( (PaddleSDK.Product.VerificationState in_state, string resultStr) => { VerificationState state = (VerificationState)in_state; bool destroyB = false; switch (state) { case VerificationState.Unverified: { // The activation is no longer valid. Destroy it, let the user know and continue with // the trial. destroyB = true; } break; case VerificationState.UnableToVerify: { // Verify that the last successful verify date is valid. // And then implement a cooldown strategy. // Ensure that the last successful verified date appears valid. // As `compare:` "detects sub-second differences" the dates should not be the same. // Equally we can't have verified the activation in the future. // future dates have a negative time span since now: if (hoursSinceSuccessT < 0) { // The last successfully verified date does not seem valid. If the time difference // is less than 24 hours, a timezone change is possible. Other than that, tampering // seems likely. // // In doubt, destroy the activation and ask the user to reactivate. destroyB = true; } // Implement a cooldown period: if the user has not gone online within the period, // then destroy the activation and ask them to go online to re-activate. double daysSinceSuccessT = spanSinceSuccessT.TotalDays; if (daysSinceSuccessT >= 30) { destroyB = true; } else { // The grace period continues, so the user can continue to use the core functionality. state = VerificationState.Verified; } } break; } if (destroyB) { product.DestroyActivation(); state = VerificationState.Unverified; } CJsonResult jResult = new CJsonResult { successB = state == VerificationState.Verified, resultI = Convert.ToInt32(state), errStr = resultStr }; task.set_result(CreateJsonResult(jResult)); }); jsonResult = task.await_result(); } } return(jsonResult); }