private Dictionary <string, string> BuildInitiationRequestBody( SteamTransactionEntity transaction ) { var body = new Dictionary <string, string> { ["key"] = Env.GetString("STEAM_PUBLISHER_KEY"), ["orderid"] = transaction.orderId.ToString(), ["steamid"] = transaction.playerSteamId.ToString(), ["appid"] = Env.GetString("STEAM_APP_ID"), ["itemcount"] = transaction.items.Count.ToString(), ["language"] = transaction.language, ["currency"] = transaction.currency }; for (int i = 0; i < transaction.items.Count; i++) { var item = transaction.items[i]; body[$"itemid[{i}]"] = item.itemId.ToString(); body[$"qty[{i}]"] = item.quantity.ToString(); body[$"amount[{i}]"] = item.totalAmountInCents.ToString(); body[$"description[{i}]"] = item.description; if (!string.IsNullOrWhiteSpace(item.category)) { body[$"category[{i}]"] = item.category; } } return(body); }
// ========================================================================= // Don't worry about the code below // ========================================================================= #region "InitiateTransaction implementation" private void ValidateTransactionProposal( SteamTransactionEntity transaction ) { if (transaction.EntityId != null) { throw new ArgumentException( "Given transaction has already been initiated." ); } if (transaction.playerSteamId == 0) { throw new ArgumentException( $"Given transaction does not have " + $"{nameof(transaction.playerSteamId)} specified." ); } if (transaction.items.Count == 0) { throw new ArgumentException( "Given transaction has no items inside of it." ); } }
private void MarkTransactionAsCompleted( SteamTransactionEntity transaction ) { transaction.state = SteamTransactionEntity.CompletedState; transaction.Save(); Log.Info("Marked transaction as completed."); }
private void MarkTransactionAsAuthorized( SteamTransactionEntity transaction ) { transaction.state = SteamTransactionEntity.AuthorizedState; transaction.Save(); Log.Info("Marked transaction as authorized."); }
private void MarkTransactionAsInitiated( SteamTransactionEntity transaction, Response response ) { transaction.state = SteamTransactionEntity.InitiatedState; transaction.transactionId = ulong.Parse( response["response"]["params"]["transid"].AsString ); transaction.Save(); Log.Info("Marked transaction as initiated."); }
private Response SendInitiationRequestToSteam( SteamTransactionEntity transaction ) { // https://partner.steamgames.com/doc/webapi/ISteamMicroTxn#InitTxn var response = Http.Post( GetSteamApiUrl() + "InitTxn/v3/", BuildInitiationRequestBody(transaction) ); response.Throw(); return(response); }
private void StoreFinalizationErrorAndThrow( SteamTransactionEntity transaction, Response response ) { transaction.state = SteamTransactionEntity.FinalizationErrorState; transaction.errorCode = response["response"]["error"]["errorcode"].AsString; transaction.errorDescription = response["response"]["error"]["errordesc"].AsString; transaction.Save(); throw new SteamMicrotransactionException( "Steam rejected transaction finalization.", transaction.orderId, transaction.errorCode, transaction.errorDescription ); }
private Response SendFinalizationRequestToSteam( SteamTransactionEntity transaction ) { // https://partner.steamgames.com/doc/webapi/ISteamMicroTxn#FinalizeTxn var response = Http.Post( GetSteamApiUrl() + "FinalizeTxn/v2/", new Dictionary <string, string> { ["key"] = Env.GetString("STEAM_PUBLISHER_KEY"), ["orderid"] = transaction.orderId.ToString(), ["appid"] = Env.GetString("STEAM_APP_ID") } ); response.Throw(); return(response); }
private void GiveProductsToPlayer(SteamTransactionEntity transaction) { foreach (var item in transaction.items) { Type productType = Type.GetType(item.productClass); if (productType == null) { throw new Exception( $"Cannot find product {item.productClass}" ); } var instance = (IVirtualProduct)Activator.CreateInstance( productType ); var method = productType.GetMethod( nameof(IVirtualProduct.GiveToPlayer) ); if (method == null) { throw new Exception( $"Class {item.productClass} does not contain " + $"method {nameof(IVirtualProduct.GiveToPlayer)}" ); } for (int i = 0; i < item.quantity; i++) { method.Invoke(instance, new object[] { transaction }); Log.Info("Product has been given to the player.", item); } } }
/// <summary> /// Call this method from anywhere within your game /// to initiate a new transaction /// </summary> /// <param name="transaction">Proposal of a new transaction</param> public void InitiateTransaction(SteamTransactionEntity transaction) { ValidateTransactionProposal(transaction); // You can add additional data to the transaction entity // e.g. the currently logged-in player ID transaction.authenticatedPlayerId = Auth.Id(); StoreNewTransaction(transaction); Response response = SendInitiationRequestToSteam(transaction); if (response["response"]["result"].AsString != "OK") { StoreInitiationErrorAndThrow(transaction, response); } MarkTransactionAsInitiated(transaction, response); // The player will be prompted by the Steam App to authorize // and pay the transaction. Then Steam will notify your game // via a Steamworks callback that is handled automatically // by the SteamPurchasingClient class. }
private void StoreNewTransaction(SteamTransactionEntity transaction) { transaction.state = SteamTransactionEntity.BeingPreparedState; transaction.Save(); }