using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Http; using System.Text.RegularExpressions; using System.Threading; using Bunq.Sdk.Context; using Bunq.Sdk.Exception; using Bunq.Sdk.Http; using Bunq.Sdk.Json; using Bunq.Sdk.Model.Generated.Endpoint; using Bunq.Sdk.Model.Generated.Object; using Newtonsoft.Json.Linq; namespace TinkerSrc.Lib { public class BunqLib { /// <summary> /// Error constatns. /// </summary> private const string ErrorCouldNotFindAProductionConfiguration = "Could not find a production configuration."; private const string ErrorCouldNotDetermineUser = "Could not determine user"; private const string ErrorUnknownSdkUserType = "Unknown SDK user type."; private const string ErrorCouldNotFindAliasTypeIban = "Could not find IBAN alias linked to MonetaryAccountBank \"%s\""; /// <summary> /// Confic constants. /// </summary> private const string BunqConnfProduction = "bunq-production.conf"; private const string BunqConfSandbox = "bunq-sandbox.conf"; /// <summary> /// Type constatns. /// </summary> private const string MonetaryAccountStatusActive = "ACTIVE"; private const string AliasTypeIban = "IBAN"; private const string AliasTypeEmail = "EMAIL"; private const string CurrencyEur = "EUR"; private const string RequestSpendingMoneyAmount = "500.0"; private const string RequestSpendingMoneyRecipient = "sugardaddy@bunq.com"; private const string RequestSpendingMoneyDescription = "Requesting some spending money."; private const int RequestSpendingMoneyWaitTimeMilliseconds = 1000; private const double BalanceZero = 0.0; private ApiEnvironmentType EnvironmentType { get; set; } public BunqLib(ApiEnvironmentType environmentType) { EnvironmentType = environmentType; SetupContext(); RequestSpendingMoneyIfNeeded(); } private void SetupContext(bool resetConfigIfNeeded = true) { if (File.Exists(DetermineBunqConfFileName())) { // Config is already present } else if (ApiEnvironmentType.SANDBOX.Equals(EnvironmentType)) { var sandboxUser = GenerateNewSandboxUser(); ApiContext.Create(ApiEnvironmentType.SANDBOX, sandboxUser.ApiKey, Environment.MachineName) .Save(this.DetermineBunqConfFileName()); } else { throw new BunqException(ErrorCouldNotFindAProductionConfiguration); } try { var apiContext = ApiContext.Restore(DetermineBunqConfFileName()); apiContext.EnsureSessionActive(); apiContext.Save(DetermineBunqConfFileName()); BunqContext.LoadApiContext(apiContext); } catch (ForbiddenException forbiddenException) { if (resetConfigIfNeeded) { HandleForbiddenExceeption(forbiddenException); } else { throw; } } } private void HandleForbiddenExceeption(ForbiddenException forbiddenException) { if (ApiEnvironmentType.SANDBOX.Equals(EnvironmentType)) { File.Delete(DetermineBunqConfFileName()); SetupContext(false); } else { throw forbiddenException; } } private string DetermineBunqConfFileName() { return ApiEnvironmentType.PRODUCTION.Equals(EnvironmentType) ? BunqConnfProduction : BunqConfSandbox; } public void UpdateContext() { BunqContext.ApiContext.Save(DetermineBunqConfFileName()); } public string GetCurrentUserDisplayName() { if (BunqContext.UserContext.IsOnlyUserPersonSet()) { return BunqContext.UserContext.UserPerson.DisplayName; } else if (BunqContext.UserContext.isOnlyUserCompanySet()) { return BunqContext.UserContext.UserCompany.DisplayName; } else { throw new BunqException(ErrorUnknownSdkUserType); } } public List<MonetaryAccountBank> GetAllMonetaryAccountBankActive(int count = 10) { var pagination = new Pagination {Count = count}; var allMonetaryAccountBank = MonetaryAccountBank.List(pagination.UrlParamsCountOnly).Value; var allMonetaryAccountBankActive = new List<MonetaryAccountBank>(); foreach (var monetaryAccountBank in allMonetaryAccountBank) { if (monetaryAccountBank.Status.Equals(MonetaryAccountStatusActive)) { allMonetaryAccountBankActive.Add(monetaryAccountBank); } } return allMonetaryAccountBankActive; } public static Pointer GetPointerIbanFromMonetaryAccountBank(MonetaryAccountBank monetaryAccountBank) { foreach (var alias in monetaryAccountBank.Alias) { if (alias.Type.Equals(AliasTypeIban)) { return alias; } } throw new BunqException( string.Format( ErrorCouldNotFindAliasTypeIban, monetaryAccountBank.Description ) ); } public List<Payment> GetAllPayment(int count = 10) { var pagination = new Pagination {Count = count}; return Payment.List(urlParams: pagination.UrlParamsCountOnly).Value; } public List<RequestInquiry> GetAllRequest(int count = 10) { var pagination = new Pagination {Count = count}; return RequestInquiry.List(urlParams: pagination.UrlParamsCountOnly).Value; } public List<Card> GetAllCard(int count = 10) { var pagination = new Pagination {Count = count}; return Card.List(pagination.UrlParamsCountOnly).Value; } public static MonetaryAccountBank GetMonetaryAccountCurrentFromCard(Card card, List<MonetaryAccountBank> allMonetaryAccountBank) { var labelIban = card.LabelMonetaryAccountCurrent.LabelMonetaryAccount.Iban; return allMonetaryAccountBank.FirstOrDefault(monetaryAccountBank => labelIban.Equals(GetPointerIbanFromMonetaryAccountBank(monetaryAccountBank).Value)); } public List<Pointer> GetAllUserAlias() { if (BunqContext.UserContext.isOnlyUserCompanySet()) { return BunqContext.UserContext.UserCompany.Alias; } else if (BunqContext.UserContext.IsOnlyUserPersonSet()) { return BunqContext.UserContext.UserPerson.Alias; } else { throw new BunqException(ErrorCouldNotDetermineUser); } } private SandboxUser GenerateNewSandboxUser() { var httpClient = new HttpClient(); httpClient.DefaultRequestHeaders.Add("X-Bunq-Client-Request-Id", "unique"); httpClient.DefaultRequestHeaders.Add("Cache-Control", "no"); httpClient.DefaultRequestHeaders.Add("X-Bunq-Geolocation", "0 0 0 0 NL"); httpClient.DefaultRequestHeaders.Add("X-Bunq-Language", "en_US"); httpClient.DefaultRequestHeaders.Add("X-Bunq-Region", "en_US"); httpClient.DefaultRequestHeaders.Add("User-Agent", "hoi"); var requestTask = httpClient.PostAsync(ApiEnvironmentType.SANDBOX.BaseUri + "sandbox-user", null); requestTask.Wait(); var responseString = requestTask.Result.Content.ReadAsStringAsync().Result; var responseJson = BunqJsonConvert.DeserializeObject<JObject>(responseString); return BunqJsonConvert.DeserializeObject<SandboxUser>(responseJson.First.First.First.First.First .ToString()); } private void RequestSpendingMoneyIfNeeded() { if (ShouldRequestSpendingMoney()) { RequestInquiry.Create( new Amount(RequestSpendingMoneyAmount, CurrencyEur), new Pointer(AliasTypeEmail, RequestSpendingMoneyRecipient), RequestSpendingMoneyDescription, false ); Thread.Sleep(RequestSpendingMoneyWaitTimeMilliseconds); } } private bool ShouldRequestSpendingMoney() { return ApiEnvironmentType.SANDBOX.Equals(EnvironmentType) && double.Parse(BunqContext.UserContext.PrimaryMonetaryAccountBank.Balance.Value) <= BalanceZero; } } }