From 614083d7889911f6faee08f9ea2d34df74ff8ccc Mon Sep 17 00:00:00 2001 From: Pontus Eliason Date: Thu, 19 Sep 2024 07:50:29 +0200 Subject: [PATCH 1/6] Updated models and client --- .idea/.gitignore | 5 + .idea/misc.xml | 6 + .idea/modules.xml | 8 + .idea/trustly-client-net.iml | 9 + .idea/vcs.xml | 6 + src/Client/JsonRpcFactory.cs | 47 +- src/Client/JsonRpcSigner.cs | 32 +- src/Client/NotificationArgs.cs | 36 +- src/Client/Serializer.cs | 63 +- src/Client/SettlementReportParser.cs | 36 +- src/Client/TrustlyApiClient.cs | 374 +- src/Client/TrustlyApiClientExtensions.cs | 90 +- .../Validation/DataAnnotationsValidator.cs | 6 + src/Domain/Any.cs | 12 + .../AbstractFromTrustlyRequestParamsData.cs | 17 - src/Domain/Base/AbstractRequestParamsData.cs | 21 - .../AbstractRequestParamsDataAttributes.cs | 13 - src/Domain/Base/AbstractResponseResultData.cs | 17 - .../AbstractToTrustlyRequestParamsData.cs | 35 - .../Base/EmptyRequestParamsDataAttributes.cs | 11 - src/Domain/Base/IData.cs | 7 - src/Domain/Base/IWithRejectionResult.cs | 9 - src/Domain/Base/JsonRpcRequest.cs | 30 - src/Domain/Base/JsonRpcResponse.cs | 55 - src/Domain/Base/RequestParams.cs | 18 - src/Domain/Base/ResponseError.cs | 14 - src/Domain/Base/ResponseErrorData.cs | 14 - src/Domain/Base/ResponseResult.cs | 22 - ...bstractDepositAndWithdrawDataAttributes.cs | 109 - .../Common/RecipientOrSenderInformation.cs | 51 - .../Common/StringBooleanJsonConverter.cs | 25 - src/Domain/Domain.cs | 6048 +++++++++++++++++ src/Domain/Domain.csproj | 3 +- .../Exceptions/AbstractTrustlyApiException.cs | 3 +- .../TrustlyNoNotificationClientException.cs | 10 - .../Notifications/AbstractCredDebitPending.cs | 30 - src/Domain/Notifications/Account.cs | 86 - src/Domain/Notifications/Cancel.cs | 23 - src/Domain/Notifications/Credit.cs | 9 - src/Domain/Notifications/Debit.cs | 9 - .../Notifications/NotificationResponse.cs | 12 - .../Notifications/PayoutConfirmation.cs | 32 - src/Domain/Notifications/Pending.cs | 9 - src/Domain/Notifications/Unknown.cs | 10 +- src/Domain/Requests/AccountLedger.cs | 101 - src/Domain/Requests/AccountPayout.cs | 108 - src/Domain/Requests/ApproveWithdrawal.cs | 30 - src/Domain/Requests/Balance.cs | 50 - src/Domain/Requests/CancelCharge.cs | 36 - src/Domain/Requests/Charge.cs | 130 - src/Domain/Requests/CreateAccount.cs | 139 - src/Domain/Requests/DenyWithdrawal.cs | 29 - src/Domain/Requests/Deposit.cs | 148 - src/Domain/Requests/GetWithdrawals.cs | 93 - src/Domain/Requests/Refund.cs | 55 - src/Domain/Requests/RegisterAccount.cs | 151 - src/Domain/Requests/RegisterAccountPayout.cs | 200 - src/Domain/Requests/SelectAccount.cs | 86 - src/Domain/Requests/SettlementReport.cs | 113 - src/Domain/Requests/Withdraw.cs | 133 - src/Website/Content/Site.css | 36 - .../Controllers/AbstractBaseController.cs | 22 - src/Website/Controllers/DepositController.cs | 75 - src/Website/Controllers/HomeController.cs | 37 - .../Controllers/NotificationController.cs | 47 - src/Website/Controllers/SuccessController.cs | 36 - src/Website/Program.cs | 28 - src/Website/Properties/launchSettings.json | 27 - src/Website/Startup.cs | 43 - src/Website/Trustly.Website.csproj | 19 - src/Website/Views/Deposit/Index.cshtml | 10 - src/Website/Views/Home/Index.cshtml | 8 - src/Website/Views/Shared/_Layout.cshtml | 28 - src/Website/Views/Success/Index.cshtml | 9 - src/Website/Views/_ViewStart.cshtml | 3 - src/Website/Views/web.config | 42 - src/Website/appsettings.Development.json | 9 - src/Website/appsettings.json | 10 - src/WiremockRecorder/Program.cs | 84 - src/WiremockRecorder/WiremockRecorder.csproj | 15 - tests/Client.UnitTests/.runsettings | 10 + .../AccountLedgerParserTest.cs | 15 +- .../Client.UnitTests/Client.UnitTests.csproj | 14 +- tests/Client.UnitTests/JsonRpcSignerTest.cs | 25 +- tests/Client.UnitTests/NotificationTests.cs | 208 +- tests/Client.UnitTests/RequestTests.cs | 130 +- tests/Client.UnitTests/SerializerTest.cs | 64 +- .../SettlementReportParserTest.cs | 14 +- trustly-client-net.sln | 17 - 89 files changed, 6723 insertions(+), 3446 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/trustly-client-net.iml create mode 100644 .idea/vcs.xml create mode 100644 src/Domain/Any.cs delete mode 100644 src/Domain/Base/AbstractFromTrustlyRequestParamsData.cs delete mode 100644 src/Domain/Base/AbstractRequestParamsData.cs delete mode 100644 src/Domain/Base/AbstractRequestParamsDataAttributes.cs delete mode 100644 src/Domain/Base/AbstractResponseResultData.cs delete mode 100644 src/Domain/Base/AbstractToTrustlyRequestParamsData.cs delete mode 100644 src/Domain/Base/EmptyRequestParamsDataAttributes.cs delete mode 100644 src/Domain/Base/IData.cs delete mode 100644 src/Domain/Base/IWithRejectionResult.cs delete mode 100644 src/Domain/Base/JsonRpcRequest.cs delete mode 100644 src/Domain/Base/JsonRpcResponse.cs delete mode 100644 src/Domain/Base/RequestParams.cs delete mode 100644 src/Domain/Base/ResponseError.cs delete mode 100644 src/Domain/Base/ResponseErrorData.cs delete mode 100644 src/Domain/Base/ResponseResult.cs delete mode 100644 src/Domain/Common/AbstractDepositAndWithdrawDataAttributes.cs delete mode 100644 src/Domain/Common/RecipientOrSenderInformation.cs delete mode 100644 src/Domain/Common/StringBooleanJsonConverter.cs create mode 100644 src/Domain/Domain.cs delete mode 100644 src/Domain/Exceptions/TrustlyNoNotificationClientException.cs delete mode 100644 src/Domain/Notifications/AbstractCredDebitPending.cs delete mode 100644 src/Domain/Notifications/Account.cs delete mode 100644 src/Domain/Notifications/Cancel.cs delete mode 100644 src/Domain/Notifications/Credit.cs delete mode 100644 src/Domain/Notifications/Debit.cs delete mode 100644 src/Domain/Notifications/NotificationResponse.cs delete mode 100644 src/Domain/Notifications/PayoutConfirmation.cs delete mode 100644 src/Domain/Notifications/Pending.cs delete mode 100644 src/Domain/Requests/AccountLedger.cs delete mode 100644 src/Domain/Requests/AccountPayout.cs delete mode 100644 src/Domain/Requests/ApproveWithdrawal.cs delete mode 100644 src/Domain/Requests/Balance.cs delete mode 100644 src/Domain/Requests/CancelCharge.cs delete mode 100644 src/Domain/Requests/Charge.cs delete mode 100644 src/Domain/Requests/CreateAccount.cs delete mode 100644 src/Domain/Requests/DenyWithdrawal.cs delete mode 100644 src/Domain/Requests/Deposit.cs delete mode 100644 src/Domain/Requests/GetWithdrawals.cs delete mode 100644 src/Domain/Requests/Refund.cs delete mode 100644 src/Domain/Requests/RegisterAccount.cs delete mode 100644 src/Domain/Requests/RegisterAccountPayout.cs delete mode 100644 src/Domain/Requests/SelectAccount.cs delete mode 100644 src/Domain/Requests/SettlementReport.cs delete mode 100644 src/Domain/Requests/Withdraw.cs delete mode 100644 src/Website/Content/Site.css delete mode 100644 src/Website/Controllers/AbstractBaseController.cs delete mode 100644 src/Website/Controllers/DepositController.cs delete mode 100644 src/Website/Controllers/HomeController.cs delete mode 100644 src/Website/Controllers/NotificationController.cs delete mode 100644 src/Website/Controllers/SuccessController.cs delete mode 100644 src/Website/Program.cs delete mode 100644 src/Website/Properties/launchSettings.json delete mode 100644 src/Website/Startup.cs delete mode 100644 src/Website/Trustly.Website.csproj delete mode 100644 src/Website/Views/Deposit/Index.cshtml delete mode 100644 src/Website/Views/Home/Index.cshtml delete mode 100644 src/Website/Views/Shared/_Layout.cshtml delete mode 100644 src/Website/Views/Success/Index.cshtml delete mode 100644 src/Website/Views/_ViewStart.cshtml delete mode 100644 src/Website/Views/web.config delete mode 100644 src/Website/appsettings.Development.json delete mode 100644 src/Website/appsettings.json delete mode 100644 src/WiremockRecorder/Program.cs delete mode 100644 src/WiremockRecorder/WiremockRecorder.csproj create mode 100644 tests/Client.UnitTests/.runsettings diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..b58b603 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..8da8e72 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..e69e5a9 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/trustly-client-net.iml b/.idea/trustly-client-net.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/trustly-client-net.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/Client/JsonRpcFactory.cs b/src/Client/JsonRpcFactory.cs index 3baa621..bd691f5 100644 --- a/src/Client/JsonRpcFactory.cs +++ b/src/Client/JsonRpcFactory.cs @@ -1,23 +1,56 @@ using System; -using Trustly.Api.Domain.Base; +using Trustly.Api.Domain; namespace Trustly.Api.Client { public class JsonRpcFactory { - public JsonRpcRequest Create(TReqData requestData, string method, string uuid = null) - where TReqData : IRequestParamsData + public JsonRpcRequest> Create(TReqData requestData, string method, string uuid = null) + where TReqAttr : AbstractRequestDataAttributes + where TReqData : AbstractRequestData { - return new JsonRpcRequest + return new JsonRpcRequest>(method) { - Method = method, - Version = 1.1, - Params = new RequestParams + Params = new JsonRpcRequestParams { UUID = uuid ?? Guid.NewGuid().ToString(), Data = requestData } }; } + + + public JsonRpcResponse> CreateResponse( + JsonRpcNotification> request, + TAckData data + ) + { + return new JsonRpcResponse>() + { + Result = new ResponseResult + { + Method = request.Method, + Data = data, + UUID = request.Params.UUID + } + }; + } + + public JsonRpcResponse> CreateResponse( + TAckData data, + string method, + string uuid + ) + { + return new JsonRpcResponse>() + { + Result = new ResponseResult + { + Method = method, + Data = data, + UUID = uuid + } + }; + } } } diff --git a/src/Client/JsonRpcSigner.cs b/src/Client/JsonRpcSigner.cs index 7d079b5..ecf2d28 100644 --- a/src/Client/JsonRpcSigner.cs +++ b/src/Client/JsonRpcSigner.cs @@ -1,9 +1,6 @@ using System; -using System.IO; using System.Text; -using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Security; -using Trustly.Api.Domain.Base; namespace Trustly.Api.Client { @@ -25,20 +22,7 @@ public string CreatePlaintext(string serializedData, string method, string uuid) return string.Format("{0}{1}{2}", method, uuid, serializedData); } - public void Sign(JsonRpcRequest request) - where TData : IRequestParamsData - { - request.Params.Signature = this.CreateSignature(request.Method, request.Params.UUID, request.Params.Data); - } - - public void Sign(JsonRpcResponse response) - where TData : IResponseResultData - { - response.Result.Signature = this.CreateSignature(response.GetMethod(), response.GetUUID(), response.GetData()); - } - - private string CreateSignature(string method, string uuid, TData data) - where TData : IData + public string CreateSignature(string method, string uuid, object data) { var serializedData = this._serializer.SerializeData(data); var plainText = this.CreatePlaintext(serializedData, method, uuid); @@ -54,19 +38,7 @@ private string CreateSignature(string method, string uuid, TData data) return Convert.ToBase64String(signedBytes); } - public bool Verify(JsonRpcRequest request) - where TData : IRequestParamsData - { - return this.Verify(request.Method, request.Params.UUID, request.Params.Signature, request.Params.Data); - } - - public bool Verify(JsonRpcResponse response) - where TData : IResponseResultData - { - return this.Verify(response.GetMethod(), response.GetUUID(), response.GetSignature(), response.GetData()); - } - - private bool Verify(string method, string uuid, string expectedSignature, IData data) + public bool Verify(string method, string uuid, TData data, string expectedSignature) { var serializedResponseData = this._serializer.SerializeData(data); var responsePlainText = this.CreatePlaintext(serializedResponseData, method, uuid); diff --git a/src/Client/NotificationArgs.cs b/src/Client/NotificationArgs.cs index c8c0eb9..5892715 100644 --- a/src/Client/NotificationArgs.cs +++ b/src/Client/NotificationArgs.cs @@ -1,43 +1,33 @@ using System; -using Trustly.Api.Domain.Base; using System.Threading.Tasks; namespace Trustly.Api.Client { - public delegate Task NotificationResponseDelegate(string method, string uuid); + public delegate Task NotificationAckDelegate(TAckData data); + public delegate Task NotificationRespondDelegate(string stringBody); - public delegate Task NotificationFailResponseDelegate(string method, string uuid, string message); - - public class NotificationArgs - where TData : IRequestParamsData + public class NotificationArgs { - public TData Data { get; } + public TNotificationData Data { get; } - private readonly string _method; - private readonly string _uuid; + internal string Method { get; private set; } + internal string UUID { get; private set; } - private readonly NotificationResponseDelegate _onOK; - private readonly NotificationFailResponseDelegate _onFailed; + internal NotificationAckDelegate Callback { get; private set; } - public NotificationArgs(TData data, string method, string uuid, NotificationResponseDelegate onOK, NotificationFailResponseDelegate onFailed) + public NotificationArgs(TNotificationData data, string method, string uuid, NotificationAckDelegate callback) { this.Data = data; - this._method = method; - this._uuid = uuid; - - this._onOK = onOK; - this._onFailed = onFailed; - } + this.Method = method; + this.UUID = uuid; - public void RespondWithOK() - { - this._onOK(this._method, this._uuid); + this.Callback = callback; } - public void RespondWithFailed(string message) + public void Respond(TAckData result) { - this._onFailed(this._method, this._uuid, message); + this.Callback(result); } } } diff --git a/src/Client/Serializer.cs b/src/Client/Serializer.cs index 614c1e1..7d9259a 100644 --- a/src/Client/Serializer.cs +++ b/src/Client/Serializer.cs @@ -3,25 +3,41 @@ using System.Text; using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using Trustly.Api.Domain.Base; namespace Trustly.Api.Client { public class Serializer { - public string SerializeData(TData data) - where TData : IData + public string SerializeData(TData data, bool silent = false) { - var settings = new JsonSerializerSettings + JObject jsonObject; + if (data is JToken token) { - NullValueHandling = NullValueHandling.Include - }; + // If the value to serialize is already a JToken, then we will assume it is an object. + // We can also work on the actual exact response, and not rely on flaky JSON -> DTO -> JSON -> String conversion. + jsonObject = (JObject) token; + } + else + { + var settings = new JsonSerializerSettings + { + NullValueHandling = NullValueHandling.Ignore + }; + + if (silent) + { + // We ignore any error; useful for test cases or other uncertain scenarios. + settings.Error = (sender, e) => + { + e.ErrorContext.Handled = true; + }; + } - var jsonString = JsonConvert.SerializeObject(data, settings); + var jsonSerializer = JsonSerializer.Create(settings); + jsonObject = JObject.FromObject(data, jsonSerializer); + } - var jsonObject = JToken.Parse(jsonString); var sb = new StringBuilder(); - this.SerializeToken(jsonObject, sb, new string[0]); return sb.ToString(); @@ -41,22 +57,6 @@ private bool SerializeToken(JToken token, StringBuilder sb, string[] propertyPat } else if (token is JValue value) { - if (propertyPath[0].ToLower().Equals("attributes")) - { - if (value.Value == null) - { - // NOTE: Special consideration is made for 'attributes' properties. - // Documentation says that should be regarded as - // But it does not specify that a not included 'attribute' property - // is that same as it not existing at all. - // This is contrary to how 'data' properties work, since they are typesafe. - // But 'attributes' properties were not typesafe, just a map, in older code. - // This discrepancy shows its' head here, since this code is typesafe. - return false; - } - } - - //sb.Append(propertyPath[propertyPath.Length - 1]); sb.Append(value.Value()); } else if (token is JProperty property) @@ -65,11 +65,18 @@ private bool SerializeToken(JToken token, StringBuilder sb, string[] propertyPat propertyPath.CopyTo(newPath, 0); newPath[newPath.Length - 1] = property.Name; - var propertyBuffer = new StringBuilder(); - if (this.SerializeToken(property.Value, propertyBuffer, newPath)) + if (property.Value.Type == JTokenType.Null) { sb.Append(property.Name); - sb.Append(propertyBuffer); + } + else + { + var propertyBuffer = new StringBuilder(); + if (this.SerializeToken(property.Value, propertyBuffer, newPath)) + { + sb.Append(property.Name); + sb.Append(propertyBuffer); + } } } else diff --git a/src/Client/SettlementReportParser.cs b/src/Client/SettlementReportParser.cs index d3acedc..1f877f7 100644 --- a/src/Client/SettlementReportParser.cs +++ b/src/Client/SettlementReportParser.cs @@ -1,14 +1,10 @@ using System; using System.Collections.Generic; using System.Globalization; -using System.IO; using System.Text; -using System.Text.RegularExpressions; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using Trustly.Api.Domain.Requests; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; +using Trustly.Api.Domain; namespace Trustly.Api.Client { @@ -19,16 +15,34 @@ public class SettlementReportParser private readonly static Mapper NOOP_MAPPER = (row, value) => { }; private readonly Dictionary _mappers = new Dictionary(); + class EnumHelper + { + public T Value { get; set; } + } + public SettlementReportParser() { this._mappers.Add("accountname", (row, value) => row.AccountName = value); this._mappers.Add("currency", (row, value) => row.Currency = value); - this._mappers.Add("messageid", (row, value) => row.MessageID = value); + this._mappers.Add("messageid", (row, value) => row.MessageId = value); this._mappers.Add("orderid", (row, value) => row.OrderID = value); - this._mappers.Add("ordertype", (row, value) => row.OrderType = value); + this._mappers.Add("ordertype", (row, value) => + { + row.OrderTypeString = value; + try + { + var json = $"{{\"value\": \"{value}\"}}"; + var result = JsonConvert.DeserializeObject>(json); + row.OrderType = result.Value; + } + catch (Exception ex) + { + row.OrderType = null; + } + }); this._mappers.Add("username", (row, value) => row.Username = value); this._mappers.Add("fxpaymentcurrency", (row, value) => row.FxPaymentCurrency = value); - this._mappers.Add("settlementbankwithdrawalid", (row, value) => row.SettlementBankWithdrawalID = value); + this._mappers.Add("settlementbankwithdrawalid", (row, value) => row.SettlementBankWithdrawalId = value); this._mappers.Add("externalreference", (row, value) => row.ExternalReference = value); this._mappers.Add("extraref", (row, value) => row.ExternalReference = value); @@ -64,12 +78,14 @@ public SettlementReportParser() this._mappers.Add("datestamp", (row, value) => { + /* if (!DateTime.TryParse(value, out DateTime result)) { throw new ArgumentException($"Could not convert value '{value}' into a DateTime"); } + */ - row.Datestamp = result; + row.Datestamp = value; }); } diff --git a/src/Client/TrustlyApiClient.cs b/src/Client/TrustlyApiClient.cs index 8868fd9..f2e562c 100644 --- a/src/Client/TrustlyApiClient.cs +++ b/src/Client/TrustlyApiClient.cs @@ -8,153 +8,114 @@ using Microsoft.AspNetCore.Http; using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using Trustly.Api.Domain.Base; +using Trustly.Api.Domain; using Trustly.Api.Domain.Exceptions; -using Trustly.Api.Domain.Notifications; -using Trustly.Api.Domain.Requests; namespace Trustly.Api.Client { - public class TrustlyApiClient : IDisposable + public class TrustlyApiClient { - private static readonly List _staticRegisteredClients = new List(); - public TrustlyApiClientSettings Settings { get; } private readonly JsonRpcFactory _objectFactory = new JsonRpcFactory(); - private readonly Serializer serializer = new Serializer(); - private readonly JsonRpcSigner _signer; - private readonly JsonRpcValidator _validator = new JsonRpcValidator(); + private readonly Serializer _serializer; + private JsonRpcValidator Validator { get; } = new JsonRpcValidator(); public Func RequestCreator { get; set; } - - public event EventHandler> OnAccount; - public event EventHandler> OnCancel; - public event EventHandler> OnCredit; - public event EventHandler> OnDebit; - public event EventHandler> OnPayoutConfirmation; - public event EventHandler> OnPending; - public event EventHandler> OnUnknownNotification; - - private readonly Dictionary> _methodToNotificationMapper - = new Dictionary>(); + public JsonRpcSigner Signer { get; } + private JsonSerializerSettings SerializerSettings { get; } + + public event EventHandler> OnAccount; + public event EventHandler> OnCancel; + public event EventHandler> OnCredit; + public event EventHandler> OnDebit; + public event EventHandler> OnPayoutConfirmation; + public event EventHandler> OnPayoutFailed; + public event EventHandler> OnPending; + public event EventHandler> OnKYC; + public event EventHandler> OnUnknownNotification; public TrustlyApiClient(TrustlyApiClientSettings settings) { + this.SerializerSettings = new JsonSerializerSettings + { + NullValueHandling = NullValueHandling.Ignore + }; + this._serializer = new Serializer(); this.Settings = settings; - this._signer = new JsonRpcSigner(serializer, this.Settings); - - this._methodToNotificationMapper.Add("account", (json, ok, error) => this.HandleNotificationFromString(json, this.OnAccount, ok, error)); - this._methodToNotificationMapper.Add("cancel", (json, ok, error) => this.HandleNotificationFromString(json, this.OnCancel, ok, error)); - this._methodToNotificationMapper.Add("credit", (json, ok, error) => this.HandleNotificationFromString(json, this.OnCredit, ok, error)); - this._methodToNotificationMapper.Add("debit", (json, ok, error) => this.HandleNotificationFromString(json, this.OnDebit, ok, error)); - this._methodToNotificationMapper.Add("payoutconfirmation", (json, ok, error) => this.HandleNotificationFromString(json, this.OnPayoutConfirmation, ok, error)); - this._methodToNotificationMapper.Add("pending", (json, ok, error) => this.HandleNotificationFromString(json, this.OnPending, ok, error)); - - this._methodToNotificationMapper.Add(string.Empty, (json, ok, error) => this.HandleNotificationFromString(json, this.OnUnknownNotification, ok, error)); - - TrustlyApiClient._staticRegisteredClients.Add(this); - } - - ~TrustlyApiClient() - { - TrustlyApiClient._staticRegisteredClients.Remove(this); - } - - public void Dispose() - { - TrustlyApiClient._staticRegisteredClients.Remove(this); - } - - public static IEnumerable GetRegisteredClients() - { - return _staticRegisteredClients; - } - - public AccountLedgerResponseData AccountLedger(AccountLedgerRequestData request, string uuid = null) - { - return this.SendRequest(request, "AccountLedger", uuid); + this.Signer = new JsonRpcSigner(_serializer, this.Settings); } + public IList AccountLedger(AccountLedgerRequestData request, string uuid = null) + => this.SendRequest>(request, "AccountLedger", uuid); public AccountPayoutResponseData AccountPayout(AccountPayoutRequestData request, string uuid = null) - { - return this.SendRequest(request, "AccountPayout", uuid); - } - + => this.SendRequest(request, "AccountPayout", uuid); public ApproveWithdrawalResponseData ApproveWithdrawal(ApproveWithdrawalRequestData request, string uuid = null) - { - return this.SendRequest(request, "ApproveWithdrawal", uuid); - } - - public BalanceResponseData Balance(BalanceRequestData request, string uuid = null) - { - return this.SendRequest(request, "Balance", uuid); - } - + => this.SendRequest(request, "ApproveWithdrawal", uuid); + public IList Balance(BalanceRequestData request, string uuid = null) + => this.SendRequest>(request, "Balance", uuid); public CancelChargeResponseData CancelCharge(CancelChargeRequestData request, string uuid = null) - { - return this.SendRequest(request, "CancelCharge", uuid); - } - - public ChargeResponseData Charge(ChargeRequestData request, string uuid = null) - { - return this.SendRequest(request, "Charge", uuid); - } - + => this.SendRequest(request, "CancelCharge", uuid); public DenyWithdrawalResponseData DenyWithdrawal(DenyWithdrawalRequestData request, string uuid = null) - { - return this.SendRequest(request, "DenyWithdrawal", uuid); - } - + => this.SendRequest(request, "DenyWithdrawal", uuid); public DepositResponseData Deposit(DepositRequestData request, string uuid = null) - { - return this.SendRequest(request, "Deposit", uuid); - } - - public GetWithdrawalsResponseData GetWithdrawals(GetWithdrawalsRequestData request, string uuid = null) - { - return this.SendRequest(request, "GetWithdrawals", uuid); - } - + => this.SendRequest(request, "Deposit", uuid); + public GetWithdrawalsResponseDataEntry[] GetWithdrawals(GetWithdrawalsRequestData request, string uuid = null) + => this.SendRequest(request, "GetWithdrawals", uuid); public RefundResponseData Refund(RefundRequestData request, string uuid = null) - { - return this.SendRequest(request, "Refund", uuid); - } - + => this.SendRequest(request, "Refund", uuid); public CreateAccountResponseData CreateAccount(CreateAccountRequestData request, string uuid = null) - { - return this.SendRequest(request, "CreateAccount", uuid); - } - + => this.SendRequest(request, "CreateAccount", uuid); public SelectAccountResponseData SelectAccount(SelectAccountRequestData request, string uuid = null) - { - return this.SendRequest(request, "SelectAccount", uuid); - } - + => this.SendRequest(request, "SelectAccount", uuid); public RegisterAccountResponseData RegisterAccount(RegisterAccountRequestData request, string uuid = null) - { - return this.SendRequest(request, "RegisterAccount", uuid); - } - + => this.SendRequest(request, "RegisterAccount", uuid); public RegisterAccountPayoutResponseData RegisterAccountPayout(RegisterAccountPayoutRequestData request, string uuid = null) - { - return this.SendRequest(request, "RegisterAccountPayout", uuid); - } + => this.SendRequest(request, "RegisterAccountPayout", uuid); + public WithdrawResponseData Withdraw(WithdrawRequestData request) + => this.SendRequest(request, "Withdraw"); + public MerchantSettlementResponseData MerchantSettlement(MerchantSettlementRequestData request) + => this.SendRequest(request, "MerchantSettlement"); + public SwishResponseData Swish(SwishRequestData request) + => this.SendRequest(request, "Swish"); + public DirectDebitMandateResponseData DirectDebitMandate(DirectDebitMandateRequestData request) + => this.SendRequest(request, "DirectDebitMandate"); + public CancelDirectDebitMandateResponseData CancelDirectDebitMandate(CancelDirectDebitRequestData request) + => this.SendRequest(request, "CancelDirectDebitMandate"); + public ImportDirectDebitMandateResponseData ImportDirectDebitMandate(ImportDirectDebitMandateRequestData request) + => this.SendRequest(request, "ImportDirectDebitMandate"); + public DirectDebitResponseData DirectDebit(DirectDebitRequestData request) + => this.SendRequest(request, "DirectDebit"); + public CancelDirectDebitResponseData CancelDirectDebit(CancelDirectDebitRequestData request) + => this.SendRequest(request, "CancelDirectDebit"); + public DirectCreditResponseData DirectCredit(DirectCreditRequestData request) + => this.SendRequest(request, "DirectCredit"); + public RefundDirectDebitResponseData RefundDirectDebit(RefundDirectDebitRequestData request) + => this.SendRequest(request, "RefundDirectDebit"); + public DirectPaymentBatchResponseData DirectPaymentBatch(DirectPaymentBatchRequestData request) + => this.SendRequest(request, "DirectPaymentBatch"); - public SettlementReportResponseData SettlementReport(SettlementReportRequestData request, string uuid = null) + public ChargeResponseData Charge(ChargeRequestData request, string uuid = null) { - var response = this.SendRequest(request, "ViewAutomaticSettlementDetailsCSV", uuid); - - var parser = new SettlementReportParser(); - var entries = parser.Parse(response.CsvContent); - response.Entries = entries; + var response = this.SendRequest(request, "Charge", uuid); + if (response.Result == StringBoolean.FALSE) + { + var message = response.Rejected ?? "The request was rejected for an unknown reason"; + throw new TrustlyRejectionException("Received a rejection response from the Trustly API: " + message) + { + Reason = response.Rejected + }; + } return response; } - public WithdrawResponseData Withdraw(WithdrawRequestData request) + public List SettlementReport(SettlementReportRequestData request, string uuid = null) { - return this.SendRequest(request, "Withdraw"); + var response = this.SendRequest(request, "ViewAutomaticSettlementDetailsCSV", uuid); + var entries = new SettlementReportParser().Parse(response.ViewAutomaticSettlementDetails); + + return entries; } /// @@ -166,13 +127,14 @@ public WithdrawResponseData Withdraw(WithdrawRequestData request) /// The request data that will be used for the request /// The method of the JsonRpc package /// A signed and validated JsonRpc request package - public JsonRpcRequest CreateRequestPackage(TReqData requestData, string method, string uuid = null) - where TReqData : IRequestParamsData + public JsonRpcRequest> CreateRequestPackage(TReqData requestData, string method, string uuid = null) + where TReqAttr : AbstractRequestDataAttributes + where TReqData : AbstractRequestData { - var rpcRequest = this._objectFactory.Create(requestData, method, uuid); + var rpcRequest = this._objectFactory.Create(requestData, method, uuid); - this._signer.Sign(rpcRequest); - this._validator.Validate(rpcRequest); + rpcRequest.Params.Signature = this.Signer.CreateSignature(rpcRequest.Method, rpcRequest.Params.UUID, requestData); + this.Validator.Validate(rpcRequest); return rpcRequest; } @@ -182,22 +144,12 @@ public JsonRpcRequest CreateRequestPackage(TReqData requestD /// /// /// A signed and validated JsonRpc response package - public JsonRpcResponse CreateResponsePackage(string method, string requestUuid, TResData responseData) - where TResData : IResponseResultData + public JsonRpcResponse> CreateResponsePackage(TResData responseData, string method, string requestUuid) { - var rpcResponse = new JsonRpcResponse - { - Result = new ResponseResult - { - Method = method, - UUID = requestUuid, - Data = responseData - }, - Version = "1.1" - }; + var rpcResponse = this._objectFactory.CreateResponse(responseData, method, requestUuid); - this._signer.Sign(rpcResponse); - this._validator.Validate(rpcResponse); + rpcResponse.Result.Signature = this.Signer.CreateSignature(rpcResponse.Result.Method, rpcResponse.Result.UUID, rpcResponse.Result.Data); + this.Validator.Validate(rpcResponse); return rpcResponse; } @@ -208,102 +160,104 @@ public JsonRpcResponse CreateResponsePackage(string method, /// Request to send to Trustly API /// The RPC method name of the request /// Optional UUID for the request. If not specified, a Guid will be generated - /// Response generated from the request - public TRespData SendRequest(TReqData requestData, string method, string uuid = null) - where TReqData : IToTrustlyRequestParamsData - where TRespData : IResponseResultData + /// Response data returned from the request + public TResData SendRequest(TReqData requestData, string method, string uuid = null) + where TReqAttr : AbstractRequestDataAttributes + where TReqData : AbstractRequestData { requestData.Username = this.Settings.Username; requestData.Password = this.Settings.Password; - var rpcRequest = this.CreateRequestPackage(requestData, method, uuid); + var rpcRequest = this.CreateRequestPackage(requestData, method, uuid); + return this.SendRequest(rpcRequest); + } - var requestString = JsonConvert.SerializeObject(rpcRequest, new JsonSerializerSettings - { - NullValueHandling = NullValueHandling.Ignore - }); + /// + /// Sends given request to Trustly. + /// + /// The full JsonRpc request to send to the Trustly API + /// Response data returned from the request + public TResData SendRequest(JsonRpcRequest> rpcRequest) + where TReqAttr : AbstractRequestDataAttributes + where TReqData : AbstractRequestData + { + var requestString = JsonConvert.SerializeObject(rpcRequest, this.SerializerSettings); var responseString = NewHttpPost(requestString); - var rpcResponse = JsonConvert.DeserializeObject>(responseString); + var responseNode = JObject.Parse(responseString); - if (!rpcResponse.IsSuccessfulResult()) + if (responseNode.ContainsKey("error") || !responseNode.ContainsKey("result")) { - var message = rpcResponse.Error?.Message ?? rpcResponse.Error?.Name ?? ("" + rpcResponse.Error?.Code); + var rpcErrorResponse = responseNode.ToObject(); + + var message = rpcErrorResponse.Error?.Message ?? rpcErrorResponse.Error?.Name ?? ("" + rpcErrorResponse.Error?.Code); throw new TrustlyDataException("Received an error response from the Trustly API: " + message) { - ResponseError = rpcResponse.Error + ResponseError = rpcErrorResponse.Error }; } - - if (rpcResponse.Result.Data is IWithRejectionResult rejectionResult) + else { - if (!rejectionResult.Result) + var rpcResponse = responseNode.ToObject>>(); + + if (!this.Signer.Verify(rpcResponse.Result.Method, rpcResponse.Result.UUID, responseNode["result"]["data"], rpcResponse.Result.Signature)) { - var message = rejectionResult.Rejected ?? "The request was rejected for an unknown reason"; - throw new TrustlyRejectionException("Received a rejection response from the Trustly API: " + message) - { - Reason = rejectionResult.Rejected - }; + throw new TrustlySignatureException("Incoming data signature is not valid"); } - } - if (!this._signer.Verify(rpcResponse)) - { - throw new TrustlySignatureException("Incoming data signature is not valid"); - } + if (string.IsNullOrEmpty(rpcResponse.Result.UUID) || !rpcResponse.Result.UUID.Equals(rpcRequest.Params.UUID)) + { + throw new TrustlyDataException("Incoming UUID is not valid"); + } - if (string.IsNullOrEmpty(rpcResponse.GetUUID()) || !rpcResponse.GetUUID().Equals(rpcRequest.Params.UUID)) - { - throw new TrustlyDataException("Incoming UUID is not valid"); + return rpcResponse.Result.Data; } - - return rpcResponse.Result.Data; } - public async Task HandleNotificationFromRequestAsync(HttpRequest request, NotificationResponseDelegate onOK = null, NotificationFailResponseDelegate onFailed = null) + public async Task HandleNotificationFromRequestAsync(HttpRequest request, NotificationRespondDelegate callback) { - if (string.Equals(request.Method, "post", StringComparison.InvariantCultureIgnoreCase)) - { - using (var sr = new StreamReader(request.Body)) - { - var requestStringBody = await sr.ReadToEndAsync(); - return this.HandleNotificationFromString(requestStringBody, onOK, onFailed); - } - } - else + if (!string.Equals(request.Method, "post", StringComparison.InvariantCultureIgnoreCase)) { throw new TrustlyNotificationException("Notifications are only allowed to be received as a HTTP Post"); } - } - - public int HandleNotificationFromString(string jsonString, NotificationResponseDelegate onOK = null, NotificationFailResponseDelegate onFailed = null) - { - var jsonToken = JToken.Parse(jsonString); - var methodToken = jsonToken.SelectToken("$.method"); - var methodValue = methodToken.Value().ToLower(CultureInfo.InvariantCulture); + using (var sr = new StreamReader(request.Body)) + { + var jsonString = await sr.ReadToEndAsync(); - var mapper = this._methodToNotificationMapper.ContainsKey(methodValue) - ? this._methodToNotificationMapper[methodValue] - : this._methodToNotificationMapper[string.Empty]; + var jsonToken = JToken.Parse(jsonString); + var methodValue = jsonToken.Value("method").ToLower(CultureInfo.InvariantCulture); - // This will then call generic method HandleNotificationFromString below. - // We do it this way to keep the dynamic generic parameters intact. - return mapper(jsonString, onOK, onFailed); + switch (methodValue) + { + case "account": return HandleNotification(jsonToken, this.OnAccount, callback); + case "cancel": return HandleNotification(jsonToken, this.OnCancel, callback); + case "credit": return HandleNotification(jsonToken, this.OnCredit, callback); + case "debit": return HandleNotification(jsonToken, this.OnDebit, callback); + case "payoutconfirmation": return HandleNotification(jsonToken, this.OnPayoutConfirmation, callback); + case "pending": return HandleNotification(jsonToken, this.OnPending, callback); + case "kyc": return HandleNotification(jsonToken, this.OnKYC, callback); + default: return HandleNotification(jsonToken, this.OnUnknownNotification, callback); + }; + } } - private int HandleNotificationFromString( - string jsonString, - EventHandler> eventHandler, - NotificationResponseDelegate onOK, - NotificationFailResponseDelegate onFailed - ) - where TReqData : IRequestParamsData + private int HandleNotification( + JToken token, + EventHandler> eventHandler, + NotificationRespondDelegate callback + ) { - var rpcRequest = JsonConvert.DeserializeObject>(jsonString); + + if (eventHandler == null) + { + return 0; + } + + var notification = token.ToObject>>(); // Verify the notification (RpcRequest from Trustly) signature. - if (!this._signer.Verify(rpcRequest)) + if (!this.Signer.Verify(notification.Method, notification.Params.UUID, notification.Params.Data, notification.Params.Signature)) { throw new TrustlySignatureException("Could not validate signature of notification from Trustly. Is the public key for Trustly the correct one, for test or production?"); } @@ -311,22 +265,24 @@ NotificationFailResponseDelegate onFailed // Validate the incoming request instance. // Most likely this will do nothing, since we are lenient on things sent from Trustly server. // But we do this in case anything is needed to be validated on the local domain classes in the future. - this._validator.Validate(rpcRequest); + this.Validator.Validate(notification); - if (eventHandler == null || eventHandler.GetInvocationList().Length == 0) + var args = new NotificationArgs(notification.Params.Data, notification.Method, notification.Params.UUID, async (ackData) => { - throw new TrustlyNoNotificationListenerException($"Received an incoming '{rpcRequest.Method}' notification, but there was no event listener subscribing to it"); - } + var responseObject = this._objectFactory.CreateResponse(notification, ackData); - try - { - eventHandler(this, new NotificationArgs(rpcRequest.Params.Data, rpcRequest.Method, rpcRequest.Params.UUID, onOK, onFailed)); - } - catch (Exception ex) - { - var message = this.Settings.IncludeExceptionMessageInNotificationResponse ? ex.Message : null; - onFailed(rpcRequest.Method, rpcRequest.Params.UUID, message); - } + responseObject.Result.Signature = this.Signer.CreateSignature( + responseObject.Result.Method, + responseObject.Result.UUID, + responseObject.Result.Data + ); + + var responseStr = JsonConvert.SerializeObject(responseObject, this.SerializerSettings); + + await callback(responseStr); + }); + + eventHandler(this, args); return eventHandler.GetInvocationList().Length; } diff --git a/src/Client/TrustlyApiClientExtensions.cs b/src/Client/TrustlyApiClientExtensions.cs index 7c04e8d..b5b3083 100644 --- a/src/Client/TrustlyApiClientExtensions.cs +++ b/src/Client/TrustlyApiClientExtensions.cs @@ -1,24 +1,30 @@ using System; -using System.Collections.Generic; using System.Net; using System.Reflection; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; -using Newtonsoft.Json; using Trustly.Api.Domain.Exceptions; -using Trustly.Api.Domain.Notifications; +using Microsoft.Extensions.Primitives; namespace Trustly.Api.Client { public static class TrustlyApiClientExtensions { - public static void UseTrustlyNotifications(this IApplicationBuilder app) + public static readonly string GENERIC_ERROR_MESSAGE = "An exception occurred (error message given by trustly-api-client for .NET)"; + + private static readonly AssemblyName assemblyName = Assembly.GetExecutingAssembly().GetName(); + private static readonly Version assemblyVersion = assemblyName.Version; + + public static void UseTrustlyNotifications(this IApplicationBuilder app, TrustlyApiClient client) { - app.Use((context, next) => HandleNotificationRequest(context, next)); + app.Use((context, next) => + { + return HandleNotificationRequest(context, next, client); + }); } - public async static Task HandleNotificationRequest(HttpContext context, Func next) + public async static Task HandleNotificationRequest(HttpContext context, Func next, TrustlyApiClient client) { var request = context.Request; var contextPath = request.Path.Value.Trim(new[] { '/' }); @@ -26,71 +32,53 @@ public async static Task HandleNotificationRequest(HttpContext context, Func - { - responseCount++; - await Respond(client, context.Response, rpcMethod, uuid, "OK", null, HttpStatusCode.OK); - }, - onFailed: async (rpcMethod, uuid, message) => + async (stringBody) => { responseCount++; - await Respond(client, context.Response, rpcMethod, uuid, "FAILED", message, HttpStatusCode.InternalServerError); + + context.Response.Headers.Add("User-Agent", new StringValues("trustly-api-client/" + assemblyVersion)); + context.Response.StatusCode = (int)HttpStatusCode.OK; + await context.Response.WriteAsync(stringBody); } ); } - - if (clientCount == 0) + catch (Exception ex) { - throw new TrustlyNoNotificationClientException("There are no registered Api Clients listening to notifications"); + context.Response.Headers.Add("User-Agent", new StringValues("trustly-api-client/" + assemblyVersion)); + context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; + + if (includeErrorMessage) + { + await context.Response.WriteAsync(ex.Message); + responseCount++; + } + else + { + await context.Response.WriteAsync(GENERIC_ERROR_MESSAGE); + responseCount++; + } } if (responseCount == 0) { - throw new TrustlyNoNotificationClientException("None of your client's event listeners responded with OK or FAILED. That must be done."); + throw new TrustlyNoNotificationListenerException("None of your clients' event listeners responded with acknowledge data. That must be done."); } } else { - await next.Invoke(); - } - } - - public static async Task Respond(TrustlyApiClient client, HttpResponse response, string method, string uuid, string status, string message, HttpStatusCode httpStatusCode) - { - var rpcResponse = client.CreateResponsePackage( - method, - uuid, - new NotificationResponse - { - Status = status - } - ); - - if (client.Settings.IncludeMessageInNotificationResponse) - { - if (string.IsNullOrEmpty(message) == false) + if (next != null) { - rpcResponse.Result.Data.ExtensionData = new Dictionary - { - { "message", message } - }; + await next.Invoke(); } } - - var rpcString = JsonConvert.SerializeObject(rpcResponse); - - var assemblyName = Assembly.GetExecutingAssembly().GetName(); - var assemblyVersion = assemblyName.Version; - - response.Headers.Add("User-Agent", new Microsoft.Extensions.Primitives.StringValues("trustly-api-client/" + assemblyVersion)); - response.StatusCode = (int)httpStatusCode; - await response.WriteAsync(rpcString); } } } diff --git a/src/Client/Validation/DataAnnotationsValidator.cs b/src/Client/Validation/DataAnnotationsValidator.cs index 25fcadd..82bf26d 100644 --- a/src/Client/Validation/DataAnnotationsValidator.cs +++ b/src/Client/Validation/DataAnnotationsValidator.cs @@ -24,6 +24,12 @@ private ICollection TryValidateObjectRecursive(T obj, ISet< return EMPTY_VALIDATION_RESULTS; } + if (obj is Newtonsoft.Json.Linq.JToken) + { + // We do not validate JSON tokens. They are recursive and never fails. + return EMPTY_VALIDATION_RESULTS; + } + validatedObjects.Add(obj); var list = new List(); var result = Validator.TryValidateObject(obj, new ValidationContext(obj, null), list, true); diff --git a/src/Domain/Any.cs b/src/Domain/Any.cs new file mode 100644 index 0000000..0aefba5 --- /dev/null +++ b/src/Domain/Any.cs @@ -0,0 +1,12 @@ + +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Trustly.Api.Domain +{ + public class Any + { + [JsonExtensionData] + public JObject AdditionalProperties { get; set; } + } +} diff --git a/src/Domain/Base/AbstractFromTrustlyRequestParamsData.cs b/src/Domain/Base/AbstractFromTrustlyRequestParamsData.cs deleted file mode 100644 index 7f63e4e..0000000 --- a/src/Domain/Base/AbstractFromTrustlyRequestParamsData.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.ComponentModel.DataAnnotations; -using Newtonsoft.Json; - -namespace Trustly.Api.Domain.Base -{ - public interface IFromTrustlyRequestParamsData : IRequestParamsData - { - } - - public class AbstractFromTrustlyRequestParamsData : AbstractRequestParamsData, IFromTrustlyRequestParamsData - where TAttr : AbstractRequestParamsDataAttributes - { - [JsonProperty(PropertyName = "attributes", NullValueHandling = NullValueHandling.Ignore)] - public TAttr Attributes { get; set; } - } -} diff --git a/src/Domain/Base/AbstractRequestParamsData.cs b/src/Domain/Base/AbstractRequestParamsData.cs deleted file mode 100644 index 5c19501..0000000 --- a/src/Domain/Base/AbstractRequestParamsData.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Trustly.Api.Domain.Base -{ - /// - /// Marker interface for restricting the generics through the project. - /// We can use it to say that we want request params data, but not at all of what type. - /// - public interface IRequestParamsData : IData - { - - } - - public abstract class AbstractRequestParamsData : IRequestParamsData - where TAttr : AbstractRequestParamsDataAttributes - { - - } -} diff --git a/src/Domain/Base/AbstractRequestParamsDataAttributes.cs b/src/Domain/Base/AbstractRequestParamsDataAttributes.cs deleted file mode 100644 index ec7eb6d..0000000 --- a/src/Domain/Base/AbstractRequestParamsDataAttributes.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Trustly.Api.Domain.Base -{ - public abstract class AbstractRequestParamsDataAttributes - { - [JsonExtensionData] - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] - public Dictionary ExtensionData { get; set; } - } -} diff --git a/src/Domain/Base/AbstractResponseResultData.cs b/src/Domain/Base/AbstractResponseResultData.cs deleted file mode 100644 index 5e60575..0000000 --- a/src/Domain/Base/AbstractResponseResultData.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Trustly.Api.Domain.Base -{ - public interface IResponseResultData : IData - { - Dictionary ExtensionData { get; set; } - } - - public abstract class AbstractResponseResultData : IResponseResultData - { - [JsonExtensionData] - public Dictionary ExtensionData { get; set; } - } -} diff --git a/src/Domain/Base/AbstractToTrustlyRequestParamsData.cs b/src/Domain/Base/AbstractToTrustlyRequestParamsData.cs deleted file mode 100644 index e8c48ba..0000000 --- a/src/Domain/Base/AbstractToTrustlyRequestParamsData.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.ComponentModel.DataAnnotations; -using Newtonsoft.Json; - -namespace Trustly.Api.Domain.Base -{ - public interface IToTrustlyRequestParamsData : IRequestParamsData - { - string Username { get; set; } - string Password { get; set; } - } - - public class AbstractToTrustlyRequestParamsData : AbstractRequestParamsData, IToTrustlyRequestParamsData - where TAttr : AbstractRequestParamsDataAttributes - { - /// - /// You do not have to set this property. - /// It is set automatically by the API Client. - /// - [Required] - [JsonProperty("Username")] - public string Username { get; set; } - - /// - /// You do not have to set this property. - /// It is set automatically by the API Client. - /// - [Required] - [JsonProperty("Password")] - public string Password { get; set; } - - [JsonProperty(PropertyName = "Attributes", NullValueHandling = NullValueHandling.Ignore)] - public TAttr Attributes { get; set; } - } -} diff --git a/src/Domain/Base/EmptyRequestParamsDataAttributes.cs b/src/Domain/Base/EmptyRequestParamsDataAttributes.cs deleted file mode 100644 index eb7fe6a..0000000 --- a/src/Domain/Base/EmptyRequestParamsDataAttributes.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Trustly.Api.Domain.Base -{ - public abstract class EmptyRequestParamsDataAttributes : AbstractRequestParamsDataAttributes - { - - } -} diff --git a/src/Domain/Base/IData.cs b/src/Domain/Base/IData.cs deleted file mode 100644 index b6594d2..0000000 --- a/src/Domain/Base/IData.cs +++ /dev/null @@ -1,7 +0,0 @@ -using System; -namespace Trustly.Api.Domain.Base -{ - public interface IData - { - } -} diff --git a/src/Domain/Base/IWithRejectionResult.cs b/src/Domain/Base/IWithRejectionResult.cs deleted file mode 100644 index b300873..0000000 --- a/src/Domain/Base/IWithRejectionResult.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; -namespace Trustly.Api.Domain.Base -{ - public interface IWithRejectionResult - { - bool Result { get; set; } - string Rejected { get; set; } - } -} diff --git a/src/Domain/Base/JsonRpcRequest.cs b/src/Domain/Base/JsonRpcRequest.cs deleted file mode 100644 index ea7485a..0000000 --- a/src/Domain/Base/JsonRpcRequest.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using Newtonsoft.Json; - -namespace Trustly.Api.Domain.Base -{ - public class JsonRpcRequest - where TParamsData : IRequestParamsData - { - [JsonProperty("method")] - public string Method { get; set; } - - [JsonProperty("params")] - public RequestParams Params { get; set; } - - private double? _version; - - [JsonProperty("version")] - public double Version - { - get - { - return _version ?? 1.1; - } - set - { - _version = value; - } - } - } -} diff --git a/src/Domain/Base/JsonRpcResponse.cs b/src/Domain/Base/JsonRpcResponse.cs deleted file mode 100644 index 6947871..0000000 --- a/src/Domain/Base/JsonRpcResponse.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using Newtonsoft.Json; - -namespace Trustly.Api.Domain.Base -{ - public class JsonRpcResponse - where TData : IResponseResultData - { - [JsonProperty("version")] - public string Version { get; set; } - - [JsonProperty("result")] - public ResponseResult Result { get; set; } - - [JsonProperty("error")] - public ResponseError Error { get; set; } - - public bool IsSuccessfulResult() - { - return Result != null && Error == null; - } - - public string GetUUID() - { - return IsSuccessfulResult() ? Result?.UUID : Error?.Error?.UUID; - } - - public IData GetData() - { - if (this.IsSuccessfulResult()) - { - return this.Result.Data; - } - else - { - if (this.Error != null && this.Error.Error != null) - { - return this.Error.Error.Data; - } - } - - return null; - } - - public string GetMethod() - { - return IsSuccessfulResult() ? Result?.Method : Error?.Error?.Method; - } - - public string GetSignature() - { - return IsSuccessfulResult() ? Result?.Signature : Error?.Error?.Signature; - } - } -} diff --git a/src/Domain/Base/RequestParams.cs b/src/Domain/Base/RequestParams.cs deleted file mode 100644 index fd8e39a..0000000 --- a/src/Domain/Base/RequestParams.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using Newtonsoft.Json; - -namespace Trustly.Api.Domain.Base -{ - public class RequestParams - where TData : IRequestParamsData - { - [JsonProperty("Signature")] - public string Signature { get; set; } - - [JsonProperty("UUID")] - public string UUID { get; set; } - - [JsonProperty("Data")] - public TData Data { get; set; } - } -} diff --git a/src/Domain/Base/ResponseError.cs b/src/Domain/Base/ResponseError.cs deleted file mode 100644 index 7918365..0000000 --- a/src/Domain/Base/ResponseError.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using Newtonsoft.Json; - -namespace Trustly.Api.Domain.Base -{ - public class ResponseError : ResponseErrorData - { - [JsonProperty("name")] - public string Name { get; set; } - - [JsonProperty("error")] - public ResponseResult Error { get; set; } - } -} diff --git a/src/Domain/Base/ResponseErrorData.cs b/src/Domain/Base/ResponseErrorData.cs deleted file mode 100644 index 50a21c7..0000000 --- a/src/Domain/Base/ResponseErrorData.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using Newtonsoft.Json; - -namespace Trustly.Api.Domain.Base -{ - public class ResponseErrorData : AbstractResponseResultData - { - [JsonProperty("code")] - public int Code { get; set; } - - [JsonProperty("message")] - public string Message { get; set; } - } -} diff --git a/src/Domain/Base/ResponseResult.cs b/src/Domain/Base/ResponseResult.cs deleted file mode 100644 index 497d70b..0000000 --- a/src/Domain/Base/ResponseResult.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Trustly.Api.Domain.Base -{ - public class ResponseResult - where TData : IResponseResultData - { - [JsonProperty("signature")] - public string Signature { get; set; } - - [JsonProperty("uuid")] - public string UUID { get; set; } - - [JsonProperty("method")] - public string Method { get; set; } - - [JsonProperty("data")] - public TData Data { get; set; } - } -} diff --git a/src/Domain/Common/AbstractDepositAndWithdrawDataAttributes.cs b/src/Domain/Common/AbstractDepositAndWithdrawDataAttributes.cs deleted file mode 100644 index accb33e..0000000 --- a/src/Domain/Common/AbstractDepositAndWithdrawDataAttributes.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System; -using System.ComponentModel.DataAnnotations; -using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; -using Trustly.Api.Domain.Base; - -namespace Trustly.Api.Domain.Common -{ - public abstract class AbstractDepositAndWithdrawAndSelectAccountDataAttributes : AbstractRequestParamsDataAttributes - { - /// - /// The end-user's first name. - /// - [Required] - public string Firstname { get; set; } - - /// - /// The end-user's last name. - /// - [Required] - public string Lastname { get; set; } - - /// - /// The ISO 3166-1-alpha-2 code of the end-user's country. This will be used for pre-selecting the country for the end-user in the iframe. Note: This will only have an effect for new end-users.If an end-user has done a previous order(with the same EndUserID), the country that was last used will be pre-selected. - /// - [Required] - public string Country { get; set; } - - /// - /// The end-users localization preference in the format[language[_territory]]. Language is the ISO 639-1 code and territory the ISO 3166-1-alpha-2 code. - /// - [Required] - public string Locale { get; set; } - - /// - /// The text to show on the end-user's bank statement after Trustly's own 10 digit reference(which always will be displayed first). The reference must let the end user identify the merchant based on this value.So the ShopperStatement should contain either your brand name, website name, or company name. - /// - [Required(ErrorMessage = "The ShopperStatement is required")] - public string ShopperStatement { get; set; } - - /// - /// The email address of the end user. - /// - public string Email { get; set; } - - /// - /// The IP-address of the end-user. - /// - public string IP { get; set; } - - /// - /// The URL to which the end-user should be redirected after a successful deposit. Do not put any logic on that page since it's not guaranteed that the end-user will in fact visit it. - /// - /// https://example.com/thank_you.html - public string SuccessURL { get; set; } - - /// - /// The URL to which the end-user should be redirected after a failed deposit. Do not put any logic on that page since it's not guaranteed that the end-user will in fact visit it. - /// - /// https://trustly.com/error.html - public string FailURL { get; set; } - - /// - /// The TemplateURL should be used if you want to design your own payment page but have it hosted on Trustly's side. - /// The URL of your template page should be provided in this attribute in every Deposit API call. - /// Our system will then fetch the content of your template page, insert the Trustly iframe into it and host the entire page on Trustly’s side. - /// In the response to the Deposit request, you will receive a URL to the hosted template page which you should redirect the user to (the hosted page cannot be iframed). - /// - public string TemplateURL { get; set; } - - /// - /// The html target/framename of the SuccessURL. Only _top, _self and _parent are suported. - /// - public string URLTarget { get; set; } - - /// - /// The mobile phone number of the end-user in international format. - /// - public string MobilePhone { get; set; } - - /// - /// The end-user's social security number / personal number / birth number / etc. Useful for some banks for identifying transactions and KYC/AML. If a Swedish personid ("personnummer") is provided, it will be pre-filled when the user logs in to their bank. - /// - public string NationalIdentificationNumber { get; set; } - - /// - /// This attribute disables the possibility to change/type in national identification number when logging in to a Swedish bank.If this attribute is sent, the attribute NationalIdentificationNumber needs to be correctly included in the request. Note: This is only available for Swedish banks. - /// - public string UnchangeableNationalIdentificationNumber { get; set; } - - /// - /// If you are using Trustly from within your native iOS app, this attribute should be sent so that we can redirect the users back to your app in case an external app is used for authentication (for example Mobile Bank ID in Sweden). - /// - public string URLScheme { get; set; } - } - - public abstract class AbstractDepositAndWithdrawDataAttributes : AbstractDepositAndWithdrawAndSelectAccountDataAttributes - { - /// - /// The minimum amount the end-user is allowed to deposit in the currency specified by Currency.Only digits. Use dot (.) as decimal separator. - /// - public string SuggestedMinAmount { get; set; } - - /// - /// The maximum amount the end-user is allowed to deposit in the currency specified by Currency.Only digits. Use dot (.) as decimal separator. - /// - public string SuggestedMaxAmount { get; set; } - } -} diff --git a/src/Domain/Common/RecipientOrSenderInformation.cs b/src/Domain/Common/RecipientOrSenderInformation.cs deleted file mode 100644 index 75e6a83..0000000 --- a/src/Domain/Common/RecipientOrSenderInformation.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using Newtonsoft.Json; - -namespace Trustly.Api.Domain.Common -{ - public class RecipientOrSenderInformation - { - /// - /// Partytype can be "PERSON" or "ORGANISATION" (if the recipient is an organisation/company). - /// - [JsonProperty("Partytype")] - public string Partytype { get; set; } - - /// - /// First name of the person, or the name of the organisation. - /// - [JsonProperty("Firstname")] - public string Firstname { get; set; } - - /// - /// Last name of the person (NULL for organisation). - /// - [JsonProperty("Lastname")] - public string Lastname { get; set; } - - /// - /// The ISO 3166-1-alpha-2 code of the country that the recipient resides in. - /// - [JsonProperty("CountryCode")] - public string CountryCode { get; set; } - - /// - /// Payment account number or an alternative consistent unique identifier(e.g.customer number). - /// Note: this is not a transaction ID or similar.This identifier must stay consistent across all transactions relating to this recipient (payee). - /// - [JsonProperty("CustomerID")] - public string CustomerID { get; set; } - - /// - /// Full address of the recipient, excluding the country. - /// - [JsonProperty("Address")] - public string Address { get; set; } - - /// - /// Date of birth (YYYY-MM-DD) of the beneficiary, or organisational number for the organisation. - /// - [JsonProperty("DateOfBirth")] - public string DateOfBirth { get; set; } - } -} diff --git a/src/Domain/Common/StringBooleanJsonConverter.cs b/src/Domain/Common/StringBooleanJsonConverter.cs deleted file mode 100644 index c1714c3..0000000 --- a/src/Domain/Common/StringBooleanJsonConverter.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using Newtonsoft.Json; - -namespace Trustly.Api.Domain.Common -{ - - public class StringBooleanJsonConverter : JsonConverter - { - public override bool ReadJson(JsonReader reader, Type objectType, bool existingValue, bool hasExistingValue, JsonSerializer serializer) - { - var valueString = (reader.Value ?? "").ToString(); - if (string.Equals("1", valueString)) - { - return true; - } - - return false; - } - - public override void WriteJson(JsonWriter writer, bool value, JsonSerializer serializer) - { - writer.WriteValue(value ? "1" : "0"); - } - } -} diff --git a/src/Domain/Domain.cs b/src/Domain/Domain.cs new file mode 100644 index 0000000..b4f1c01 --- /dev/null +++ b/src/Domain/Domain.cs @@ -0,0 +1,6048 @@ +// Generated by Omnigen @ 2024-09-10T09:36:45.343Z + +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Runtime.Serialization; + +namespace Trustly.Api.Domain +{ + public class WithRejection + { + [JsonProperty("result")] + public TResult Result { get; set; } + [JsonProperty("rejected")] + public TRejected Rejected { get; set; } + } + + public class WithdrawResponseData + { + /// + /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the request. + /// + /// 9594811343 + [JsonProperty("orderid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string OrderID { get; set; } + /// + /// The URL that should be loaded so that the end-user can continue with the interactive process. Please see our general guidelines around iFraming, nativeApps etc for best usability. In general, never iFrame the url for mobile devices. + /// + [JsonProperty("url", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string URL { get; set; } + } + + /// + /// The html target/frame-name. Only _top, _self and _parent are supported. + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum UrlTarget + { + [EnumMember(Value = "_top")] + TOP, + [EnumMember(Value = "_self")] + SELF, + [EnumMember(Value = "_parent")] + PARENT, + } + + public class SwishResponseData + { + /// + /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the request. + /// + /// 9594811343 + [JsonProperty("orderid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string OrderID { get; set; } + /// + /// The URL that should be loaded so that the end-user can continue with the interactive process. Please see our general guidelines around iFraming, nativeApps etc for best usability. In general, never iFrame the url for mobile devices. + /// + [JsonProperty("url")] + public string URL { get; set; } + [JsonProperty("qrcode")] + public string Qrcode { get; set; } + } + + [JsonConverter(typeof(StringEnumConverter))] + public enum SwishCancelReason + { + [EnumMember(Value = "DECLINED")] + DECLINED, + [EnumMember(Value = "CANCELED")] + CANCELED, + [EnumMember(Value = "ERROR")] + ERROR, + } + + [JsonConverter(typeof(StringEnumConverter))] + public enum StringBoolean + { + [EnumMember(Value = "0")] + FALSE, + [EnumMember(Value = "1")] + TRUE, + } + + public class SettlementReportResponseData + { + [JsonProperty("view_automatic_settlement_details", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string ViewAutomaticSettlementDetails { get; set; } + } + + /// + /// Required. The APIVersion. Must be "1.2". We also have older versions of the report, but those should not be implemented by new merchants. + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum SettlementReportRequestDataAttributesApiVersion + { + [EnumMember(Value = "1.2")] + _1_2, + } + + public class SelectAccountResponseData + { + /// + /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the charge. + /// + /// 9594811343 + [JsonProperty("orderid")] + public long OrderID { get; set; } + /// + /// The URL that should be loaded so that the end-user can continue with the interactive process. Please see our general guidelines around iFraming, nativeApps etc for best usability. In general, never iFrame the url for mobile devices. + /// + [JsonProperty("url")] + public string URL { get; set; } + } + + public class ResponseResult + { + [JsonProperty("signature", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Signature { get; set; } + [JsonProperty("uuid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string UUID { get; set; } + [JsonProperty("data", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public TData Data { get; set; } + [JsonProperty("method", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Method { get; set; } + } + + public class WithdrawResponseResult : ResponseResult + { + public WithdrawResponseResult() + { + base.Method = "Withdraw"; + } + } + + public class SwishResponseResult : ResponseResult + { + public SwishResponseResult() + { + base.Method = "Swish"; + } + } + + public class SettlementReportResponseResult : ResponseResult + { + public SettlementReportResponseResult() + { + base.Method = "SettlementReport"; + } + } + + public class SelectAccountResponseResult : ResponseResult + { + public SelectAccountResponseResult() + { + base.Method = "SelectAccount"; + } + } + + public class RegisterAccountResponseData + { + /// + /// The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + /// + /// 1234567890 + /// 7653385737 + [JsonProperty("accountid")] + public string AccountID { get; set; } + /// + /// The clearing house of the end-user's bank account. Typically the name of a country in uppercase letters. See examples or table at https://developers.trustly.com/emea/docs/registeraccount. + /// + /// AUSTRIA + /// BELGIUM + /// BULGARIA + /// CROATIA + /// CYPRUS + /// CZECH_REPUBLIC + /// DENMARK + /// ESTONIA + /// FINLAND + /// FRANCE + /// GERMANY + /// GREECE + /// HUNGARY + /// IRELAND + /// ITALY + /// LATVIA + /// LITHUANIA + /// LUXEMBOURG + /// MALTA + /// NETHERLANDS + /// NORWAY + /// POLAND + /// PORTUGAL + /// ROMANIA + /// SLOVAKIA + /// SLOVENIA + /// SPAIN + /// SWEDEN + /// UNITED_KINGDOM + [JsonProperty("clearinghouse")] + public string ClearingHouse { get; set; } + /// + /// The bank for this account + /// + /// SEB + /// Skandiabanken + [JsonProperty("bank")] + public string Bank { get; set; } + /// + /// A text that is safe to show the enduser for identifying the account. Do not parse this text since it will be a different format for different accounts. + /// + /// ***4057 + [JsonProperty("descriptor")] + public string Descriptor { get; set; } + [JsonExtensionData] + public JObject AdditionalProperties { get; set; } + } + + public class RegisterAccountResponseResult : ResponseResult + { + public RegisterAccountResponseResult() + { + base.Method = "RegisterAccount"; + } + } + + public class RefundResponseData + { + /// + /// The OrderID specified when calling the method. + /// + [JsonProperty("orderid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string OrderID { get; set; } + /// + /// "1" if the refund request is accepted by Trustly's system. If the refund request is not accepted, you will get an error code back in JsonRpcResponse -> error. + /// + [JsonProperty("result", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public StringBoolean? Result { get; set; } + } + + public class RefundResponseResult : ResponseResult + { + public RefundResponseResult() + { + base.Method = "Refund"; + } + } + + [JsonConverter(typeof(StringEnumConverter))] + public enum RefundDirectDebitRejected + { + [EnumMember(Value = "ERROR_CHARGE_NOT_FOUND")] + ERROR_CHARGE_NOT_FOUND, + [EnumMember(Value = "ERROR_CHARGE_NOT_REFUNDABLE")] + ERROR_CHARGE_NOT_REFUNDABLE, + [EnumMember(Value = "ERROR_AMOUNT_FAILURE")] + ERROR_AMOUNT_FAILURE, + [EnumMember(Value = "ERROR_CURRENCY_FAILURE")] + ERROR_CURRENCY_FAILURE, + } + + public class RefundDirectDebitResponseData : WithRejection + { + + } + + public class RefundDirectDebitResponseResult : ResponseResult + { + public RefundDirectDebitResponseResult() + { + base.Method = "RefundDirectDebit"; + } + } + + [JsonConverter(typeof(StringEnumConverter))] + public enum RefundDirectDebitCancelReason + { + [EnumMember(Value = "INVALID_ACCOUNT")] + INVALID_ACCOUNT, + [EnumMember(Value = "FAILED")] + FAILED, + } + + [JsonConverter(typeof(StringEnumConverter))] + public enum PartyTypeKind + { + [EnumMember(Value = "PERSON")] + PERSON, + [EnumMember(Value = "ORGANISATION")] + ORGANISATION, + } + + public class RecipientOrSenderInformation + { + /// + /// Partytype can be PERSON or ORGANISATION (if the recipient or ultimate debtor is an organisation/company). + /// + [JsonProperty("Partytype", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public PartyTypeKind? Partytype { get; set; } + /// + /// First name of the person, or the name of the organization/company. + /// + [JsonProperty("Firstname", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Firstname { get; set; } + /// + /// Last name of the person (NULL/empty for organization/company). + /// + [JsonProperty("Lastname", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Lastname { get; set; } + /// + /// The ISO 3166-1-alpha-2 code of the country that the recipient resides in. + /// + [JsonProperty("CountryCode", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string CountryCode { get; set; } + /// + /// Payment account number or an alternative consistent unique identifier (e.g.customer number). Note: this is not a transaction ID or similar. This identifier must stay consistent across all transactions relating to this recipient (payee). + /// + [JsonProperty("CustomerID")] + public string CustomerID { get; set; } + /// + /// Full address of the recipient, excluding the country. + /// + [JsonProperty("Address")] + public string Address { get; set; } + /// + /// Date of birth (YYYY-MM-DD, ISO 8601) of the beneficiary, or organisational number for the organisation. + /// + /// Date string in the ISO 8601 format (YYYY-MM-DD) + /// 2014-04-01 + [JsonProperty("DateOfBirth")] + public string DateOfBirth { get; set; } + } + + /// + /// Information about the Payer (ultimate debtor). This is required for some merchants and partners. SenderInformation is mandatory to send in Attributes{} for money transfer services (including remittance houses), e-wallets, prepaid cards, as well as for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account (other cases may also apply). + /// + public class SenderInformation : RecipientOrSenderInformation + { + + } + + /// + /// Information about the Payee (ultimate creditor). The burden of identifying who the Payee for any given transaction is lies with the Trustly customer. Required for some merchants and partners. RecipientInformation is mandatory to send for money transfer services (including remittance houses), e-wallets, prepaid cards, as well as for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account (other cases may also apply). + /// + public class RecipientInformation : RecipientOrSenderInformation + { + + } + + /// + /// The type of the order associated with the transaction, if available.Text See list of possible orderypes in the table below. + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum OrderType + { + [EnumMember(Value = "Deposit")] + DEPOSIT, + [EnumMember(Value = "Refund")] + REFUND, + [EnumMember(Value = "Charge")] + CHARGE, + [EnumMember(Value = "Withdraw")] + WITHDRAW, + [EnumMember(Value = "AccountPayout")] + ACCOUNT_PAYOUT, + [EnumMember(Value = "Deposit Fee")] + DEPOSIT_FEE, + [EnumMember(Value = "Refund Fee")] + REFUND_FEE, + [EnumMember(Value = "Charge Fee")] + CHARGE_FEE, + [EnumMember(Value = "Withdraw Fee")] + WITHDRAW_FEE, + [EnumMember(Value = "Settlement Fee")] + SETTLEMENT_FEE, + [EnumMember(Value = "AccountPayout Fee")] + ACCOUNT_PAYOUT_FEE, + [EnumMember(Value = "Failed Refund")] + FAILED_REFUND, + [EnumMember(Value = "Failed Refund Fee")] + FAILED_REFUND_FEE, + [EnumMember(Value = "FX")] + FX, + [EnumMember(Value = "Float Adjustment")] + FLOAT_ADJUSTMENT, + [EnumMember(Value = "Automatic Float Adjustment")] + AUTOMATIC_FLOAT_ADJUSTMENT, + } + + public class SettlementReportResponseDataEntry + { + /// + /// The account the money was transferred from (if the amount is positive), or the account the money was transferred to (if the amount is negative). + /// + [JsonProperty("accountName")] + public string AccountName { get; set; } + /// + /// The monetary amount of the transaction, rounded down to two decimal places. + /// + [JsonProperty("amount")] + public decimal Amount { get; set; } + /// + /// The three-letter currency code of the transaction. + /// + [JsonProperty("currency")] + public string Currency { get; set; } + /// + /// The timestamp of the transaction, including the UTC offset. As the timestamps are always in UTC, the offset is always +00 + /// + [JsonProperty("datestamp")] + public string Datestamp { get; set; } + /// + /// MessageID of the order associated with the transaction, if available. + /// + [JsonProperty("messageId")] + public string MessageId { get; set; } + /// + /// OrderID of the order associated with the transaction, if available. + /// + [JsonProperty("orderid")] + public string OrderID { get; set; } + /// + /// The type of the order associated with the transaction, if available.Text See list of possible orderypes in the table below. + /// + [JsonProperty("orderType")] + public OrderType? OrderType { get; set; } + /// + /// Can be used in case there is an unknown order type that was received + /// + [JsonProperty("orderTypeString")] + public string OrderTypeString { get; set; } + /// + /// The sum of all amounts of the respective currency within the report. + /// + [JsonProperty("total")] + public decimal Total { get; set; } + /// + /// The username of the child merchant account. + /// + [JsonProperty("username")] + public string Username { get; set; } + /// + /// The amount that the end user paid, if the currency is different from the requested deposit currency. For transactions where the payment currency is the same as the requested currency, this field will be empty. + /// + [JsonProperty("fxPaymentAmount")] + public decimal FxPaymentAmount { get; set; } + /// + /// The currency that the user paid with, if the currency is different from the requested deposit currency. For transactions where the payment currency is the same as the requested currency, this field will be empty. + /// + [JsonProperty("fxPaymentCurrency")] + public string FxPaymentCurrency { get; set; } + /// + /// The 10 digit reference that will show up on the merchant's bank statement for this automatic settlement batch. The same value will be sent on every row in the report. + /// + [JsonProperty("settlementBankWithdrawalId")] + public string SettlementBankWithdrawalId { get; set; } + /// + /// Contains the ExternalReference value for Deposit, Charge, and Refund transactions if provided. Otherwise empty. + /// + [JsonProperty("externalReference")] + public string ExternalReference { get; set; } + } + + public enum NumberBoolean + { + FALSE = 0, + TRUE = 1, + } + + public class RegisterAccountPayoutResponseData + { + /// + /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the charge. + /// + /// 9594811343 + [JsonProperty("orderid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public long OrderID { get; set; } + /// + /// 1 if the payout could be accepted and 0 otherwise. + /// + [JsonProperty("result", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public NumberBoolean? Result { get; set; } + } + + public class RegisterAccountPayoutResponseResult : ResponseResult + { + public RegisterAccountPayoutResponseResult() + { + base.Method = "RegisterAccountPayout"; + } + } + + public class NotificationResponseDataBase + { + [JsonProperty("message")] + public string Message { get; set; } + [JsonProperty("status", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public T Status { get; set; } + } + + public class MerchantSettlementResponseData + { + /// + /// The unique reference generated for the settlement. + /// + [JsonProperty("reference", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Reference { get; set; } + [JsonExtensionData] + public JObject AdditionalProperties { get; set; } + } + + public class MerchantSettlementResponseResult : ResponseResult + { + public MerchantSettlementResponseResult() + { + base.Method = "MerchantSettlement"; + } + } + + [JsonConverter(typeof(StringEnumConverter))] + public enum MandateAccountSource + { + [EnumMember(Value = "AIS")] + AIS, + [EnumMember(Value = "MANUAL_ENTRY")] + MANUAL_ENTRY, + [EnumMember(Value = "ACCOUNT_ID")] + ACCOUNT_ID, + [EnumMember(Value = "REGISTRATION_SCHEME")] + REGISTRATION_SCHEME, + } + + [JsonConverter(typeof(StringEnumConverter))] + public enum KYCNotificationResponseDataStatus + { + [EnumMember(Value = "OK")] + OK, + [EnumMember(Value = "FINISH")] + FINISH, + [EnumMember(Value = "CONTINUE")] + CONTINUE, + } + + public class KYCNotificationResponseData : NotificationResponseDataBase + { + /// BGN: 100.00 + /// CZK: 100.00 + /// DKK: 100.00 + /// EUR: 100.00 + /// GBP: 100.00 + /// HRK: 100.00 + /// HUF: 100 + /// NOK: 100.00 + /// PLN: 100.00 + /// RON: 100.00 + /// SEK: 100.00 + [JsonProperty("limit")] + public string Limit { get; set; } + } + + public class KYCNotificationResponseResult : ResponseResult + { + public KYCNotificationResponseResult() + { + base.Method = "kyc"; + } + } + + /// + /// Generic class to describe the JsonRpc response package + /// + public class JsonRpcResponse + where T : ResponseResult + { + [JsonProperty("version")] + public string Version { get; } = "1.1"; + [JsonProperty("result", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public T Result { get; set; } + } + + public class WithdrawResponse : JsonRpcResponse + { + + } + + public class SwishResponse : JsonRpcResponse + { + + } + + public class SettlementReportResponse : JsonRpcResponse + { + + } + + public class SelectAccountResponse : JsonRpcResponse + { + + } + + public class RegisterAccountResponse : JsonRpcResponse + { + + } + + public class RegisterAccountPayoutResponse : JsonRpcResponse + { + + } + + public class RefundResponse : JsonRpcResponse + { + + } + + public class RefundDirectDebitResponse : JsonRpcResponse + { + + } + + public class MerchantSettlementResponse : JsonRpcResponse + { + + } + + public class KYCNotificationResponse : JsonRpcResponse + { + + } + + /// + /// Generic class to describe the JsonRpc callback params + /// + public class JsonRpcNotificationParams + { + /// + /// The signature that the Trustly server generated, which you can verify against with our public key + /// + [JsonProperty("signature", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Signature { get; set; } + /// + /// The unique identifier for this request + /// + [JsonProperty("uuid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string UUID { get; set; } + [JsonProperty("data", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public T Data { get; set; } + } + + /// + /// Generic class to describe the JsonRpc callback package + /// + public class JsonRpcNotification + where TParams : JsonRpcNotificationParams + { + [JsonProperty("version", NullValueHandling = NullValueHandling.Include)] + [Required] + public string Version { get; } = "1.1"; + [JsonProperty("method", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Method { get; } + [JsonProperty("params")] + public TParams Params { get; set; } + + public JsonRpcNotification(string method) + { + this.Method = method; + } + } + + public class JsonRpcErrorErrorData + { + [JsonExtensionData] + public JObject AdditionalProperties { get; set; } + } + + public class JsonRpcErrorError : ResponseResult + { + [JsonExtensionData] + public JObject AdditionalProperties { get; set; } + } + + /// + /// Generic class to describe the JsonRpc error inside an error response + /// + public class JsonRpcError + { + [JsonProperty("code")] + public int Code { get; set; } = -1; + [JsonProperty("message")] + public string Message { get; set; } = "Unknown Error"; + [JsonProperty("error")] + public JsonRpcErrorError Error { get; set; } + [JsonProperty("name")] + public string Name { get; } = "JSONRPCError"; + } + + /// + /// Reasons for not being able to import the mandate + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum ImportDirectDebitReject + { + [EnumMember(Value = "ERROR_ACCOUNT_NOT_FOUND")] + ERROR_ACCOUNT_NOT_FOUND, + [EnumMember(Value = "ERROR_IMPORT_MANDATE_NOT_ALLOWED")] + ERROR_IMPORT_MANDATE_NOT_ALLOWED, + [EnumMember(Value = "BANK_ACCOUNT_NUMBER_BLOCKED")] + BANK_ACCOUNT_NUMBER_BLOCKED, + [EnumMember(Value = "ERROR_INVALID_ACCOUNT_NUMBER")] + ERROR_INVALID_ACCOUNT_NUMBER, + [EnumMember(Value = "ERROR_UNKNOWN")] + ERROR_UNKNOWN, + } + + public class ImportDirectDebitMandateResponseData : WithRejection + { + + } + + public class ImportDirectDebitMandateResponseResult : ResponseResult + { + public ImportDirectDebitMandateResponseResult() + { + base.Method = "ImportDirectDebitMandate"; + } + } + + public class ImportDirectDebitMandateResponse : JsonRpcResponse + { + + } + + public class GetWithdrawalsResponseDataEntry + { + /// + /// Reference code for the withdrawal generated by Trustly. + /// + [JsonProperty("reference", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Reference { get; set; } + /// + /// Date and time when the withdrawal was last updated. + /// + [JsonProperty("modificationdate", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Modificationdate { get; set; } + /// + /// OrderID of the withdrawal + /// + [JsonProperty("orderid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string OrderID { get; set; } + /// + /// Date and time when the withdrawal request was received. + /// + [JsonProperty("datestamp", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Datestamp { get; set; } + /// + /// The current state of the withdrawal. + /// It's important that no logic is built on the merchant side based on any specific transferState. New states can be added, and existing states can be changed or removed without notice. + /// + /// EXECUTING + /// EXECUTED + /// PENDING + /// QUEUED + /// PREPARING + /// PREPARED + /// BOUNCED + /// ERROR + /// FAILED + /// RETURNED + /// CONFIRMED + [JsonProperty("transferstate", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Transferstate { get; set; } + /// + /// The amount of the withdrawal. + /// + [JsonProperty("amount", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Amount { get; set; } + /// + /// The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + /// + /// 1234567890 + /// 7653385737 + [JsonProperty("accountid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string AccountID { get; set; } + /// + /// The currency of the withdrawal. + /// + [JsonProperty("currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Currency { get; set; } + /// + /// The estimated date and time for when the funds will be available on the receiving bank account. If this information is not available it will be null. + /// + [JsonProperty("eta")] + public string Eta { get; set; } + } + + public class GetWithdrawalsResponseResult : ResponseResult> + { + public GetWithdrawalsResponseResult() + { + base.Method = "GetWithdrawals"; + } + } + + public class GetWithdrawalsResponse : JsonRpcResponse, GetWithdrawalsResponseResult> + { + + } + + public class ErrorUnknownError : JsonRpcError + { + + } + + /// + /// Generic class to describe the JsonRpc error response package + /// + public class JsonRpcErrorResponse + { + [JsonProperty("version")] + public string Version { get; } = "1.1"; + [JsonProperty("error", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public ErrorUnknownError Error { get; set; } + } + + public class ErrorUnknown : JsonRpcErrorResponse + { + + } + + [JsonConverter(typeof(StringEnumConverter))] + public enum DirectPaymentBatchRejected + { + [EnumMember(Value = "ERROR_DIRECT_DEBIT_NOT_ALLOWED")] + ERROR_DIRECT_DEBIT_NOT_ALLOWED, + [EnumMember(Value = "ERROR_PAYMENT_DATE_FAILURE")] + ERROR_PAYMENT_DATE_FAILURE, + [EnumMember(Value = "ERROR_UNABLE_TO_READ_BATCH_FILE")] + ERROR_UNABLE_TO_READ_BATCH_FILE, + [EnumMember(Value = "ERROR_MISSING_BATCH_FILE")] + ERROR_MISSING_BATCH_FILE, + [EnumMember(Value = "ERROR_INVALID_CHECKSUM")] + ERROR_INVALID_CHECKSUM, + } + + /// + /// 1 if the charge was accepted for processing, 0 otherwise. Note that this is an acceptance of the order, no money has been charged from the account until you receive notifications thereof. + /// + public class DirectPaymentBatchResponseData : WithRejection + { + /// + /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the request. + /// + /// 9594811343 + [JsonProperty("orderid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string OrderID { get; set; } + } + + public class DirectPaymentBatchResponseResult : ResponseResult + { + public DirectPaymentBatchResponseResult() + { + base.Method = "DirectPaymentBatch"; + } + } + + public class DirectPaymentBatchResponse : JsonRpcResponse + { + + } + + [JsonConverter(typeof(StringEnumConverter))] + public enum DirectDebitTheme + { + [EnumMember(Value = "DARK")] + DARK, + [EnumMember(Value = "LIGHT")] + LIGHT, + [EnumMember(Value = "DEFAULT")] + DEFAULT, + } + + [JsonConverter(typeof(StringEnumConverter))] + public enum DirectDebitRejected + { + [EnumMember(Value = "ERROR_MANDATE_NOT_FOUND")] + ERROR_MANDATE_NOT_FOUND, + [EnumMember(Value = "ERROR_DIRECT_DEBIT_NOT_ALLOWED")] + ERROR_DIRECT_DEBIT_NOT_ALLOWED, + [EnumMember(Value = "ERROR_PAYMENT_DATE_FAILURE")] + ERROR_PAYMENT_DATE_FAILURE, + [EnumMember(Value = "ERROR_AMOUNT_FAILURE")] + ERROR_AMOUNT_FAILURE, + [EnumMember(Value = "ERROR_CURRENCY_FAILURE")] + ERROR_CURRENCY_FAILURE, + [EnumMember(Value = "ERROR_COLLECTION_TYPE_FAILURE")] + ERROR_COLLECTION_TYPE_FAILURE, + } + + public class DirectDebitResponseData : WithRejection + { + /// + /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the request. + /// + /// 9594811343 + [JsonProperty("orderid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string OrderID { get; set; } + [JsonExtensionData] + public JObject AdditionalProperties { get; set; } + } + + public class DirectDebitResponseResult : ResponseResult + { + public DirectDebitResponseResult() + { + base.Method = "DirectDebit"; + } + } + + public class DirectDebitResponse : JsonRpcResponse + { + + } + + /// + /// If the payment plan is known in advance, this information is displayed when approving the mandate. + /// + public class DirectDebitPaymentSchedule + { + [JsonExtensionData] + public JObject AdditionalProperties { get; set; } + } + + public class DirectDebitMandateResponseData + { + /// + /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the request. + /// + /// 9594811343 + [JsonProperty("orderid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string OrderID { get; set; } + /// + /// The URL that should be loaded so that the end-user can continue with the interactive process. Please see our general guidelines around iFraming, nativeApps etc for best usability. In general, never iFrame the url for mobile devices. + /// + [JsonProperty("url", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string URL { get; set; } + } + + public class DirectDebitMandateResponseResult : ResponseResult + { + public DirectDebitMandateResponseResult() + { + base.Method = "DirectDebitMandate"; + } + } + + public class DirectDebitMandateResponse : JsonRpcResponse + { + + } + + [JsonConverter(typeof(StringEnumConverter))] + public enum DirectDebitImportType + { + [EnumMember(Value = "CREATE")] + CREATE, + [EnumMember(Value = "REGISTER")] + REGISTER, + } + + [JsonConverter(typeof(StringEnumConverter))] + public enum DirectDebitCollectionType + { + [EnumMember(Value = "INITIAL")] + INITIAL, + [EnumMember(Value = "RECURRING")] + RECURRING, + [EnumMember(Value = "RE_SUBMITTED")] + RE_SUBMITTED, + [EnumMember(Value = "FINAL")] + FINAL, + } + + [JsonConverter(typeof(StringEnumConverter))] + public enum DirectDebitCancelReason + { + [EnumMember(Value = "ERROR_MANDATE_INVALID")] + ERROR_MANDATE_INVALID, + [EnumMember(Value = "ERROR_CHARGE_NOT_APPROVED")] + ERROR_CHARGE_NOT_APPROVED, + [EnumMember(Value = "CANCELLED")] + CANCELLED, + [EnumMember(Value = "FAILED")] + FAILED, + } + + [JsonConverter(typeof(StringEnumConverter))] + public enum DirectCreditRejected + { + [EnumMember(Value = "ERROR_MANDATE_NOT_FOUND")] + ERROR_MANDATE_NOT_FOUND, + [EnumMember(Value = "ERROR_DIRECT_DEBIT_NOT_ALLOWED")] + ERROR_DIRECT_DEBIT_NOT_ALLOWED, + [EnumMember(Value = "ERROR_PAYMENT_DATE_FAILURE")] + ERROR_PAYMENT_DATE_FAILURE, + [EnumMember(Value = "ERROR_AMOUNT_FAILURE")] + ERROR_AMOUNT_FAILURE, + [EnumMember(Value = "ERROR_CURRENCY_FAILURE")] + ERROR_CURRENCY_FAILURE, + } + + public class DirectCreditResponseData : WithRejection + { + /// + /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the request. + /// + /// 9594811343 + [JsonProperty("orderid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string OrderID { get; set; } + } + + public class DirectCreditResponseResult : ResponseResult + { + public DirectCreditResponseResult() + { + base.Method = "DirectCredit"; + } + } + + public class DirectCreditResponse : JsonRpcResponse + { + + } + + [JsonConverter(typeof(StringEnumConverter))] + public enum DirectCreditDebitNotificationReason + { + [EnumMember(Value = "FAILED")] + FAILED, + } + + [JsonConverter(typeof(StringEnumConverter))] + public enum DirectCreditCancelReason + { + [EnumMember(Value = "INVALID_ACCOUNT")] + INVALID_ACCOUNT, + [EnumMember(Value = "CANCELLED")] + CANCELLED, + [EnumMember(Value = "FAILED")] + FAILED, + } + + public class DepositResponseData + { + /// + /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the request. + /// + /// 9594811343 + [JsonProperty("orderid")] + public string OrderID { get; set; } + /// + /// The URL that should be loaded so that the end-user can complete the deposit. + /// + [JsonProperty("url")] + public string URL { get; set; } + } + + public class DepositResponseResult : ResponseResult + { + public DepositResponseResult() + { + base.Method = "Deposit"; + } + } + + public class DepositResponse : JsonRpcResponse + { + + } + + public class DenyWithdrawalResponseData + { + /// + /// The OrderID specified when calling the method. + /// + [JsonProperty("orderid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public long OrderID { get; set; } + /// + /// '1' if the refund request is accepted by Trustly's system. If the refund request is not accepted, you will get an error code back in the JsonRpcResponse -> error + /// + [JsonProperty("result", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public StringBoolean? Result { get; set; } + } + + public class DenyWithdrawalResponseResult : ResponseResult + { + public DenyWithdrawalResponseResult() + { + base.Method = "DenyWithdrawal"; + } + } + + public class DenyWithdrawalResponse : JsonRpcResponse + { + + } + + [JsonConverter(typeof(StringEnumConverter))] + public enum DebitNotificationResponseDataStatus + { + [EnumMember(Value = "OK")] + OK, + [EnumMember(Value = "FAILED")] + FAILED, + } + + public class DebitNotificationResponseData : NotificationResponseDataBase + { + + } + + public class DebitRefundDirectDebitNotificationResponseResult : ResponseResult + { + public DebitRefundDirectDebitNotificationResponseResult() + { + base.Method = "debit"; + } + } + + public class DebitRefundDirectDebitNotificationResponse : JsonRpcResponse + { + + } + + public class DebitNotificationResponseResult : ResponseResult + { + public DebitNotificationResponseResult() + { + base.Method = "debit"; + } + } + + public class DebitNotificationResponse : JsonRpcResponse + { + + } + + public class DebitDirectDebitNotificationResponseResult : ResponseResult + { + public DebitDirectDebitNotificationResponseResult() + { + base.Method = "debit"; + } + } + + public class DebitDirectDebitNotificationResponse : JsonRpcResponse + { + + } + + [JsonConverter(typeof(StringEnumConverter))] + public enum DebitDirectDebitNotificationReason + { + [EnumMember(Value = "ERROR_MANDATE_INVALID")] + ERROR_MANDATE_INVALID, + [EnumMember(Value = "ERROR_CHARGE_NOT_APPROVED")] + ERROR_CHARGE_NOT_APPROVED, + [EnumMember(Value = "CANCELLED")] + CANCELLED, + [EnumMember(Value = "FAILED")] + FAILED, + } + + public class DebitDirectCreditNotificationResponseResult : ResponseResult + { + public DebitDirectCreditNotificationResponseResult() + { + base.Method = "debit"; + } + } + + public class DebitDirectCreditNotificationResponse : JsonRpcResponse + { + + } + + [JsonConverter(typeof(StringEnumConverter))] + public enum CreditRefundDirectDebitCancelReason + { + [EnumMember(Value = "DECLINED")] + DECLINED, + [EnumMember(Value = "CANCELED")] + CANCELED, + [EnumMember(Value = "ERROR")] + ERROR, + [EnumMember(Value = "CANCELLED")] + CANCELLED, + [EnumMember(Value = "FAILED")] + FAILED, + [EnumMember(Value = "MANDATE_ALREADY_EXISTS")] + MANDATE_ALREADY_EXISTS, + [EnumMember(Value = "INVALID_ACCOUNT_ID")] + INVALID_ACCOUNT_ID, + [EnumMember(Value = "ERROR_MANDATE_INVALID")] + ERROR_MANDATE_INVALID, + [EnumMember(Value = "ERROR_CHARGE_NOT_APPROVED")] + ERROR_CHARGE_NOT_APPROVED, + [EnumMember(Value = "INVALID_ACCOUNT")] + INVALID_ACCOUNT, + } + + public class CreateAccountResponseData + { + /// + /// The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + /// + /// 7653385737 + [JsonProperty("accountId")] + public double AccountId { get; set; } + /// + /// The clearing house of the end-user's bank account. Typically the name of a country in uppercase letters. See examples or table at https://developers.trustly.com/emea/docs/registeraccount. + /// + /// AUSTRIA + /// BELGIUM + /// BULGARIA + /// CROATIA + /// CYPRUS + /// CZECH_REPUBLIC + /// DENMARK + /// ESTONIA + /// FINLAND + /// FRANCE + /// GERMANY + /// GREECE + /// HUNGARY + /// IRELAND + /// ITALY + /// LATVIA + /// LITHUANIA + /// LUXEMBOURG + /// MALTA + /// NETHERLANDS + /// NORWAY + /// POLAND + /// PORTUGAL + /// ROMANIA + /// SLOVAKIA + /// SLOVENIA + /// SPAIN + /// SWEDEN + /// UNITED_KINGDOM + [JsonProperty("clearingHouse")] + public string ClearingHouse { get; set; } + /// + /// The bank for this account + /// + /// SEB + /// Skandiabanken + [JsonProperty("bank")] + public string Bank { get; set; } + /// + /// A text that is safe to show the enduser for identifying the account. Do not parse this text since it will be a different format for different accounts. + /// + /// ***4057 + [JsonProperty("descriptor")] + public string Descriptor { get; set; } + } + + public class CreateAccountResponseResult : ResponseResult + { + public CreateAccountResponseResult() + { + base.Method = "CreateAccount"; + } + } + + public class CreateAccountResponse : JsonRpcResponse + { + + } + + public class ChargeResponseData : WithRejection + { + [JsonProperty("orderid")] + public string OrderID { get; set; } + } + + public class ChargeResponseResult : ResponseResult + { + public ChargeResponseResult() + { + base.Method = "Charge"; + } + } + + public class ChargeResponse : JsonRpcResponse + { + + } + + [JsonConverter(typeof(StringEnumConverter))] + public enum CancelMandateNotificationDataAttributesCancelReason + { + [EnumMember(Value = "MANDATE_ALREADY_EXISTS")] + MANDATE_ALREADY_EXISTS, + [EnumMember(Value = "CANCELLED")] + CANCELLED, + [EnumMember(Value = "FAILED")] + FAILED, + [EnumMember(Value = "INVALID_ACCOUNT_ID")] + INVALID_ACCOUNT_ID, + } + + /// + /// If the cancel was NOT accepted, a textual code describing the rejection reason, null otherwise. + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum CancelDirectDebitReject + { + [EnumMember(Value = "ERROR_CHARGE_NOT_FOUND")] + ERROR_CHARGE_NOT_FOUND, + [EnumMember(Value = "ERROR_CHARGE_ALREADY_PROCESSED")] + ERROR_CHARGE_ALREADY_PROCESSED, + } + + public class CancelDirectDebitResponseData : WithRejection + { + + } + + public class CancelDirectDebitResponseResult : ResponseResult + { + public CancelDirectDebitResponseResult() + { + base.Method = "CancelDirectDebit"; + } + } + + public class CancelDirectDebitResponse : JsonRpcResponse + { + + } + + /// + /// If the cancel was NOT accepted, a textual code describing the rejection reason, null otherwise. + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum CancelDirectDebitMandateReject + { + [EnumMember(Value = "ERROR_MANDATE_NOT_FOUND")] + ERROR_MANDATE_NOT_FOUND, + } + + public class CancelDirectDebitMandateResponseData : WithRejection + { + + } + + public class CancelDirectDebitMandateResponseResult : ResponseResult + { + public CancelDirectDebitMandateResponseResult() + { + base.Method = "CancelDirectDebitMandate"; + } + } + + public class CancelDirectDebitMandateResponse : JsonRpcResponse + { + + } + + /// + /// 1 if the Charge could be canceled, and 0 otherwise. + /// + public class CancelChargeResponseData : WithRejection + { + /// + /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the request. + /// + /// 9594811343 + [JsonProperty("orderid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string OrderID { get; set; } + } + + public class CancelChargeResponseResult : ResponseResult + { + public CancelChargeResponseResult() + { + base.Method = "CancelCharge"; + } + } + + public class CancelChargeResponse : JsonRpcResponse + { + + } + + public class BalanceResponseDataEntry + { + /// + /// The currency + /// + [JsonProperty("currency")] + public string Currency { get; set; } + /// + /// The balance with 2 decimals + /// + [JsonProperty("balance")] + public string Balance { get; set; } + } + + public class BalanceResponseResult : ResponseResult> + { + public BalanceResponseResult() + { + base.Method = "Balance"; + } + } + + public class BalanceResponse : JsonRpcResponse, BalanceResponseResult> + { + + } + + public class ApproveWithdrawalResponseData + { + /// + /// The OrderID specified when calling the method. + /// + [JsonProperty("orderid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public long OrderID { get; set; } + /// + /// 1 if the withdrawal could be approved and 0 otherwise. + /// + [JsonProperty("result", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public StringBoolean? Result { get; set; } + } + + public class ApproveWithdrawalResponseResult : ResponseResult + { + public ApproveWithdrawalResponseResult() + { + base.Method = "ApproveWithdrawal"; + } + } + + public class ApproveWithdrawalResponse : JsonRpcResponse + { + + } + + [JsonConverter(typeof(StringEnumConverter))] + public enum AckDataStatus + { + [EnumMember(Value = "OK")] + OK, + } + + public class AckData : NotificationResponseDataBase + { + [JsonExtensionData] + public JObject AdditionalProperties { get; set; } + } + + public class PendingRefundDirectDebitNotificationResponseResult : ResponseResult + { + public PendingRefundDirectDebitNotificationResponseResult() + { + base.Method = "pending"; + } + } + + public class PendingRefundDirectDebitNotificationResponse : JsonRpcResponse + { + + } + + public class PendingNotificationResponseResult : ResponseResult + { + public PendingNotificationResponseResult() + { + base.Method = "pending"; + } + } + + public class PendingNotificationResponse : JsonRpcResponse + { + + } + + public class PendingDirectPaymentBatchNotificationResponseResult : ResponseResult + { + public PendingDirectPaymentBatchNotificationResponseResult() + { + base.Method = "pending"; + } + } + + public class PendingDirectPaymentBatchNotificationResponse : JsonRpcResponse + { + + } + + public class PendingDirectDebitNotificationResponseResult : ResponseResult + { + public PendingDirectDebitNotificationResponseResult() + { + base.Method = "pending"; + } + } + + public class PendingDirectDebitNotificationResponse : JsonRpcResponse + { + + } + + public class PendingDirectCreditNotificationResponseResult : ResponseResult + { + public PendingDirectCreditNotificationResponseResult() + { + base.Method = "pending"; + } + } + + public class PendingDirectCreditNotificationResponse : JsonRpcResponse + { + + } + + public class PayoutFailedNotificationResponseResult : ResponseResult + { + public PayoutFailedNotificationResponseResult() + { + base.Method = "payoutfailed"; + } + } + + public class PayoutFailedNotificationResponse : JsonRpcResponse + { + + } + + public class PayoutConfirmationNotificationResponseResult : ResponseResult + { + public PayoutConfirmationNotificationResponseResult() + { + base.Method = "payoutconfirmation"; + } + } + + public class PayoutConfirmationNotificationResponse : JsonRpcResponse + { + + } + + public class CreditSwishNotificationResponseResult : ResponseResult + { + public CreditSwishNotificationResponseResult() + { + base.Method = "credit"; + } + } + + public class CreditSwishNotificationResponse : JsonRpcResponse + { + + } + + public class CreditRefundDirectDebitNotificationResponseResult : ResponseResult + { + public CreditRefundDirectDebitNotificationResponseResult() + { + base.Method = "credit"; + } + } + + public class CreditRefundDirectDebitNotificationResponse : JsonRpcResponse + { + + } + + public class CreditNotificationResponseResult : ResponseResult + { + public CreditNotificationResponseResult() + { + base.Method = "credit"; + } + } + + public class CreditNotificationResponse : JsonRpcResponse + { + + } + + public class CreditDirectDebitNotificationResponseResult : ResponseResult + { + public CreditDirectDebitNotificationResponseResult() + { + base.Method = "credit"; + } + } + + public class CreditDirectDebitNotificationResponse : JsonRpcResponse + { + + } + + public class CreditDirectCreditNotificationResponseResult : ResponseResult + { + public CreditDirectCreditNotificationResponseResult() + { + base.Method = "credit"; + } + } + + public class CreditDirectCreditNotificationResponse : JsonRpcResponse + { + + } + + public class CancelSwishNotificationResponseResult : ResponseResult + { + public CancelSwishNotificationResponseResult() + { + base.Method = "cancel"; + } + } + + public class CancelSwishNotificationResponse : JsonRpcResponse + { + + } + + public class CancelRefundDirectDebitNotificationResponseResult : ResponseResult + { + public CancelRefundDirectDebitNotificationResponseResult() + { + base.Method = "cancel"; + } + } + + public class CancelRefundDirectDebitNotificationResponse : JsonRpcResponse + { + + } + + public class CancelNotificationResponseResult : ResponseResult + { + public CancelNotificationResponseResult() + { + base.Method = "cancel"; + } + } + + public class CancelNotificationResponse : JsonRpcResponse + { + + } + + public class CancelMandateNotificationResponseResult : ResponseResult + { + public CancelMandateNotificationResponseResult() + { + base.Method = "cancel"; + } + } + + public class CancelMandateNotificationResponse : JsonRpcResponse + { + + } + + public class CancelDirectPaymentBatchNotificationResponseResult : ResponseResult + { + public CancelDirectPaymentBatchNotificationResponseResult() + { + base.Method = "cancel"; + } + } + + public class CancelDirectPaymentBatchNotificationResponse : JsonRpcResponse + { + + } + + public class CancelDirectDebitNotificationResponseResult : ResponseResult + { + public CancelDirectDebitNotificationResponseResult() + { + base.Method = "cancel"; + } + } + + public class CancelDirectDebitNotificationResponse : JsonRpcResponse + { + + } + + public class CancelDirectCreditNotificationResponseResult : ResponseResult + { + public CancelDirectCreditNotificationResponseResult() + { + base.Method = "cancel"; + } + } + + public class CancelDirectCreditNotificationResponse : JsonRpcResponse + { + + } + + public class AccountPayoutResponseData + { + /// + /// The globally unique OrderID the account payout order was assigned in our system. + /// + [JsonProperty("orderid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public long OrderID { get; set; } + /// + /// "1" if the payout could be accepted and "0" otherwise. + /// + [JsonProperty("result", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public StringBoolean? Result { get; set; } + } + + public class AccountPayoutResponseResult : ResponseResult + { + public AccountPayoutResponseResult() + { + base.Method = "AccountPayout"; + } + } + + public class AccountPayoutResponse : JsonRpcResponse + { + + } + + public class AccountNotificationResponseResult : ResponseResult + { + public AccountNotificationResponseResult() + { + base.Method = "account"; + } + } + + public class AccountNotificationResponse : JsonRpcResponse + { + + } + + public class AccountMandateNotificationResponseResult : ResponseResult + { + public AccountMandateNotificationResponseResult() + { + base.Method = "account"; + } + } + + public class AccountMandateNotificationResponse : JsonRpcResponse + { + + } + + public class AccountLedgerResponseDataEntry + { + /// + /// Your userid in our system. + /// + [JsonProperty("userid")] + public string UserID { get; set; } + /// + /// The datestamp for when this ledger row affected your balance in our system. + /// + [JsonProperty("datestamp")] + public string Datestamp { get; set; } + /// + /// The globally unique OrderID that resulted in this ledger record. + /// + [JsonProperty("orderid")] + public long OrderID { get; set; } + /// + /// The name of the bookkeeping account this ledger record belongs to. + /// + [JsonProperty("accountname")] + public string Accountname { get; set; } + /// + /// Your unique MessageID that you used to create the order that resulted in this ledger record. + /// + [JsonProperty("messageid")] + public string MessageID { get; set; } + /// + /// A human friendly description of this ledger record. + /// + /// CLIENT_FUNDS_SWEDEN_ESSE + [JsonProperty("transactiontype")] + public string Transactiontype { get; set; } + /// + /// The currency of the amount in this ledger record. + /// + [JsonProperty("currency")] + public string Currency { get; set; } + /// + /// The amount your balance in our system was affected with due to this ledger record. May contain a lot of decimals. + /// + [JsonProperty("amount")] + public string Amount { get; set; } + /// + /// An ID meaning different things for different payment methods, you probably don't need this data. + /// + /// 3209647863 + [JsonProperty("gluepayid")] + public string Gluepayid { get; set; } + } + + public class AccountLedgerResponseResult : ResponseResult> + { + public AccountLedgerResponseResult() + { + base.Method = "AccountLedger"; + } + } + + public class AccountLedgerResponse : JsonRpcResponse, AccountLedgerResponseResult> + { + + } + + public class AccountDefaultNotificationResponseResult : ResponseResult + { + public AccountDefaultNotificationResponseResult() + { + base.Method = "account"; + } + } + + public class AccountDefaultNotificationResponse : JsonRpcResponse + { + + } + + public abstract class AbstractRequestDataAttributes + { + [JsonExtensionData] + public JObject AdditionalProperties { get; set; } + } + + public class WithdrawRequestDataAttributes : AbstractRequestDataAttributes + { + /// + /// First name of the person, or the name of the organization/company. + /// + [JsonProperty("Firstname", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Firstname { get; set; } + /// + /// Last name of the person (NULL/empty for organization/company). + /// + [JsonProperty("Lastname", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Lastname { get; set; } + /// + /// The ISO 3166-1-alpha-2 code of the end-user's country. This will be used for pre-selecting the country for the end-user in the iframe. + /// Note: This will only have an effect for new end-users. If an end-user has done a previous order (with the same EndUserID), the country that was last used will be pre-selected. + /// + [JsonProperty("Country", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Country { get; set; } + /// + /// The end-users localization preference in the format language[_territory]. Language is the ISO 639-1 code and territory the ISO 3166-1-alpha-2 code. + /// + [JsonProperty("Locale", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Locale { get; set; } + /// + /// The text to show on the end-user's bank statement after Trustly's own 10 digit reference (which always will be displayed first). The reference must let the end user identify the merchant based on this value. So the ShopperStatement should contain either your brand name, website name, or company name. + /// + /// If possible, try to keep this text as short as possible to maximise the chance that the full reference will fit into the reference field on the customer's bank since some banks allow only a limited number of characters. If the full ShopperStatement does not fit into the reference it will be truncated from the end. + /// + [JsonProperty("ShopperStatement", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string ShopperStatement { get; set; } + /// + /// The email address of the end user. + /// + /// test@trustly.com + [JsonProperty("Email")] + public string Email { get; set; } + /// + /// The mobile phone number to the end-user in international format. This is used for KYC and AML routines. + /// + [JsonProperty("MobilePhone")] + public string MobilePhone { get; set; } + /// + /// The IP-address of the end-user. + /// + [JsonProperty("IP")] + public string IP { get; set; } + /// + /// The URL to which the end-user should be redirected after a successful deposit. Do not put any logic on that page since it's not guaranteed that the end-user will in fact visit it. + /// + [JsonProperty("SuccessURL", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string SuccessURL { get; set; } + /// + /// The URL to which the end-user should be redirected after a failed deposit. Do not put any logic on that page since it's not guaranteed that the end-user will in fact visit it. + /// + [JsonProperty("FailURL", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string FailURL { get; set; } + /// + /// The TemplateURL should be used if you want to design your own payment page but have it hosted on Trustly's side. The URL of your template page should be provided in this attribute in every Deposit API call. Our system will then fetch the content of your template page, insert the Trustly iframe into it and host the entire page on Trustly’s side. In the response to the Deposit request, you will receive a URL to the hosted template page which you should redirect the user to (the hosted page cannot be put inside an iframe). + /// + [JsonProperty("TemplateURL")] + public string TemplateURL { get; set; } + /// + /// The html target/frame-name of the SuccessURL. Only _top, _self and _parent are supported. + /// + [JsonProperty("URLTarget")] + public UrlTarget? URLTarget { get; set; } + /// + /// The end-user's social security number / personal number / birth number / etc. Useful for some banks for identifying transactions and KYC/AML. If a Swedish personid ("personnummer") is provided, it will be pre-filled when the user logs in to their bank. + /// + /// 790131-1234 + [JsonProperty("NationalIdentificationNumber")] + public string NationalIdentificationNumber { get; set; } + /// + /// This attribute disables the possibility to change/type in national identification number when logging in to a Swedish bank. If this attribute is sent, the attribute NationalIdentificationNumber needs to be correctly included in the request. Note: This is only available for Swedish banks. + /// + [JsonProperty("UnchangeableNationalIdentificationNumber")] + public string UnchangeableNationalIdentificationNumber { get; set; } + /// + /// If you are using Trustly from within your native iOS app, this attribute should be sent so that we can redirect the users back to your app in case an external app is used for authentication (for example Mobile Bank ID in Sweden). + /// + [JsonProperty("URLScheme")] + public string URLScheme { get; set; } + /// + /// When rendering the Trustly Checkout in a native app you are required to pass your application's url as an attribute to the order initiation request. By doing so, Trustly can redirect users back to your app after using external identification apps such as Mobile BankID: Please visit documentation site for more information. It must not be included for transactions that are not originating from an app. + /// + /// NOTE! This value is only used for redirecting users back to the native app within the flows. See also SuccessURL and FailURL descriptions. + /// + [JsonProperty("ReturnToAppURL")] + public string ReturnToAppURL { get; set; } + /// + /// The minimum amount the end-user is allowed to deposit in the currency specified by Currency.Only digits. Use dot (.) as decimal separator. + /// + [JsonProperty("SuggestedMinAmount")] + public string SuggestedMinAmount { get; set; } + /// + /// The maximum amount the end-user is allowed to deposit in the currency specified by Currency. Only digits. Use dot (.) as decimal separator. + /// + [JsonProperty("SuggestedMaxAmount")] + public string SuggestedMaxAmount { get; set; } + /// + /// Sets a fixed withdrawal amount which cannot be changed by the end-user in the Trustly iframe. If this attribute is not sent, the end-user will be asked to select the withdrawal amount in the Trustly iframe. Do not use in combination with suggestedMinAmount and suggestedMaxAmount. Use dot(.) as decimal separator. + /// + [JsonProperty("SuggestedAmount")] + public string SuggestedAmount { get; set; } + /// + /// The end-user's date of birth. + /// + [JsonProperty("DateOfBirth")] + public string DateOfBirth { get; set; } + /// + /// The ISO 3166-1-alpha-2 code of the recipient address country. + /// + [JsonProperty("AddressCountry")] + public string AddressCountry { get; set; } + /// + /// The postalcode of the recipient address. + /// + [JsonProperty("AddressPostalCode")] + public string AddressPostalCode { get; set; } + /// + /// The city of the recipient address. + /// + [JsonProperty("AddressCity")] + public string AddressCity { get; set; } + /// + /// Recipient address street + /// + /// Main Street 1 + [JsonProperty("AddressLine1")] + public string AddressLine1 { get; set; } + /// + /// Additional address information of the recipient. + /// + [JsonProperty("AddressLine2")] + public string AddressLine2 { get; set; } + /// + /// The entire shipping address. + /// This attribute should only be used if you are unable to provide the shipping address information in the 5 separate properties: AddressCountry, AddressCity, AddressPostalCode, AddressLine1, AddressLine2 + /// + /// Birgerstreet 14, SE-11411, Stockholm, Sweden + [JsonProperty("Address")] + public string Address { get; set; } + /// + /// The ExternalReference is a reference set by the merchant for any purpose and does not need to be unique for every API call. For example, it can be used for invoice references, OCR numbers and also for offering end users the option to part-pay an invoice using the same ExternalReference. The ExternalReference will be included in version 1.2 of the settlement report, ViewAutomaticSettlementDetailsCSV. + /// + /// 32423534523 + [JsonProperty("ExternalReference")] + public string ExternalReference { get; set; } + /// + /// Human-readable identifier of the consumer-facing merchant (e.g. legal name or trade name) + /// Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + /// Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + /// + [JsonProperty("PSPMerchant")] + public string PSPMerchant { get; set; } + /// + /// URL of the consumer-facing website where the order is initiated + /// Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + /// Mandatory attributes for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + /// + [JsonProperty("PSPMerchantURL")] + public string PSPMerchantURL { get; set; } + /// + /// VISA category codes describing the merchant's nature of business. + /// Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + /// Mandatory attributes for Trustly Partners that are using Express account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + /// + [JsonProperty("MerchantCategoryCode")] + public string MerchantCategoryCode { get; set; } + /// + /// Information about the Payer (ultimate debtor). This is required for some merchants and partners. SenderInformation is mandatory to send in Attributes{} for money transfer services (including remittance houses), e-wallets, prepaid cards, as well as for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account (other cases may also apply). + /// + [JsonProperty("SenderInformation")] + public SenderInformation SenderInformation { get; set; } + } + + /// + /// https://eu.developers.trustly.com/doc/reference/swish + /// + public class SwishRequestDataAttributes : AbstractRequestDataAttributes + { + /// + /// The Swish number of the payee. + /// + /// 1231181189 + [JsonProperty("MerchantSwishNumber", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string MerchantSwishNumber { get; set; } + [JsonProperty("UseMobile")] + public StringBoolean? UseMobile { get; set; } + /// + /// The URL to which the end-user should be redirected after a successful deposit. Do not put any logic on that page since it's not guaranteed that the end-user will in fact visit it. + /// + [JsonProperty("SuccessURL")] + public string SuccessURL { get; set; } + /// + /// The URL to which the end-user should be redirected after a failed deposit. Do not put any logic on that page since it's not guaranteed that the end-user will in fact visit it. + /// + [JsonProperty("FailURL")] + public string FailURL { get; set; } + /// + /// The amount to deposit with exactly two decimals in the currency specified by Currency. Do not use this attribute in combination withsuggestedMinAmount and suggestedMaxAmount. Only digits. Use dot (.) as decimal separator. + /// + [JsonProperty("Amount", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Amount { get; set; } + /// + /// The ISO 4217 code of the currency. See documentation + /// + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK + [JsonProperty("Currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Currency { get; set; } + /// + /// Merchant supplies a message about the payment/order. Max 50 characters. Common allowed characters are the letters a-ö, A-Ö, the numbers 0-9, and special characters !?(),.-:; + /// + /// Payment + [JsonProperty("Message")] + public string Message { get; set; } + /// + /// The registered cellphone number of the person that makes the payment. It can only contain numbers and has to be at least 8 and at most 15 numbers. It also needs to match the following format in order to be found in Swish: country code + cell phone number (without leading zero). + /// + [JsonProperty("MobilePhone")] + public string MobilePhone { get; set; } + /// + /// The end-user's social security number / personal number / birth number / etc. Useful for some banks for identifying transactions and KYC/AML. If a Swedish personid ("personnummer") is provided, it will be pre-filled when the user logs in to their bank. + /// + /// 790131-1234 + [JsonProperty("NationalIdentificationNumber")] + public string NationalIdentificationNumber { get; set; } + /// + /// Minimum age (in years) that the individual connected to the payerAlias has to be in order for the payment to be accepted. Value has to be in the range of 1 to 99. + /// + [JsonProperty("AgeLimit")] + public string AgeLimit { get; set; } + } + + public class SettlementReportRequestDataAttributes : AbstractRequestDataAttributes + { + /// + /// Required. The APIVersion. Must be "1.2". We also have older versions of the report, but those should not be implemented by new merchants. + /// + [JsonProperty("APIVersion", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public SettlementReportRequestDataAttributesApiVersion? APIVersion { get; set; } + } + + public class SelectAccountRequestDataAttributes : AbstractRequestDataAttributes + { + /// + /// First name of the person, or the name of the organization/company. + /// + [JsonProperty("Firstname", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Firstname { get; set; } + /// + /// Last name of the person (NULL/empty for organization/company). + /// + [JsonProperty("Lastname", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Lastname { get; set; } + /// + /// The ISO 3166-1-alpha-2 code of the end-user's country. This will be used for pre-selecting the country for the end-user in the iframe. + /// Note: This will only have an effect for new end-users. If an end-user has done a previous order (with the same EndUserID), the country that was last used will be pre-selected. + /// + [JsonProperty("Country", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Country { get; set; } + /// + /// The end-users localization preference in the format language[_territory]. Language is the ISO 639-1 code and territory the ISO 3166-1-alpha-2 code. + /// + [JsonProperty("Locale", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Locale { get; set; } + /// + /// The text to show on the end-user's bank statement after Trustly's own 10 digit reference (which always will be displayed first). The reference must let the end user identify the merchant based on this value. So the ShopperStatement should contain either your brand name, website name, or company name. + /// + /// If possible, try to keep this text as short as possible to maximise the chance that the full reference will fit into the reference field on the customer's bank since some banks allow only a limited number of characters. If the full ShopperStatement does not fit into the reference it will be truncated from the end. + /// + [JsonProperty("ShopperStatement")] + public string ShopperStatement { get; set; } + /// + /// The email address of the end user. + /// + /// test@trustly.com + [JsonProperty("Email")] + public string Email { get; set; } + /// + /// The mobile phone number to the end-user in international format. This is used for KYC and AML routines. + /// + [JsonProperty("MobilePhone")] + public string MobilePhone { get; set; } + /// + /// The IP-address of the end-user. + /// + [JsonProperty("IP")] + public string IP { get; set; } + /// + /// The URL to which the end-user should be redirected after a successful deposit. Do not put any logic on that page since it's not guaranteed that the end-user will in fact visit it. + /// + [JsonProperty("SuccessURL", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string SuccessURL { get; set; } + /// + /// The URL to which the end-user should be redirected after a failed deposit. Do not put any logic on that page since it's not guaranteed that the end-user will in fact visit it. + /// + [JsonProperty("FailURL", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string FailURL { get; set; } + /// + /// The TemplateURL should be used if you want to design your own payment page but have it hosted on Trustly's side. The URL of your template page should be provided in this attribute in every Deposit API call. Our system will then fetch the content of your template page, insert the Trustly iframe into it and host the entire page on Trustly’s side. In the response to the Deposit request, you will receive a URL to the hosted template page which you should redirect the user to (the hosted page cannot be put inside an iframe). + /// + [JsonProperty("TemplateURL")] + public string TemplateURL { get; set; } + /// + /// The html target/frame-name of the SuccessURL. Only _top, _self and _parent are supported. + /// + [JsonProperty("URLTarget")] + public UrlTarget? URLTarget { get; set; } + /// + /// The end-user's social security number / personal number / birth number / etc. Useful for some banks for identifying transactions and KYC/AML. If a Swedish personid ("personnummer") is provided, it will be pre-filled when the user logs in to their bank. + /// + /// 790131-1234 + [JsonProperty("NationalIdentificationNumber")] + public string NationalIdentificationNumber { get; set; } + /// + /// This attribute disables the possibility to change/type in national identification number when logging in to a Swedish bank. If this attribute is sent, the attribute NationalIdentificationNumber needs to be correctly included in the request. Note: This is only available for Swedish banks. + /// + [JsonProperty("UnchangeableNationalIdentificationNumber")] + public string UnchangeableNationalIdentificationNumber { get; set; } + /// + /// If you are using Trustly from within your native iOS app, this attribute should be sent so that we can redirect the users back to your app in case an external app is used for authentication (for example Mobile Bank ID in Sweden). + /// + [JsonProperty("URLScheme")] + public string URLScheme { get; set; } + /// + /// When rendering the Trustly Checkout in a native app you are required to pass your application's url as an attribute to the order initiation request. By doing so, Trustly can redirect users back to your app after using external identification apps such as Mobile BankID: Please visit documentation site for more information. It must not be included for transactions that are not originating from an app. + /// + /// NOTE! This value is only used for redirecting users back to the native app within the flows. See also SuccessURL and FailURL descriptions. + /// + [JsonProperty("ReturnToAppURL")] + public string ReturnToAppURL { get; set; } + /// + /// Only for Trustly Direct Debit. Request a direct debit mandate from the selected account. 1 or 0. See section "Direct Debit Mandates" for details. If this is set to 1, then email is required. + /// + [JsonProperty("RequestDirectDebitMandate")] + public NumberBoolean? RequestDirectDebitMandate { get; set; } + /// + /// The end-user's date of birth. + /// + [JsonProperty("DateOfBirth")] + public string DateOfBirth { get; set; } + /// + /// Human-readable identifier of the consumer-facing merchant (e.g. legal name or trade name) + /// Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + /// Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + /// + [JsonProperty("PSPMerchant")] + public string PSPMerchant { get; set; } + /// + /// URL of the consumer-facing website where the order is initiated + /// Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + /// Mandatory attributes for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + /// + [JsonProperty("PSPMerchantURL")] + public string PSPMerchantURL { get; set; } + /// + /// VISA category codes describing the merchant's nature of business. + /// Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + /// Mandatory attributes for Trustly Partners that are using Express account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + /// + [JsonProperty("MerchantCategoryCode")] + public string MerchantCategoryCode { get; set; } + } + + public class RegisterAccountRequestDataAttributes : AbstractRequestDataAttributes + { + /// + /// The end-user's date of birth. + /// + [JsonProperty("DateOfBirth")] + public string DateOfBirth { get; set; } + /// + /// The mobile phone number to the end-user in international format. This is used for KYC and AML routines. + /// + [JsonProperty("MobilePhone")] + public string MobilePhone { get; set; } + /// + /// The end-user's social security number / personal number / birth number / etc. Useful for some banks for identifying transactions and KYC/AML. If a Swedish personid ("personnummer") is provided, it will be pre-filled when the user logs in to their bank. + /// + /// 790131-1234 + [JsonProperty("NationalIdentificationNumber")] + public string NationalIdentificationNumber { get; set; } + /// + /// The ISO 3166-1-alpha-2 code of the recipient address country. + /// + [JsonProperty("AddressCountry")] + public string AddressCountry { get; set; } + /// + /// The postalcode of the recipient address. + /// + [JsonProperty("AddressPostalCode")] + public string AddressPostalCode { get; set; } + /// + /// The city of the recipient address. + /// + [JsonProperty("AddressCity")] + public string AddressCity { get; set; } + /// + /// The ISO 3166-1-alpha-2 code of the recipient address country. + /// + [JsonProperty("AddressLine1")] + public string AddressLine1 { get; set; } + /// + /// The ISO 3166-1-alpha-2 code of the recipient address country. + /// + [JsonProperty("AddressLine2")] + public string AddressLine2 { get; set; } + /// + /// The entire shipping address. + /// This attribute should only be used if you are unable to provide the shipping address information in the 5 separate properties: AddressCountry, AddressCity, AddressPostalCode, AddressLine1, AddressLine2 + /// + /// Birgerstreet 14, SE-11411, Stockholm, Sweden + [JsonProperty("Address")] + public string Address { get; set; } + /// + /// The email address of the end user. + /// + /// test@trustly.com + [JsonProperty("Email")] + public string Email { get; set; } + } + + public class RegisterAccountPayoutRequestDataAttributes : AbstractRequestDataAttributes + { + /// + /// The text to show on the end-user's bank statement after Trustly's own 10 digit reference (which always will be displayed first). The reference must let the end user identify the merchant based on this value. So the ShopperStatement should contain either your brand name, website name, or company name. + /// + /// If possible, try to keep this text as short as possible to maximise the chance that the full reference will fit into the reference field on the customer's bank since some banks allow only a limited number of characters. If the full ShopperStatement does not fit into the reference it will be truncated from the end. + /// + [JsonProperty("ShopperStatement", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string ShopperStatement { get; set; } + /// + /// The ExternalReference is a reference set by the merchant for any purpose and does not need to be unique for every API call. For example, it can be used for invoice references, OCR numbers and also for offering end users the option to part-pay an invoice using the same ExternalReference. The ExternalReference will be included in version 1.2 of the settlement report, ViewAutomaticSettlementDetailsCSV. + /// + /// 32423534523 + [JsonProperty("ExternalReference")] + public string ExternalReference { get; set; } + /// + /// Human-readable identifier of the consumer-facing merchant (e.g. legal name or trade name) + /// Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + /// Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + /// + [JsonProperty("PSPMerchant")] + public string PSPMerchant { get; set; } + /// + /// URL of the consumer-facing website where the order is initiated + /// Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + /// Mandatory attributes for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + /// + [JsonProperty("PSPMerchantURL")] + public string PSPMerchantURL { get; set; } + /// + /// VISA category codes describing the merchant's nature of business. + /// Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + /// Mandatory attributes for Trustly Partners that are using Express account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + /// + [JsonProperty("MerchantCategoryCode")] + public string MerchantCategoryCode { get; set; } + /// + /// Information about the Payer (ultimate debtor). This is required for some merchants and partners. SenderInformation is mandatory to send in Attributes{} for money transfer services (including remittance houses), e-wallets, prepaid cards, as well as for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account (other cases may also apply). + /// + [JsonProperty("SenderInformation")] + public SenderInformation SenderInformation { get; set; } + /// + /// The end-user's date of birth. + /// + [JsonProperty("DateOfBirth")] + public string DateOfBirth { get; set; } + /// + /// The mobile phone number to the end-user in international format. This is used for KYC and AML routines. + /// + [JsonProperty("MobilePhone")] + public string MobilePhone { get; set; } + /// + /// The end-user's social security number / personal number / birth number / etc. Useful for some banks for identifying transactions and KYC/AML. If a Swedish personid ("personnummer") is provided, it will be pre-filled when the user logs in to their bank. + /// + /// 790131-1234 + [JsonProperty("NationalIdentificationNumber")] + public string NationalIdentificationNumber { get; set; } + /// + /// The ISO 3166-1-alpha-2 code of the recipient address country. + /// + [JsonProperty("AddressCountry")] + public string AddressCountry { get; set; } + /// + /// The postalcode of the recipient address. + /// + [JsonProperty("AddressPostalCode")] + public string AddressPostalCode { get; set; } + /// + /// The city of the recipient address. + /// + [JsonProperty("AddressCity")] + public string AddressCity { get; set; } + /// + /// Recipient address street + /// + /// Main Street 1 + [JsonProperty("AddressLine1")] + public string AddressLine1 { get; set; } + /// + /// Additional address information of the recipient. + /// + [JsonProperty("AddressLine2")] + public string AddressLine2 { get; set; } + /// + /// The entire shipping address. + /// This attribute should only be used if you are unable to provide the shipping address information in the 5 separate properties: AddressCountry, AddressCity, AddressPostalCode, AddressLine1, AddressLine2 + /// + /// Birgerstreet 14, SE-11411, Stockholm, Sweden + [JsonProperty("Address")] + public string Address { get; set; } + /// + /// The email address of the end user. + /// + /// test@trustly.com + [JsonProperty("Email")] + public string Email { get; set; } + } + + public class RefundRequestDataAttributes : AbstractRequestDataAttributes + { + /// + /// The ExternalReference is a reference set by the merchant for any purpose and does not need to be unique for every API call. For example, it can be used for invoice references, OCR numbers and also for offering end users the option to part-pay an invoice using the same ExternalReference. The ExternalReference will be included in version 1.2 of the settlement report, ViewAutomaticSettlementDetailsCSV. + /// + /// 32423534523 + [JsonProperty("ExternalReference")] + public string ExternalReference { get; set; } + } + + public class KYCNotificationDataAttributes : AbstractRequestDataAttributes + { + /// + /// An ID that uniquely identifies the account holder. Only present in markets where SSN is applicable. Note: The format of this field will for some countries look different than the example. + /// + /// SE198201019876 + /// 19900501 + [JsonProperty("personid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string PersonID { get; set; } + /// + /// First name of the person, or the name of the organization/company. + /// + [JsonProperty("firstname", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Firstname { get; set; } + /// + /// Last name of the person (NULL/empty for organization/company). + /// + [JsonProperty("lastname", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Lastname { get; set; } + /// + /// The end-user's date of birth. + /// + [JsonProperty("dob", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Dob { get; set; } + /// + /// Recipient address street + /// + /// Main Street 1 + [JsonProperty("street", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Street { get; set; } + /// + /// The postalcode of the recipient address. + /// + [JsonProperty("zipcode", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Zipcode { get; set; } + /// + /// The city of the recipient address. + /// + [JsonProperty("city", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string City { get; set; } + /// + /// The ISO 3166-1-alpha-2 code of the recipient address country. + /// + [JsonProperty("country", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Country { get; set; } + } + + public class ImportDirectDebitMandateRequestDataAttributes : AbstractRequestDataAttributes + { + /// + /// The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + /// + /// 1234567890 + /// 7653385737 + [JsonProperty("AccountID")] + public string AccountID { get; set; } + /// + /// This parameter in a way identifies the mandate you are to setup. If it's already used, you will receive an error, ERROR_MERCHANT_REFERENCE_ALREADY_EXISTS + /// which basically informs you that there's already a mandate with that reference. + /// + /// [BACS]: The unique mandate reference. 6 - 10 characters consisting of A-Z and 0-9. Can not begin with DDIC and neither consists of the same characters, eg. AAAAAAA. + /// [Bankgiro]: The unique mandate reference. This must be numeric and unique for the payer, eg nationalId or similar can be used. Format needs to follow regexp [1-9][0-9]{5-15} + /// [SEPA-DD]: The unique mandate reference. This must be unique for the end-user for you as a merchant. Format needs to follow regexp [0-9,a-z,A-Z]{10-35} + /// + /// 123ABC0123 + [JsonProperty("MerchantReference", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string MerchantReference { get; set; } + [JsonProperty("ImportType", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public DirectDebitImportType? ImportType { get; set; } + /// + /// The country where the mandate is to be created. + /// + [JsonProperty("Country", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Country { get; set; } + /// + /// The first name of the end user. + /// [BACS]: Only mandatory if manual entry should be enabled. + /// [Bankgiro]: Mandatory + /// [Sepa-DD]: Mandatory + /// + [JsonProperty("Firstname")] + public string Firstname { get; set; } + /// + /// The last name of the end user. + /// [BACS]: Only mandatory if manual entry should be enabled. + /// [Bankgiro]: Mandatory + /// [Sepa-DD]: Mandatory + /// + [JsonProperty("Lastname")] + public string Lastname { get; set; } + /// + /// The email address of the end user. + /// + /// test@trustly.com + [JsonProperty("Email", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Email { get; set; } + /// + /// The mobile phone number to the end-user in international format. This is used for KYC and AML routines. + /// + [JsonProperty("MobilePhone")] + public string MobilePhone { get; set; } + /// + /// The text to show on the end-user's bank statement after Trustly's own 10 digit reference (which always will be displayed first). The reference must let the end user identify the merchant based on this value. So the ShopperStatement should contain either your brand name, website name, or company name. + /// + /// If possible, try to keep this text as short as possible to maximise the chance that the full reference will fit into the reference field on the customer's bank since some banks allow only a limited number of characters. If the full ShopperStatement does not fit into the reference it will be truncated from the end. + /// + [JsonProperty("ShopperStatement")] + public string ShopperStatement { get; set; } + /// + /// The national identification number.Format is yyyyMMddxxxx. Only applicable for Bankgiro(SE) + /// + /// [Bankgiro]: To preset the nationalId to use for setting up the mandate. To make the end-user journey smooth, please use this parameter. + /// + [JsonProperty("NationalIdentificationNumber")] + public string NationalIdentificationNumber { get; set; } + /// + /// [BACS]:If flat and building is available, then use that for this field. If there's no flat/building at all, then use the street and number. Note that without AddressLine1, manual entry will be disabled. + /// [Bankgiro]: Not mandatory + /// [SepaDD]: Mandatory + /// + [JsonProperty("AddressLine1")] + public string AddressLine1 { get; set; } + /// + /// [BACS]:If there are flat and building information, then use addressLine2 for the street and number. Note that without AddressLine1, manual entry will be disabled. + /// [Bankgiro]: Not mandatory + /// [SepaDD]: Optional and depends on the country if needed. + /// + [JsonProperty("AddressLine2")] + public string AddressLine2 { get; set; } + /// + /// The city of the recipient address. + /// + [JsonProperty("AddressCity")] + public string AddressCity { get; set; } + /// + /// The postalcode of the recipient address. + /// + [JsonProperty("AddressPostalCode")] + public string AddressPostalCode { get; set; } + /// + /// The ISO 3166-1-alpha-2 code of the recipient address country. + /// + [JsonProperty("AddressCountry")] + public string AddressCountry { get; set; } + } + + public class DirectPaymentBatchRequestDataAttributes : AbstractRequestDataAttributes + { + /// + /// Date string in the ISO 8601 format (YYYY-MM-DD) + /// + /// 2014-04-01 + [JsonProperty("PaymentDate")] + public string PaymentDate { get; set; } + /// + /// The uploaded unique file name on the SFTP server containing the instructions. + /// + /// unique-filename.csv + [JsonProperty("BatchFile")] + public string BatchFile { get; set; } + /// + /// The MD5 checksum for the file + /// + /// 0cdf0945096283b9ba94e42150ba84d8 + [JsonProperty("Checksum")] + public string Checksum { get; set; } + } + + public class DirectDebitRequestDataAttributes : AbstractRequestDataAttributes + { + [JsonProperty("CollectionType")] + public DirectDebitCollectionType? CollectionType { get; set; } + /// + /// Date string in the ISO 8601 format (YYYY-MM-DD) + /// + /// 2014-04-01 + [JsonProperty("PaymentDate")] + public string PaymentDate { get; set; } + /// + /// The text to show on the end-user's bank statement after Trustly's own 10 digit reference (which always will be displayed first). The reference must let the end user identify the merchant based on this value. So the ShopperStatement should contain either your brand name, website name, or company name. + /// + /// If possible, try to keep this text as short as possible to maximise the chance that the full reference will fit into the reference field on the customer's bank since some banks allow only a limited number of characters. If the full ShopperStatement does not fit into the reference it will be truncated from the end. + /// + [JsonProperty("ShopperStatement")] + public string ShopperStatement { get; set; } + } + + public class DirectDebitMandateRequestDataAttributes : AbstractRequestDataAttributes + { + /// + /// The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + /// + /// 1234567890 + /// 7653385737 + [JsonProperty("AccountId")] + public string AccountId { get; set; } + /// + /// This parameter in a way identifies the mandate you are to setup. If it's already used, you will receive an error, ERROR_MERCHANT_REFERENCE_ALREADY_EXISTS + /// which basically informs you that there's already a mandate with that reference. + /// + /// [BACS]: The unique mandate reference. 6 - 10 characters consisting of A-Z and 0-9. Can not begin with DDIC and neither consists of the same characters, eg. AAAAAAA. + /// [Bankgiro]: The unique mandate reference. This must be numeric and unique for the payer, eg nationalId or similar can be used. Format needs to follow regexp [1-9][0-9]{5-15} + /// [SEPA-DD]: The unique mandate reference. This must be unique for the end-user for you as a merchant. Format needs to follow regexp [0-9,a-z,A-Z]{10-35} + /// + /// 123ABC0123 + [JsonProperty("MerchantReference", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string MerchantReference { get; set; } + /// + /// The country where the mandate is to be created. + /// + [JsonProperty("Country", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Country { get; set; } + /// + /// The first name of the end user. + /// [BACS]: Only mandatory if manual entry should be enabled. + /// [Bankgiro]: Mandatory + /// [Sepa-DD]: Mandatory + /// + [JsonProperty("Firstname")] + public string Firstname { get; set; } + /// + /// The last name of the end user. + /// [BACS]: Only mandatory if manual entry should be enabled. + /// [Bankgiro]: Mandatory + /// [Sepa-DD]: Mandatory + /// + [JsonProperty("Lastname")] + public string Lastname { get; set; } + /// + /// The email address of the end user. + /// + /// test@trustly.com + [JsonProperty("Email", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Email { get; set; } + /// + /// The mobile phone number to the end-user in international format. This is used for KYC and AML routines. + /// + [JsonProperty("MobilePhone")] + public string MobilePhone { get; set; } + /// + /// The URL to which the end-user should be redirected after a successful deposit. Do not put any logic on that page since it's not guaranteed that the end-user will in fact visit it. + /// + [JsonProperty("SuccessURL", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string SuccessURL { get; set; } + /// + /// The URL to which the end-user should be redirected after a failed deposit. Do not put any logic on that page since it's not guaranteed that the end-user will in fact visit it. + /// + [JsonProperty("FailURL", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string FailURL { get; set; } + /// + /// The end-user's date of birth. + /// + [JsonProperty("DateOfBirth")] + public string DateOfBirth { get; set; } + /// + /// The national identification number.Format is yyyyMMddxxxx. Only applicable for Bankgiro(SE) + /// + /// [Bankgiro]: To preset the nationalId to use for setting up the mandate. To make the end-user journey smooth, please use this parameter. + /// + [JsonProperty("NationalIdentificationNumber")] + public string NationalIdentificationNumber { get; set; } + /// + /// Only applicable for Bankgiro(SE) + /// [Bankgiro]If the nationalId should be locked to the value of NationalIdentificationNumber, then set this to 1 or omit the parameter (you may set it to 0 as well). + /// + [JsonProperty("UnchangeableNationalIdentificationNumber")] + public string UnchangeableNationalIdentificationNumber { get; set; } + /// + /// If the payment plan is known in advance, this information is displayed when approving the mandate. + /// + [JsonProperty("PaymentSchedule")] + public DirectDebitPaymentSchedule PaymentSchedule { get; set; } + /// + /// Recipient address street + /// + /// Main Street 1 + [JsonProperty("AddressLine1")] + public string AddressLine1 { get; set; } + /// + /// Additional address information of the recipient. + /// + [JsonProperty("AddressLine2")] + public string AddressLine2 { get; set; } + /// + /// The city of the recipient address. + /// + [JsonProperty("AddressCity")] + public string AddressCity { get; set; } + /// + /// The postalcode of the recipient address. + /// + [JsonProperty("AddressPostalCode")] + public string AddressPostalCode { get; set; } + /// + /// The ISO 3166-1-alpha-2 code of the recipient address country. + /// + [JsonProperty("AddressCountry")] + public string AddressCountry { get; set; } + /// + /// The end-users localization preference in the format language[_territory]. Language is the ISO 639-1 code and territory the ISO 3166-1-alpha-2 code. + /// + [JsonProperty("Locale")] + public string Locale { get; set; } + [JsonProperty("Theme")] + public DirectDebitTheme? Theme { get; set; } + /// + /// When rendering the Trustly Checkout in a native app you are required to pass your application's url as an attribute to the order initiation request. By doing so, Trustly can redirect users back to your app after using external identification apps such as Mobile BankID: Please visit documentation site for more information. It must not be included for transactions that are not originating from an app. + /// + /// NOTE! This value is only used for redirecting users back to the native app within the flows. See also SuccessURL and FailURL descriptions. + /// + [JsonProperty("ReturnToAppURL")] + public string ReturnToAppURL { get; set; } + /// + /// The text to show on the end-user's bank statement after Trustly's own 10 digit reference (which always will be displayed first). The reference must let the end user identify the merchant based on this value. So the ShopperStatement should contain either your brand name, website name, or company name. + /// + /// If possible, try to keep this text as short as possible to maximise the chance that the full reference will fit into the reference field on the customer's bank since some banks allow only a limited number of characters. If the full ShopperStatement does not fit into the reference it will be truncated from the end. + /// + [JsonProperty("ShopperStatement")] + public string ShopperStatement { get; set; } + } + + public class DepositRequestDataAttributes : AbstractRequestDataAttributes + { + /// + /// First name of the person, or the name of the organization/company. + /// + [JsonProperty("Firstname", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Firstname { get; set; } + /// + /// Last name of the person (NULL/empty for organization/company). + /// + [JsonProperty("Lastname", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Lastname { get; set; } + /// + /// The ISO 3166-1-alpha-2 code of the end-user's country. This will be used for pre-selecting the country for the end-user in the iframe. + /// Note: This will only have an effect for new end-users. If an end-user has done a previous order (with the same EndUserID), the country that was last used will be pre-selected. + /// + [JsonProperty("Country", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Country { get; set; } + /// + /// The end-users localization preference in the format language[_territory]. Language is the ISO 639-1 code and territory the ISO 3166-1-alpha-2 code. + /// + [JsonProperty("Locale", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Locale { get; set; } + /// + /// The text to show on the end-user's bank statement after Trustly's own 10 digit reference (which always will be displayed first). The reference must let the end user identify the merchant based on this value. So the ShopperStatement should contain either your brand name, website name, or company name. + /// + /// If possible, try to keep this text as short as possible to maximise the chance that the full reference will fit into the reference field on the customer's bank since some banks allow only a limited number of characters. If the full ShopperStatement does not fit into the reference it will be truncated from the end. + /// + [JsonProperty("ShopperStatement", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string ShopperStatement { get; set; } + /// + /// The email address of the end user. + /// + /// test@trustly.com + [JsonProperty("Email", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Email { get; set; } + /// + /// The mobile phone number to the end-user in international format. This is used for KYC and AML routines. + /// + [JsonProperty("MobilePhone")] + public string MobilePhone { get; set; } + /// + /// The IP-address of the end-user. + /// + [JsonProperty("IP")] + public string IP { get; set; } + /// + /// The URL to which the end-user should be redirected after a successful deposit. Do not put any logic on that page since it's not guaranteed that the end-user will in fact visit it. + /// + [JsonProperty("SuccessURL", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string SuccessURL { get; set; } + /// + /// The URL to which the end-user should be redirected after a failed deposit. Do not put any logic on that page since it's not guaranteed that the end-user will in fact visit it. + /// + [JsonProperty("FailURL", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string FailURL { get; set; } + /// + /// The TemplateURL should be used if you want to design your own payment page but have it hosted on Trustly's side. The URL of your template page should be provided in this attribute in every Deposit API call. Our system will then fetch the content of your template page, insert the Trustly iframe into it and host the entire page on Trustly’s side. In the response to the Deposit request, you will receive a URL to the hosted template page which you should redirect the user to (the hosted page cannot be put inside an iframe). + /// + [JsonProperty("TemplateURL")] + public string TemplateURL { get; set; } + /// + /// The html target/frame-name of the SuccessURL. Only _top, _self and _parent are supported. + /// + [JsonProperty("URLTarget")] + public UrlTarget? URLTarget { get; set; } + /// + /// The end-user's social security number / personal number / birth number / etc. Useful for some banks for identifying transactions and KYC/AML. If a Swedish personid ("personnummer") is provided, it will be pre-filled when the user logs in to their bank. + /// + /// 790131-1234 + [JsonProperty("NationalIdentificationNumber")] + public string NationalIdentificationNumber { get; set; } + /// + /// This attribute disables the possibility to change/type in national identification number when logging in to a Swedish bank. If this attribute is sent, the attribute NationalIdentificationNumber needs to be correctly included in the request. Note: This is only available for Swedish banks. + /// + [JsonProperty("UnchangeableNationalIdentificationNumber")] + public string UnchangeableNationalIdentificationNumber { get; set; } + /// + /// If you are using Trustly from within your native iOS app, this attribute should be sent so that we can redirect the users back to your app in case an external app is used for authentication (for example Mobile Bank ID in Sweden). + /// + [JsonProperty("URLScheme")] + public string URLScheme { get; set; } + /// + /// When rendering the Trustly Checkout in a native app you are required to pass your application's url as an attribute to the order initiation request. By doing so, Trustly can redirect users back to your app after using external identification apps such as Mobile BankID: Please visit documentation site for more information. It must not be included for transactions that are not originating from an app. + /// + /// NOTE! This value is only used for redirecting users back to the native app within the flows. See also SuccessURL and FailURL descriptions. + /// + [JsonProperty("ReturnToAppURL")] + public string ReturnToAppURL { get; set; } + /// + /// iDeal. The iDEAL integration offered by Trustly allows for both iDEAL and Trustly payments on a single integration with all transactions visible in the same AccountLedger. To initiate a new iDEAL payment, add Method = "deposit.bank.netherlands.ideal" to the Deposit attributes. + /// + /// deposit.bank.netherlands.ideal + [JsonProperty("Method")] + public string Method { get; set; } + /// + /// The ISO 4217 code of the currency. See documentation + /// + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK + [JsonProperty("Currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Currency { get; set; } + /// + /// The amount to deposit with exactly two decimals in the currency specified by Currency. Do not use this attribute in combination withsuggestedMinAmount and suggestedMaxAmount. Only digits. Use dot (.) as decimal separator. + /// + [JsonProperty("Amount")] + public string Amount { get; set; } + /// + /// The ISO 3166-1-alpha-2 code of the shipping address country. + /// + [JsonProperty("ShippingAddressCountry")] + public string ShippingAddressCountry { get; set; } + /// + /// The postal code of the shipping address. + /// + [JsonProperty("ShippingAddressPostalCode")] + public string ShippingAddressPostalCode { get; set; } + /// + /// The city of the shipping address. + /// + [JsonProperty("ShippingAddressCity")] + public string ShippingAddressCity { get; set; } + /// + /// Shipping address street + /// + [JsonProperty("ShippingAddressLine1")] + public string ShippingAddressLine1 { get; set; } + /// + /// Additional shipping address information. + /// + [JsonProperty("ShippingAddressLine2")] + public string ShippingAddressLine2 { get; set; } + /// + /// The entire shipping address. This attribute should only be used if you are unable to provide the shipping address information in the 5 separate attributes: ShippingAddressCountry, ShippingAddressCity, ShippingAddressPostalCode, ShippingAddressLine, ShippingAddressLine + /// + [JsonProperty("ShippingAddress")] + public string ShippingAddress { get; set; } + /// + /// In addition to the deposit, request a direct debit mandate from the account used for the deposit. 1 enables, 0 disables. The default is disabled. If this attribute is set, additional account notifications might be sent. You can read more about Trustly Direct Debit here, under section 2.1 + /// + [JsonProperty("RequestDirectDebitMandate")] + public StringBoolean? RequestDirectDebitMandate { get; set; } + /// + /// The AccountID received from an account notification which shall be charged in a Trustly Direct Debit deposit. This attribute should only be sent in combination with {"QuickDeposit" : 1} + /// + [JsonProperty("ChargeAccountId")] + public string ChargeAccountId { get; set; } + /// + /// Set to 1 for Trustly Direct Debit deposits. QuickDeposit should be set set to 1 when the end user attempts a quick deposit, even if ChargeAccountID is not set. You can read more about QuickDeposits here, under section 1.1 and 1.2. + /// + [JsonProperty("QuickDeposit")] + public StringBoolean? QuickDeposit { get; set; } + /// + /// The ExternalReference is a reference set by the merchant for any purpose and does not need to be unique for every API call. For example, it can be used for invoice references, OCR numbers and also for offering end users the option to part-pay an invoice using the same ExternalReference. The ExternalReference will be included in version 1.2 of the settlement report, ViewAutomaticSettlementDetailsCSV. + /// + /// 32423534523 + [JsonProperty("ExternalReference")] + public string ExternalReference { get; set; } + /// + /// Human-readable identifier of the consumer-facing merchant (e.g. legal name or trade name) + /// Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + /// Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + /// + [JsonProperty("PSPMerchant")] + public string PSPMerchant { get; set; } + /// + /// URL of the consumer-facing website where the order is initiated + /// Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + /// Mandatory attributes for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + /// + [JsonProperty("PSPMerchantURL")] + public string PSPMerchantURL { get; set; } + /// + /// VISA category codes describing the merchant's nature of business. + /// Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + /// Mandatory attributes for Trustly Partners that are using Express account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + /// + [JsonProperty("MerchantCategoryCode")] + public string MerchantCategoryCode { get; set; } + /// + /// The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + /// + /// 1234567890 + /// 7653385737 + [JsonProperty("AccountId")] + public string AccountId { get; set; } + /// + /// Information about the Payee (ultimate creditor). The burden of identifying who the Payee for any given transaction is lies with the Trustly customer. Required for some merchants and partners. RecipientInformation is mandatory to send for money transfer services (including remittance houses), e-wallets, prepaid cards, as well as for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account (other cases may also apply). + /// + [JsonProperty("RecipientInformation")] + public RecipientInformation RecipientInformation { get; set; } + /// + /// Trustly will send a KYC notification to the merchant’s NotificationURL if the attribute "RequestKYC" : "1" is sent in a Deposit API call. The KYC notification should be expected after the end user has performed a successful login to their bank, and always before a deposit transfer is initiated. + /// + [JsonProperty("RequestKYC")] + public StringBoolean? RequestKYC { get; set; } + /// + /// The minimum amount the end-user is allowed to deposit in the currency specified by Currency.Only digits. Use dot (.) as decimal separator. + /// + [JsonProperty("SuggestedMinAmount")] + public string SuggestedMinAmount { get; set; } + /// + /// The maximum amount the end-user is allowed to deposit in the currency specified by Currency. Only digits. Use dot (.) as decimal separator. + /// + [JsonProperty("SuggestedMaxAmount")] + public string SuggestedMaxAmount { get; set; } + } + + public class DebitRefundDirectDebitNotificationDataAttributes : AbstractRequestDataAttributes + { + /// + /// Payment reference, from the bank, of the payment that occurred based on the Payment request. Only available if status is PAID. + /// + /// 1E2FC19E5E5E4E18916609B7F8911C12 + /// TRLY80494-1001 + [JsonProperty("reference")] + public string Reference { get; set; } + /// + /// Statement that appear on the end users bank account + /// + /// TRLY80494-1001 + [JsonProperty("statement")] + public string Statement { get; set; } + } + + public class DebitDirectDebitNotificationDataAttributes : AbstractRequestDataAttributes + { + /// + /// Payment reference, from the bank, of the payment that occurred based on the Payment request. Only available if status is PAID. + /// + /// 1E2FC19E5E5E4E18916609B7F8911C12 + /// TRLY80494-1001 + [JsonProperty("reference")] + public string Reference { get; set; } + /// + /// Statement that appear on the end users bank account + /// + /// TRLY80494-1001 + [JsonProperty("statement")] + public string Statement { get; set; } + [JsonProperty("reason")] + public DebitDirectDebitNotificationReason? Reason { get; set; } + /// + /// Description of reason. If Direct Debit Mandate, then this applies when reason is FAILED: BACS ADDACS_1(INSTRUCTION CANCELLED BY PAYER). See https://eu.developers.trustly.com/doc/reference/mdd#description-of-details-eg-failure-details + /// + [JsonProperty("details")] + public string Details { get; set; } + } + + public class DebitDirectCreditNotificationDataAttributes : AbstractRequestDataAttributes + { + /// + /// Payment reference, from the bank, of the payment that occurred based on the Payment request. Only available if status is PAID. + /// + /// 1E2FC19E5E5E4E18916609B7F8911C12 + /// TRLY80494-1001 + [JsonProperty("reference")] + public string Reference { get; set; } + /// + /// Statement that appear on the end users bank account + /// + /// TRLY80494-1001 + [JsonProperty("statement")] + public string Statement { get; set; } + [JsonProperty("reason")] + public DirectCreditDebitNotificationReason? Reason { get; set; } + /// + /// Description of reason. If Direct Debit Mandate, then this applies when reason is FAILED: BACS ADDACS_1(INSTRUCTION CANCELLED BY PAYER). See https://eu.developers.trustly.com/doc/reference/mdd#description-of-details-eg-failure-details + /// + [JsonProperty("details")] + public string Details { get; set; } + } + + public class CreateAccountRequestDataAttributes : AbstractRequestDataAttributes + { + /// + /// The end-user's date of birth. + /// + [JsonProperty("DateOfBirth")] + public string DateOfBirth { get; set; } + /// + /// The mobile phone number to the end-user in international format. This is used for KYC and AML routines. + /// + [JsonProperty("MobilePhone")] + public string MobilePhone { get; set; } + /// + /// The end-user's social security number / personal number / birth number / etc. Useful for some banks for identifying transactions and KYC/AML. If a Swedish personid ("personnummer") is provided, it will be pre-filled when the user logs in to their bank. + /// + /// 790131-1234 + [JsonProperty("NationalIdentificationNumber")] + public string NationalIdentificationNumber { get; set; } + /// + /// The ISO 3166-1-alpha-2 code of the recipient address country. + /// + [JsonProperty("AddressCountry")] + public string AddressCountry { get; set; } + /// + /// The postalcode of the recipient address. + /// + [JsonProperty("AddressPostalCode")] + public string AddressPostalCode { get; set; } + /// + /// The city of the recipient address. + /// + [JsonProperty("AddressCity")] + public string AddressCity { get; set; } + /// + /// Recipient address street + /// + /// Main Street 1 + [JsonProperty("AddressLine1")] + public string AddressLine1 { get; set; } + /// + /// Additional address information of the recipient. + /// + [JsonProperty("AddressLine2")] + public string AddressLine2 { get; set; } + /// + /// The entire shipping address. + /// This attribute should only be used if you are unable to provide the shipping address information in the 5 separate properties: AddressCountry, AddressCity, AddressPostalCode, AddressLine1, AddressLine2 + /// + /// Birgerstreet 14, SE-11411, Stockholm, Sweden + [JsonProperty("Address")] + public string Address { get; set; } + /// + /// The email address of the end user. + /// + /// test@trustly.com + [JsonProperty("Email")] + public string Email { get; set; } + } + + public class ChargeRequestDataAttributes : AbstractRequestDataAttributes + { + /// + /// The text to show on the end-user's bank statement after Trustly's own 10 digit reference (which always will be displayed first). The reference must let the end user identify the merchant based on this value. So the ShopperStatement should contain either your brand name, website name, or company name. + /// + /// If possible, try to keep this text as short as possible to maximise the chance that the full reference will fit into the reference field on the customer's bank since some banks allow only a limited number of characters. If the full ShopperStatement does not fit into the reference it will be truncated from the end. + /// + [JsonProperty("ShopperStatement", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string ShopperStatement { get; set; } + /// + /// The email address of the end user. + /// + /// test@trustly.com + [JsonProperty("Email", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Email { get; set; } + /// + /// The date when the funds will be charged from the end user's bank account. If this attribute is not sent, the charge will be attempted as soon as possible. + /// + [JsonProperty("PaymentDate")] + public string PaymentDate { get; set; } + /// + /// The ExternalReference is a reference set by the merchant for any purpose and does not need to be unique for every API call. For example, it can be used for invoice references, OCR numbers and also for offering end users the option to part-pay an invoice using the same ExternalReference. The ExternalReference will be included in version 1.2 of the settlement report, ViewAutomaticSettlementDetailsCSV. + /// + /// 32423534523 + [JsonProperty("ExternalReference")] + public string ExternalReference { get; set; } + /// + /// Human-readable identifier of the consumer-facing merchant (e.g. legal name or trade name) + /// Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + /// Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + /// + [JsonProperty("PSPMerchant")] + public string PSPMerchant { get; set; } + /// + /// URL of the consumer-facing website where the order is initiated + /// Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + /// Mandatory attributes for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + /// + [JsonProperty("PSPMerchantURL")] + public string PSPMerchantURL { get; set; } + /// + /// VISA category codes describing the merchant's nature of business. + /// Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + /// Mandatory attributes for Trustly Partners that are using Express account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + /// + [JsonProperty("MerchantCategoryCode")] + public string MerchantCategoryCode { get; set; } + } + + public class CancelSwishNotificationDataAttributes : AbstractRequestDataAttributes + { + [JsonProperty("reason")] + public SwishCancelReason? Reason { get; set; } + /// + /// Description of reason + /// + /// User Declined + [JsonProperty("details")] + public string Details { get; set; } + } + + public class CancelRefundDirectDebitNotificationDataAttributes : AbstractRequestDataAttributes + { + [JsonProperty("reason")] + public RefundDirectDebitCancelReason? Reason { get; set; } + /// + /// Description of reason. If Direct Debit Mandate, then this applies when reason is FAILED: BACS ADDACS_1(INSTRUCTION CANCELLED BY PAYER). See https://eu.developers.trustly.com/doc/reference/mdd#description-of-details-eg-failure-details + /// + [JsonProperty("details")] + public string Details { get; set; } + } + + public class CancelMandateNotificationDataAttributes : AbstractRequestDataAttributes + { + [JsonProperty("reason")] + public CancelMandateNotificationDataAttributesCancelReason? Reason { get; set; } + /// + /// Description of reason. If Direct Debit Mandate, then this applies when reason is FAILED: BACS ADDACS_1(INSTRUCTION CANCELLED BY PAYER). See https://eu.developers.trustly.com/doc/reference/mdd#description-of-details-eg-failure-details + /// + [JsonProperty("details")] + public string Details { get; set; } + /// + /// The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + /// + /// 1234567890 + /// 7653385737 + [JsonProperty("accountid")] + public string AccountID { get; set; } + /// + /// This parameter in a way identifies the mandate you are to setup. If it's already used, you will receive an error, ERROR_MERCHANT_REFERENCE_ALREADY_EXISTS + /// which basically informs you that there's already a mandate with that reference. + /// + /// [BACS]: The unique mandate reference. 6 - 10 characters consisting of A-Z and 0-9. Can not begin with DDIC and neither consists of the same characters, eg. AAAAAAA. + /// [Bankgiro]: The unique mandate reference. This must be numeric and unique for the payer, eg nationalId or similar can be used. Format needs to follow regexp [1-9][0-9]{5-15} + /// [SEPA-DD]: The unique mandate reference. This must be unique for the end-user for you as a merchant. Format needs to follow regexp [0-9,a-z,A-Z]{10-35} + /// + /// 123ABC0123 + [JsonProperty("merchantreference")] + public string Merchantreference { get; set; } + } + + public class CancelDirectDebitNotificationDataAttributes : AbstractRequestDataAttributes + { + [JsonProperty("reason")] + public DirectDebitCancelReason? Reason { get; set; } + /// + /// Description of reason. If Direct Debit Mandate, then this applies when reason is FAILED: BACS ADDACS_1(INSTRUCTION CANCELLED BY PAYER). See https://eu.developers.trustly.com/doc/reference/mdd#description-of-details-eg-failure-details + /// + [JsonProperty("details")] + public string Details { get; set; } + } + + public class CancelDirectCreditNotificationDataAttributes : AbstractRequestDataAttributes + { + [JsonProperty("reason")] + public DirectCreditCancelReason? Reason { get; set; } + /// + /// Description of reason. If Direct Debit Mandate, then this applies when reason is FAILED: BACS ADDACS_1(INSTRUCTION CANCELLED BY PAYER). See https://eu.developers.trustly.com/doc/reference/mdd#description-of-details-eg-failure-details + /// + [JsonProperty("details")] + public string Details { get; set; } + } + + public class AnyAttributes : AbstractRequestDataAttributes + { + + } + + public class AccountPayoutRequestDataAttributes : AbstractRequestDataAttributes + { + /// + /// The text to show on the end-user's bank statement after Trustly's own 10 digit reference (which always will be displayed first). The reference must let the end user identify the merchant based on this value. So the ShopperStatement should contain either your brand name, website name, or company name. + /// + /// If possible, try to keep this text as short as possible to maximise the chance that the full reference will fit into the reference field on the customer's bank since some banks allow only a limited number of characters. If the full ShopperStatement does not fit into the reference it will be truncated from the end. + /// + [JsonProperty("ShopperStatement", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string ShopperStatement { get; set; } + /// + /// The ExternalReference is a reference set by the merchant for any purpose and does not need to be unique for every API call. For example, it can be used for invoice references, OCR numbers and also for offering end users the option to part-pay an invoice using the same ExternalReference. The ExternalReference will be included in version 1.2 of the settlement report, ViewAutomaticSettlementDetailsCSV. + /// + /// 32423534523 + [JsonProperty("ExternalReference")] + public string ExternalReference { get; set; } + /// + /// Human-readable identifier of the consumer-facing merchant (e.g. legal name or trade name) + /// Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + /// Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + /// + [JsonProperty("PSPMerchant")] + public string PSPMerchant { get; set; } + /// + /// URL of the consumer-facing website where the order is initiated + /// Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + /// Mandatory attributes for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + /// + [JsonProperty("PSPMerchantURL")] + public string PSPMerchantURL { get; set; } + /// + /// VISA category codes describing the merchant's nature of business. + /// Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + /// Mandatory attributes for Trustly Partners that are using Express account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + /// + [JsonProperty("MerchantCategoryCode")] + public string MerchantCategoryCode { get; set; } + /// + /// Information about the Payer (ultimate debtor). This is required for some merchants and partners. SenderInformation is mandatory to send in Attributes{} for money transfer services (including remittance houses), e-wallets, prepaid cards, as well as for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account (other cases may also apply). + /// + [JsonProperty("SenderInformation")] + public SenderInformation SenderInformation { get; set; } + } + + public class AbstractRequestData + where T : AbstractRequestDataAttributes + { + [JsonProperty("Username", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Username { get; set; } + [JsonProperty("Password", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Password { get; set; } + [JsonProperty("Attributes")] + public T Attributes { get; set; } + } + + public class WithdrawRequestData : AbstractRequestData + { + /// + /// The URL to which notifications for this should be sent to. This URL should be hard to guess and not contain a ? ("question mark"). + /// + /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh + [JsonProperty("NotificationURL", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string NotificationURL { get; set; } + /// + /// ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + /// Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + /// + [JsonProperty("EndUserID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string EndUserID { get; set; } + /// + /// Your unique ID of the transaction. + /// + /// 12345678 + [JsonProperty("MessageID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string MessageID { get; set; } + /// + /// The ISO 4217 code of the currency. See documentation + /// + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK + [JsonProperty("Currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Currency { get; set; } + } + + public class SwishRequestData : AbstractRequestData + { + /// + /// The URL to which notifications for this should be sent to. This URL should be hard to guess and not contain a ? ("question mark"). + /// + /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh + [JsonProperty("NotificationURL")] + public string NotificationURL { get; set; } + /// + /// ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + /// Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + /// + [JsonProperty("EndUserID")] + public string EndUserID { get; set; } + /// + /// Your unique ID of the transaction. + /// + /// 12345678 + [JsonProperty("MessageID")] + public string MessageID { get; set; } + } + + public class SettlementReportRequestData : AbstractRequestData + { + /// + /// If the value is specified (i.e. not "null"), the system will only search for a settlement executed in that particular currency. If unspecified, settlements executed in any currency are included in the report. + /// + /// The ISO 4217 code of the currency. See documentation + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK + [JsonProperty("Currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Currency { get; set; } + /// + /// The date when the settlement was processed. + /// + [JsonProperty("SettlementDate", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string SettlementDate { get; set; } + } + + /// + /// https://eu.developers.trustly.com/doc/reference/selectaccount + /// + public class SelectAccountRequestData : AbstractRequestData + { + /// + /// The URL to which notifications for this should be sent to. This URL should be hard to guess and not contain a ? ("question mark"). + /// + /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh + [JsonProperty("NotificationURL", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string NotificationURL { get; set; } + /// + /// ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + /// Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + /// + [JsonProperty("EndUserID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string EndUserID { get; set; } + /// + /// Your unique ID of the transaction. + /// + /// 12345678 + [JsonProperty("MessageID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string MessageID { get; set; } + } + + public class RegisterAccountRequestData : AbstractRequestData + { + /// + /// ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + /// Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + /// + [JsonProperty("EndUserID")] + public string EndUserID { get; set; } + /// + /// The clearing house of the end-user's bank account. Typically the name of a country in uppercase letters. See examples or table at https://developers.trustly.com/emea/docs/registeraccount. + /// + /// AUSTRIA + /// BELGIUM + /// BULGARIA + /// CROATIA + /// CYPRUS + /// CZECH_REPUBLIC + /// DENMARK + /// ESTONIA + /// FINLAND + /// FRANCE + /// GERMANY + /// GREECE + /// HUNGARY + /// IRELAND + /// ITALY + /// LATVIA + /// LITHUANIA + /// LUXEMBOURG + /// MALTA + /// NETHERLANDS + /// NORWAY + /// POLAND + /// PORTUGAL + /// ROMANIA + /// SLOVAKIA + /// SLOVENIA + /// SPAIN + /// SWEDEN + /// UNITED_KINGDOM + [JsonProperty("ClearingHouse", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string ClearingHouse { get; set; } + /// + /// The bank number identifying the end-user's bank in the given clearing house. For bank accounts in IBAN format you should just provide an empty string (""). For non-IBAN format, see examples. The BankNumber for Swedish bank accounts should be the local "clearing number", and the AccountNumber parameter should contain the rest of the account number. Most Swedish banks have a 4-digit clearing number, but a 5-digit clearing number is used for Swedbank accounts when the clearing number starts with "8". Nordea accounts where the account number is the same as the person's national identification number always has "3300" as the clearing number. + /// + /// IBAN for Swedish bank accounts is supported upon request. When making API calls with Swedish IBAN, ensure to include the Clearinghouse attribute as "IBAN" instead of "SWEDEN". See more at https://developers.trustly.com/emea/docs/registeraccount + /// + /// Sweden: ^[0-9]{4,5}$ + /// United Kingdom: ^[0-9]{6}$ + [JsonProperty("BankNumber", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string BankNumber { get; set; } + /// + /// The account number, identifying the end-user's account in the bank. Can be either IBAN or country-specific format, see examples or read more at https://developers.trustly.com/emea/docs/registeraccount + /// + /// 6112 + /// 391124057 + /// AUSTRIA: ^AT[0-9]{18}$ + /// BELGIUM: ^BE[0-9]{14}$ + /// BULGARIA: ^BG[0-9]{2}[A-Z]{4}[0-9]{4}[0-9]{2}[A-Z0-9]{8}$ + /// CROATIA: ^HR[0-9]{2}[0-9]{7}[0-9]{10}$ + /// CYPRUS: ^CY[0-9]{10}[0-9A-Z]{16}$ + /// CZECH_REPUBLIC: ^CZ[0-9]{22}$ + /// DENMARK: ^DK[0-9]{16}$ + /// ESTONIA: ^EE[0-9]{18}$ + /// FINLAND: ^FI[0-9]{16}$ + /// FRANCE: ^FR[0-9]{12}[0-9A-Z]{11}[0-9]{2}$ + /// GERMANY: ^DE[0-9]{20}$ + /// GREECE: ^GR[0-9]{25}$ + /// HUNGARY: ^HU[0-9]{26}$ + /// IRELAND: ^IE[0-9]{2}[A-Z]{4}[0-9]{14}$ + /// ITALY: ^IT[0-9]{2}[A-Z][0-9]{10}[0-9A-Z]{12}$ + /// LATVIA: ^LV[0-9]{2}[A-Z]{4}[0-9A-Z]{13}$ + /// LITHUANIA: ^LT[0-9]{18}$ + /// LUXEMBOURG: ^LU[0-9]{18}$ + /// MALTA: ^MT[0-9]{2}[A-Z]{4}[0-9]{5}[0-9A-Z]{18}$ + /// NETHERLANDS: ^NL[0-9]{2}[A-Z]{4}[0-9]{10}$ + /// NORWAY: ^NO[0-9]{13}$ + /// POLAND: ^PL[0-9]{26}$ + /// PORTUGAL: ^PT[0-9]{23}$ + /// ROMANIA: ^RO[0-9]{2}[A-Z]{4}[0-9A-Z]{16}$ + /// SLOVAKIA: ^SK[0-9]{22}$ + /// SLOVENIA: ^SI56[0-9]{15}$ + /// SPAIN: ^ES[0-9]{22}$ + /// SWEDEN:* [0-9]{1,15}$ + /// UNITED_KINGDOM: ^[0-9]{8}$ + [JsonProperty("AccountNumber", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string AccountNumber { get; set; } + /// + /// First name of the person, or the name of the organization/company. + /// + [JsonProperty("Firstname", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Firstname { get; set; } + /// + /// Last name of the person (NULL/empty for organization/company). + /// + [JsonProperty("Lastname", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Lastname { get; set; } + } + + public class RegisterAccountPayoutRequestData : AbstractRequestData + { + /// + /// ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + /// Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + /// + [JsonProperty("EndUserID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string EndUserID { get; set; } + /// + /// The clearing house of the end-user's bank account. Typically the name of a country in uppercase letters. See examples or table at https://developers.trustly.com/emea/docs/registeraccount. + /// + /// AUSTRIA + /// BELGIUM + /// BULGARIA + /// CROATIA + /// CYPRUS + /// CZECH_REPUBLIC + /// DENMARK + /// ESTONIA + /// FINLAND + /// FRANCE + /// GERMANY + /// GREECE + /// HUNGARY + /// IRELAND + /// ITALY + /// LATVIA + /// LITHUANIA + /// LUXEMBOURG + /// MALTA + /// NETHERLANDS + /// NORWAY + /// POLAND + /// PORTUGAL + /// ROMANIA + /// SLOVAKIA + /// SLOVENIA + /// SPAIN + /// SWEDEN + /// UNITED_KINGDOM + [JsonProperty("ClearingHouse", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string ClearingHouse { get; set; } + /// + /// The bank number identifying the end-user's bank in the given clearing house. For bank accounts in IBAN format you should just provide an empty string (""). For non-IBAN format, see examples. The BankNumber for Swedish bank accounts should be the local "clearing number", and the AccountNumber parameter should contain the rest of the account number. Most Swedish banks have a 4-digit clearing number, but a 5-digit clearing number is used for Swedbank accounts when the clearing number starts with "8". Nordea accounts where the account number is the same as the person's national identification number always has "3300" as the clearing number. + /// + /// IBAN for Swedish bank accounts is supported upon request. When making API calls with Swedish IBAN, ensure to include the Clearinghouse attribute as "IBAN" instead of "SWEDEN". See more at https://developers.trustly.com/emea/docs/registeraccount + /// + /// Sweden: ^[0-9]{4,5}$ + /// United Kingdom: ^[0-9]{6}$ + [JsonProperty("BankNumber", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string BankNumber { get; set; } + /// + /// The account number, identifying the end-user's account in the bank. Can be either IBAN or country-specific format, see examples or read more at https://developers.trustly.com/emea/docs/registeraccount + /// + /// 6112 + /// 391124057 + /// AUSTRIA: ^AT[0-9]{18}$ + /// BELGIUM: ^BE[0-9]{14}$ + /// BULGARIA: ^BG[0-9]{2}[A-Z]{4}[0-9]{4}[0-9]{2}[A-Z0-9]{8}$ + /// CROATIA: ^HR[0-9]{2}[0-9]{7}[0-9]{10}$ + /// CYPRUS: ^CY[0-9]{10}[0-9A-Z]{16}$ + /// CZECH_REPUBLIC: ^CZ[0-9]{22}$ + /// DENMARK: ^DK[0-9]{16}$ + /// ESTONIA: ^EE[0-9]{18}$ + /// FINLAND: ^FI[0-9]{16}$ + /// FRANCE: ^FR[0-9]{12}[0-9A-Z]{11}[0-9]{2}$ + /// GERMANY: ^DE[0-9]{20}$ + /// GREECE: ^GR[0-9]{25}$ + /// HUNGARY: ^HU[0-9]{26}$ + /// IRELAND: ^IE[0-9]{2}[A-Z]{4}[0-9]{14}$ + /// ITALY: ^IT[0-9]{2}[A-Z][0-9]{10}[0-9A-Z]{12}$ + /// LATVIA: ^LV[0-9]{2}[A-Z]{4}[0-9A-Z]{13}$ + /// LITHUANIA: ^LT[0-9]{18}$ + /// LUXEMBOURG: ^LU[0-9]{18}$ + /// MALTA: ^MT[0-9]{2}[A-Z]{4}[0-9]{5}[0-9A-Z]{18}$ + /// NETHERLANDS: ^NL[0-9]{2}[A-Z]{4}[0-9]{10}$ + /// NORWAY: ^NO[0-9]{13}$ + /// POLAND: ^PL[0-9]{26}$ + /// PORTUGAL: ^PT[0-9]{23}$ + /// ROMANIA: ^RO[0-9]{2}[A-Z]{4}[0-9A-Z]{16}$ + /// SLOVAKIA: ^SK[0-9]{22}$ + /// SLOVENIA: ^SI56[0-9]{15}$ + /// SPAIN: ^ES[0-9]{22}$ + /// SWEDEN:* [0-9]{1,15}$ + /// UNITED_KINGDOM: ^[0-9]{8}$ + [JsonProperty("AccountNumber", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string AccountNumber { get; set; } + /// + /// First name of the person, or the name of the organization/company. + /// + [JsonProperty("Firstname", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Firstname { get; set; } + /// + /// Last name of the person (NULL/empty for organization/company). + /// + [JsonProperty("Lastname", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Lastname { get; set; } + /// + /// The URL to which notifications for this should be sent to. This URL should be hard to guess and not contain a ? ("question mark"). + /// + /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh + [JsonProperty("NotificationURL", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string NotificationURL { get; set; } + /// + /// Your unique ID for the payout. If the MessageID is a previously initiated P2P order then the payout will be attached to that P2P order and the amount must be equal to or lower than the previously deposited amount. + /// + [JsonProperty("MessageID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string MessageID { get; set; } + /// + /// The amount to send with exactly two decimals. Only digits. Use dot (.) as decimal separator. If the end-user holds a balance in the merchant's system then the amount must have been deducted from that balance before calling this method. + /// + [JsonProperty("Amount", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Amount { get; set; } + /// + /// The ISO 4217 code of the currency. See documentation + /// + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK + [JsonProperty("Currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Currency { get; set; } + [JsonExtensionData] + public JObject AdditionalProperties { get; set; } + } + + public class RefundRequestData : AbstractRequestData + { + /// + /// The OrderID of the initial deposit. + /// + [JsonProperty("OrderID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string OrderID { get; set; } + /// + /// The amount to refund the customer with exactly two decimals. Only digits. Use dot (.) as decimal separator. + /// + [JsonProperty("Amount", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Amount { get; set; } + /// + /// The currency of the amount to refund the customer. + /// + [JsonProperty("Currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Currency { get; set; } + [JsonExtensionData] + public JObject AdditionalProperties { get; set; } + } + + public class RefundDirectDebitRequestData : AbstractRequestData + { + /// + /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the charge. + /// + /// 9594811343 + [JsonProperty("OrderID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public long OrderID { get; set; } + /// + /// Your unique ID of the transaction. + /// + /// 12345678 + [JsonProperty("MessageID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string MessageID { get; set; } + /// + /// The amount to deposit with exactly two decimals in the currency specified by Currency. Do not use this attribute in combination withsuggestedMinAmount and suggestedMaxAmount. Only digits. Use dot (.) as decimal separator. + /// + [JsonProperty("Amount", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Amount { get; set; } + /// + /// The ISO 4217 code of the currency. See documentation + /// + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK + [JsonProperty("Currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Currency { get; set; } + } + + public class MerchantSettlementRequestData : AbstractRequestData + { + /// + /// Your unique ID for the payout. If the MessageID is a previously initiated P2P order then the payout will be attached to that P2P order and the amount must be equal to or lower than the previously deposited amount. + /// + [JsonProperty("MessageID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string MessageID { get; set; } + /// + /// The amount to send. See format in Handling currencies. Only digits. Use dot (.) as decimal separator. If the end-user holds a balance in the merchant's system then the amount must have been deducted from that balance before calling this method. + /// + [JsonProperty("Amount", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Amount { get; set; } + /// + /// The currency of the amount to send. + /// + [JsonProperty("Currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Currency { get; set; } + } + + /// + /// Generic class to describe the JsonRpc request params + /// + public class JsonRpcRequestParams + where T0 : AbstractRequestDataAttributes + where T : AbstractRequestData + { + /// + /// The signature which validates your request to the Trustly server + /// + [JsonProperty("Signature", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Signature { get; set; } + /// + /// The unique identifier for this request + /// + [JsonProperty("UUID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string UUID { get; set; } + [JsonProperty("Data", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public T Data { get; set; } + } + + public class WithdrawRequestParams : JsonRpcRequestParams + { + + } + + public class SwishRequestParams : JsonRpcRequestParams + { + + } + + public class SettlementReportRequestParams : JsonRpcRequestParams + { + + } + + public class SelectAccountRequestParams : JsonRpcRequestParams + { + + } + + public class RegisterAccountRequestParams : JsonRpcRequestParams + { + + } + + public class RegisterAccountPayoutRequestParams : JsonRpcRequestParams + { + + } + + public class RefundRequestParams : JsonRpcRequestParams + { + + } + + public class RefundDirectDebitRequestParams : JsonRpcRequestParams + { + + } + + public class MerchantSettlementRequestParams : JsonRpcRequestParams + { + + } + + /// + /// Generic class to describe the JsonRpc request package + /// + public class JsonRpcRequest + where T0 : AbstractRequestDataAttributes + where T1 : AbstractRequestData + where TParams : JsonRpcRequestParams + { + [JsonProperty("version", NullValueHandling = NullValueHandling.Include)] + [Required] + public string Version { get; } = "1.1"; + [JsonProperty("method", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Method { get; } + [JsonProperty("params")] + public TParams Params { get; set; } + + public JsonRpcRequest(string method) + { + this.Method = method; + } + } + + public class WithdrawRequest : JsonRpcRequest + { + public WithdrawRequest() : base("Withdraw") { } + } + + public class SwishRequest : JsonRpcRequest + { + public SwishRequest() : base("Swish") { } + } + + public class SettlementReportRequest : JsonRpcRequest + { + public SettlementReportRequest() : base("SettlementReport") { } + } + + public class SelectAccountRequest : JsonRpcRequest + { + public SelectAccountRequest() : base("SelectAccount") { } + } + + public class RegisterAccountRequest : JsonRpcRequest + { + public RegisterAccountRequest() : base("RegisterAccount") { } + } + + public class RegisterAccountPayoutRequest : JsonRpcRequest + { + public RegisterAccountPayoutRequest() : base("RegisterAccountPayout") { } + } + + public class RefundRequest : JsonRpcRequest + { + public RefundRequest() : base("Refund") { } + } + + public class RefundDirectDebitRequest : JsonRpcRequest + { + public RefundDirectDebitRequest() : base("RefundDirectDebit") { } + } + + public class MerchantSettlementRequest : JsonRpcRequest + { + public MerchantSettlementRequest() : base("MerchantSettlement") { } + } + + public class ImportDirectDebitMandateRequestData : AbstractRequestData + { + /// + /// The URL to which notifications for this should be sent to. This URL should be hard to guess and not contain a ? ("question mark"). + /// + /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh + [JsonProperty("NotificationURL", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string NotificationURL { get; set; } + /// + /// ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + /// Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + /// + [JsonProperty("EndUserID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string EndUserID { get; set; } + /// + /// Your unique ID of the transaction. + /// + /// 12345678 + [JsonProperty("MessageID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string MessageID { get; set; } + } + + public class ImportDirectDebitMandateRequestParams : JsonRpcRequestParams + { + + } + + public class ImportDirectDebitMandateRequest : JsonRpcRequest + { + public ImportDirectDebitMandateRequest() : base("ImportDirectDebitMandate") { } + } + + public class GetWithdrawalsRequestData : AbstractRequestData + { + /// + /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the charge. + /// + /// 9594811343 + [JsonProperty("OrderID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public long OrderID { get; set; } + } + + public class GetWithdrawalsRequestParams : JsonRpcRequestParams + { + + } + + public class GetWithdrawalsRequest : JsonRpcRequest + { + public GetWithdrawalsRequest() : base("GetWithdrawals") { } + } + + public class DirectPaymentBatchRequestData : AbstractRequestData + { + /// + /// Your unique ID of the transaction. + /// + /// 12345678 + [JsonProperty("MessageID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string MessageID { get; set; } + /// + /// The URL to which notifications for this should be sent to. This URL should be hard to guess and not contain a ? ("question mark"). + /// + /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh + [JsonProperty("NotificationURL", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string NotificationURL { get; set; } + /// + /// The ISO 4217 code of the currency. See documentation + /// + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK + [JsonProperty("Currency")] + public string Currency { get; set; } + /// + /// The ISO 3166-1-alpha-2 code of the end-user's country. This will be used for pre-selecting the country for the end-user in the iframe. + /// Note: This will only have an effect for new end-users. If an end-user has done a previous order (with the same EndUserID), the country that was last used will be pre-selected. + /// + [JsonProperty("Country")] + public string Country { get; set; } + } + + public class DirectPaymentBatchRequestParams : JsonRpcRequestParams + { + + } + + public class DirectPaymentBatchRequest : JsonRpcRequest + { + public DirectPaymentBatchRequest() : base("DirectPaymentBatch") { } + } + + public class DirectDebitRequestData : AbstractRequestData + { + /// + /// Your unique ID of the transaction. + /// + /// 12345678 + [JsonProperty("MessageID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string MessageID { get; set; } + /// + /// The URL to which notifications for this should be sent to. This URL should be hard to guess and not contain a ? ("question mark"). + /// + /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh + [JsonProperty("NotificationURL", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string NotificationURL { get; set; } + /// + /// The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + /// + /// 1234567890 + /// 7653385737 + [JsonProperty("AccountID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string AccountID { get; set; } + /// + /// This parameter in a way identifies the mandate you are to setup. If it's already used, you will receive an error, ERROR_MERCHANT_REFERENCE_ALREADY_EXISTS + /// which basically informs you that there's already a mandate with that reference. + /// + /// [BACS]: The unique mandate reference. 6 - 10 characters consisting of A-Z and 0-9. Can not begin with DDIC and neither consists of the same characters, eg. AAAAAAA. + /// [Bankgiro]: The unique mandate reference. This must be numeric and unique for the payer, eg nationalId or similar can be used. Format needs to follow regexp [1-9][0-9]{5-15} + /// [SEPA-DD]: The unique mandate reference. This must be unique for the end-user for you as a merchant. Format needs to follow regexp [0-9,a-z,A-Z]{10-35} + /// + /// 123ABC0123 + [JsonProperty("MerchantReference")] + public string MerchantReference { get; set; } + /// + /// The amount to deposit with exactly two decimals in the currency specified by Currency. Do not use this attribute in combination withsuggestedMinAmount and suggestedMaxAmount. Only digits. Use dot (.) as decimal separator. + /// + [JsonProperty("Amount", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Amount { get; set; } + /// + /// The ISO 4217 code of the currency. See documentation + /// + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK + [JsonProperty("Currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Currency { get; set; } + [JsonExtensionData] + public JObject AdditionalProperties { get; set; } + } + + public class DirectDebitRequestParams : JsonRpcRequestParams + { + + } + + public class DirectDebitRequest : JsonRpcRequest + { + public DirectDebitRequest() : base("DirectDebit") { } + } + + public class DirectDebitMandateRequestData : AbstractRequestData + { + /// + /// Your unique ID of the transaction. + /// + /// 12345678 + [JsonProperty("MessageID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string MessageID { get; set; } + /// + /// The URL to which notifications for this should be sent to. This URL should be hard to guess and not contain a ? ("question mark"). + /// + /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh + [JsonProperty("NotificationURL", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string NotificationURL { get; set; } + /// + /// ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + /// Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + /// + [JsonProperty("EndUserID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string EndUserID { get; set; } + } + + public class DirectDebitMandateRequestParams : JsonRpcRequestParams + { + + } + + public class DirectDebitMandateRequest : JsonRpcRequest + { + public DirectDebitMandateRequest() : base("DirectDebitMandate") { } + } + + public class DirectCreditRequestData : AbstractRequestData + { + /// + /// Your unique ID of the transaction. + /// + /// 12345678 + [JsonProperty("MessageID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string MessageID { get; set; } + /// + /// ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + /// Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + /// + [JsonProperty("EndUserID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string EndUserID { get; set; } + /// + /// The URL to which notifications for this should be sent to. This URL should be hard to guess and not contain a ? ("question mark"). + /// + /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh + [JsonProperty("NotificationURL", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string NotificationURL { get; set; } + /// + /// The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + /// + /// 1234567890 + /// 7653385737 + [JsonProperty("AccountID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string AccountID { get; set; } + /// + /// The branch identifier + /// + /// 6160 + /// 6000 + /// bg + /// 123123 + /// HANDSESS + [JsonProperty("BankIdentifier")] + public string BankIdentifier { get; set; } + /// + /// The account number, identifying the end-user's account in the bank. Can be either IBAN or country-specific format, see examples or read more at https://developers.trustly.com/emea/docs/registeraccount + /// + /// 6112 + /// 391124057 + /// AUSTRIA: ^AT[0-9]{18}$ + /// BELGIUM: ^BE[0-9]{14}$ + /// BULGARIA: ^BG[0-9]{2}[A-Z]{4}[0-9]{4}[0-9]{2}[A-Z0-9]{8}$ + /// CROATIA: ^HR[0-9]{2}[0-9]{7}[0-9]{10}$ + /// CYPRUS: ^CY[0-9]{10}[0-9A-Z]{16}$ + /// CZECH_REPUBLIC: ^CZ[0-9]{22}$ + /// DENMARK: ^DK[0-9]{16}$ + /// ESTONIA: ^EE[0-9]{18}$ + /// FINLAND: ^FI[0-9]{16}$ + /// FRANCE: ^FR[0-9]{12}[0-9A-Z]{11}[0-9]{2}$ + /// GERMANY: ^DE[0-9]{20}$ + /// GREECE: ^GR[0-9]{25}$ + /// HUNGARY: ^HU[0-9]{26}$ + /// IRELAND: ^IE[0-9]{2}[A-Z]{4}[0-9]{14}$ + /// ITALY: ^IT[0-9]{2}[A-Z][0-9]{10}[0-9A-Z]{12}$ + /// LATVIA: ^LV[0-9]{2}[A-Z]{4}[0-9A-Z]{13}$ + /// LITHUANIA: ^LT[0-9]{18}$ + /// LUXEMBOURG: ^LU[0-9]{18}$ + /// MALTA: ^MT[0-9]{2}[A-Z]{4}[0-9]{5}[0-9A-Z]{18}$ + /// NETHERLANDS: ^NL[0-9]{2}[A-Z]{4}[0-9]{10}$ + /// NORWAY: ^NO[0-9]{13}$ + /// POLAND: ^PL[0-9]{26}$ + /// PORTUGAL: ^PT[0-9]{23}$ + /// ROMANIA: ^RO[0-9]{2}[A-Z]{4}[0-9A-Z]{16}$ + /// SLOVAKIA: ^SK[0-9]{22}$ + /// SLOVENIA: ^SI56[0-9]{15}$ + /// SPAIN: ^ES[0-9]{22}$ + /// SWEDEN:* [0-9]{1,15}$ + /// UNITED_KINGDOM: ^[0-9]{8}$ + [JsonProperty("AccountNumber")] + public string AccountNumber { get; set; } + /// + /// The amount to deposit with exactly two decimals in the currency specified by Currency. Do not use this attribute in combination withsuggestedMinAmount and suggestedMaxAmount. Only digits. Use dot (.) as decimal separator. + /// + [JsonProperty("Amount")] + public string Amount { get; set; } + /// + /// The ISO 4217 code of the currency. See documentation + /// + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK + [JsonProperty("Currency")] + public string Currency { get; set; } + /// + /// The ISO 3166-1-alpha-2 code of the end-user's country. This will be used for pre-selecting the country for the end-user in the iframe. + /// Note: This will only have an effect for new end-users. If an end-user has done a previous order (with the same EndUserID), the country that was last used will be pre-selected. + /// + [JsonProperty("Country")] + public string Country { get; set; } + } + + public class DirectCreditRequestParams : JsonRpcRequestParams + { + + } + + public class DirectCreditRequest : JsonRpcRequest + { + public DirectCreditRequest() : base("DirectCredit") { } + } + + public class DepositRequestData : AbstractRequestData + { + /// + /// The URL to which notifications for this should be sent to. This URL should be hard to guess and not contain a ? ("question mark"). + /// + /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh + [JsonProperty("NotificationURL", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string NotificationURL { get; set; } + /// + /// ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + /// Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + /// + [JsonProperty("EndUserID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string EndUserID { get; set; } + /// + /// Your unique ID of the transaction. + /// + /// 12345678 + [JsonProperty("MessageID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string MessageID { get; set; } + [JsonExtensionData] + public JObject AdditionalProperties { get; set; } + } + + public class DepositRequestParams : JsonRpcRequestParams + { + + } + + public class DepositRequest : JsonRpcRequest + { + public DepositRequest() : base("Deposit") { } + } + + public class DenyWithdrawalRequestData : AbstractRequestData + { + /// + /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the charge. + /// + /// 9594811343 + [JsonProperty("OrderID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public long OrderID { get; set; } + } + + public class DenyWithdrawalRequestParams : JsonRpcRequestParams + { + + } + + public class DenyWithdrawalRequest : JsonRpcRequest + { + public DenyWithdrawalRequest() : base("DenyWithdrawal") { } + } + + public class CreateAccountRequestData : AbstractRequestData + { + /// + /// ID, username, hash or anything uniquely identifying the end-user holding this account. Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + /// + [JsonProperty("EndUserID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string EndUserID { get; set; } + /// + /// The clearing house of the end-user's bank account. Typically the name of a country in uppercase letters. See examples or table at https://developers.trustly.com/emea/docs/registeraccount. + /// + /// AUSTRIA + /// BELGIUM + /// BULGARIA + /// CROATIA + /// CYPRUS + /// CZECH_REPUBLIC + /// DENMARK + /// ESTONIA + /// FINLAND + /// FRANCE + /// GERMANY + /// GREECE + /// HUNGARY + /// IRELAND + /// ITALY + /// LATVIA + /// LITHUANIA + /// LUXEMBOURG + /// MALTA + /// NETHERLANDS + /// NORWAY + /// POLAND + /// PORTUGAL + /// ROMANIA + /// SLOVAKIA + /// SLOVENIA + /// SPAIN + /// SWEDEN + /// UNITED_KINGDOM + [JsonProperty("ClearingHouse", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string ClearingHouse { get; set; } + /// + /// The bank number identifying the end-user's bank in the given clearing house. For bank accounts in IBAN format you should just provide an empty string (""). For non-IBAN format, see examples. The BankNumber for Swedish bank accounts should be the local "clearing number", and the AccountNumber parameter should contain the rest of the account number. Most Swedish banks have a 4-digit clearing number, but a 5-digit clearing number is used for Swedbank accounts when the clearing number starts with "8". Nordea accounts where the account number is the same as the person's national identification number always has "3300" as the clearing number. + /// + /// IBAN for Swedish bank accounts is supported upon request. When making API calls with Swedish IBAN, ensure to include the Clearinghouse attribute as "IBAN" instead of "SWEDEN". See more at https://developers.trustly.com/emea/docs/registeraccount + /// + /// Sweden: ^[0-9]{4,5}$ + /// United Kingdom: ^[0-9]{6}$ + [JsonProperty("BankNumber", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string BankNumber { get; set; } + /// + /// The account number, identifying the end-user's account in the bank. Can be either IBAN or country-specific format, see examples or read more at https://developers.trustly.com/emea/docs/registeraccount + /// + /// 6112 + /// 391124057 + /// AUSTRIA: ^AT[0-9]{18}$ + /// BELGIUM: ^BE[0-9]{14}$ + /// BULGARIA: ^BG[0-9]{2}[A-Z]{4}[0-9]{4}[0-9]{2}[A-Z0-9]{8}$ + /// CROATIA: ^HR[0-9]{2}[0-9]{7}[0-9]{10}$ + /// CYPRUS: ^CY[0-9]{10}[0-9A-Z]{16}$ + /// CZECH_REPUBLIC: ^CZ[0-9]{22}$ + /// DENMARK: ^DK[0-9]{16}$ + /// ESTONIA: ^EE[0-9]{18}$ + /// FINLAND: ^FI[0-9]{16}$ + /// FRANCE: ^FR[0-9]{12}[0-9A-Z]{11}[0-9]{2}$ + /// GERMANY: ^DE[0-9]{20}$ + /// GREECE: ^GR[0-9]{25}$ + /// HUNGARY: ^HU[0-9]{26}$ + /// IRELAND: ^IE[0-9]{2}[A-Z]{4}[0-9]{14}$ + /// ITALY: ^IT[0-9]{2}[A-Z][0-9]{10}[0-9A-Z]{12}$ + /// LATVIA: ^LV[0-9]{2}[A-Z]{4}[0-9A-Z]{13}$ + /// LITHUANIA: ^LT[0-9]{18}$ + /// LUXEMBOURG: ^LU[0-9]{18}$ + /// MALTA: ^MT[0-9]{2}[A-Z]{4}[0-9]{5}[0-9A-Z]{18}$ + /// NETHERLANDS: ^NL[0-9]{2}[A-Z]{4}[0-9]{10}$ + /// NORWAY: ^NO[0-9]{13}$ + /// POLAND: ^PL[0-9]{26}$ + /// PORTUGAL: ^PT[0-9]{23}$ + /// ROMANIA: ^RO[0-9]{2}[A-Z]{4}[0-9A-Z]{16}$ + /// SLOVAKIA: ^SK[0-9]{22}$ + /// SLOVENIA: ^SI56[0-9]{15}$ + /// SPAIN: ^ES[0-9]{22}$ + /// SWEDEN:* [0-9]{1,15}$ + /// UNITED_KINGDOM: ^[0-9]{8}$ + [JsonProperty("AccountNumber", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string AccountNumber { get; set; } + /// + /// First name of the person, or the name of the organization/company. + /// + [JsonProperty("Firstname", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Firstname { get; set; } + /// + /// Last name of the person (NULL/empty for organization/company). + /// + [JsonProperty("Lastname", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Lastname { get; set; } + } + + public class CreateAccountRequestParams : JsonRpcRequestParams + { + + } + + public class CreateAccountRequest : JsonRpcRequest + { + public CreateAccountRequest() : base("CreateAccount") { } + } + + public class ChargeRequestData : AbstractRequestData + { + /// + /// The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + /// + /// 1234567890 + /// 7653385737 + [JsonProperty("AccountID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string AccountID { get; set; } + /// + /// The URL to which notifications for this should be sent to. This URL should be hard to guess and not contain a ? ("question mark"). + /// + /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh + [JsonProperty("NotificationURL", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string NotificationURL { get; set; } + /// + /// ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + /// Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + /// + [JsonProperty("EndUserID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string EndUserID { get; set; } + /// + /// Your unique ID of the transaction. + /// + /// 12345678 + [JsonProperty("MessageID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string MessageID { get; set; } + /// BGN: 100.00 + /// CZK: 100.00 + /// DKK: 100.00 + /// EUR: 100.00 + /// GBP: 100.00 + /// HRK: 100.00 + /// HUF: 100 + /// NOK: 100.00 + /// PLN: 100.00 + /// RON: 100.00 + /// SEK: 100.00 + [JsonProperty("Amount", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Amount { get; set; } + /// + /// The ISO 4217 code of the currency. See documentation + /// + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK + [JsonProperty("Currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Currency { get; set; } + } + + public class ChargeRequestParams : JsonRpcRequestParams + { + + } + + public class ChargeRequest : JsonRpcRequest + { + public ChargeRequest() : base("Charge") { } + } + + public class CancelDirectDebitRequestData : AbstractRequestData + { + /// + /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the request. + /// + /// 9594811343 + [JsonProperty("OrderID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string OrderID { get; set; } + } + + public class CancelDirectDebitRequestParams : JsonRpcRequestParams + { + + } + + public class CancelDirectDebitRequest : JsonRpcRequest + { + public CancelDirectDebitRequest() : base("CancelDirectDebit") { } + } + + public class CancelDirectDebitMandateRequestData : AbstractRequestData + { + /// + /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the request. + /// + /// 9594811343 + [JsonProperty("OrderID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string OrderID { get; set; } + } + + public class CancelDirectDebitMandateRequestParams : JsonRpcRequestParams + { + + } + + public class CancelDirectDebitMandateRequest : JsonRpcRequest + { + public CancelDirectDebitMandateRequest() : base("CancelDirectDebitMandate") { } + } + + public class CancelChargeRequestData : AbstractRequestData + { + /// + /// The OrderID of the Charge request that should be canceled. + /// + [JsonProperty("OrderID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string OrderID { get; set; } + } + + public class CancelChargeRequestParams : JsonRpcRequestParams + { + + } + + public class CancelChargeRequest : JsonRpcRequest + { + public CancelChargeRequest() : base("CancelCharge") { } + } + + public class BalanceRequestData : AbstractRequestData + { + + } + + public class BalanceRequestParams : JsonRpcRequestParams + { + + } + + public class BalanceRequest : JsonRpcRequest + { + public BalanceRequest() : base("Balance") { } + } + + public class ApproveWithdrawalRequestData : AbstractRequestData + { + /// + /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the charge. + /// + /// 9594811343 + [JsonProperty("OrderID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public long OrderID { get; set; } + } + + public class ApproveWithdrawalRequestParams : JsonRpcRequestParams + { + + } + + public class ApproveWithdrawalRequest : JsonRpcRequest + { + public ApproveWithdrawalRequest() : base("ApproveWithdrawal") { } + } + + public class AccountPayoutRequestData : AbstractRequestData + { + /// + /// The URL to which notifications for this payment should be sent to. This URL should be hard to guess and not contain a ? ("question mark"). + /// + [JsonProperty("NotificationURL", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string NotificationURL { get; set; } + /// + /// The AccountID received from an Account notification to which the money shall be sent. + /// + [JsonProperty("AccountID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string AccountID { get; set; } + /// + /// ID, username, hash or anything uniquely identifying the end-user requesting the withdrawal. Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + /// + [JsonProperty("EndUserID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string EndUserID { get; set; } + /// + /// Your unique ID for the payout. If the MessageID is a previously initiated P2P order then the payout will be attached to that P2P order and the amount must be equal to or lower than the previously deposited amount. + /// + [JsonProperty("MessageID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string MessageID { get; set; } + /// + /// The amount to send. Only digits. Use dot (.) as decimal separator. If the end-user holds a balance in the merchant's system then the amount must have been deducted from that balance before calling this method. + /// + [JsonProperty("Amount", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Amount { get; set; } + /// + /// The ISO 4217 code of the currency. See documentation + /// + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK + [JsonProperty("Currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Currency { get; set; } + } + + public class AccountPayoutRequestParams : JsonRpcRequestParams + { + + } + + public class AccountPayoutRequest : JsonRpcRequest + { + public AccountPayoutRequest() : base("AccountPayout") { } + } + + public class AccountLedgerRequestData : AbstractRequestData + { + /// + /// Date string in the ISO 8601 format (YYYY-MM-DD) + /// + /// 2014-04-01 + [JsonProperty("FromDate", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string FromDate { get; set; } + /// + /// Date string in the ISO 8601 format (YYYY-MM-DD) + /// + /// 2014-04-01 + [JsonProperty("ToDate", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string ToDate { get; set; } + /// + /// The ISO 4217 code of the currency. See documentation + /// + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK + [JsonProperty("Currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Currency { get; set; } + } + + public class AccountLedgerRequestParams : JsonRpcRequestParams + { + + } + + public class AccountLedgerRequest : JsonRpcRequest + { + public AccountLedgerRequest() : base("AccountLedger") { } + } + + public abstract class AbstractNotificationResponse + { + + } + + public abstract class AbstractNotificationRequestData + { + /// + /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the request. + /// + /// 9594811343 + [JsonProperty("orderid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string OrderID { get; set; } + /// + /// Your unique ID of the transaction. + /// + /// 12345678 + [JsonProperty("messageid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string MessageID { get; set; } + /// + /// Unique ID for this notification. Each notification must only be handled once in your system. + /// + [JsonProperty("notificationid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string NotificationID { get; set; } + } + + public class PayoutFailedNotificationData : AbstractNotificationRequestData + { + /// 98.02 + [JsonProperty("amount", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public decimal Amount { get; set; } + /// + /// The ISO 4217 code of the currency. See documentation + /// + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK + [JsonProperty("currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Currency { get; set; } + /// + /// ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + /// Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + /// + [JsonProperty("enduserid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string EndUserID { get; set; } + /// + /// The time of the transaction and the GMT offset (+01 means GMT + 1 hours). + /// + /// 2014-01-30 13:28:45.652299+01 + /// 2014-03-31 11:50:06.46106+00 + [JsonProperty("timestamp", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Timestamp { get; set; } + /// + /// Short code of the error + /// + /// incorrect_account_number + [JsonProperty("errorcode")] + public string Errorcode { get; set; } + /// + /// Description of the error + /// + /// Format of the account number specified is not correct + [JsonProperty("errormessage")] + public string Errormessage { get; set; } + [JsonProperty("attributes")] + public AnyAttributes Attributes { get; set; } + } + + public class PayoutFailedNotificationParams : JsonRpcNotificationParams + { + + } + + public class PayoutFailedNotification : JsonRpcNotification + { + public PayoutFailedNotification() : base("payoutfailed") { } + } + + public class PayoutConfirmationNotificationData : AbstractNotificationRequestData + { + /// 98.02 + [JsonProperty("amount", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public decimal Amount { get; set; } + /// + /// The ISO 4217 code of the currency. See documentation + /// + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK + [JsonProperty("currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Currency { get; set; } + /// + /// ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + /// Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + /// + [JsonProperty("enduserid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string EndUserID { get; set; } + /// + /// The time of the transaction and the GMT offset (+01 means GMT + 1 hours). + /// + /// 2014-01-30 13:28:45.652299+01 + /// 2014-03-31 11:50:06.46106+00 + [JsonProperty("timestamp", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Timestamp { get; set; } + [JsonProperty("attributes")] + public AnyAttributes Attributes { get; set; } + } + + public class PayoutConfirmationNotificationParams : JsonRpcNotificationParams + { + + } + + public class PayoutConfirmationNotification : JsonRpcNotification + { + public PayoutConfirmationNotification() : base("payoutconfirmation") { } + } + + public abstract class AbstractPendingNotificationData : AbstractNotificationRequestData + { + /// 98.02 + [JsonProperty("amount", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public decimal Amount { get; set; } + /// + /// The ISO 4217 code of the currency. See documentation + /// + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK + [JsonProperty("currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Currency { get; set; } + /// + /// The time of the transaction and the GMT offset (+01 means GMT + 1 hours). + /// + /// 2014-01-30 13:28:45.652299+01 + /// 2014-03-31 11:50:06.46106+00 + [JsonProperty("timestamp", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Timestamp { get; set; } + [JsonProperty("attributes")] + public AnyAttributes Attributes { get; set; } + } + + public class PendingRefundDirectDebitNotificationData : AbstractPendingNotificationData + { + /// + /// ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + /// Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + /// + [JsonProperty("enduserid")] + public string EndUserID { get; set; } + /// + /// Flag indicating that this is for Direct Debit refund. Note that this flag is not sent unless it's for a refund. Only value will be 1. + /// + [JsonProperty("refund")] + public string Refund { get; } = "1"; + } + + public class PendingRefundDirectDebitNotificationParams : JsonRpcNotificationParams + { + + } + + public class PendingRefundDirectDebitNotification : JsonRpcNotification + { + public PendingRefundDirectDebitNotification() : base("pending") { } + } + + public class PendingDirectPaymentBatchNotificationData : AbstractPendingNotificationData + { + + } + + public class PendingDirectPaymentBatchNotificationParams : JsonRpcNotificationParams + { + + } + + public class PendingDirectPaymentBatchNotification : JsonRpcNotification + { + public PendingDirectPaymentBatchNotification() : base("pending") { } + } + + public class PendingDirectDebitNotificationData : AbstractPendingNotificationData + { + /// + /// ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + /// Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + /// + [JsonProperty("enduserid")] + public string EndUserID { get; set; } + /// + /// The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + /// + /// 1234567890 + /// 7653385737 + [JsonProperty("accountid")] + public string AccountID { get; set; } + /// + /// The expected payment date for the debit. Note that this gives you an indication if the paymentDate you submitted has been adjusted eg due to a bank holiday. + /// + [JsonProperty("paymentdate")] + public string Paymentdate { get; set; } + } + + public class PendingDirectDebitNotificationParams : JsonRpcNotificationParams + { + + } + + public class PendingDirectDebitNotification : JsonRpcNotification + { + public PendingDirectDebitNotification() : base("pending") { } + } + + public class PendingDirectCreditNotificationData : AbstractPendingNotificationData + { + /// + /// ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + /// Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + /// + [JsonProperty("enduserid")] + public string EndUserID { get; set; } + } + + public class PendingDirectCreditNotificationParams : JsonRpcNotificationParams + { + + } + + public class PendingDirectCreditNotification : JsonRpcNotification + { + public PendingDirectCreditNotification() : base("pending") { } + } + + public class PendingDefaultNotificationData : AbstractPendingNotificationData + { + /// + /// ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + /// Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + /// + [JsonProperty("enduserid")] + public string EndUserID { get; set; } + } + + public class PendingNotificationData + { + private PendingDefaultNotificationData _pendingDefaultNotificationData; + private PendingDirectDebitNotificationData _pendingDirectDebitNotificationData; + private PendingDirectCreditNotificationData _pendingDirectCreditNotificationData; + private PendingRefundDirectDebitNotificationData _pendingRefundDirectDebitNotificationData; + private PendingDirectPaymentBatchNotificationData _pendingDirectPaymentBatchNotificationData; + + public PendingNotificationData(dynamic raw) + { + this.Raw = raw; + } + + public PendingDefaultNotificationData GetPendingDefaultNotificationData(Func transformer) + { + if (this._pendingDefaultNotificationData != null) + { + return this._pendingDefaultNotificationData; + } + return this._pendingDefaultNotificationData = transformer(this.Raw); + } + + public PendingDirectDebitNotificationData GetPendingDirectDebitNotificationData(Func transformer) + { + if (this._pendingDirectDebitNotificationData != null) + { + return this._pendingDirectDebitNotificationData; + } + return this._pendingDirectDebitNotificationData = transformer(this.Raw); + } + + public PendingDirectCreditNotificationData GetPendingDirectCreditNotificationData(Func transformer) + { + if (this._pendingDirectCreditNotificationData != null) + { + return this._pendingDirectCreditNotificationData; + } + return this._pendingDirectCreditNotificationData = transformer(this.Raw); + } + + public PendingRefundDirectDebitNotificationData GetPendingRefundDirectDebitNotificationData(Func transformer) + { + if (this._pendingRefundDirectDebitNotificationData != null) + { + return this._pendingRefundDirectDebitNotificationData; + } + return this._pendingRefundDirectDebitNotificationData = transformer(this.Raw); + } + + public PendingDirectPaymentBatchNotificationData GetPendingDirectPaymentBatchNotificationData(Func transformer) + { + if (this._pendingDirectPaymentBatchNotificationData != null) + { + return this._pendingDirectPaymentBatchNotificationData; + } + return this._pendingDirectPaymentBatchNotificationData = transformer(this.Raw); + } + + public dynamic Raw { get; set; } + } + + public class PendingNotificationParams : JsonRpcNotificationParams + { + + } + + public class PendingNotification : JsonRpcNotification + { + public PendingNotification() : base("pending") { } + } + + public abstract class AbstractNotificationRequest + { + [JsonProperty("method")] + public string Method { get; set; } + } + + public class AbstractKYCNotificationData : AbstractNotificationRequestData + { + /// + /// Trustly generated unique identifier based on player’s bank account profile*. + /// Can be used as an identifier when personid is not available. + /// + /// ***The identifier may change, hence our suggestion is to have a logic that does not include KYCEntityID + /// + /// 29a750aa-0bad-4a28-a42d-ffb9a690d93a + [JsonProperty("kycentityid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Kycentityid { get; set; } + [JsonProperty("attributes")] + public KYCNotificationDataAttributes Attributes { get; set; } + } + + public class KYCDefaultNotificationData : AbstractKYCNotificationData + { + + } + + public class KYCAbortNotificationData : AbstractKYCNotificationData + { + [JsonProperty("abort", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public StringBoolean? Abort { get; set; } + /// unverified + /// underage + [JsonProperty("abortmessage", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Abortmessage { get; set; } + } + + public class KYCNotificationData + { + private KYCDefaultNotificationData _kycDefaultNotificationData; + private KYCAbortNotificationData _kycAbortNotificationData; + + public KYCNotificationData(dynamic raw) + { + this.Raw = raw; + } + + public KYCDefaultNotificationData GetKycDefaultNotificationData(Func transformer) + { + if (this._kycDefaultNotificationData != null) + { + return this._kycDefaultNotificationData; + } + return this._kycDefaultNotificationData = transformer(this.Raw); + } + + public KYCAbortNotificationData GetKycAbortNotificationData(Func transformer) + { + if (this._kycAbortNotificationData != null) + { + return this._kycAbortNotificationData; + } + return this._kycAbortNotificationData = transformer(this.Raw); + } + + public dynamic Raw { get; set; } + } + + public class KYCNotificationParams : JsonRpcNotificationParams + { + + } + + public class KYCNotification : JsonRpcNotification + { + public KYCNotification() : base("kyc") { } + } + + public class AbstractDebitNotificationData : AbstractNotificationRequestData + where T : AbstractRequestDataAttributes + { + /// BGN: 100.00 + /// CZK: 100.00 + /// DKK: 100.00 + /// EUR: 100.00 + /// GBP: 100.00 + /// HRK: 100.00 + /// HUF: 100 + /// NOK: 100.00 + /// PLN: 100.00 + /// RON: 100.00 + /// SEK: 100.00 + [JsonProperty("amount", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Amount { get; set; } + /// + /// The ISO 4217 code of the currency. See documentation + /// + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK + [JsonProperty("currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Currency { get; set; } + /// + /// ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + /// Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + /// + [JsonProperty("enduserid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string EndUserID { get; set; } + /// + /// The time of the transaction and the GMT offset (+01 means GMT + 1 hours). + /// + /// 2014-01-30 13:28:45.652299+01 + /// 2014-03-31 11:50:06.46106+00 + [JsonProperty("timestamp", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string Timestamp { get; set; } + [JsonExtensionData] + public JObject AdditionalProperties { get; set; } + [JsonProperty("attributes")] + public T Attributes { get; set; } + } + + public class DebitRefundDirectDebitNotificationData : AbstractDebitNotificationData + { + /// + /// Flag indicating that this is for Direct Debit refund. Note that this flag is not sent unless it's for a refund. Only value will be 1. + /// + [JsonProperty("refund")] + public string Refund { get; } = "1"; + } + + public class DebitRefundDirectDebitNotificationParams : JsonRpcNotificationParams + { + + } + + public class DebitRefundDirectDebitNotification : JsonRpcNotification + { + public DebitRefundDirectDebitNotification() : base("debit") { } + } + + public class DebitDirectDebitNotificationData : AbstractDebitNotificationData + { + + } + + public class DebitDirectDebitNotificationParams : JsonRpcNotificationParams + { + + } + + public class DebitDirectDebitNotification : JsonRpcNotification + { + public DebitDirectDebitNotification() : base("debit") { } + } + + public class DebitDirectCreditNotificationData : AbstractDebitNotificationData + { + + } + + public class DebitDirectCreditNotificationParams : JsonRpcNotificationParams + { + + } + + public class DebitDirectCreditNotification : JsonRpcNotification + { + public DebitDirectCreditNotification() : base("debit") { } + } + + public class DebitDefaultNotificationData : AbstractDebitNotificationData + { + + } + + public class DebitNotificationData + { + private DebitDefaultNotificationData _debitDefaultNotificationData; + private DebitDirectDebitNotificationData _debitDirectDebitNotificationData; + private DebitDirectCreditNotificationData _debitDirectCreditNotificationData; + private DebitRefundDirectDebitNotificationData _debitRefundDirectDebitNotificationData; + + public DebitNotificationData(dynamic raw) + { + this.Raw = raw; + } + + public DebitDefaultNotificationData GetDebitDefaultNotificationData(Func transformer) + { + if (this._debitDefaultNotificationData != null) + { + return this._debitDefaultNotificationData; + } + return this._debitDefaultNotificationData = transformer(this.Raw); + } + + public DebitDirectDebitNotificationData GetDebitDirectDebitNotificationData(Func transformer) + { + if (this._debitDirectDebitNotificationData != null) + { + return this._debitDirectDebitNotificationData; + } + return this._debitDirectDebitNotificationData = transformer(this.Raw); + } + + public DebitDirectCreditNotificationData GetDebitDirectCreditNotificationData(Func transformer) + { + if (this._debitDirectCreditNotificationData != null) + { + return this._debitDirectCreditNotificationData; + } + return this._debitDirectCreditNotificationData = transformer(this.Raw); + } + + public DebitRefundDirectDebitNotificationData GetDebitRefundDirectDebitNotificationData(Func transformer) + { + if (this._debitRefundDirectDebitNotificationData != null) + { + return this._debitRefundDirectDebitNotificationData; + } + return this._debitRefundDirectDebitNotificationData = transformer(this.Raw); + } + + public dynamic Raw { get; set; } + } + + public class DebitNotificationParams : JsonRpcNotificationParams + { + + } + + public class DebitNotification : JsonRpcNotification + { + public DebitNotification() : base("debit") { } + } + + public class AbstractCreditNotificationDataAttributes : AbstractRequestDataAttributes + { + + } + + public class CreditSwishNotificationDataAttributes : AbstractCreditNotificationDataAttributes + { + /// + /// Payment reference, from the bank, of the payment that occurred based on the Payment request. Only available if status is PAID. + /// + /// 1E2FC19E5E5E4E18916609B7F8911C12 + /// TRLY80494-1001 + [JsonProperty("reference")] + public string Reference { get; set; } + /// + /// Payment reference, from the bank, of the payment that occurred based on the Payment request. Only available if status is PAID. + /// + /// 467123476 + [JsonProperty("payerAlias")] + public string PayerAlias { get; set; } + } + + public class CreditRefundDirectDebitNotificationDataAttributes : AbstractCreditNotificationDataAttributes + { + /// + /// Payment reference, from the bank, of the payment that occurred based on the Payment request. Only available if status is PAID. + /// + /// 1E2FC19E5E5E4E18916609B7F8911C12 + /// TRLY80494-1001 + [JsonProperty("reference")] + public string Reference { get; set; } + /// + /// Statement that appear on the end users bank account + /// + /// TRLY80494-1001 + [JsonProperty("statement")] + public string Statement { get; set; } + [JsonProperty("reason")] + public CreditRefundDirectDebitCancelReason? Reason { get; set; } + /// + /// Description of reason. If Direct Debit Mandate, then this applies when reason is FAILED: BACS ADDACS_1(INSTRUCTION CANCELLED BY PAYER). See https://eu.developers.trustly.com/doc/reference/mdd#description-of-details-eg-failure-details + /// + [JsonProperty("details")] + public string Details { get; set; } + } + + public class CreditDirectDebitNotificationDataAttributes : AbstractCreditNotificationDataAttributes + { + /// + /// Payment reference, from the bank, of the payment that occurred based on the Payment request. Only available if status is PAID. + /// + /// 1E2FC19E5E5E4E18916609B7F8911C12 + /// TRLY80494-1001 + [JsonProperty("reference")] + public string Reference { get; set; } + /// + /// Statement that appear on the end users bank account + /// + /// TRLY80494-1001 + [JsonProperty("statement")] + public string Statement { get; set; } + } + + public class CreditDirectCreditNotificationDataAttributes : AbstractCreditNotificationDataAttributes + { + /// + /// Payment reference, from the bank, of the payment that occurred based on the Payment request. Only available if status is PAID. + /// + /// 1E2FC19E5E5E4E18916609B7F8911C12 + /// TRLY80494-1001 + [JsonProperty("reference")] + public string Reference { get; set; } + /// + /// Statement that appear on the end users bank account + /// + /// TRLY80494-1001 + [JsonProperty("statement")] + public string Statement { get; set; } + } + + public class CreditDefaultNotificationDataAttributes : AbstractCreditNotificationDataAttributes + { + + } + + public class AbstractCreditNotificationData : AbstractNotificationRequestData + where T : AbstractRequestDataAttributes + { + /// + /// ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + /// Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + /// + [JsonProperty("enduserid")] + public string EndUserID { get; set; } + /// 98.02 + [JsonProperty("amount")] + public decimal Amount { get; set; } + /// + /// The ISO 4217 code of the currency. See documentation + /// + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK + [JsonProperty("currency")] + public string Currency { get; set; } + /// + /// The time of the transaction and the GMT offset (+01 means GMT + 1 hours). + /// + /// 2014-01-30 13:28:45.652299+01 + /// 2014-03-31 11:50:06.46106+00 + [JsonProperty("timestamp")] + public string Timestamp { get; set; } + [JsonProperty("attributes")] + public T Attributes { get; set; } + } + + public class CreditSwishNotificationData : AbstractCreditNotificationData + { + + } + + public class CreditSwishNotificationParams : JsonRpcNotificationParams + { + + } + + public class CreditSwishNotification : JsonRpcNotification + { + public CreditSwishNotification() : base("credit") { } + } + + public class CreditRefundDirectDebitNotificationData : AbstractCreditNotificationData + { + /// + /// Flag indicating that this is for Direct Debit refund. Note that this flag is not sent unless it's for a refund. Only value will be 1. + /// + [JsonProperty("refund")] + public string Refund { get; } = "1"; + } + + public class CreditRefundDirectDebitNotificationParams : JsonRpcNotificationParams + { + + } + + public class CreditRefundDirectDebitNotification : JsonRpcNotification + { + public CreditRefundDirectDebitNotification() : base("credit") { } + } + + public class CreditDirectDebitNotificationData : AbstractCreditNotificationData + { + /// + /// The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + /// + /// 1234567890 + /// 7653385737 + [JsonProperty("accountid")] + public string AccountID { get; set; } + } + + public class CreditDirectDebitNotificationParams : JsonRpcNotificationParams + { + + } + + public class CreditDirectDebitNotification : JsonRpcNotification + { + public CreditDirectDebitNotification() : base("credit") { } + } + + public class CreditDirectCreditNotificationData : AbstractCreditNotificationData + { + + } + + public class CreditDirectCreditNotificationParams : JsonRpcNotificationParams + { + + } + + public class CreditDirectCreditNotification : JsonRpcNotification + { + public CreditDirectCreditNotification() : base("credit") { } + } + + public class CreditDefaultNotificationData : AbstractCreditNotificationData + { + + } + + public class CreditNotificationData + { + private CreditDefaultNotificationData _creditDefaultNotificationData; + private CreditDirectDebitNotificationData _creditDirectDebitNotificationData; + private CreditDirectCreditNotificationData _creditDirectCreditNotificationData; + private CreditRefundDirectDebitNotificationData _creditRefundDirectDebitNotificationData; + private CreditSwishNotificationData _creditSwishNotificationData; + + public CreditNotificationData(dynamic raw) + { + this.Raw = raw; + } + + public CreditDefaultNotificationData GetCreditDefaultNotificationData(Func transformer) + { + if (this._creditDefaultNotificationData != null) + { + return this._creditDefaultNotificationData; + } + return this._creditDefaultNotificationData = transformer(this.Raw); + } + + public CreditDirectDebitNotificationData GetCreditDirectDebitNotificationData(Func transformer) + { + if (this._creditDirectDebitNotificationData != null) + { + return this._creditDirectDebitNotificationData; + } + return this._creditDirectDebitNotificationData = transformer(this.Raw); + } + + public CreditDirectCreditNotificationData GetCreditDirectCreditNotificationData(Func transformer) + { + if (this._creditDirectCreditNotificationData != null) + { + return this._creditDirectCreditNotificationData; + } + return this._creditDirectCreditNotificationData = transformer(this.Raw); + } + + public CreditRefundDirectDebitNotificationData GetCreditRefundDirectDebitNotificationData(Func transformer) + { + if (this._creditRefundDirectDebitNotificationData != null) + { + return this._creditRefundDirectDebitNotificationData; + } + return this._creditRefundDirectDebitNotificationData = transformer(this.Raw); + } + + public CreditSwishNotificationData GetCreditSwishNotificationData(Func transformer) + { + if (this._creditSwishNotificationData != null) + { + return this._creditSwishNotificationData; + } + return this._creditSwishNotificationData = transformer(this.Raw); + } + + public dynamic Raw { get; set; } + } + + public class CreditNotificationParams : JsonRpcNotificationParams + { + + } + + public class CreditNotification : JsonRpcNotification + { + public CreditNotification() : base("credit") { } + } + + public class AbstractCancelNotificationData : AbstractNotificationRequestData + where T : AbstractRequestDataAttributes + { + [JsonProperty("attributes")] + public T Attributes { get; set; } + } + + public class CancelSwishNotificationData : AbstractCancelNotificationData + { + /// + /// The time of the transaction and the GMT offset (+01 means GMT + 1 hours). + /// + /// 2014-01-30 13:28:45.652299+01 + /// 2014-03-31 11:50:06.46106+00 + [JsonProperty("timestamp")] + public string Timestamp { get; set; } + } + + public class CancelSwishNotificationParams : JsonRpcNotificationParams + { + + } + + public class CancelSwishNotification : JsonRpcNotification + { + public CancelSwishNotification() : base("cancel") { } + } + + public class CancelRefundDirectDebitNotificationData : AbstractCancelNotificationData + { + /// + /// Flag indicating that this is for Direct Debit refund. Note that this flag is not sent unless it's for a refund. Only value will be 1. + /// + [JsonProperty("refund")] + public string Refund { get; } = "1"; + } + + public class CancelRefundDirectDebitNotificationParams : JsonRpcNotificationParams + { + + } + + public class CancelRefundDirectDebitNotification : JsonRpcNotification + { + public CancelRefundDirectDebitNotification() : base("cancel") { } + } + + public class CancelMandateNotificationData : AbstractCancelNotificationData + { + + } + + public class CancelMandateNotificationParams : JsonRpcNotificationParams + { + + } + + public class CancelMandateNotification : JsonRpcNotification + { + public CancelMandateNotification() : base("cancel") { } + } + + public class CancelDirectPaymentBatchNotificationData : AbstractCancelNotificationData + { + + } + + public class CancelDirectPaymentBatchNotificationParams : JsonRpcNotificationParams + { + + } + + public class CancelDirectPaymentBatchNotification : JsonRpcNotification + { + public CancelDirectPaymentBatchNotification() : base("cancel") { } + } + + public class CancelDirectDebitNotificationData : AbstractCancelNotificationData + { + + } + + public class CancelDirectDebitNotificationParams : JsonRpcNotificationParams + { + + } + + public class CancelDirectDebitNotification : JsonRpcNotification + { + public CancelDirectDebitNotification() : base("cancel") { } + } + + public class CancelDirectCreditNotificationData : AbstractCancelNotificationData + { + + } + + public class CancelDirectCreditNotificationParams : JsonRpcNotificationParams + { + + } + + public class CancelDirectCreditNotification : JsonRpcNotification + { + public CancelDirectCreditNotification() : base("cancel") { } + } + + public class CancelDefaultNotificationData : AbstractCancelNotificationData + { + /// + /// ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + /// Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + /// + [JsonProperty("enduserid")] + public string EndUserID { get; set; } + /// + /// The time of the transaction and the GMT offset (+01 means GMT + 1 hours). + /// + /// 2014-01-30 13:28:45.652299+01 + /// 2014-03-31 11:50:06.46106+00 + [JsonProperty("timestamp")] + public string Timestamp { get; set; } + } + + public class CancelNotificationData + { + private CancelDefaultNotificationData _cancelDefaultNotificationData; + private CancelSwishNotificationData _cancelSwishNotificationData; + private CancelDirectDebitNotificationData _cancelDirectDebitNotificationData; + private CancelDirectCreditNotificationData _cancelDirectCreditNotificationData; + private CancelRefundDirectDebitNotificationData _cancelRefundDirectDebitNotificationData; + private CancelMandateNotificationData _cancelMandateNotificationData; + private CancelDirectPaymentBatchNotificationData _cancelDirectPaymentBatchNotificationData; + + public CancelNotificationData(dynamic raw) + { + this.Raw = raw; + } + + public CancelDefaultNotificationData GetCancelDefaultNotificationData(Func transformer) + { + if (this._cancelDefaultNotificationData != null) + { + return this._cancelDefaultNotificationData; + } + return this._cancelDefaultNotificationData = transformer(this.Raw); + } + + public CancelSwishNotificationData GetCancelSwishNotificationData(Func transformer) + { + if (this._cancelSwishNotificationData != null) + { + return this._cancelSwishNotificationData; + } + return this._cancelSwishNotificationData = transformer(this.Raw); + } + + public CancelDirectDebitNotificationData GetCancelDirectDebitNotificationData(Func transformer) + { + if (this._cancelDirectDebitNotificationData != null) + { + return this._cancelDirectDebitNotificationData; + } + return this._cancelDirectDebitNotificationData = transformer(this.Raw); + } + + public CancelDirectCreditNotificationData GetCancelDirectCreditNotificationData(Func transformer) + { + if (this._cancelDirectCreditNotificationData != null) + { + return this._cancelDirectCreditNotificationData; + } + return this._cancelDirectCreditNotificationData = transformer(this.Raw); + } + + public CancelRefundDirectDebitNotificationData GetCancelRefundDirectDebitNotificationData(Func transformer) + { + if (this._cancelRefundDirectDebitNotificationData != null) + { + return this._cancelRefundDirectDebitNotificationData; + } + return this._cancelRefundDirectDebitNotificationData = transformer(this.Raw); + } + + public CancelMandateNotificationData GetCancelMandateNotificationData(Func transformer) + { + if (this._cancelMandateNotificationData != null) + { + return this._cancelMandateNotificationData; + } + return this._cancelMandateNotificationData = transformer(this.Raw); + } + + public CancelDirectPaymentBatchNotificationData GetCancelDirectPaymentBatchNotificationData(Func transformer) + { + if (this._cancelDirectPaymentBatchNotificationData != null) + { + return this._cancelDirectPaymentBatchNotificationData; + } + return this._cancelDirectPaymentBatchNotificationData = transformer(this.Raw); + } + + public dynamic Raw { get; set; } + } + + public class CancelNotificationParams : JsonRpcNotificationParams + { + + } + + public class CancelNotification : JsonRpcNotification + { + public CancelNotification() : base("cancel") { } + } + + public class AbstractAccountNotificationDataAttributes : AbstractRequestDataAttributes + { + /// + /// The clearing house of the end-user's bank account. Typically the name of a country in uppercase letters. See examples or table at https://developers.trustly.com/emea/docs/registeraccount. + /// + /// AUSTRIA + /// BELGIUM + /// BULGARIA + /// CROATIA + /// CYPRUS + /// CZECH_REPUBLIC + /// DENMARK + /// ESTONIA + /// FINLAND + /// FRANCE + /// GERMANY + /// GREECE + /// HUNGARY + /// IRELAND + /// ITALY + /// LATVIA + /// LITHUANIA + /// LUXEMBOURG + /// MALTA + /// NETHERLANDS + /// NORWAY + /// POLAND + /// PORTUGAL + /// ROMANIA + /// SLOVAKIA + /// SLOVENIA + /// SPAIN + /// SWEDEN + /// UNITED_KINGDOM + [JsonProperty("clearinghouse")] + public string ClearingHouse { get; set; } + /// + /// The bank for this account + /// + /// SEB + /// Skandiabanken + [JsonProperty("bank")] + public string Bank { get; set; } + /// + /// A text that is safe to show the enduser for identifying the account. Do not parse this text since it will be a different format for different accounts. + /// + /// ***4057 + [JsonProperty("descriptor")] + public string Descriptor { get; set; } + /// + /// The last digits of the bank account number.This can be used for matching against received KYC data from your manual routines. + /// + [JsonProperty("lastdigits")] + public string Lastdigits { get; set; } + /// + /// An ID that uniquely identifies the account holder. Only present in markets where SSN is applicable. Note: The format of this field will for some countries look different than the example. + /// + /// SE198201019876 + /// 19900501 + [JsonProperty("personid")] + public string PersonID { get; set; } + /// + /// The name of the account holder + /// + /// John Doe + [JsonProperty("name")] + public string Name { get; set; } + /// + /// The address of the account holder + /// + [JsonProperty("address")] + public string Address { get; set; } + /// + /// The zipcode of the account holder + /// + /// 12345 + [JsonProperty("zipcode")] + public string Zipcode { get; set; } + /// + /// The city of the account holder + /// + /// Examplecity + [JsonProperty("city")] + public string City { get; set; } + } + + public class AccountMandateNotificationDataAttributes : AbstractAccountNotificationDataAttributes + { + /// + /// Whether the direct debit mandate is active or not, 1 for active, 0 for non-active. + /// + [JsonProperty("directdebitmandate")] + public NumberBoolean? DirectDebitMandate { get; set; } + /// + /// The ISO 3166-1-alpha-2 code of the end-user's country. This will be used for pre-selecting the country for the end-user in the iframe. + /// Note: This will only have an effect for new end-users. If an end-user has done a previous order (with the same EndUserID), the country that was last used will be pre-selected. + /// + [JsonProperty("country")] + public string Country { get; set; } + /// + /// The bank number identifying the end-user's bank in the given clearing house. For bank accounts in IBAN format you should just provide an empty string (""). For non-IBAN format, see examples. The BankNumber for Swedish bank accounts should be the local "clearing number", and the AccountNumber parameter should contain the rest of the account number. Most Swedish banks have a 4-digit clearing number, but a 5-digit clearing number is used for Swedbank accounts when the clearing number starts with "8". Nordea accounts where the account number is the same as the person's national identification number always has "3300" as the clearing number. + /// + /// IBAN for Swedish bank accounts is supported upon request. When making API calls with Swedish IBAN, ensure to include the Clearinghouse attribute as "IBAN" instead of "SWEDEN". See more at https://developers.trustly.com/emea/docs/registeraccount + /// + /// Sweden: ^[0-9]{4,5}$ + /// United Kingdom: ^[0-9]{6}$ + [JsonProperty("bankcode")] + public string Bankcode { get; set; } + /// + /// Name of the account + /// + /// Salary account + [JsonProperty("accountname")] + public string Accountname { get; set; } + [JsonProperty("accountholders")] + public IList Accountholders { get; set; } + /// + /// The branch identifier + /// + /// 6160 + /// 6000 + /// bg + /// 123123 + /// HANDSESS + [JsonProperty("bankidentifier")] + public string Bankidentifier { get; set; } + /// + /// The account number, identifying the end-user's account in the bank. Can be either IBAN or country-specific format, see examples or read more at https://developers.trustly.com/emea/docs/registeraccount + /// + /// 6112 + /// 391124057 + /// AUSTRIA: ^AT[0-9]{18}$ + /// BELGIUM: ^BE[0-9]{14}$ + /// BULGARIA: ^BG[0-9]{2}[A-Z]{4}[0-9]{4}[0-9]{2}[A-Z0-9]{8}$ + /// CROATIA: ^HR[0-9]{2}[0-9]{7}[0-9]{10}$ + /// CYPRUS: ^CY[0-9]{10}[0-9A-Z]{16}$ + /// CZECH_REPUBLIC: ^CZ[0-9]{22}$ + /// DENMARK: ^DK[0-9]{16}$ + /// ESTONIA: ^EE[0-9]{18}$ + /// FINLAND: ^FI[0-9]{16}$ + /// FRANCE: ^FR[0-9]{12}[0-9A-Z]{11}[0-9]{2}$ + /// GERMANY: ^DE[0-9]{20}$ + /// GREECE: ^GR[0-9]{25}$ + /// HUNGARY: ^HU[0-9]{26}$ + /// IRELAND: ^IE[0-9]{2}[A-Z]{4}[0-9]{14}$ + /// ITALY: ^IT[0-9]{2}[A-Z][0-9]{10}[0-9A-Z]{12}$ + /// LATVIA: ^LV[0-9]{2}[A-Z]{4}[0-9A-Z]{13}$ + /// LITHUANIA: ^LT[0-9]{18}$ + /// LUXEMBOURG: ^LU[0-9]{18}$ + /// MALTA: ^MT[0-9]{2}[A-Z]{4}[0-9]{5}[0-9A-Z]{18}$ + /// NETHERLANDS: ^NL[0-9]{2}[A-Z]{4}[0-9]{10}$ + /// NORWAY: ^NO[0-9]{13}$ + /// POLAND: ^PL[0-9]{26}$ + /// PORTUGAL: ^PT[0-9]{23}$ + /// ROMANIA: ^RO[0-9]{2}[A-Z]{4}[0-9A-Z]{16}$ + /// SLOVAKIA: ^SK[0-9]{22}$ + /// SLOVENIA: ^SI56[0-9]{15}$ + /// SPAIN: ^ES[0-9]{22}$ + /// SWEDEN:* [0-9]{1,15}$ + /// UNITED_KINGDOM: ^[0-9]{8}$ + [JsonProperty("accountnumber")] + public string Accountnumber { get; set; } + [JsonProperty("accountsource")] + public MandateAccountSource? Accountsource { get; set; } + } + + public class AccountDefaultNotificationDataAttributes : AbstractAccountNotificationDataAttributes + { + + } + + public class AbstractAccountNotificationData : AbstractNotificationRequestData + where T : AbstractRequestDataAttributes + { + /// + /// The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + /// + /// 1234567890 + /// 7653385737 + [JsonProperty("accountid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string AccountID { get; set; } + /// + /// Whether the account is verified or not. 0 for not verified, 1 for verified. + /// + [JsonProperty("verified", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public StringBoolean? Verified { get; set; } + [JsonProperty("attributes")] + public T Attributes { get; set; } + } + + public class AccountMandateNotificationData : AbstractAccountNotificationData + { + + } + + public class AccountMandateNotificationParams : JsonRpcNotificationParams + { + + } + + public class AccountMandateNotification : JsonRpcNotification + { + public AccountMandateNotification() : base("account") { } + } + + public class AccountDefaultNotificationData : AbstractAccountNotificationData + { + + } + + public class AccountNotificationData + { + private AccountDefaultNotificationData _accountDefaultNotificationData; + private AccountMandateNotificationData _accountMandateNotificationData; + + public AccountNotificationData(dynamic raw) + { + this.Raw = raw; + } + + public AccountDefaultNotificationData GetAccountDefaultNotificationData(Func transformer) + { + if (this._accountDefaultNotificationData != null) + { + return this._accountDefaultNotificationData; + } + return this._accountDefaultNotificationData = transformer(this.Raw); + } + + public AccountMandateNotificationData GetAccountMandateNotificationData(Func transformer) + { + if (this._accountMandateNotificationData != null) + { + return this._accountMandateNotificationData; + } + return this._accountMandateNotificationData = transformer(this.Raw); + } + + public dynamic Raw { get; set; } + } + + public class AccountNotificationParams : JsonRpcNotificationParams + { + + } + + public class AccountNotification : JsonRpcNotification + { + public AccountNotification() : base("account") { } + } + + public class AccountDefaultNotificationParams : JsonRpcNotificationParams + { + + } + + public class AccountDefaultNotification : JsonRpcNotification + { + public AccountDefaultNotification() : base("account") { } + } +} diff --git a/src/Domain/Domain.csproj b/src/Domain/Domain.csproj index db2c418..a756995 100644 --- a/src/Domain/Domain.csproj +++ b/src/Domain/Domain.csproj @@ -17,14 +17,13 @@ + - - diff --git a/src/Domain/Exceptions/AbstractTrustlyApiException.cs b/src/Domain/Exceptions/AbstractTrustlyApiException.cs index 37018d3..7f31b12 100644 --- a/src/Domain/Exceptions/AbstractTrustlyApiException.cs +++ b/src/Domain/Exceptions/AbstractTrustlyApiException.cs @@ -1,5 +1,4 @@ using System; -using Trustly.Api.Domain.Base; namespace Trustly.Api.Domain.Exceptions { @@ -8,6 +7,6 @@ public abstract class AbstractTrustlyApiException : Exception public AbstractTrustlyApiException(string message) : base(message) { } public AbstractTrustlyApiException(string message, Exception cause) : base(message, cause) { } - public ResponseError ResponseError { get; set; } + public JsonRpcError ResponseError { get; set; } } } diff --git a/src/Domain/Exceptions/TrustlyNoNotificationClientException.cs b/src/Domain/Exceptions/TrustlyNoNotificationClientException.cs deleted file mode 100644 index b3fe3e7..0000000 --- a/src/Domain/Exceptions/TrustlyNoNotificationClientException.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; - -namespace Trustly.Api.Domain.Exceptions -{ - public class TrustlyNoNotificationClientException : AbstractTrustlyApiException - { - public TrustlyNoNotificationClientException(string message) : base(message) { } - public TrustlyNoNotificationClientException(string message, Exception cause) : base(message, cause) { } - } -} diff --git a/src/Domain/Notifications/AbstractCredDebitPending.cs b/src/Domain/Notifications/AbstractCredDebitPending.cs deleted file mode 100644 index e96102e..0000000 --- a/src/Domain/Notifications/AbstractCredDebitPending.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using Newtonsoft.Json; -using Trustly.Api.Domain.Base; - -namespace Trustly.Api.Domain.Notifications -{ - public class AbstractCreditDebitPendingPayoutNotificationData : AbstractFromTrustlyRequestParamsData - { - [JsonProperty("amount")] - public string Amount { get; set; } - - [JsonProperty("currency")] - public string Currency { get; set; } - - [JsonProperty("messageid")] - public string MessageID { get; set; } - - [JsonProperty("orderid")] - public string OrderID { get; set; } - - [JsonProperty("enduserid")] - public string EnduserID { get; set; } - - [JsonProperty("notificationid")] - public string NotificationID { get; set; } - - [JsonProperty("timestamp")] - public string Timestamp { get; set; } - } -} diff --git a/src/Domain/Notifications/Account.cs b/src/Domain/Notifications/Account.cs deleted file mode 100644 index 8b4363b..0000000 --- a/src/Domain/Notifications/Account.cs +++ /dev/null @@ -1,86 +0,0 @@ -using Newtonsoft.Json; -using Trustly.Api.Domain.Base; - -namespace Trustly.Api.Domain.Notifications -{ - public class AccountNotificationData : AbstractFromTrustlyRequestParamsData - { - [JsonProperty("messageid")] - public string MessageID { get; set; } - - [JsonProperty("orderid")] - public string OrderID { get; set; } - - [JsonProperty("notificationid")] - public string NotificationID { get; set; } - - [JsonProperty("accountid")] - public string AccountID { get; set; } - - [JsonProperty("verified")] - public string Verified { get; set; } - } - - public class AccountNotificationDataAttributes : AbstractRequestParamsDataAttributes - { - /// - /// The clearinghouse for this account - /// - [JsonProperty("clearinghouse")] - public string Clearinghouse { get; set; } - - /// - /// The bank for this account - /// - [JsonProperty("bank")] - public string Bank { get; set; } - - /// - /// A text that is safe to show the enduser for identifying the account.Do not parse this text since it will be a different format for different accounts. - /// - [JsonProperty("descriptor")] - public string Descriptor { get; set; } - - /// - /// The last digits of the bank account number.This can be used for matching against received KYC data from your manual routines. - /// - [JsonProperty("lastdigits")] - public string Lastdigits { get; set; } - - /// - /// An ID that uniquely identifies the account holder.Note: The format of this field will for some countries look different than the example. - /// - [JsonProperty("personid")] - public string PersonID { get; set; } - - /// - /// The name of the account holder - /// - [JsonProperty("name")] - public string Name { get; set; } - - /// - /// The address of the account holder - /// - [JsonProperty("address")] - public string Address { get; set; } - - /// - /// The zipcode of the account holder - /// - [JsonProperty("zipcode")] - public string Zipcode { get; set; } - - /// - /// The city of the account holder - /// - [JsonProperty("city")] - public string City { get; set; } - - /// - /// 1 if a direct debit mandate exists for this account, 0 otherwise - /// - [JsonProperty("directdebitmandate")] - public int? DirectDebitMandate { get; set; } - } -} diff --git a/src/Domain/Notifications/Cancel.cs b/src/Domain/Notifications/Cancel.cs deleted file mode 100644 index 7c19202..0000000 --- a/src/Domain/Notifications/Cancel.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Newtonsoft.Json; -using Trustly.Api.Domain.Base; - -namespace Trustly.Api.Domain.Notifications -{ - public class CancelNotificationData : AbstractFromTrustlyRequestParamsData - { - [JsonProperty("messageid")] - public string MessageID { get; set; } - - [JsonProperty("orderid")] - public string OrderID { get; set; } - - [JsonProperty("enduserid")] - public string EnduserID { get; set; } - - [JsonProperty("notificationid")] - public string NotificationID { get; set; } - - [JsonProperty("timestamp")] - public string Timestamp { get; set; } - } -} diff --git a/src/Domain/Notifications/Credit.cs b/src/Domain/Notifications/Credit.cs deleted file mode 100644 index 0b0d735..0000000 --- a/src/Domain/Notifications/Credit.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Newtonsoft.Json; -using Trustly.Api.Domain.Base; - -namespace Trustly.Api.Domain.Notifications -{ - public class CreditNotificationData : AbstractCreditDebitPendingPayoutNotificationData - { - } -} diff --git a/src/Domain/Notifications/Debit.cs b/src/Domain/Notifications/Debit.cs deleted file mode 100644 index 2fa1fdc..0000000 --- a/src/Domain/Notifications/Debit.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Newtonsoft.Json; -using Trustly.Api.Domain.Base; - -namespace Trustly.Api.Domain.Notifications -{ - public class DebitNotificationData : AbstractCreditDebitPendingPayoutNotificationData - { - } -} diff --git a/src/Domain/Notifications/NotificationResponse.cs b/src/Domain/Notifications/NotificationResponse.cs deleted file mode 100644 index 1e91455..0000000 --- a/src/Domain/Notifications/NotificationResponse.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using Newtonsoft.Json; -using Trustly.Api.Domain.Base; - -namespace Trustly.Api.Domain.Notifications -{ - public class NotificationResponse : AbstractResponseResultData - { - [JsonProperty("status")] - public string Status { get; set; } - } -} diff --git a/src/Domain/Notifications/PayoutConfirmation.cs b/src/Domain/Notifications/PayoutConfirmation.cs deleted file mode 100644 index 05f5e4e..0000000 --- a/src/Domain/Notifications/PayoutConfirmation.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Newtonsoft.Json; -using Trustly.Api.Domain.Base; - -namespace Trustly.Api.Domain.Notifications -{ - /// - /// This is a notification that Trustly will send to the merchant's system in order to confirm that a payout has been sent. - /// - /// This notification is not enabled by default. Please contact your Trustly integration manager in case you want to receive it. - /// - /// - /// - /// In many cases, the “payoutconfirmation” will be sent within minutes after the AccountPayout request has been received by Trustly. - /// But in some cases there will be a delay of 1 day or more, since Trustly relies on receiving statement files from banks. - /// - /// If you have sent an AccountPayout request and haven’t received a “payoutconfirmation” within an hour or so, - /// it doesn’t necessarily mean that something is wrong.If you experience this and need to know the actual status of the payout, - /// you can either use Trustly’s backoffice (Transactions > Withdrawals), or use the GetWithdrawals API method. - /// - /// If you use the GetWithdrawals method and receive status EXECUTING or EXECUTED, - /// it means that the withdrawal is currently being processed or has been processed, but is not confirmed yet. - /// - /// The GetWithdrawals method must not be used more than once every 15 minutes per payout. - /// - /// Please note that even if a “payoutconfirmation” has been sent, the payout can still fail afterwards. - /// If that happens, Trustly will send a credit notification to the merchant’s NotificationURL. - /// This can happen for example if the funds are sent to a bank account that is closed. - /// - public class PayoutConfirmationNotificationData : AbstractCreditDebitPendingPayoutNotificationData - { - } -} diff --git a/src/Domain/Notifications/Pending.cs b/src/Domain/Notifications/Pending.cs deleted file mode 100644 index e6c1ac9..0000000 --- a/src/Domain/Notifications/Pending.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Newtonsoft.Json; -using Trustly.Api.Domain.Base; - -namespace Trustly.Api.Domain.Notifications -{ - public class PendingNotificationData : AbstractCreditDebitPendingPayoutNotificationData - { - } -} diff --git a/src/Domain/Notifications/Unknown.cs b/src/Domain/Notifications/Unknown.cs index ada177b..d02eaf4 100644 --- a/src/Domain/Notifications/Unknown.cs +++ b/src/Domain/Notifications/Unknown.cs @@ -1,14 +1,14 @@ using System; using System.Collections.Generic; using Newtonsoft.Json; -using Trustly.Api.Domain.Base; namespace Trustly.Api.Domain.Notifications { - public class UnknownNotificationData : AbstractFromTrustlyRequestParamsData + public class UnknownNotificationRequest : JsonRpcNotification> { - [JsonExtensionData] - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] - public Dictionary ExtensionData { get; set; } + public UnknownNotificationRequest(JsonRpcNotificationParams @params, string method) : base(method) + { + this.Params = @params; + } } } diff --git a/src/Domain/Requests/AccountLedger.cs b/src/Domain/Requests/AccountLedger.cs deleted file mode 100644 index e8eb05f..0000000 --- a/src/Domain/Requests/AccountLedger.cs +++ /dev/null @@ -1,101 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using Trustly.Api.Domain.Base; - -namespace Trustly.Api.Domain.Requests -{ - public class AccountLedgerRequestData : AbstractToTrustlyRequestParamsData - { - [Required] - public string FromDate { get; set; } - - [Required] - public string ToDate { get; set; } - - [Required] - public string Currency { get; set; } - } - - [JsonConverter(typeof(AccountLedgerResponseDataConverter))] - public class AccountLedgerResponseData : AbstractResponseResultData - { - public List Entries { get; set; } - } - - public class AccountLedgerResponseDataConverter : JsonConverter - { - public override AccountLedgerResponseData ReadJson(JsonReader reader, Type objectType, AccountLedgerResponseData existingValue, bool hasExistingValue, JsonSerializer serializer) - { - var jarray = JToken.Load(reader); - return new AccountLedgerResponseData - { - Entries = jarray.ToObject>() - }; - } - - public override void WriteJson(JsonWriter writer, AccountLedgerResponseData value, JsonSerializer serializer) - { - JToken.FromObject(value.Entries).WriteTo(writer); - } - } - - public class AccountLedgerResponseDataEntry - { - /// - /// Your userid in our system. - /// - [JsonProperty("userid")] - public string UserID { get; set; } - - /// - /// The datestamp for when this ledger row affected your balance in our system. - /// - [JsonProperty("datestamp")] - public string Datestamp { get; set; } - - /// - /// The globally unique OrderID that resulted in this ledger record. - /// - [JsonProperty("orderid")] - public string OrderID { get; set; } - - /// - /// The name of the bookkeeping account this ledger record belongs to. - /// - [JsonProperty("accountname")] - public string AccountName { get; set; } - - /// - /// Your unique MessageID that you used to create the order that resulted in this ledger record. - /// - [JsonProperty("messageid")] - public string MessageID { get; set; } - - /// - /// A human friendly description of this ledger record. - /// - [JsonProperty("transactiontype")] - public string TransactionType { get; set; } - - /// - /// The currency of the amount in this ledger record. - /// - [JsonProperty("currency")] - public string Currency { get; set; } - - /// - /// The amount your balance in our system was affected with due to this ledger record. May contain a lot of decimals. - /// - [JsonProperty("amount")] - public string Amount { get; set; } - - /// - /// An ID meaning different things for different payment methods, you probably don't need this data. - /// - [JsonProperty("gluepayid")] - public string GluepayID { get; set; } - } -} diff --git a/src/Domain/Requests/AccountPayout.cs b/src/Domain/Requests/AccountPayout.cs deleted file mode 100644 index 4e57d42..0000000 --- a/src/Domain/Requests/AccountPayout.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System; -using System.ComponentModel.DataAnnotations; -using Newtonsoft.Json; -using Trustly.Api.Domain.Base; -using Trustly.Api.Domain.Common; - -namespace Trustly.Api.Domain.Requests -{ - public class AccountPayoutRequestData : AbstractToTrustlyRequestParamsData - { - /// - /// The URL to which notifications for this payment should be sent to. This URL should be hard to guess and not contain a ? ("question mark"). - /// - [Required] - public string NotificationURL { get; set; } - - /// - /// The AccountID received from an account notification to which the money shall be sent. - /// - [Required] - public string AccountID { get; set; } - - /// - /// ID, username, hash or anything uniquely identifying the end-user requesting the withdrawal, - /// Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. - /// - [Required] - public string EndUserID { get; set; } - - /// - /// Your unique ID for the payout. - /// If the MessageID is a previously initiated P2P order then the payout will be attached to that P2P order and the amount must be equal to or lower than the previously deposited amount. - /// - [Required] - public string MessageID { get; set; } - - /// - /// The amount to send with exactly two decimals. Only digits. Use dot (.) as decimal separator. - /// If the end-user holds a balance in the merchant's system then the amount must have been deducted from that balance before calling this method. - /// - [Required] - public string Amount { get; set; } - - /// - /// The currency of the end-user's account in the merchant's system. - /// - [Required] - public string Currency { get; set; } - } - - public class AccountPayoutResponseData : AbstractResponseResultData - { - /// - /// The globally unique OrderID the account payout order was assigned in our system. - /// - [JsonProperty("orderid")] - public long OrderID { get; set; } - - /// - /// "1" if the payout could be accepted and "0" otherwise. - /// - [JsonProperty("result")] - [JsonConverter(typeof(StringBooleanJsonConverter))] - public bool Result { get; set; } - } - - public class AccountPayoutRequestDataAttributes : AbstractRequestParamsDataAttributes - { - /// - /// The text to show on the end-user's bank statement after Trustly's own 10 digit reference (which always will be displayed first). - /// The reference must let the end user identify the merchant based on this value. So the ShopperStatement should contain either your brand name, website name, or company name. - /// - /// If possible, try to keep this text as short as possible to maximise the chance that the full reference - /// will fit into the reference field on the customer's bank since some banks allow only a limited number of characters. - /// - [Required] - public string ShopperStatement { get; set; } - - /// - /// The ExternalReference is a reference set by the merchant for any purpose and does not need to be unique - /// for every API call. The ExternalReference will be included in version 1.2 of the settlement report, ViewAutomaticSettlementDetailsCSV. - /// - public string ExternalReference { get; set; } - - /// - /// Human-readable identifier of the consumer-facing merchant (e.g. legal name or trade name) - /// Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. - /// - public string PSPMerchant { get; set; } - - /// - /// URL of the consumer-facing website where the order is initiated - /// Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. - /// - public string PSPMerchantURL { get; set; } - - /// - /// VISA category codes describing the merchant's nature of business. - /// Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. - /// - public string MerchantCategoryCode { get; set; } - - /// - /// Information about the Payer (ultimate debtor). This is required for some merchants and partners, see below. - /// - public RecipientOrSenderInformation SenderInformation { get; set; } - } -} diff --git a/src/Domain/Requests/ApproveWithdrawal.cs b/src/Domain/Requests/ApproveWithdrawal.cs deleted file mode 100644 index d22fe49..0000000 --- a/src/Domain/Requests/ApproveWithdrawal.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.ComponentModel.DataAnnotations; -using Newtonsoft.Json; -using Trustly.Api.Domain.Base; -using Trustly.Api.Domain.Common; - -namespace Trustly.Api.Domain.Requests -{ - public class ApproveWithdrawalRequestData : AbstractToTrustlyRequestParamsData - { - public long OrderID { get; set; } - } - - public class ApproveWithdrawalResponseData : AbstractResponseResultData - { - /// - /// The OrderID specified when calling the method. - /// - [Required] - [JsonProperty("orderid")] - public long OrderID { get; set; } - - /// - /// 1 if the withdrawal could be approved and 0 otherwise. - /// - [JsonProperty("result")] - [JsonConverter(typeof(StringBooleanJsonConverter))] - public bool Result { get; set; } - } -} diff --git a/src/Domain/Requests/Balance.cs b/src/Domain/Requests/Balance.cs deleted file mode 100644 index 01bbd94..0000000 --- a/src/Domain/Requests/Balance.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.Collections.Generic; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using Trustly.Api.Domain.Base; - -namespace Trustly.Api.Domain.Requests -{ - public class BalanceRequestData : AbstractToTrustlyRequestParamsData - { - } - - [JsonConverter(typeof(BalanceResponseDataConverter))] - public class BalanceResponseData : AbstractResponseResultData - { - public List Entries { get; set; } - } - - public class BalanceResponseDataConverter : JsonConverter - { - public override BalanceResponseData ReadJson(JsonReader reader, Type objectType, BalanceResponseData existingValue, bool hasExistingValue, JsonSerializer serializer) - { - var jarray = JToken.Load(reader); - return new BalanceResponseData - { - Entries = jarray.ToObject>() - }; - } - - public override void WriteJson(JsonWriter writer, BalanceResponseData value, JsonSerializer serializer) - { - JToken.FromObject(value.Entries).WriteTo(writer); - } - } - - public class BalanceResponseDataEntry - { - /// - /// The currency - /// - [JsonProperty("currency")] - public string Currency { get; set; } - - /// - /// The balance with 2 decimals - /// - [JsonProperty("balance")] - public string Balance { get; set; } - } -} diff --git a/src/Domain/Requests/CancelCharge.cs b/src/Domain/Requests/CancelCharge.cs deleted file mode 100644 index b04c6f5..0000000 --- a/src/Domain/Requests/CancelCharge.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using System.ComponentModel.DataAnnotations; -using Newtonsoft.Json; -using Trustly.Api.Domain.Base; -using Trustly.Api.Domain.Common; - -namespace Trustly.Api.Domain.Requests -{ - public class CancelChargeRequestData : AbstractToTrustlyRequestParamsData - { - /// - /// The OrderID of the Charge request that should be canceled. - /// - [Required] - public string OrderId { get; set; } - } - - public class CancelChargeResponseData : AbstractResponseResultData, IWithRejectionResult - { - /// - /// "1" if the Charge could be canceled, and "0" otherwise. - /// - [JsonProperty("result")] - [JsonConverter(typeof(StringBooleanJsonConverter))] - public bool Result { get; set; } - - /// - /// If the CancelCharge was NOT accepted and result 0 is sent, - /// a textual code describing the rejection reason will be sent here. - /// - /// For a successful CancelCharge, this will be null. - /// - [JsonProperty("rejected", NullValueHandling = NullValueHandling.Include)] - public string Rejected { get; set; } - } -} diff --git a/src/Domain/Requests/Charge.cs b/src/Domain/Requests/Charge.cs deleted file mode 100644 index d44071c..0000000 --- a/src/Domain/Requests/Charge.cs +++ /dev/null @@ -1,130 +0,0 @@ -using System; -using System.ComponentModel.DataAnnotations; -using Newtonsoft.Json; -using Trustly.Api.Domain.Base; -using Trustly.Api.Domain.Common; - -namespace Trustly.Api.Domain.Requests -{ - public class ChargeRequestData : AbstractToTrustlyRequestParamsData - { - /// - /// The AccountID received from an account notification which shall be charged. - /// - [Required] - public string AccountID { get; set; } - - /// - /// The URL to which notifications for this payment should be sent to.This URL should be hard to guess and not contain a? ("question mark"). - /// - [Required] - public string NotificationURL { get; set; } - - /// - /// ID, username, hash or anything uniquely identifying the end-user being charged. - /// - /// Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. - /// - [Required] - public string EndUserID { get; set; } - - /// - /// Your unique ID for the charge. - /// - [Required] - public string MessageID { get; set; } - - /// - /// The amount to charge with exactly two decimals.Only digits. Use dot (.) as decimal separator. - /// - [Required] - public string Amount { get; set; } - - /// - /// The currency of the amount to charge. - /// - [Required] - public string Currency { get; set; } - } - - public class ChargeResponseData : AbstractResponseResultData, IWithRejectionResult - { - /// - /// 1 if the charge was accepted for processing, 0 otherwise. Note that this is an acceptance of the order, no money has been charged from the account until you receive notifications thereof. - /// - [JsonProperty("result")] - [JsonConverter(typeof(StringBooleanJsonConverter))] - public bool Result { get; set; } - - /// - /// The globally unique OrderID the charge order was assigned in our system, or null if the charge was not accepted. - /// The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the charge. See section "Notifications" below for details. - /// - [JsonProperty("orderid")] - public string OrderID { get; set; } - - /// - /// If the charge was NOT accepted, a textual code describing the rejection reason, null otherwise. - /// - /// The possible rejected codes are: - /// - /// ERROR_MANDATE_NOT_FOUND - the AccountID does not have an active mandate - /// ERROR_DIRECT_DEBIT_NOT_ALLOWED - Trustly Direct Debit is not enabled on the merchant's account in Trustly's system. - /// ERROR_ACCOUNT_NOT_FOUND - the specified AccountID does not exist. - /// - [JsonProperty("rejected")] - public string Rejected { get; set; } - } - - public class ChargeRequestDataAttributes : AbstractRequestParamsDataAttributes - { - /// - /// The text to show on the end-user's bank statement as well as in end-user e-mail communication. - /// On the bank statement, only the first seven characters (along with Trustly's reference) will be shown. - /// Allowed characters: A-Z(both upper and lower case), 0-9, ".", "-", "_", " " (dot, dash, underscore, space). - /// - /// - /// - /// Shopperstatement: "Sport Shop". Will result in "T Sport S xyz" in bank statement and "Sport Shop" in e-mails. - /// - [Required] - public string ShopperStatement { get; set; } - - /// - /// The email address of the end user. - /// - [Required] - public string Email { get; set; } - - /// - /// The date when the funds will be charged from the end user's bank account. If this attribute is not sent, the charge will be attempted as soon as possible. - /// - public string PaymentDate { get; set; } - - /// - /// The ExternalReference is a reference set by the merchant for any purpose and does not need to be unique for every API call. - /// For example, it can be used for invoice references, OCR numbers and also for offering end users the option to part-pay an invoice using the same ExternalReference. - /// The ExternalReference will be included in version 1.2 of the settlement report, ViewAutomaticSettlementDetailsCSV. - /// - /// 32423534523 - public string ExternalReference { get; set; } - - /// - /// Human-readable identifier of the consumer-facing merchant (e.g. legal name or trade name) - /// Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. - /// - public string PSPMerchant { get; set; } - - /// - /// URL of the consumer-facing website where the order is initiated - /// Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. - /// - public string PSPMerchantURL { get; set; } - - /// - /// VISA category codes describing the merchant's nature of business. - /// Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. - /// - public string MerchantCategoryCode { get; set; } - } -} diff --git a/src/Domain/Requests/CreateAccount.cs b/src/Domain/Requests/CreateAccount.cs deleted file mode 100644 index bd12773..0000000 --- a/src/Domain/Requests/CreateAccount.cs +++ /dev/null @@ -1,139 +0,0 @@ -using System; -using System.ComponentModel.DataAnnotations; -using Newtonsoft.Json; -using Trustly.Api.Domain.Base; -using Trustly.Api.Domain.Common; - -namespace Trustly.Api.Domain.Requests -{ - public class CreateAccountRequestData : AbstractToTrustlyRequestParamsData - { - /// - /// ID, username, hash or anything uniquely identifying the end-user holding this account. - /// - /// Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. - /// - [Required] - public string EndUserID { get; set; } - - /// - /// The clearing house of the end-user's bank account. Typically the name of a country in uppercase letters. See table* below. - /// - [Required] - public string ClearingHouse { get; set; } - - /// - /// The bank number identifying the end-user's bank in the given clearing house. For bank accounts in IBAN format you should just provide an empty string (""). For non-IBAN format, see table* below. - /// - [Required] - public string BankNumber { get; set; } - - /// - /// The account number, identifying the end-user's account in the bank. Can be either IBAN or country-specific format, see table* below. - /// - [Required] - public string AccountNumber { get; set; } - /// - /// First name of the account holder (or the name of the company/organization) - /// - [Required] - public string Firstname { get; set; } - - /// - /// Last name of the account holder(empty for organizations/companies) - /// - [Required] - public string Lastname { get; set; } - } - - public class CreateAccountResponseData : AbstractResponseResultData - { - /// - /// The globally unique AccountID the account was assigned in our system. - /// - [JsonProperty("accountid")] - public string AccountID { get; set; } - - /// - /// The clearinghouse for this account. - /// - [JsonProperty("clearinghouse")] - public string ClearingHouse { get; set; } - - /// - /// The name of the bank for this account. - /// - [JsonProperty("bank")] - public string Bank { get; set; } - - /// - /// A descriptor for this account that is safe to show to the end user. - /// - [JsonProperty("descriptor")] - public string Descriptor { get; set; } - } - - public class CreateAccountRequestDataAttributes : AbstractRequestParamsDataAttributes - { - /// - /// The date of birth of the account holder(ISO 8601). - /// - public string DateOfBirth { get; set; } - - /// - /// The mobile phonenumber to the account holder in international format.This is used for KYC and AML routines. - /// - public string MobilePhone { get; set; } - - /// - /// The account holder's social security number / personal number / birth number / etc. - /// Useful for some banks for identifying transactions and KYC/AML. - /// - public string NationalIdentificationNumber { get; set; } - - /// - /// The ISO 3166-1-alpha-2 code of the account holder's country. - /// - public string AddressCountry { get; set; } - - /// - /// Postal code of the account holder. - /// - public string AddressPostalCode { get; set; } - - /// - /// City of the account holder. - /// - public string AddressCity { get; set; } - - /// - /// Street address of the account holder. - /// - public string AddressLine1 { get; set; } - - /// - /// Additional address information of the account holder. - /// - public string AddressLine2 { get; set; } - - /// - /// The entire address of the account holder. - /// This attribute should only be used if you are unable to provide the address information in the 5 separate attributes: - /// - ///
    - ///
  • AddressCountry
  • - ///
  • AddressPostalCode
  • - ///
  • AddressCity
  • - ///
  • AddressLine1
  • - ///
  • AddressLine2
  • - ///
- /// - ///
- public string Address { get; set; } - - /// - /// The email address of the account holder. - /// - public string Email { get; set; } - } -} diff --git a/src/Domain/Requests/DenyWithdrawal.cs b/src/Domain/Requests/DenyWithdrawal.cs deleted file mode 100644 index b3d405a..0000000 --- a/src/Domain/Requests/DenyWithdrawal.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using Newtonsoft.Json; -using Trustly.Api.Domain.Base; -using Trustly.Api.Domain.Common; - -namespace Trustly.Api.Domain.Requests -{ - public class DenyWithdrawalRequestData : AbstractToTrustlyRequestParamsData - { - public long OrderID { get; set; } - } - - public class DenyWithdrawalResponseData : AbstractResponseResultData - { - /// - /// The OrderID specified when calling the method. - /// - [JsonProperty("orderid")] - public long OrderID { get; set; } - - /// - /// "1" if the refund request is accepted by Trustly's system. - /// If the refund request is not accepted, you will get an error code back in the - /// - [JsonProperty("result")] - [JsonConverter(typeof(StringBooleanJsonConverter))] - public bool Result { get; set; } - } -} diff --git a/src/Domain/Requests/Deposit.cs b/src/Domain/Requests/Deposit.cs deleted file mode 100644 index 993edbe..0000000 --- a/src/Domain/Requests/Deposit.cs +++ /dev/null @@ -1,148 +0,0 @@ -using System; -using Newtonsoft.Json; -using Trustly.Api.Domain.Base; -using Trustly.Api.Domain.Common; - -namespace Trustly.Api.Domain.Requests -{ - public class DepositRequestData : AbstractToTrustlyRequestParamsData - { - public string NotificationURL { get; set; } - - public string EndUserID { get; set; } - - public string MessageID { get; set; } - } - - public class DepositResponseData : AbstractResponseResultData - { - /// - /// The OrderID specified when calling the method. - /// - [JsonProperty("orderid")] - public string OrderID { get; set; } - - /// - /// The URL that should be loaded so that the end-user can complete the deposit. - /// - [JsonProperty("url")] - public string URL { get; set; } - } - - public class DepositRequestDataAttributes : AbstractDepositAndWithdrawDataAttributes - { - /// - /// iDeal. - /// - /// The iDEAL integration offered by Trustly allows for both iDEAL and Trustly payments on a single integration with all transactions visible in the same AccountLedger. - /// To initiate a new iDEAL payment, add Method = "deposit.bank.netherlands.ideal" to the Deposit attributes. - /// - public string Method { get; set; } - - /// - /// The currency of the end-user's account in the merchant's system. - /// - [JsonProperty("Currency", Required = Required.Always)] - public string Currency { get; set; } - - /// - /// The amount to deposit with exactly two decimals in the currency specified by Currency. - /// Do not use this attribute in combination with and .. - /// Only digits. Use dot (.) as decimal separator. - /// - [JsonProperty("Amount")] - public string Amount { get; set; } - - /// - /// The ISO 3166-1-alpha-2 code of the shipping address country. - /// - public string ShippingAddressCountry { get; set; } - - /// - /// The postalcode of the shipping address. - /// - public string ShippingAddressPostalCode { get; set; } - - /// - /// The city of the shipping address. - /// - public string ShippingAddressCity { get; set; } - - /// - /// Shipping address street - /// - public string ShippingAddressLine1 { get; set; } - - /// - /// Additional shipping address information. - /// - public string ShippingAddressLine2 { get; set; } - - /// - /// The entire shipping address. - /// This attribute should only be used if you are unable to provide the shipping address information in the 5 separate attributes above - /// (ShippingAddressCountry, ShippingAddressCity, ShippingAddressPostalCode, ShippingAddressLine1, ShippingAddressLine2) - /// - public string ShippingAddress { get; set; } - - - /// - /// In addition to the deposit, request a direct debit mandate from the account used for the deposit. 1 enables, 0 disables. - /// The default is disabled. If this attribute is set, additional account notifications might be sent. - /// You can read more about Trustly Direct Debit here, under section 2.1 - /// - public string RequestDirectDebitMandate { get; set; } - - /// - /// The AccountID received from an account notification which shall be charged in a Trustly Direct Debit deposit. - /// This attribute should only be sent in combination with "QuickDeposit" : 1 - /// - public string ChargeAccountID { get; set; } - - /// - /// Set to 1 for Trustly Direct Debit deposits. QuickDeposit should be set set to 1 when the end user attempts a quick deposit, - /// even if ChargeAccountID is not set. You can read more about QuickDeposits here, under section 1.1 and 1.2. - /// - public int? QuickDeposit { get; set; } - - /// - /// The ExternalReference is a reference set by the merchant for any purpose and does not need to be unique for every API call. - /// The ExternalReference will be included in version 1.2 of the settlement report, ViewAutomaticSettlementDetailsCSV. - /// - public string ExternalReference { get; set; } - - /// - /// Human-readable identifier of the consumer-facing merchant (e.g. legal name or trade name) - /// Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. - /// - public string PSPMerchant { get; set; } - - /// - /// URL of the consumer-facing website where the order is initiated - /// Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. - /// - public string PSPMerchantURL { get; set; } - - /// - /// VISA category codes describing the merchant's nature of business. - /// Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. - /// - public string MerchantCategoryCode { get; set; } - - /// - /// The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. - /// - public string AccountID { get; set; } - - /// - /// Information about the Payee (ultimate creditor). - /// The burden of identifying who the Payee for any given transaction is lies with the Trustly customer. - /// - /// Required for some merchants and partners. - /// - /// RecipientInformation{} is mandatory to send for money transfer services (including remittance houses), e-wallets, prepaid cards, - /// as well as for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account (other cases may also apply). - /// - public RecipientOrSenderInformation RecipientInformation { get; set; } - } -} diff --git a/src/Domain/Requests/GetWithdrawals.cs b/src/Domain/Requests/GetWithdrawals.cs deleted file mode 100644 index 4951f7c..0000000 --- a/src/Domain/Requests/GetWithdrawals.cs +++ /dev/null @@ -1,93 +0,0 @@ -using System; -using System.Collections.Generic; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using Trustly.Api.Domain.Base; - -namespace Trustly.Api.Domain.Requests -{ - public class GetWithdrawalsRequestData : AbstractToTrustlyRequestParamsData - { - public string OrderID { get; set; } - } - - [JsonConverter(typeof(GetWithdrawalsResponseDataConverter))] - public class GetWithdrawalsResponseData : AbstractResponseResultData - { - public List Entries { get; set; } - } - - public class GetWithdrawalsResponseDataConverter : JsonConverter - { - public override GetWithdrawalsResponseData ReadJson(JsonReader reader, Type objectType, GetWithdrawalsResponseData existingValue, bool hasExistingValue, JsonSerializer serializer) - { - var jarray = JToken.Load(reader); - return new GetWithdrawalsResponseData - { - Entries = jarray.ToObject>() - }; - } - - public override void WriteJson(JsonWriter writer, GetWithdrawalsResponseData value, JsonSerializer serializer) - { - JToken.FromObject(value.Entries).WriteTo(writer); - } - } - - public class GetWithdrawalsResponseDataEntry - { - /// - /// Reference code for the withdrawal generated by Trustly. - /// - [JsonProperty("reference")] - public string Reference { get; set; } - - /// - /// Date and time when the withdrawal was last updated. - /// - [JsonProperty("modificationdate")] - public string ModificationDate { get; set; } - - /// - /// OrderID of the withdrawal - /// - [JsonProperty("orderid")] - public string OrderID { get; set; } - - /// - /// Date and time when the withdrawal request was received. - /// - [JsonProperty("datestamp")] - public string Datestamp { get; set; } - - /// - /// The current state* of the withdrawal. - /// - [JsonProperty("transferstate")] - public string TransferState { get; set; } - - /// - /// The amount of the withdrawal. - /// - [JsonProperty("amount")] - public string Amount { get; set; } - - /// - /// The accountid of the receiving account. - /// - [JsonProperty("accountid")] - public string Accountid { get; set; } - - /// - /// The currency of the withdrawal. - /// - [JsonProperty("currency")] - public string Currency { get; set; } - - /// - /// The estimated date and time for when the funds will be available on the receiving bank account.If this information is not available it will be null. - /// - [JsonProperty("eta")] - public string Eta { get; set; } - } -} diff --git a/src/Domain/Requests/Refund.cs b/src/Domain/Requests/Refund.cs deleted file mode 100644 index f15a27b..0000000 --- a/src/Domain/Requests/Refund.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using System.ComponentModel.DataAnnotations; -using Newtonsoft.Json; -using Trustly.Api.Domain.Base; -using Trustly.Api.Domain.Common; - -namespace Trustly.Api.Domain.Requests -{ - public class RefundRequestData : AbstractToTrustlyRequestParamsData - { - /// - /// The OrderID of the initial deposit. - /// - [Required] - public string OrderID { get; set; } - - /// - /// The amount to refund the customer with exactly two decimals. Only digits. Use dot (.) as decimal separator. - /// - [Required] - public string Amount { get; set; } - - /// - /// The currency of the amount to refund the customer. - /// - [Required] - public string Currency { get; set; } - } - - public class RefundResponseData : AbstractResponseResultData - { - /// - /// The OrderID specified when calling the method. - /// ] - [JsonProperty("orderid")] - public long OrderID { get; set; } - - /// - /// "1" if the refund request is accepted by Trustly's system. - /// If the refund request is not accepted, you will get an error code back in the - /// - [JsonProperty("result")] - [JsonConverter(typeof(StringBooleanJsonConverter))] - public bool Result { get; set; } - } - - public class RefundRequestDataAttributes : AbstractRequestParamsDataAttributes - { - /// - /// The ExternalReference is a reference set by the merchant for any purpose and does not need to be unique for every API call. - /// The ExternalReference will be included in version 1.2 of the settlement report, ViewAutomaticSettlementDetailsCSV. - /// - public string ExternalReference { get; set; } - } -} diff --git a/src/Domain/Requests/RegisterAccount.cs b/src/Domain/Requests/RegisterAccount.cs deleted file mode 100644 index 2f6ad2f..0000000 --- a/src/Domain/Requests/RegisterAccount.cs +++ /dev/null @@ -1,151 +0,0 @@ -using System; -using System.ComponentModel.DataAnnotations; -using Newtonsoft.Json; -using Trustly.Api.Domain.Base; -using Trustly.Api.Domain.Common; - -namespace Trustly.Api.Domain.Requests -{ - public class RegisterAccountRequestData : AbstractToTrustlyRequestParamsData - { - - /// - /// ID, username, hash or anything uniquely identifying the end-user to be identified. - /// Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department - /// - public string EndUserID { get; set; } - - /// - /// The clearing house of the end-user's bank account. Typically the name of a country in uppercase letters. See table - /// at https://developers.trustly.com/emea/docs/registeraccount - /// - /// SWEDEN - public string ClearingHouse { get; set; } - - /// - /// The bank number identifying the end-user's bank in the given clearing house. For bank accounts in IBAN format you should just - /// provide an empty string (""). For non-IBAN format, see table at https://developers.trustly.com/emea/docs/registeraccount - /// - public string BankNumber { get; set; } - - /// - /// The account number, identifying the end-user's account in the bank. Can be either IBAN or country-specific format, see table - /// at https://developers.trustly.com/emea/docs/registeraccount - /// - public string AccountNumber { get; set; } - - /// - /// First name of the account holder (or the name of the company/organization) - /// - public string Firstname { get; set; } - - /// - /// Last name of the account holder (empty for organizations/companies) - /// - public string Lastname { get; set; } - } - - public class RegisterAccountRequestDataAttributes : AbstractRequestParamsDataAttributes - { - /// - /// The end-user's date of birth. - /// - /// 1979-01-31 - public string DateOfBirth { get; set; } - - /// - /// The mobile phonenumber to the account holder in international format. This is used for KYC and AML routines. - /// - /// +46709876543 - public string MobilePhone { get; set; } - - /// - /// The account holder's social security number / personal number / birth number / etc. Useful for some banks for identifying transactions and KYC/AML. - /// - /// 790131-1234 - public string NationalIdentificationNumber { get; set; } - - /// - /// The ISO 3166-1-alpha-2 code of the account holder's country. - /// - /// SE - public string AddressCountry { get; set; } - - /// - /// Postal code of the account holder. - /// - /// SE-11253 - public string AddressPostalCode { get; set; } - - /// - /// City of the account holder. - /// - /// Stockholm - public string AddressCity { get; set; } - - /// - /// Street address of the account holder. - /// - /// Main street 1 - public string AddressLine1 { get; set; } - - /// - /// Additional address information of the account holder. - /// - /// Apartment 123, 2 stairs up - public string AddressLine2 { get; set; } - - /// - /// The entire address of the account holder. This attribute should only be used if you are unable to provide - /// the address information in the 5 separate attributes above (AddressCountry, AddressPostalCode, AddressCity, AddressLine1 and AddressLine2). - /// - /// Birgerstreet 14, SE-11411 Stockholm, Sweden - public string Address { get; set; } - - /// - /// The email address of the account holder. - /// - /// test@trustly.com - public string Email { get; set; } - - } - - public class RegisterAccountResponseData : AbstractResponseResultData - { - /// - /// The globally unique AccountID the account was assigned in our system. - /// - /// 7653385737 - [JsonProperty("accountid")] - public string AccountId { get; set; } - - /// - /// The clearinghouse for this account. - /// - /// SWEDEN - [JsonProperty("clearinghouse")] - public string ClearingHouse { get; set; } - - /// - /// The name of the bank for this account. - /// - /// Skandiabanken - [JsonProperty("bank")] - public string Bank { get; set; } - - /// - /// A descriptor for this account that is safe to show to the end user. - /// - /// ***4057 - [JsonProperty("descriptor")] - public string Descriptor { get; set; } - } - - public class RegisterAccount - { - public RegisterAccount() - { - } - } -} - diff --git a/src/Domain/Requests/RegisterAccountPayout.cs b/src/Domain/Requests/RegisterAccountPayout.cs deleted file mode 100644 index 08c0337..0000000 --- a/src/Domain/Requests/RegisterAccountPayout.cs +++ /dev/null @@ -1,200 +0,0 @@ -using System; -using System.ComponentModel.DataAnnotations; -using Newtonsoft.Json; -using Trustly.Api.Domain.Base; -using Trustly.Api.Domain.Common; - -namespace Trustly.Api.Domain.Requests -{ - public class RegisterAccountPayoutRequestData : AbstractToTrustlyRequestParamsData - { - /// - /// ID, username, hash or anything uniquely identifying the end-user to be identified. - /// Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department - /// - public string EndUserID { get; set; } - - /// - /// The clearing house of the end-user's bank account. Typically the name of a country in uppercase letters. See table - /// at https://developers.trustly.com/emea/docs/registeraccount - /// - /// SWEDEN - public string ClearingHouse { get; set; } - - /// - /// The bank number identifying the end-user's bank in the given clearing house. For bank accounts in IBAN format you should just - /// provide an empty string (""). For non-IBAN format, see table at https://developers.trustly.com/emea/docs/registeraccount - /// - public string BankNumber { get; set; } - - /// - /// The account number, identifying the end-user's account in the bank. Can be either IBAN or country-specific format, see table - /// at https://developers.trustly.com/emea/docs/registeraccount - /// - public string AccountNumber { get; set; } - - /// - /// First name of the account holder (or the name of the company/organization) - /// - public string Firstname { get; set; } - - /// - /// Last name of the account holder (empty for organizations/companies) - /// - public string Lastname { get; set; } - - /// - /// The URL to which notifications for this payment should be sent to. This URL should be hard to guess and not contain a ? ("question mark"). - /// - [Required] - public string NotificationURL { get; set; } - - /// - /// Your unique ID for the payout. - /// If the MessageID is a previously initiated P2P order then the payout will be attached to that P2P order and the amount must be equal to or lower than the previously deposited amount. - /// - [Required] - public string MessageID { get; set; } - - /// - /// The amount to send with exactly two decimals. Only digits. Use dot (.) as decimal separator. - /// If the end-user holds a balance in the merchant's system then the amount must have been deducted from that balance before calling this method. - /// - [Required] - public string Amount { get; set; } - - /// - /// The currency of the end-user's account in the merchant's system. - /// - [Required] - public string Currency { get; set; } - } - - public class RegisterAccountPayoutRequestDataAttributes : AbstractRequestParamsDataAttributes - { - /// - /// The text to show on the end-user's bank statement after Trustly's own 10 digit reference (which always will be displayed first). - /// The reference must let the end user identify the merchant based on this value. So the ShopperStatement should contain either your brand name, website name, or company name. - /// - /// If possible, try to keep this text as short as possible to maximise the chance that the full reference - /// will fit into the reference field on the customer's bank since some banks allow only a limited number of characters. - /// - [Required] - public string ShopperStatement { get; set; } - - /// - /// The ExternalReference is a reference set by the merchant for any purpose and does not need to be unique - /// for every API call. The ExternalReference will be included in version 1.2 of the settlement report, ViewAutomaticSettlementDetailsCSV. - /// - public string ExternalReference { get; set; } - - /// - /// Human-readable identifier of the consumer-facing merchant (e.g. legal name or trade name) - /// - /// Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. - public string PSPMerchant { get; set; } - - /// - /// URL of the consumer-facing website where the order is initiated - //// - // Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. - public string PSPMerchantURL { get; set; } - - /// - /// VISA category codes describing the merchant's nature of business. - /// - /// Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. - public string MerchantCategoryCode { get; set; } - - /// - /// Information about the Payer (ultimate debtor). This is required for some merchants and partners, see below. - /// - public RecipientOrSenderInformation SenderInformation { get; set; } - - /// - /// The end-user's date of birth. - /// - /// 1979-01-31 - public string DateOfBirth { get; set; } - - /// - /// The mobile phonenumber to the account holder in international format. This is used for KYC and AML routines. - /// - /// +46709876543 - public string MobilePhone { get; set; } - - /// - /// The account holder's social security number / personal number / birth number / etc. Useful for some banks for identifying transactions and KYC/AML. - /// - /// 790131-1234 - public string NationalIdentificationNumber { get; set; } - - /// - /// The ISO 3166-1-alpha-2 code of the account holder's country. - /// - /// SE - public string AddressCountry { get; set; } - - /// - /// Postal code of the account holder. - /// - /// SE-11253 - public string AddressPostalCode { get; set; } - - /// - /// City of the account holder. - /// - /// Stockholm - public string AddressCity { get; set; } - - /// - /// Street address of the account holder. - /// - /// Main street 1 - public string AddressLine1 { get; set; } - - /// - /// Additional address information of the account holder. - /// - /// Apartment 123, 2 stairs up - public string AddressLine2 { get; set; } - - /// - /// The entire address of the account holder. This attribute should only be used if you are unable to provide - /// the address information in the 5 separate attributes above (AddressCountry, AddressPostalCode, AddressCity, AddressLine1 and AddressLine2). - /// - /// Birgerstreet 14, SE-11411 Stockholm, Sweden - public string Address { get; set; } - - /// - /// The email address of the account holder. - /// - /// test@trustly.com - public string Email { get; set; } - } - - public class RegisterAccountPayoutResponseData : AbstractResponseResultData - { - /// - /// The globally unique OrderID the account payout order was assigned in our system. - /// - [JsonProperty("orderid")] - public long OrderID { get; set; } - - /// - /// "1" if the payout could be accepted and "0" otherwise. - /// - [JsonProperty("result")] - [JsonConverter(typeof(StringBooleanJsonConverter))] - public bool Result { get; set; } - - } - - public class RegisterAccountPayout - { - public RegisterAccountPayout() - { - } - } -} - diff --git a/src/Domain/Requests/SelectAccount.cs b/src/Domain/Requests/SelectAccount.cs deleted file mode 100644 index e9fcca9..0000000 --- a/src/Domain/Requests/SelectAccount.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System; -using System.ComponentModel.DataAnnotations; -using Newtonsoft.Json; -using Trustly.Api.Domain.Base; -using Trustly.Api.Domain.Common; - -namespace Trustly.Api.Domain.Requests -{ - public class SelectAccountRequestData : AbstractToTrustlyRequestParamsData - { - /// - /// The URL to which notifications for this order should be sent to.This URL should be hard to guess and not contain a? ("question mark"). - /// - /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh - [Required] - public string NotificationURL { get; set; } - - /// - /// ID, username, hash or anything uniquely identifying the end-user to be identified. - /// Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department - /// - [Required] - public string EndUserID { get; set; } - - /// - /// Your unique ID for the account selection order. Each order you create must have an unique MessageID. - /// - [Required] - public string MessageID { get; set; } - } - - public class SelectAccountResponseData : AbstractResponseResultData - { - /// - /// The globally unique OrderID the account selection order was assigned in our system. - /// - /// 7653345737 - [JsonProperty("orderid")] - public string OrderID { get; set; } - - /// - /// The URL that should be loaded so that the end-user can complete the identification process. - /// - /// https://trustly.com/_/2f6b14fa-446a-4364-92f8-84b738d589ff - [JsonProperty("url")] - public string URL { get; set; } - } - - public class SelectAccountRequestDataAttributes : AbstractDepositAndWithdrawAndSelectAccountDataAttributes - { - /// - /// Only for Trustly Direct Debit. - /// Request a direct debit mandate from the selected account. 1 or 0. See section "Direct Debit Mandates" below for details. - /// - /// If this is set to 1, then is required. - /// - public int RequestDirectDebitMandate { get; set; } - - /// - /// The end-user's date of birth. - /// - /// 1979-01-31 - public string DateOfBirth { get; set; } - - /// - /// Human-readable identifier of the consumer-facing merchant(e.g.legal name or trade name) - /// - /// Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. - /// Merchant Ltd. - public string PSPMerchant { get; set; } - - /// - /// URL of the consumer-facing website where the order is initiated - /// - /// Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. - /// www.merchant.com - public string PSPMerchantURL { get; set; } - - /// - /// VISA category codes describing the merchant's nature of business. - /// Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. - /// - public string MerchantCategoryCode { get; set; } - - } -} diff --git a/src/Domain/Requests/SettlementReport.cs b/src/Domain/Requests/SettlementReport.cs deleted file mode 100644 index 2844c38..0000000 --- a/src/Domain/Requests/SettlementReport.cs +++ /dev/null @@ -1,113 +0,0 @@ -using System; -using System.Collections.Generic; -using Newtonsoft.Json; -using Trustly.Api.Domain.Base; - -namespace Trustly.Api.Domain.Requests -{ - public class SettlementReportRequestData : AbstractToTrustlyRequestParamsData - { - /// - /// If the value is specified (i.e. not "null"), the system will only search for a settlement executed in that particular currency. If unspecified, settlements executed in any currency are included in the report. - /// - public string Currency { get; set; } - - /// - /// The date when the settlement was processed. - /// - /// 2014-04-01 - public string SettlementDate { get; set; } - } - - public class SettlementReportRequestDataAttributes : AbstractRequestParamsDataAttributes - { - /// - /// Required. - /// The APIVersion. Must be "1.2". We also have older versions of the report, but those should not be implemented by new merchants. - /// - public string APIVersion { get; set; } - } - - public class SettlementReportResponseData : AbstractResponseResultData - { - [JsonProperty("view_automatic_settlement_details")] - public string CsvContent { get; set; } - - [JsonIgnore] - public List Entries { get; set; } - } - - public class SettlementReportResponseDataEntry - { - /// - /// The account the money was transferred from(if the amount is positive), or the account the money was transferred to(if the amount is negative). - /// - public string AccountName { get; set; } - - /// - /// The monetary amount of the transaction, rounded down to two decimal places. - /// - public decimal? Amount { get; set; } - - /// - /// The three-letter currency code of the transaction. - /// - public string Currency { get; set; } - - /// - /// The timestamp of the transaction, including the UTC offset.As the timestamps are always in UTC, the offset is always +00 - /// - /// 2014-03-31 11:50:06.46106+00 - public DateTime Datestamp { get; set; } - - /// - /// MessageID of the order associated with the transaction, if available. - /// - public string MessageID { get; set; } - - /// - /// OrderID of the order associated with the transaction, if available. - /// - public string OrderID { get; set; } - - /// - /// The type of the order associated with the transaction, if available.Text See list of possible orderypes in the table below. - /// - public string OrderType { get; set; } - - /// - /// The sum of all amounts of the respective currency within the report. - /// - public decimal? Total { get; set; } - - /// - /// The username of the child merchant account. - /// - public string Username { get; set; } - - /// - /// The amount that the end user paid, if the currency is different from the requested deposit currency. For transactions where the payment currency is the same as the requested currency, this field will be empty. - /// - public decimal? FxPaymentAmount { get; set; } - - /// - /// The currency that the user paid with, if the currency is different from the requested deposit currency. For transactions where the payment currency is the same as the requested currency, this field will be empty. - /// - public string FxPaymentCurrency { get; set; } - - /// - /// The 10 digit reference that will show up on the merchant's bank statement for this automatic settlement batch. The same value will be sent on every row in the report. - /// - public string SettlementBankWithdrawalID { get; set; } - - /// - /// Contains the ExternalReference value for Deposit, Charge, and Refund transactions if provided.Otherwise empty. - /// - public string ExternalReference { get; set; } - - public string ExtraRef { - get { return this.ExternalReference; } - set { this.ExternalReference = value; } - } - } -} \ No newline at end of file diff --git a/src/Domain/Requests/Withdraw.cs b/src/Domain/Requests/Withdraw.cs deleted file mode 100644 index 8293c8a..0000000 --- a/src/Domain/Requests/Withdraw.cs +++ /dev/null @@ -1,133 +0,0 @@ -using System; -using Newtonsoft.Json; -using Trustly.Api.Domain.Base; -using Trustly.Api.Domain.Common; - -namespace Trustly.Api.Domain.Requests -{ - public class WithdrawRequestData : AbstractToTrustlyRequestParamsData - { - /// - /// The URL to which notifications for this payment should be sent to. This URL should be hard to guess and not contain a ? ("question mark"). - /// - public string NotificationURL { get; set; } - - /// - /// ID, username, hash or anything uniquely identifying the end-user requesting the withdrawal, - /// Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. - /// - public string EndUserID { get; set; } - - /// - /// Your unique ID for the withdrawal. - /// - public string MessageID { get; set; } - - /// - /// The currency of the end-user's account in the merchant's system. - /// - public string Currency { get; set; } - } - - public class WithdrawResponseData : AbstractResponseResultData - { - /// - /// The globally unique OrderID the withdrawal was assigned in our system. - /// - [JsonProperty("orderid")] - public long OrderId { get; set; } - - /// - /// The URL that should be loaded so that the end-user can complete the withdrawal. - /// - [JsonProperty("url")] - public string URL { get; set; } - } - - public class WithdrawRequestDataAttributes : AbstractDepositAndWithdrawDataAttributes - { - /// - /// Sets a fixed withdrawal amount which cannot be changed by the end-user in the Trustly iframe. - /// If this attribute is not sent, the end-user will be asked to select the withdrawal amount in the Trustly iframe - /// - /// Do not use in combination with and . - /// - /// Use dot(.) as decimal separator. - /// - public string SuggestedAmount { get; set; } - - /// - /// The end-user's first name. - /// - public string DateOfBirth { get; set; } - - /// - /// The ISO 3166-1-alpha-2 code of the shipping address country. - /// - public string AddressCountry { get; set; } - - /// - /// The postalcode of the shipping address. - /// - public string AddressPostalCode { get; set; } - - /// - /// The city of the shipping address. - /// - public string AddressCity { get; set; } - - /// - /// Shipping address street - /// - public string AddressLine1 { get; set; } - - /// - /// Additional shipping address information. - /// - public string AddressLine2 { get; set; } - - /// - /// The entire shipping address. - /// This attribute should only be used if you are unable to provide the shipping address information in the 5 separate properties: - /// * - /// * - /// * - /// * - /// * - /// - public string Address { get; set; } - - /// - /// The ExternalReference is a reference set by the merchant for any purpose and does not need to be unique for every API call. - /// The ExternalReference will be included in version 1.2 of the settlement report, ViewAutomaticSettlementDetailsCSV. - /// - public string ExternalReference { get; set; } - - /// - /// Human-readable identifier of the consumer-facing merchant (e.g. legal name or trade name) - /// Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. - /// - public string PSPMerchant { get; set; } - - /// - /// URL of the consumer-facing website where the order is initiated - /// Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. - /// - public string PSPMerchantURL { get; set; } - - /// - /// VISA category codes describing the merchant's nature of business. - /// Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. - /// - public string MerchantCategoryCode { get; set; } - - /// - /// Information about the Payer (ultimate debtor). - /// - /// Mandatory for certain types of merchants and partners. - /// SenderInformation is mandatory to send in Attributes{} for money transfer services (including remittance houses), - /// e-wallets, prepaid cards, as well as for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account (other cases may also apply). - /// - public RecipientOrSenderInformation SenderInformation { get; set; } - } -} diff --git a/src/Website/Content/Site.css b/src/Website/Content/Site.css deleted file mode 100644 index 1188350..0000000 --- a/src/Website/Content/Site.css +++ /dev/null @@ -1,36 +0,0 @@ -body { - padding-top: 20px; - padding-bottom: 20px; - font-family: Verdana, Geneva, sans-serif -} - -/* Set padding to keep content from hitting the edges */ -.body-content { - padding-left: 15px; - padding-right: 15px; -} - -/* Set width on the form input elements since they're 100% wide by default */ -input, -select, -textarea { - max-width: 280px; -} - -.button { - padding:10px; - background: #5EB9EB; /* For browsers that do not support gradients */ - background: -webkit-linear-gradient(#5EB9EB, #C4EAFF); /* For Safari 5.1 to 6.0 */ - background: -o-linear-gradient(#5EB9EB, #C4EAFF); /* For Opera 11.1 to 12.0 */ - background: -moz-linear-gradient(#5EB9EB, #C4EAFF); /* For Firefox 3.6 to 15 */ - background: linear-gradient(#5EB9EB, #C4EAFF); /* Standard syntax */ - border: 1px solid #5EB9EB; - border-radius: 5px; - display: inline-block; - text-decoration: none; - color: black; -} - -.iframe { - border: none !important; -} \ No newline at end of file diff --git a/src/Website/Controllers/AbstractBaseController.cs b/src/Website/Controllers/AbstractBaseController.cs deleted file mode 100644 index a171bb3..0000000 --- a/src/Website/Controllers/AbstractBaseController.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using Microsoft.AspNetCore.Mvc; -using Trustly.Api.Client; - -namespace Trustly.Website.Controllers -{ - public abstract class AbstractBaseController : Controller - { - protected TrustlyApiClient Client { get; private set; } - - public AbstractBaseController() - { - this.Client = new TrustlyApiClient(TrustlyApiClientSettings.ForDefaultTest()); - - this.Client = new TrustlyApiClient(TrustlyApiClientSettings - .ForTest() - .WithCredentialsFromUserHome() - .WithCertificatesFromUserHome() - .AndTrustlyCertificate()); - } - } -} diff --git a/src/Website/Controllers/DepositController.cs b/src/Website/Controllers/DepositController.cs deleted file mode 100644 index 3234ca9..0000000 --- a/src/Website/Controllers/DepositController.cs +++ /dev/null @@ -1,75 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2017 Trustly Group AB -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using Microsoft.AspNetCore.Mvc; -using System; - -namespace Trustly.Website.Controllers -{ - [Route("Deposit")] - public class DepositController : AbstractBaseController - { - [HttpGet] - public ActionResult Index( - [FromQuery(Name = "amount")] string amount, - [FromQuery(Name = "currency")] string currency - ) - { - var request = new Api.Domain.Requests.DepositRequestData - { - EndUserID = "user@email.com", - MessageID = Guid.NewGuid().ToString(), - NotificationURL = "https://localhost:52714/api/Notification", - Attributes = new Api.Domain.Requests.DepositRequestDataAttributes - { - Locale = "en_GB", - Firstname = "John", - Lastname = "Smith", - Email = "user@email.com", - MobilePhone = "070-1234567", - NationalIdentificationNumber = "010101-1234", - SuccessURL = "https://localhost:52714/Success", - Amount = amount ?? "10.00", - Currency = currency ?? "EUR", - Country = "SE", - ShopperStatement = "A Statement" - } - }; - - var response = this.Client.Deposit(request); - - return View(new DepositViewModel - { - URL = response.URL, - Amount = request.Attributes.Amount, - Currency = request.Attributes.Currency - }); - } - } - - public class DepositViewModel - { - public string URL { get; set; } - public string Currency { get; set; } - public string Amount { get; set; } - } -} diff --git a/src/Website/Controllers/HomeController.cs b/src/Website/Controllers/HomeController.cs deleted file mode 100644 index cfc8627..0000000 --- a/src/Website/Controllers/HomeController.cs +++ /dev/null @@ -1,37 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2017 Trustly Group AB -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - - -using Microsoft.AspNetCore.Mvc; - -namespace Trustly.Website.Controllers -{ - [Route("/")] - public class HomeController : AbstractBaseController - { - [HttpGet] - public IActionResult Index() - { - return View(); - } - } -} \ No newline at end of file diff --git a/src/Website/Controllers/NotificationController.cs b/src/Website/Controllers/NotificationController.cs deleted file mode 100644 index c6938dd..0000000 --- a/src/Website/Controllers/NotificationController.cs +++ /dev/null @@ -1,47 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2017 Trustly Group AB -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -namespace Trustly.Website.Controllers -{ - public class NotificationController : AbstractBaseController - { - /* - TrustlyApi _trustlyApi; - - public NotificationController() - { - _trustlyApi = new TrustlyApi(); - } - - public HttpResponseMessage Get() - { - string body = Request.Content.ReadAsStringAsync().Result; - - Notification notification = _trustlyApi.HandleNotification(body); - - Response notificationResponse = _trustlyApi.PrepareNotificationResponse(notification); - - return Request.CreateResponse(System.Net.HttpStatusCode.OK, notificationResponse); - } - */ - } -} \ No newline at end of file diff --git a/src/Website/Controllers/SuccessController.cs b/src/Website/Controllers/SuccessController.cs deleted file mode 100644 index 0007e54..0000000 --- a/src/Website/Controllers/SuccessController.cs +++ /dev/null @@ -1,36 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2017 Trustly Group AB -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using Microsoft.AspNetCore.Mvc; - -namespace Trustly.Website.Controllers -{ - [Route("Success")] - public class SuccessController : AbstractBaseController - { - [HttpGet] - public ActionResult Index() - { - return View(); - } - } -} \ No newline at end of file diff --git a/src/Website/Program.cs b/src/Website/Program.cs deleted file mode 100644 index e780391..0000000 --- a/src/Website/Program.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; - -namespace Trustly.Website -{ - public class Program - { - public static void Main(string[] args) - { - //CreateHostBuilder(args).Build().Run(); - } - - /* - public static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - }); - */ - } -} diff --git a/src/Website/Properties/launchSettings.json b/src/Website/Properties/launchSettings.json deleted file mode 100644 index c5b925d..0000000 --- a/src/Website/Properties/launchSettings.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:28446", - "sslPort": 44332 - } - }, - "profiles": { - "Website": { - "commandName": "Project", - "launchBrowser": true, - "applicationUrl": "https://localhost:52714;http://localhost:8363", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} \ No newline at end of file diff --git a/src/Website/Startup.cs b/src/Website/Startup.cs deleted file mode 100644 index c36d5b7..0000000 --- a/src/Website/Startup.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Trustly.Api.Client; - -namespace Trustly.Website -{ - public class Startup - { - // This method gets called by the runtime. Use this method to add services to the container. - // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 - public void ConfigureServices(IServiceCollection services) - { - services.AddMvc(); - } - - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - /* - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - - app.UseRouting(); - - app.UseTrustlyNotifications(); - - app.UseEndpoints(endpoints => - { - endpoints.MapControllers(); - }); - } - */ - } -} diff --git a/src/Website/Trustly.Website.csproj b/src/Website/Trustly.Website.csproj deleted file mode 100644 index e503b6e..0000000 --- a/src/Website/Trustly.Website.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - netcoreapp2.2 - - - - - - - - - - - - - - - diff --git a/src/Website/Views/Deposit/Index.cshtml b/src/Website/Views/Deposit/Index.cshtml deleted file mode 100644 index ffa16f0..0000000 --- a/src/Website/Views/Deposit/Index.cshtml +++ /dev/null @@ -1,10 +0,0 @@ -@model Trustly.Website.Controllers.DepositViewModel -@{ - ViewBag.Title = "Custom Deposit"; -} - -@Html.ActionLink("Home", "Index", "Home", null, new { @class = "button" }) - -

Deposit @Model.Amount in @Model.Currency

- - diff --git a/src/Website/Views/Home/Index.cshtml b/src/Website/Views/Home/Index.cshtml deleted file mode 100644 index 5dfc89d..0000000 --- a/src/Website/Views/Home/Index.cshtml +++ /dev/null @@ -1,8 +0,0 @@ -@{ - ViewBag.Title = "Web API Test"; -} - -

Web API Test

- -@Html.ActionLink("Deposit 100", "Index", "Deposit", new { amount = "100.00" }, new { @class = "button" })
-@Html.ActionLink("Deposit Unknown sum", "Index", "Deposit", new { }, new { @class = "button" }) diff --git a/src/Website/Views/Shared/_Layout.cshtml b/src/Website/Views/Shared/_Layout.cshtml deleted file mode 100644 index b795513..0000000 --- a/src/Website/Views/Shared/_Layout.cshtml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - @ViewBag.Title - - - - - -
- @RenderBody() -
-
-
-
- - \ No newline at end of file diff --git a/src/Website/Views/Success/Index.cshtml b/src/Website/Views/Success/Index.cshtml deleted file mode 100644 index 2e779c2..0000000 --- a/src/Website/Views/Success/Index.cshtml +++ /dev/null @@ -1,9 +0,0 @@ - -@{ - ViewBag.Title = "Success"; -} - -

Success

- -@Html.ActionLink("Home", "Index", "Home", null, new { @class = "button" }) - diff --git a/src/Website/Views/_ViewStart.cshtml b/src/Website/Views/_ViewStart.cshtml deleted file mode 100644 index 9c30ccf..0000000 --- a/src/Website/Views/_ViewStart.cshtml +++ /dev/null @@ -1,3 +0,0 @@ -@{ - Layout = "~/Views/Shared/_Layout.cshtml"; -} \ No newline at end of file diff --git a/src/Website/Views/web.config b/src/Website/Views/web.config deleted file mode 100644 index bd211d5..0000000 --- a/src/Website/Views/web.config +++ /dev/null @@ -1,42 +0,0 @@ - - - - - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Website/appsettings.Development.json b/src/Website/appsettings.Development.json deleted file mode 100644 index 8983e0f..0000000 --- a/src/Website/appsettings.Development.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft": "Warning", - "Microsoft.Hosting.Lifetime": "Information" - } - } -} diff --git a/src/Website/appsettings.json b/src/Website/appsettings.json deleted file mode 100644 index d9d9a9b..0000000 --- a/src/Website/appsettings.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft": "Warning", - "Microsoft.Hosting.Lifetime": "Information" - } - }, - "AllowedHosts": "*" -} diff --git a/src/WiremockRecorder/Program.cs b/src/WiremockRecorder/Program.cs deleted file mode 100644 index 3aaa94e..0000000 --- a/src/WiremockRecorder/Program.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using Newtonsoft.Json.Linq; -using WireMock.Server; -using WireMock.Settings; - -namespace WiremockRecorder -{ - class Program - { - /// - /// Run this program to start a proxy to the Trustly Test API. - /// - /// You will then find the generated mappings inside the target directory. - /// Usually this is: ./bin/Debug/net5.0/__admin/mappings - /// - /// - static void Main(string[] args) - { - var server = WireMockServer.Start(new WireMockServerSettings - { - Urls = new[] { "http://+:5001" }, - - UseSSL = true, - CertificateSettings = new WireMockCertificateSettings - { - - }, - - ProxyAndRecordSettings = new ProxyAndRecordSettings - { - Url = "https://test.trustly.com/api/1", - - AllowAutoRedirect = true, - SaveMapping = true, - SaveMappingToFile = true - } - }); - - Console.WriteLine("Listening to http://localhost:5001, proxying to https://test.trustly.com/api/1"); - Console.ReadLine(); - - server.Stop(); - - Console.WriteLine("Stopped listening"); - - var directory = new DirectoryInfo("__admin/mappings"); - - if (directory.Exists) - { - foreach (var file in directory.GetFiles()) - { - var fileContent = File.ReadAllText(file.FullName); - var mapping = JObject.Parse(fileContent); - - var getCount = mapping - .SelectTokens("$.Request.Methods[*]") - .Select(t => string.Equals(t.Value(), "GET", StringComparison.InvariantCultureIgnoreCase)) - .Count(); - - if (getCount > 0) - { - file.Delete(); - } - else - { - // Let's figure out a better name for the mappings - - - var method = mapping.SelectTokens("$.Request.Methods[0]").Value(); - var rpcMethod = ""; - var rpcBodyChecksum = ""; - var httpResponseStatus = ""; - - // Rename, so it's something like POST_Deposit_AFF123_200, POST_Deposit_FEF21C_400 - } - } - } - - server.Stop(); - } - } -} diff --git a/src/WiremockRecorder/WiremockRecorder.csproj b/src/WiremockRecorder/WiremockRecorder.csproj deleted file mode 100644 index f441c35..0000000 --- a/src/WiremockRecorder/WiremockRecorder.csproj +++ /dev/null @@ -1,15 +0,0 @@ - - - - Exe - net5.0 - - - - - - - - - - diff --git a/tests/Client.UnitTests/.runsettings b/tests/Client.UnitTests/.runsettings new file mode 100644 index 0000000..60e6ebe --- /dev/null +++ b/tests/Client.UnitTests/.runsettings @@ -0,0 +1,10 @@ + + + + + + Debug + 5 + + + diff --git a/tests/Client.UnitTests/AccountLedgerParserTest.cs b/tests/Client.UnitTests/AccountLedgerParserTest.cs index b988b04..8f335c3 100644 --- a/tests/Client.UnitTests/AccountLedgerParserTest.cs +++ b/tests/Client.UnitTests/AccountLedgerParserTest.cs @@ -1,8 +1,7 @@ using System; using Newtonsoft.Json; using NUnit.Framework; -using Trustly.Api.Domain.Base; -using Trustly.Api.Domain.Requests; +using Trustly.Api.Domain; namespace Trustly.Api.Client.UnitTests { @@ -45,14 +44,14 @@ public void TestParser() } }"; - var rpcResponse = JsonConvert.DeserializeObject>(jsonResponse); + var rpcResponse = JsonConvert.DeserializeObject(jsonResponse); - Assert.AreEqual(2, rpcResponse.Result.Data.Entries.Count); + Assert.That(rpcResponse.Result.Data.Count, Is.EqualTo(2)); - Assert.AreEqual("9e4345db-6093-bb35-07d3-e335f1e28793", rpcResponse.Result.UUID); - Assert.AreEqual("3839426635", rpcResponse.Result.Data.Entries[0].UserID); - Assert.AreEqual("5.00000000000000000000", rpcResponse.Result.Data.Entries[0].Amount); - Assert.AreEqual("-3.01", rpcResponse.Result.Data.Entries[1].Amount); + Assert.That(rpcResponse.Result.UUID, Is.EqualTo("9e4345db-6093-bb35-07d3-e335f1e28793")); + Assert.That(rpcResponse.Result.Data[0].UserID, Is.EqualTo("3839426635")); + Assert.That(rpcResponse.Result.Data[0].Amount, Is.EqualTo("5.00000000000000000000")); + Assert.That(rpcResponse.Result.Data[1].Amount, Is.EqualTo("-3.01")); } } } diff --git a/tests/Client.UnitTests/Client.UnitTests.csproj b/tests/Client.UnitTests/Client.UnitTests.csproj index 612909b..ace684c 100644 --- a/tests/Client.UnitTests/Client.UnitTests.csproj +++ b/tests/Client.UnitTests/Client.UnitTests.csproj @@ -1,24 +1,24 @@ - net472 + net481 false Trustly.Api.Client.UnitTests - + - + - - + + - + - + diff --git a/tests/Client.UnitTests/JsonRpcSignerTest.cs b/tests/Client.UnitTests/JsonRpcSignerTest.cs index 66962c0..6b5d867 100644 --- a/tests/Client.UnitTests/JsonRpcSignerTest.cs +++ b/tests/Client.UnitTests/JsonRpcSignerTest.cs @@ -1,7 +1,7 @@ using System; using NUnit.Framework; using Trustly.Api.Client; -using Trustly.Api.Domain.Requests; +using Trustly.Api.Domain; namespace Trustly.Api.Client.UnitTests { @@ -40,32 +40,37 @@ public void TestSerializingDeposit() Amount = "100.00", Currency = "SEK", Country = "SE", + Locale = "sv_SE", Firstname = "John", Lastname = "Doe", + Email = "test@trustly.com", + SuccessURL = "https://google.com?q=success", + FailURL = "https://google.com?q=fail", + ShopperStatement = "Shop", } }; - var jsonRpcRequest = factory.Create(requestData, "Deposit", "258a2184-2842-b485-25ca-293525152425"); + var jsonRpcRequest = factory.Create(requestData, "Deposit", "e43f9dd4-e0ee-4c0a-9464-b962d590cfac"); var serializer = new Serializer(); - var serialized = serializer.SerializeData(jsonRpcRequest.Params.Data); - var expectedSerialized = "AttributesAmount100.00CountrySECurrencySEKFirstnameJohnLastnameDoeEndUserID127.0.0.1MessageID82bdbc09-7605-4265-b416-1e9549397eddNotificationURLlocalhost:1000Passworda6e404c9-7ca8-1204-863d-5642e27c2747Usernameteam_ceres"; + var serialized = serializer.SerializeData(jsonRpcRequest.Params.Data, true); + var expectedSerialized = "AttributesAmount100.00CountrySECurrencySEKEmailtest@trustly.comFailURLhttps://google.com?q=failFirstnameJohnLastnameDoeLocalesv_SEShopperStatementShopSuccessURLhttps://google.com?q=successEndUserID127.0.0.1MessageID82bdbc09-7605-4265-b416-1e9549397eddNotificationURLlocalhost:1000Passworda6e404c9-7ca8-1204-863d-5642e27c2747Usernameteam_ceres"; - Assert.AreEqual(expectedSerialized, serialized); + Assert.That(serialized, Is.EqualTo(expectedSerialized)); var signer = new JsonRpcSigner(serializer, settings); var plaintext = signer.CreatePlaintext(serialized, jsonRpcRequest.Method, jsonRpcRequest.Params.UUID); - var expectedPlaintext = "Deposit258a2184-2842-b485-25ca-293525152425AttributesAmount100.00CountrySECurrencySEKFirstnameJohnLastnameDoeEndUserID127.0.0.1MessageID82bdbc09-7605-4265-b416-1e9549397eddNotificationURLlocalhost:1000Passworda6e404c9-7ca8-1204-863d-5642e27c2747Usernameteam_ceres"; + var expectedPlaintext = "Deposite43f9dd4-e0ee-4c0a-9464-b962d590cfacAttributesAmount100.00CountrySECurrencySEKEmailtest@trustly.comFailURLhttps://google.com?q=failFirstnameJohnLastnameDoeLocalesv_SEShopperStatementShopSuccessURLhttps://google.com?q=successEndUserID127.0.0.1MessageID82bdbc09-7605-4265-b416-1e9549397eddNotificationURLlocalhost:1000Passworda6e404c9-7ca8-1204-863d-5642e27c2747Usernameteam_ceres"; - Assert.AreEqual(expectedPlaintext, plaintext); + Assert.That(plaintext, Is.EqualTo(expectedPlaintext)); - signer.Sign(jsonRpcRequest); + var actualSignature = signer.CreateSignature(jsonRpcRequest.Method, jsonRpcRequest.Params.UUID, jsonRpcRequest.Params.Data); - var expectedSignature = "xRed4cLfZs2L5WoJVHiRFvD9yTTvbT0i/BgfhitnTvX7DpfmAz9cmGs3wcTpfYanGlW6hkY7zg7esuaGjPr3NvsWxLGLKBxw97oS7KDmp/FFPnrYulle4MsmKFH5jPB1HMZn2kybXO7a/v1QhVkyKgPGtGSznMBmR8iObbkBGjKbaHdpzwUR2HBK0bomwjIdG7Qx25UMTkMU8a9iNpvwXI71zO9/97DQJK3UiXCicJLNReOTtqcxWL/gUi9h/H7tK6M5kDeNtyRolOhznVZLX/rkFg7exhRvjPk8nEGjMJ3B1O4nEm/xFM0fh4uqfv8QyZrYEzX/K7cfNXflax4n0g=="; + var expectedSignature = "09zQ00rONzJK+j1Yc+q85SvKmQsGUT9uyysdsARPukhSRaFLmH84k/LW0hbW619GoV/DwAr3s/zQvFM5b8fT+SW9GX0Mf9OpMcK45RuEPlK+E2RBYPZhrKpb47RLeLmGMlI2dSmNc8kxotFh1zwQf2h8WWh1IGwmLobqn+Uun+AbC+uxi7PRkiqKBhRZtZlUPxyvUm05xd33RuB2uDrjEVeTQK9i99fO/EML/IviAQL4SebI6LfmfrP8HitkKvgcpjzVTCkkOwbb9spe/xLX8N/zRtdl7rUAAKBkyOtMuPoHjj1/F7BmPfTXnfAOBOeeWlEkDLcEzb8/agBH02H2GQ=="; - Assert.AreEqual(expectedSignature, jsonRpcRequest.Params.Signature); + Assert.That(actualSignature, Is.EqualTo(expectedSignature)); } } } \ No newline at end of file diff --git a/tests/Client.UnitTests/NotificationTests.cs b/tests/Client.UnitTests/NotificationTests.cs index 41e7046..9d6324f 100644 --- a/tests/Client.UnitTests/NotificationTests.cs +++ b/tests/Client.UnitTests/NotificationTests.cs @@ -6,9 +6,8 @@ using Moq; using Newtonsoft.Json; using NUnit.Framework; -using Trustly.Api.Domain.Base; +using Trustly.Api.Domain; using Trustly.Api.Domain.Exceptions; -using Trustly.Api.Domain.Notifications; namespace Trustly.Api.Client.Tests { @@ -42,12 +41,6 @@ public void SetUp() this.client = new TrustlyApiClient(settings); } - [TearDown] - public void TearDown() - { - this.client.Dispose(); - } - [Test] public async Task TestNotificationHandlerFromRequest() { @@ -58,9 +51,9 @@ public async Task TestNotificationHandlerFromRequest() }; var mockRequest = this.CreateMockDebitNotificationRequest(); - await client.HandleNotificationFromRequestAsync(mockRequest.Object); + await client.HandleNotificationFromRequestAsync(mockRequest.Object, str => Task.Delay(TimeSpan.MinValue)); - Assert.AreEqual(1, receivedDebitNotifications); + Assert.That(receivedDebitNotifications, Is.EqualTo(1)); } [Test] @@ -70,23 +63,28 @@ public async Task TestNotificationHandlerFromMiddlewareRequest() client.OnDebit += (sender, args) => { receivedDebitNotifications++; - args.RespondWithOK(); + args.Respond(new DebitNotificationResponseData + { + Status = DebitNotificationResponseDataStatus.OK + }); }; var mockRequest = this.CreateMockDebitNotificationRequest(); var mockHttpContext = new Mock(); var mockResponse = new Mock(); + var responseStream = new MemoryStream(); mockResponse.SetupAllProperties(); - mockResponse.Setup(r => r.Headers).Returns(new HeaderDictionary()); + mockResponse.Setup(_ => _.Headers).Returns(new HeaderDictionary()); + mockResponse.Setup(_ => _.Body).Returns(responseStream); - mockHttpContext.Setup(x => x.Request).Returns(mockRequest.Object); - mockHttpContext.Setup(x => x.Response).Returns(mockResponse.Object); + mockHttpContext.Setup(_ => _.Request).Returns(mockRequest.Object); + mockHttpContext.Setup(_ => _.Response).Returns(mockResponse.Object); - await TrustlyApiClientExtensions.HandleNotificationRequest(mockHttpContext.Object, null); + await TrustlyApiClientExtensions.HandleNotificationRequest(mockHttpContext.Object, null, client); - Assert.AreEqual(1, receivedDebitNotifications); - Assert.AreEqual(200, mockResponse.Object.StatusCode); + Assert.That(receivedDebitNotifications, Is.EqualTo(1)); + Assert.That(mockResponse.Object.StatusCode, Is.EqualTo(200)); } [Test] @@ -96,23 +94,59 @@ public async Task TestNotificationHandlerFromMiddlewareRequestWithErrorResponse( client.OnDebit += (sender, args) => { receivedDebitNotifications++; - args.RespondWithFailed("Things went badly"); + throw new InvalidOperationException("Things went badly"); }; var mockHttpContext = new DefaultHttpContext(); this.SetHttpRequestProperties(mockHttpContext.Request); mockHttpContext.Response.Body = new MemoryStream(); - await TrustlyApiClientExtensions.HandleNotificationRequest(mockHttpContext, null); + await TrustlyApiClientExtensions.HandleNotificationRequest(mockHttpContext, null, client); - Assert.AreEqual(1, receivedDebitNotifications); - Assert.AreEqual(500, mockHttpContext.Response.StatusCode); + Assert.That(receivedDebitNotifications, Is.EqualTo(1)); + Assert.That(mockHttpContext.Response.StatusCode, Is.EqualTo(500)); mockHttpContext.Response.Body.Position = 0; using (var sr = new StreamReader(mockHttpContext.Response.Body)) { var bodyString = sr.ReadToEnd(); - Assert.IsTrue(bodyString.Contains("Things went badly")); + Assert.That(bodyString, Is.EqualTo(TrustlyApiClientExtensions.GENERIC_ERROR_MESSAGE)); + } + } + + [Test] + public async Task TestNotificationHandlerFromMiddlewareRequestWithInternalErrorResponse() + { + var receivedDebitNotifications = 0; + var previous = client.Settings.IncludeExceptionMessageInNotificationResponse; + try + { + client.Settings.IncludeExceptionMessageInNotificationResponse = true; + client.OnDebit += (sender, args) => + { + receivedDebitNotifications++; + throw new InvalidOperationException("Things went badly"); + }; + + var mockHttpContext = new DefaultHttpContext(); + this.SetHttpRequestProperties(mockHttpContext.Request); + mockHttpContext.Response.Body = new MemoryStream(); + + await TrustlyApiClientExtensions.HandleNotificationRequest(mockHttpContext, null, client); + + Assert.That(receivedDebitNotifications, Is.EqualTo(1)); + Assert.That(500, Is.EqualTo(mockHttpContext.Response.StatusCode)); + + mockHttpContext.Response.Body.Position = 0; + using (var sr = new StreamReader(mockHttpContext.Response.Body)) + { + var bodyString = sr.ReadToEnd(); + Assert.That(bodyString, Is.EqualTo("Things went badly")); + } + } + finally + { + client.Settings.IncludeExceptionMessageInNotificationResponse = previous; } } @@ -131,7 +165,7 @@ public void TestNotificationHandlerFromMiddlewareRequestWithoutListener() Assert.ThrowsAsync(async () => { - await TrustlyApiClientExtensions.HandleNotificationRequest(mockHttpContext.Object, null); + await TrustlyApiClientExtensions.HandleNotificationRequest(mockHttpContext.Object, null, client); }); } @@ -148,10 +182,10 @@ public void TestNotificationHandlerFromRequestWithWrongHttpMethod() Assert.ThrowsAsync(async () => { - await client.HandleNotificationFromRequestAsync(mockRequest.Object); + await client.HandleNotificationFromRequestAsync(mockRequest.Object, str => Task.Delay(TimeSpan.MinValue)); }); - Assert.AreEqual(0, receivedDebitNotifications); + Assert.That(receivedDebitNotifications, Is.EqualTo(0)); } [Test] @@ -169,18 +203,21 @@ public async Task TestUnknownNotification() { receivedUnknownNotifications++; - Assert.IsFalse(args.Data.ExtensionData.ContainsKey("Amount")); - Assert.IsFalse(args.Data.ExtensionData.ContainsKey("EnduserID")); + Assert.That(args.Data.AdditionalProperties.ContainsKey("Amount"), Is.False); + Assert.That(args.Data.AdditionalProperties.ContainsKey("EnduserID"), Is.False); - Assert.AreEqual("100.00", args.Data.ExtensionData["amount"]); - Assert.AreEqual("user@email.com", args.Data.ExtensionData["enduserid"]); + Assert.That(args.Data.AdditionalProperties["Amount"], Is.Null); + Assert.That(args.Data.AdditionalProperties["EnduserID"], Is.Null); + + Assert.That(args.Data.AdditionalProperties.Value("amount"), Is.EqualTo("100.00")); + Assert.That(args.Data.AdditionalProperties.Value("enduserid"), Is.EqualTo("user@email.com")); }; var mockRequest = this.CreateMockDebitNotificationRequest(rpcMethod: "blaha"); - await client.HandleNotificationFromRequestAsync(mockRequest.Object); + await client.HandleNotificationFromRequestAsync(mockRequest.Object, str => Task.Delay(TimeSpan.MinValue)); - Assert.AreEqual(0, receivedDebitNotifications); - Assert.AreEqual(1, receivedUnknownNotifications); + Assert.That(receivedDebitNotifications, Is.EqualTo(0)); + Assert.That(receivedUnknownNotifications, Is.EqualTo(1)); } [Test] @@ -196,9 +233,9 @@ public async Task TestAccountNotification() }; var mockRequest = this.CreateMockAccountNotificationRequest(); - await client.HandleNotificationFromRequestAsync(mockRequest.Object); + await client.HandleNotificationFromRequestAsync(mockRequest.Object, str => Task.Delay(TimeSpan.MinValue)); - Assert.AreEqual(1, receivedCount); + Assert.That(receivedCount, Is.EqualTo(1)); } [Test] @@ -217,6 +254,7 @@ public void TestExpectedNotificationSerialization() + " \"verified\": \"0\",\n" + " \"accountid\": \"4052851907\",\n" + " \"messageid\": \"100137003A703263176\",\n" + + " \"notificationid\": \"123\",\n" + " \"attributes\": {\n" + " \"bank\": \"Commerzbank\",\n" + " \"descriptor\": \"****************441300\",\n" @@ -226,14 +264,14 @@ public void TestExpectedNotificationSerialization() + " }\n" + " }\n" + "}"; - var expectedSerialization = "accountid4052851907attributesbankCommerzbankclearinghouseGERMANYdescriptor****************441300lastdigits441300messageid100137003A703263176notificationidorderid7520047953verified0"; + var expectedSerialization = "accountid4052851907attributesbankCommerzbankclearinghouseGERMANYdescriptor****************441300lastdigits441300messageid100137003A703263176notificationid123orderid7520047953verified0"; - var rpcRequest = JsonConvert.DeserializeObject>(requestJson); + var rpcRequest = JsonConvert.DeserializeObject(requestJson); var serializer = new Serializer(); - var serializedData = serializer.SerializeData(rpcRequest.Params.Data); + var serializedData = serializer.SerializeData(rpcRequest.Params.Data, true); - Assert.AreEqual(expectedSerialization, serializedData); + Assert.That(serializedData, Is.EqualTo(expectedSerialization)); } [Test] @@ -252,19 +290,20 @@ public void TestExpectedNotificationSerializationWithEmptyAttributes() + " \"verified\": \"0\",\n" + " \"accountid\": \"4052851907\",\n" + " \"messageid\": \"100137003A703263176\",\n" + + " \"notificationid\": \"123\",\n" + " \"attributes\": {\n" + " }\n" + " }\n" + " }\n" + "}"; - var expectedSerialization = "accountid4052851907attributesmessageid100137003A703263176notificationidorderid7520047953verified0"; + var expectedSerialization = "accountid4052851907attributesmessageid100137003A703263176notificationid123orderid7520047953verified0"; - var rpcRequest = JsonConvert.DeserializeObject>(requestJson); + var rpcRequest = JsonConvert.DeserializeObject(requestJson); var serializer = new Serializer(); var serializedData = serializer.SerializeData(rpcRequest.Params.Data); - Assert.AreEqual(expectedSerialization, serializedData); + Assert.That(serializedData, Is.EqualTo(expectedSerialization)); } [Test] @@ -282,18 +321,19 @@ public void TestExpectedNotificationSerializationWithNullAttributes() + " \"orderid\": \"7520047953\",\n" + " \"verified\": \"0\",\n" + " \"accountid\": \"4052851907\",\n" - + " \"messageid\": \"100137003A703263176\"\n" + + " \"messageid\": \"100137003A703263176\",\n" + + " \"notificationid\": \"123\"\n" + " }\n" + " }\n" + "}"; - var expectedSerialization = "accountid4052851907messageid100137003A703263176notificationidorderid7520047953verified0"; + var expectedSerialization = "accountid4052851907messageid100137003A703263176notificationid123orderid7520047953verified0"; - var rpcRequest = JsonConvert.DeserializeObject>(requestJson); + var rpcRequest = JsonConvert.DeserializeObject(requestJson); var serializer = new Serializer(); var serializedData = serializer.SerializeData(rpcRequest.Params.Data); - Assert.AreEqual(expectedSerialization, serializedData); + Assert.That(serializedData, Is.EqualTo(expectedSerialization)); } private Mock CreateMockDebitNotificationRequest(string method = "POST", string rpcMethod = "debit") @@ -329,23 +369,43 @@ private void SetHttpRequestProperties(HttpRequest request, string method = "POST request.Path = "/trustly/notifications"; } - private Stream CreateMockDebitNotificationRequestBody(String rpcMethod) + public class DebitIshNotificationRequest : JsonRpcNotification> { - var json = JsonConvert.SerializeObject( - client.CreateRequestPackage( - new DebitNotificationData - { - Amount = "100.00", - Currency = "EUR", - EnduserID = "user@email.com", - MessageID = Guid.NewGuid().ToString(), - OrderID = Guid.NewGuid().ToString(), - NotificationID = Guid.NewGuid().ToString(), - Timestamp = "2021-01-01 01:01:01" - }, - rpcMethod - ) + public DebitIshNotificationRequest(string rpcMethod) : base(rpcMethod) { } + } + + private Stream CreateMockDebitNotificationRequestBody(string rpcMethod) + { + var debitParamsData = new DebitDefaultNotificationData + { + Amount = "100.00", + Currency = "EUR", + EndUserID = "user@email.com", + MessageID = Guid.NewGuid().ToString(), + OrderID = Guid.NewGuid().ToString(), + NotificationID = Guid.NewGuid().ToString(), + Timestamp = "2021-01-01 01:01:01" + }; + + var debitParams = new JsonRpcNotificationParams + { + UUID = Guid.NewGuid().ToString(), + Data = debitParamsData, + }; + + var debitNotification = new DebitIshNotificationRequest(rpcMethod) + { + Params = debitParams, + }; + + debitNotification.Params.Signature = this.client.Signer.CreateSignature( + debitNotification.Method, + debitNotification.Params.UUID, + debitNotification.Params.Data ); + //this._validator.Validate(debitNotification); + + var json = JsonConvert.SerializeObject(debitNotification); var byteArray = Encoding.UTF8.GetBytes(json); return new MemoryStream(byteArray); @@ -359,18 +419,18 @@ private Mock CreateMockAccountNotificationRequest(string method = " mockRequest.Setup(x => x.Body).Returns(() => { - var json = JsonConvert.SerializeObject( - client.CreateRequestPackage( - new AccountNotificationData - { + var mandateNotification = new AccountMandateNotification { + Params = new AccountMandateNotificationParams { + UUID = Guid.NewGuid().ToString(), + Data = new AccountMandateNotificationData { MessageID = Guid.NewGuid().ToString(), OrderID = Guid.NewGuid().ToString(), NotificationID = Guid.NewGuid().ToString(), AccountID = "123", - Verified = "1", - Attributes = new AccountNotificationDataAttributes + Verified = StringBoolean.TRUE, + Attributes = new AccountMandateNotificationDataAttributes { - Clearinghouse = "SWEDEN", + ClearingHouse = "SWEDEN", Bank = "The Bank", Descriptor = "**** *084057", Lastdigits = "084057", @@ -381,10 +441,18 @@ private Mock CreateMockAccountNotificationRequest(string method = " City = "Examplecity", DirectDebitMandate = 0 } - }, - "account" - ) + } + } + }; + + mandateNotification.Params.Signature = this.client.Signer.CreateSignature( + mandateNotification.Method, + mandateNotification.Params.UUID, + mandateNotification.Params.Data ); + //this._validator.Validate(debitNotification); + + var json = JsonConvert.SerializeObject(mandateNotification); var byteArray = Encoding.UTF8.GetBytes(json); var stream = new MemoryStream(byteArray); diff --git a/tests/Client.UnitTests/RequestTests.cs b/tests/Client.UnitTests/RequestTests.cs index 4003143..bef9926 100644 --- a/tests/Client.UnitTests/RequestTests.cs +++ b/tests/Client.UnitTests/RequestTests.cs @@ -1,11 +1,9 @@ using System; using NUnit.Framework; -using Trustly.Api.Client; using Trustly.Api.Domain.Exceptions; -using System.Threading.Tasks; -using Trustly.Api.Domain.Base; using Newtonsoft.Json; using System.Net; +using Trustly.Api.Domain; namespace Trustly.Api.Client.Tests { @@ -22,29 +20,29 @@ public void SetUp() [Test] public void TestAccountLedger() { - var response = client.AccountLedger(new Trustly.Api.Domain.Requests.AccountLedgerRequestData + var response = client.AccountLedger(new AccountLedgerRequestData { Currency = "SEK", FromDate = "2010-01-01 00:00:00", ToDate = "2021-01-01 00:00.00" }); - Assert.NotNull(response); - Assert.NotNull(response.Entries); + Assert.That(response, Is.Not.Null); } - private class FooAttributes : AbstractRequestParamsDataAttributes + private class FooAttributes : AbstractRequestDataAttributes { public string NationalIdentificationNumber { get; set; } } - private class FooRequestData : AbstractToTrustlyRequestParamsData + private class FooRequestData : AbstractRequestData { public string EndUserID { get; set; } public string ClearingHouse { get; set; } + //public FooAttributes Attributes { get; set; } } - private class FooResponse : AbstractResponseResultData + private class FooResponseData //: AbstractResponseResult { [JsonProperty("descriptor")] public string Descriptor { get; set; } @@ -55,7 +53,7 @@ public void TestCustomInvalidFunction() { var ex = Assert.Throws(() => { - var response = client.SendRequest(new FooRequestData + var response = client.SendRequest(new FooRequestData { EndUserID = "123", ClearingHouse = "CLRNGHS", @@ -66,7 +64,7 @@ public void TestCustomInvalidFunction() }, "Foo", Guid.NewGuid().ToString()); }); - Assert.AreEqual("ERROR_INVALID_FUNCTION", ex.ResponseError.Message); + Assert.That(ex.ResponseError.Message, Is.EqualTo("ERROR_INVALID_FUNCTION")); } [Test] @@ -74,7 +72,7 @@ public void TestAccountPayout() { var ex = Assert.Throws(() => { - var response = client.AccountPayout(new Trustly.Api.Domain.Requests.AccountPayoutRequestData + var response = client.AccountPayout(new AccountPayoutRequestData { NotificationURL = "https://fake.test.notification.trustly.com", MessageID = Guid.NewGuid().ToString(), @@ -83,15 +81,15 @@ public void TestAccountPayout() Currency = "SEK", Amount = "100.1", - Attributes = new Trustly.Api.Domain.Requests.AccountPayoutRequestDataAttributes + Attributes = new AccountPayoutRequestDataAttributes { ShopperStatement = "A Shopper Statement" } }); }); - Assert.AreEqual("ERROR_INVALID_BANK_ACCOUNT_NUMBER", ex.ResponseError.Message); - Assert.AreEqual("ERROR_INVALID_BANK_ACCOUNT_NUMBER", ex.ResponseError.Error.Data.Message); + Assert.That(ex.ResponseError.Message, Is.EqualTo("ERROR_INVALID_BANK_ACCOUNT_NUMBER")); + Assert.That(ex.ResponseError.Error.Data.AdditionalProperties["message"].ToString(), Is.EqualTo("ERROR_INVALID_BANK_ACCOUNT_NUMBER")); } [Test] @@ -99,24 +97,23 @@ public void TestApproveWithdrawal() { var ex = Assert.Throws(() => { - var response = client.ApproveWithdrawal(new Trustly.Api.Domain.Requests.ApproveWithdrawalRequestData + var response = client.ApproveWithdrawal(new ApproveWithdrawalRequestData { OrderID = 123_123 }); }); - Assert.AreEqual("ERROR_NOT_FOUND", ex.ResponseError.Message); + Assert.That(ex.ResponseError.Message, Is.EqualTo("ERROR_NOT_FOUND")); } [Test] public void TestBalance() { - var response = client.Balance(new Trustly.Api.Domain.Requests.BalanceRequestData + var response = client.Balance(new BalanceRequestData { }); - Assert.NotNull(response); - Assert.NotNull(response.Entries); // If not null, then something has been set, even if empty. + Assert.That(response, Is.Not.Null); // TODO: If empty, can we somehow do a deposit from the API, to simulate one? } @@ -126,13 +123,13 @@ public void TestCancelCharge() { var ex = Assert.Throws(() => { - var response = client.CancelCharge(new Trustly.Api.Domain.Requests.CancelChargeRequestData + var response = client.CancelCharge(new CancelChargeRequestData { - OrderId = "123123" + OrderID = "123123" }); }); - Assert.AreEqual("ERROR_INVALID_ORDER_ID", ex.ResponseError.Message); + Assert.That(ex.ResponseError.Message, Is.EqualTo("ERROR_INVALID_ORDER_ID")); } [Test] @@ -140,7 +137,7 @@ public void TestCharge() { var ex = Assert.Throws(() => { - var response = client.Charge(new Trustly.Api.Domain.Requests.ChargeRequestData + var response = client.Charge(new ChargeRequestData { NotificationURL = "https://fake.test.notification.trustly.com", @@ -150,7 +147,7 @@ public void TestCharge() Amount = "100.00", EndUserID = "pontus.eliason@trustly.com", - Attributes = new Trustly.Api.Domain.Requests.ChargeRequestDataAttributes + Attributes = new ChargeRequestDataAttributes { Email = "pontus.eliason@trustly.com", ShopperStatement = "A Shopper Statement" @@ -158,7 +155,7 @@ public void TestCharge() }); }); - Assert.AreEqual("ERROR_ACCOUNT_NOT_FOUND", ex.Reason); + Assert.That(ex.Reason, Is.EqualTo("ERROR_ACCOUNT_NOT_FOUND")); } [Test] @@ -166,19 +163,19 @@ public void TestDenyWithdrawals() { var ex = Assert.Throws(() => { - var response = client.DenyWithdrawal(new Trustly.Api.Domain.Requests.DenyWithdrawalRequestData + var response = client.DenyWithdrawal(new DenyWithdrawalRequestData { OrderID = 123_123 }); }); - Assert.AreEqual("ERROR_NOT_FOUND", ex.ResponseError.Message); + Assert.That(ex.ResponseError.Message, Is.EqualTo("ERROR_NOT_FOUND")); } [Test] public void TestRegisterAccount() { - var response = client.RegisterAccount(new Trustly.Api.Domain.Requests.RegisterAccountRequestData + var response = client.RegisterAccount(new RegisterAccountRequestData { EndUserID = "123123", ClearingHouse = "SWEDEN", @@ -186,7 +183,7 @@ public void TestRegisterAccount() AccountNumber = "69706212", Firstname = "Steve", Lastname = "Smith", - Attributes = new Trustly.Api.Domain.Requests.RegisterAccountRequestDataAttributes + Attributes = new RegisterAccountRequestDataAttributes { DateOfBirth = "1979-01-31", MobilePhone = "+46709876543", @@ -201,16 +198,16 @@ public void TestRegisterAccount() } }); - Assert.NotNull(response); - Assert.AreEqual(response.Descriptor, "**706212"); - Assert.AreEqual(response.ClearingHouse, "SWEDEN"); - Assert.AreEqual(response.Bank, "Handelsbanken"); + Assert.That(response, Is.Not.Null); + Assert.That("**706212", Is.EqualTo(response.Descriptor)); + Assert.That("SWEDEN", Is.EqualTo(response.ClearingHouse)); + Assert.That("Handelsbanken", Is.EqualTo(response.Bank)); } [Test] public void TestRegisterAccountPayout() { - var response = client.RegisterAccountPayout(new Trustly.Api.Domain.Requests.RegisterAccountPayoutRequestData + var response = client.RegisterAccountPayout(new RegisterAccountPayoutRequestData { EndUserID = "123123", ClearingHouse = "SWEDEN", @@ -223,7 +220,7 @@ public void TestRegisterAccountPayout() Currency = "SEK", Amount = "100.1", - Attributes = new Trustly.Api.Domain.Requests.RegisterAccountPayoutRequestDataAttributes + Attributes = new RegisterAccountPayoutRequestDataAttributes { DateOfBirth = "1979-01-31", MobilePhone = "+46709876543", @@ -239,20 +236,19 @@ public void TestRegisterAccountPayout() } }); - Assert.NotNull(response); - Assert.NotNull(response.OrderID); + Assert.That(response, Is.Not.Null); + Assert.That(response.OrderID, Is.Not.Null); } - [Test] public void TestDeposit() { - var response = client.Deposit(new Trustly.Api.Domain.Requests.DepositRequestData + var response = client.Deposit(new DepositRequestData { NotificationURL = "https://fake.test.notification.trustly.com", MessageID = Guid.NewGuid().ToString(), EndUserID = "pontus.eliason@trustly.com", - Attributes = new Trustly.Api.Domain.Requests.DepositRequestDataAttributes + Attributes = new DepositRequestDataAttributes { Amount = "100.00", Firstname = "John", @@ -261,12 +257,14 @@ public void TestDeposit() Currency = "EUR", Country = "SE", Locale = "sv_SE", - ShopperStatement = "Trustly Test Deposit" + ShopperStatement = "Trustly Test Deposit", + SuccessURL = "https://google.com?q=success", + FailURL = "https://google.com?q=fail", } }); - Assert.NotNull(response); - Assert.IsFalse(string.IsNullOrEmpty(response.URL)); + Assert.That(response, Is.Not.Null); + Assert.That(response.URL, Is.Not.Empty); } [Test] @@ -285,12 +283,12 @@ public void TestDepositWithCustomProxyClient() } }; - var response = proxyClient.Deposit(new Trustly.Api.Domain.Requests.DepositRequestData + var response = proxyClient.Deposit(new DepositRequestData { NotificationURL = "https://fake.test.notification.trustly.com", MessageID = Guid.NewGuid().ToString(), EndUserID = "pontus.eliason@trustly.com", - Attributes = new Trustly.Api.Domain.Requests.DepositRequestDataAttributes + Attributes = new DepositRequestDataAttributes { Amount = "100.00", Firstname = "John", @@ -299,26 +297,27 @@ public void TestDepositWithCustomProxyClient() Currency = "EUR", Country = "SE", Locale = "sv_SE", - ShopperStatement = "Trustly Test Deposit" + ShopperStatement = "Trustly Test Deposit", + SuccessURL = "https://google.com?q=success", + FailURL = "https://google.com?q=fail", } }); - Assert.NotNull(response); - Assert.IsFalse(string.IsNullOrEmpty(response.URL)); - Assert.AreEqual(1, callCount); + Assert.That(response, Is.Not.Null); + Assert.That(response.URL, Is.Not.Empty); + Assert.That(callCount, Is.EqualTo(1)); } [Test] public void TestGetWithdrawals() { // GetWithdrawals seems to work even if the OrderID does not exist. - var response = client.GetWithdrawals(new Trustly.Api.Domain.Requests.GetWithdrawalsRequestData + var response = client.GetWithdrawals(new GetWithdrawalsRequestData { - OrderID = "123123" + OrderID = 123123 }); - Assert.NotNull(response); - Assert.NotNull(response.Entries); // If not null, at least something was set + Assert.That(response, Is.Not.Null); } [Test] @@ -326,46 +325,45 @@ public void TestRefund() { var ex = Assert.Throws(() => { - var response = client.Refund(new Trustly.Api.Domain.Requests.RefundRequestData + var response = client.Refund(new RefundRequestData { OrderID = "123123", Currency = "SEK", Amount = "100.00", - Attributes = new Trustly.Api.Domain.Requests.RefundRequestDataAttributes + Attributes = new RefundRequestDataAttributes { ExternalReference = "Reference" + new Random().Next() } }); }); - Assert.NotNull("ERROR_INVALID_ORDER_ID", ex.ResponseError.Message); + Assert.That(ex.ResponseError.Message, Is.EqualTo("ERROR_INVALID_ORDER_ID")); } [Ignore("It gives ERROR_UNKNOWN if empty response is returned. Not trustworthy.")] [Test] public void TestSettlementReport() { - var response = client.SettlementReport(new Trustly.Api.Domain.Requests.SettlementReportRequestData + var response = client.SettlementReport(new SettlementReportRequestData { Currency = "SEK", SettlementDate = "2020-01-01 00:00:00" }); - Assert.NotNull(response); - Assert.NotNull(response.Entries); // If not null, something was set. + Assert.That(response, Is.Not.Null); } [Test] public void TestWithdraw() { - var response = client.Withdraw(new Trustly.Api.Domain.Requests.WithdrawRequestData + var response = client.Withdraw(new WithdrawRequestData { NotificationURL = "https://fake.test.notification.trustly.com", MessageID = Guid.NewGuid().ToString(), EndUserID = "pontus.eliason@trustly.com", Currency = "SEK", - Attributes = new Trustly.Api.Domain.Requests.WithdrawRequestDataAttributes + Attributes = new WithdrawRequestDataAttributes { SuggestedAmount = "100.00", SuggestedMinAmount = "10.00", @@ -375,12 +373,14 @@ public void TestWithdraw() Email = "pontus.eliason@trustly.com", Country = "SE", Locale = "sv_SE", - ShopperStatement = "Trustly Test Deposit" + ShopperStatement = "Trustly Test Deposit", + SuccessURL = "https://google.com?q=success", + FailURL = "https://google.com?q=fail", } }); - Assert.NotNull(response); - Assert.IsFalse(string.IsNullOrEmpty(response.URL)); + Assert.That(response, Is.Not.Null); + Assert.That(response.URL, Is.Not.Empty); } } } \ No newline at end of file diff --git a/tests/Client.UnitTests/SerializerTest.cs b/tests/Client.UnitTests/SerializerTest.cs index 3582f5b..db21064 100644 --- a/tests/Client.UnitTests/SerializerTest.cs +++ b/tests/Client.UnitTests/SerializerTest.cs @@ -1,9 +1,9 @@ +using Newtonsoft.Json; using NUnit.Framework; using Trustly.Api.Client; -using Trustly.Api.Domain.Base; +using Trustly.Api.Domain; using Trustly.Api.Domain.Exceptions; using Trustly.Api.Domain.Notifications; -using Trustly.Api.Domain.Requests; namespace Trustly.Api.Client.UnitTests { @@ -15,7 +15,7 @@ public void TestSerializingDepositWithoutValidation() var serializer = new Serializer(); var factory = new JsonRpcFactory(); - var jsonRpc = factory.Create(new DepositRequestData + var jsonRpc = factory.Create(new DepositRequestData { Username = "merchant_username", Password = "merchant_password", @@ -25,19 +25,23 @@ public void TestSerializingDepositWithoutValidation() Attributes = new DepositRequestDataAttributes { Locale = "sv_SE", + Country = "sv", Currency = "SEK", IP = "123.123.123.123", MobilePhone = "+46709876543", + Email = "test@trustly.com", Firstname = "John", Lastname = "Doe", - NationalIdentificationNumber = "790131-1234" + NationalIdentificationNumber = "790131-1234", + SuccessURL = "https://google.com/?q=success", + FailURL = "https://google.com/?q=fail" } }, "Deposit"); - var serialized = serializer.SerializeData(jsonRpc.Params.Data); - var expected = "AttributesCurrencySEKFirstnameJohnIP123.123.123.123LastnameDoeLocalesv_SEMobilePhone+46709876543NationalIdentificationNumber790131-1234EndUserID12345MessageIDyour_unique_deposit_idNotificationURLURL_to_your_notification_servicePasswordmerchant_passwordUsernamemerchant_username"; + var serialized = serializer.SerializeData(jsonRpc.Params.Data, true); + var expected = "AttributesCountrysvCurrencySEKEmailtest@trustly.comFailURLhttps://google.com/?q=failFirstnameJohnIP123.123.123.123LastnameDoeLocalesv_SEMobilePhone+46709876543NationalIdentificationNumber790131-1234SuccessURLhttps://google.com/?q=successEndUserID12345MessageIDyour_unique_deposit_idNotificationURLURL_to_your_notification_servicePasswordmerchant_passwordUsernamemerchant_username"; - Assert.AreEqual(expected, serialized); + Assert.That(serialized, Is.EqualTo(expected)); } [Test] @@ -63,18 +67,21 @@ public void TestNullProperties() var client = new TrustlyApiClient(settings); var signer = new JsonRpcSigner(serializer, settings); - var rpcResponse = client.CreateResponsePackage("account", "e76ffbe5-e0f9-4402-8689-f868ed2021f8", new NotificationResponse { Status = "OK" }); + var rpcResponse = client.CreateResponsePackage(new AckData() { Status = AckDataStatus.OK }, "account", "e76ffbe5-e0f9-4402-8689-f868ed2021f8"); - var serialized = serializer.SerializeData(rpcResponse.GetData()); + var serialized = serializer.SerializeData(rpcResponse.Result.Data); - Assert.AreEqual("statusOK", serialized); + Assert.That(serialized, Is.EqualTo("statusOK")); - signer.Sign(rpcResponse); - - Assert.AreEqual( - "J28IN0yXZN3dlV2ikg4nQKwnP98kso8lzpmuwBcfbXr8i3XeEyydRM4jRwsOOeF0ilGuXyr1Kyb3+1j4mVtgU0SwjVgBHWrYPMegNeykY3meto/aoATH0mvop4Ex1OKO7w/S/ktR2J0J5Npn/EuiKGiVy5GztHYTh9hWmZBCElYPZf4Rsd1CJQJAPlZeAuRcrb5dnbiGJvTEaL/7VLcPT27oqAUefSNb/zNt5yL+wH6BihlkpZ/mtE61lX5OpC46iql6hpsrlOBD3BroYfcwgk1t3YdcNOhVWrmkrlVptGQ/oy6T/LSIKbkG/tJsuV8sl6w1Z31IesK6MZDfSJbcXw==", - rpcResponse.GetSignature() + var actualSignature = signer.CreateSignature( + rpcResponse.Result.Method, + rpcResponse.Result.UUID, + rpcResponse.Result.Data ); + + Assert.That(actualSignature, Is.EqualTo( + "J28IN0yXZN3dlV2ikg4nQKwnP98kso8lzpmuwBcfbXr8i3XeEyydRM4jRwsOOeF0ilGuXyr1Kyb3+1j4mVtgU0SwjVgBHWrYPMegNeykY3meto/aoATH0mvop4Ex1OKO7w/S/ktR2J0J5Npn/EuiKGiVy5GztHYTh9hWmZBCElYPZf4Rsd1CJQJAPlZeAuRcrb5dnbiGJvTEaL/7VLcPT27oqAUefSNb/zNt5yL+wH6BihlkpZ/mtE61lX5OpC46iql6hpsrlOBD3BroYfcwgk1t3YdcNOhVWrmkrlVptGQ/oy6T/LSIKbkG/tJsuV8sl6w1Z31IesK6MZDfSJbcXw==" + )); } [Test] @@ -84,7 +91,7 @@ public void TestMissingDepositShopperStatement() var factory = new JsonRpcFactory(); var validator = new JsonRpcValidator(); - var jsonRpc = factory.Create(new DepositRequestData + var jsonRpc = factory.Create(new DepositRequestData { Username = "merchant_username", Password = "merchant_password", @@ -100,9 +107,13 @@ public void TestMissingDepositShopperStatement() MobilePhone = "+46709876543", Firstname = "John", Lastname = "Doe", - NationalIdentificationNumber = "790131-1234" + NationalIdentificationNumber = "790131-1234", + Email = "test@trustly.com", + SuccessURL = "https://google.com/?q=success", + FailURL = "https://google.com/?q=fail" } }, "Deposit"); + jsonRpc.Params.Signature = "FakeSignature"; Assert.Throws(() => { @@ -113,5 +124,24 @@ public void TestMissingDepositShopperStatement() validator.Validate(jsonRpc); } + + public class UrlTargetWrapper + { + [JsonProperty("target")] + public UrlTarget Target { get; set; } + } + + [Test] + public void TestUrlTarget() + { + var json = "{\"target\":\"_self\"}"; + var obj = JsonConvert.DeserializeObject(json); + + Assert.That(obj.Target, Is.EqualTo(UrlTarget.SELF)); + + var backToJson = JsonConvert.SerializeObject(obj); + + Assert.That(backToJson, Is.EqualTo(json)); + } } } \ No newline at end of file diff --git a/tests/Client.UnitTests/SettlementReportParserTest.cs b/tests/Client.UnitTests/SettlementReportParserTest.cs index a98bda8..0eab971 100644 --- a/tests/Client.UnitTests/SettlementReportParserTest.cs +++ b/tests/Client.UnitTests/SettlementReportParserTest.cs @@ -25,15 +25,15 @@ public void TestParser() var rows = parser.Parse(csv); - Assert.AreEqual(10, rows.Count); - Assert.AreEqual("SUSPENSE_ACCOUNT_CLIENT_FUNDS_FINLAND_OKOY", rows[0].AccountName); - Assert.AreEqual("TRANSACTION_FEE_BANK_WITHDRAWAL", rows[9].AccountName); + Assert.That(rows.Count, Is.EqualTo(10)); + Assert.That(rows[0].AccountName, Is.EqualTo("SUSPENSE_ACCOUNT_CLIENT_FUNDS_FINLAND_OKOY")); + Assert.That(rows[9].AccountName, Is.EqualTo("TRANSACTION_FEE_BANK_WITHDRAWAL")); - Assert.AreEqual("1434179572", rows[0].SettlementBankWithdrawalID); - Assert.AreEqual("1434179572", rows[9].SettlementBankWithdrawalID); + Assert.That(rows[0].SettlementBankWithdrawalId, Is.EqualTo("1434179572")); + Assert.That(rows[9].SettlementBankWithdrawalId, Is.EqualTo("1434179572")); - Assert.AreEqual(null, rows[0].ExternalReference); - Assert.AreEqual("someref", rows[9].ExternalReference); + Assert.That(rows[0].ExternalReference, Is.Null); + Assert.That(rows[9].ExternalReference, Is.EqualTo("someref")); } } } diff --git a/trustly-client-net.sln b/trustly-client-net.sln index f965d07..8c2de47 100644 --- a/trustly-client-net.sln +++ b/trustly-client-net.sln @@ -13,15 +13,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Domain", "src\Domain\Domain EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client", "src\Client\Client.csproj", "{05296A4D-D1DC-4377-94AC-BFCEF0A1C927}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Trustly.Website", "src\Website\Trustly.Website.csproj", "{30E9E7A9-7C78-43FB-A2DD-DB7681AD451F}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{9A6EE2F0-3CB1-4FA1-9357-388DEEF0EEC9}" ProjectSection(SolutionItems) = preProject nuget.config = nuget.config EndProjectSection EndProject -Project("{9344BDBB-3E7F-41FC-A0DD-8665D75EE146}") = "WiremockRecorder", "src\WiremockRecorder\WiremockRecorder.csproj", "{E1F6D8B3-6B54-4443-8AA1-FA1645D4EA1F}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -50,24 +46,11 @@ Global {05296A4D-D1DC-4377-94AC-BFCEF0A1C927}.Release|Any CPU.Build.0 = Release|Any CPU {05296A4D-D1DC-4377-94AC-BFCEF0A1C927}.Default|Any CPU.ActiveCfg = Debug|Any CPU {05296A4D-D1DC-4377-94AC-BFCEF0A1C927}.Default|Any CPU.Build.0 = Debug|Any CPU - {30E9E7A9-7C78-43FB-A2DD-DB7681AD451F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {30E9E7A9-7C78-43FB-A2DD-DB7681AD451F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {30E9E7A9-7C78-43FB-A2DD-DB7681AD451F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {30E9E7A9-7C78-43FB-A2DD-DB7681AD451F}.Release|Any CPU.Build.0 = Release|Any CPU - {30E9E7A9-7C78-43FB-A2DD-DB7681AD451F}.Default|Any CPU.ActiveCfg = Debug|Any CPU - {30E9E7A9-7C78-43FB-A2DD-DB7681AD451F}.Default|Any CPU.Build.0 = Debug|Any CPU - {E1F6D8B3-6B54-4443-8AA1-FA1645D4EA1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E1F6D8B3-6B54-4443-8AA1-FA1645D4EA1F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E1F6D8B3-6B54-4443-8AA1-FA1645D4EA1F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E1F6D8B3-6B54-4443-8AA1-FA1645D4EA1F}.Release|Any CPU.Build.0 = Release|Any CPU - {E1F6D8B3-6B54-4443-8AA1-FA1645D4EA1F}.Default|Any CPU.ActiveCfg = Default|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {E92A565A-40CF-4963-AD34-B79A5D7EA8DC} = {664D406C-2F83-48F0-BFC3-408D5CB53C65} {57F73BC3-8014-4DAC-AB7B-5309B5F1FDBA} = {6ED356A7-8B47-4613-AD01-C85CF28491BD} {05296A4D-D1DC-4377-94AC-BFCEF0A1C927} = {6ED356A7-8B47-4613-AD01-C85CF28491BD} - {30E9E7A9-7C78-43FB-A2DD-DB7681AD451F} = {6ED356A7-8B47-4613-AD01-C85CF28491BD} - {E1F6D8B3-6B54-4443-8AA1-FA1645D4EA1F} = {6ED356A7-8B47-4613-AD01-C85CF28491BD} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {3CB609D9-5D54-4C11-A371-DAAC8B74E430} From b2654a5a4e90531c95109dc701f3a2b7c7e71c32 Mon Sep 17 00:00:00 2001 From: Pontus Eliason Date: Thu, 19 Sep 2024 09:16:20 +0200 Subject: [PATCH 2/6] being able to set notification listener url --- src/Client/TrustlyApiClientExtensions.cs | 2 +- src/Client/TrustlyApiClientSettings.cs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Client/TrustlyApiClientExtensions.cs b/src/Client/TrustlyApiClientExtensions.cs index b5b3083..8b46561 100644 --- a/src/Client/TrustlyApiClientExtensions.cs +++ b/src/Client/TrustlyApiClientExtensions.cs @@ -29,7 +29,7 @@ public async static Task HandleNotificationRequest(HttpContext context, Func Date: Mon, 23 Sep 2024 10:47:31 +0200 Subject: [PATCH 3/6] Fix JToken conversion type --- src/Client/Serializer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Client/Serializer.cs b/src/Client/Serializer.cs index 7d9259a..d5a91b6 100644 --- a/src/Client/Serializer.cs +++ b/src/Client/Serializer.cs @@ -10,12 +10,12 @@ public class Serializer { public string SerializeData(TData data, bool silent = false) { - JObject jsonObject; + JToken jsonObject; if (data is JToken token) { // If the value to serialize is already a JToken, then we will assume it is an object. // We can also work on the actual exact response, and not rely on flaky JSON -> DTO -> JSON -> String conversion. - jsonObject = (JObject) token; + jsonObject = (JToken) token; } else { From 21095bcaaeea8c75cf34ce1c4dee04e61b9eb8f6 Mon Sep 17 00:00:00 2001 From: Pontus Eliason Date: Tue, 24 Sep 2024 10:09:57 +0200 Subject: [PATCH 4/6] Better null handling in test case --- src/Client/TrustlyApiClient.cs | 13 +++++++------ tests/Client.UnitTests/NotificationTests.cs | 12 +++++------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/Client/TrustlyApiClient.cs b/src/Client/TrustlyApiClient.cs index f2e562c..e9b9ac5 100644 --- a/src/Client/TrustlyApiClient.cs +++ b/src/Client/TrustlyApiClient.cs @@ -15,6 +15,11 @@ namespace Trustly.Api.Client { public class TrustlyApiClient { + public static JsonSerializerSettings DEFAULT_SERIALIZER_SETTINGS = new JsonSerializerSettings + { + NullValueHandling = NullValueHandling.Ignore + }; + public TrustlyApiClientSettings Settings { get; } private readonly JsonRpcFactory _objectFactory = new JsonRpcFactory(); @@ -37,10 +42,7 @@ public class TrustlyApiClient public TrustlyApiClient(TrustlyApiClientSettings settings) { - this.SerializerSettings = new JsonSerializerSettings - { - NullValueHandling = NullValueHandling.Ignore - }; + this.SerializerSettings = TrustlyApiClient.DEFAULT_SERIALIZER_SETTINGS; this._serializer = new Serializer(); this.Settings = settings; this.Signer = new JsonRpcSigner(_serializer, this.Settings); @@ -248,7 +250,6 @@ private int HandleNotification( NotificationRespondDelegate callback ) { - if (eventHandler == null) { return 0; @@ -257,7 +258,7 @@ NotificationRespondDelegate callback var notification = token.ToObject>>(); // Verify the notification (RpcRequest from Trustly) signature. - if (!this.Signer.Verify(notification.Method, notification.Params.UUID, notification.Params.Data, notification.Params.Signature)) + if (!this.Signer.Verify(notification.Method, notification.Params.UUID, token["params"]["data"], notification.Params.Signature)) { throw new TrustlySignatureException("Could not validate signature of notification from Trustly. Is the public key for Trustly the correct one, for test or production?"); } diff --git a/tests/Client.UnitTests/NotificationTests.cs b/tests/Client.UnitTests/NotificationTests.cs index 9d6324f..3b80fc8 100644 --- a/tests/Client.UnitTests/NotificationTests.cs +++ b/tests/Client.UnitTests/NotificationTests.cs @@ -266,7 +266,7 @@ public void TestExpectedNotificationSerialization() + "}"; var expectedSerialization = "accountid4052851907attributesbankCommerzbankclearinghouseGERMANYdescriptor****************441300lastdigits441300messageid100137003A703263176notificationid123orderid7520047953verified0"; - var rpcRequest = JsonConvert.DeserializeObject(requestJson); + var rpcRequest = JsonConvert.DeserializeObject(requestJson, TrustlyApiClient.DEFAULT_SERIALIZER_SETTINGS); var serializer = new Serializer(); var serializedData = serializer.SerializeData(rpcRequest.Params.Data, true); @@ -298,7 +298,7 @@ public void TestExpectedNotificationSerializationWithEmptyAttributes() + "}"; var expectedSerialization = "accountid4052851907attributesmessageid100137003A703263176notificationid123orderid7520047953verified0"; - var rpcRequest = JsonConvert.DeserializeObject(requestJson); + var rpcRequest = JsonConvert.DeserializeObject(requestJson, TrustlyApiClient.DEFAULT_SERIALIZER_SETTINGS); var serializer = new Serializer(); var serializedData = serializer.SerializeData(rpcRequest.Params.Data); @@ -328,7 +328,7 @@ public void TestExpectedNotificationSerializationWithNullAttributes() + "}"; var expectedSerialization = "accountid4052851907messageid100137003A703263176notificationid123orderid7520047953verified0"; - var rpcRequest = JsonConvert.DeserializeObject(requestJson); + var rpcRequest = JsonConvert.DeserializeObject(requestJson, TrustlyApiClient.DEFAULT_SERIALIZER_SETTINGS); var serializer = new Serializer(); var serializedData = serializer.SerializeData(rpcRequest.Params.Data); @@ -403,9 +403,8 @@ private Stream CreateMockDebitNotificationRequestBody(string rpcMethod) debitNotification.Params.UUID, debitNotification.Params.Data ); - //this._validator.Validate(debitNotification); - var json = JsonConvert.SerializeObject(debitNotification); + var json = JsonConvert.SerializeObject(debitNotification, TrustlyApiClient.DEFAULT_SERIALIZER_SETTINGS); var byteArray = Encoding.UTF8.GetBytes(json); return new MemoryStream(byteArray); @@ -450,9 +449,8 @@ private Mock CreateMockAccountNotificationRequest(string method = " mandateNotification.Params.UUID, mandateNotification.Params.Data ); - //this._validator.Validate(debitNotification); - var json = JsonConvert.SerializeObject(mandateNotification); + var json = JsonConvert.SerializeObject(mandateNotification, TrustlyApiClient.DEFAULT_SERIALIZER_SETTINGS); var byteArray = Encoding.UTF8.GetBytes(json); var stream = new MemoryStream(byteArray); From 7a2c784f37f14e2889633b63acdab2449d64585b Mon Sep 17 00:00:00 2001 From: Pontus Eliason Date: Wed, 25 Sep 2024 16:22:00 +0200 Subject: [PATCH 5/6] Union deserialization test case and fixes --- src/Client/TrustlyApiClient.cs | 3 +- src/Domain/Domain.cs | 903 ++++++++++++++++++-- src/Domain/WrapperConverter.cs | 45 + tests/Client.UnitTests/NotificationTests.cs | 20 +- 4 files changed, 896 insertions(+), 75 deletions(-) create mode 100644 src/Domain/WrapperConverter.cs diff --git a/src/Client/TrustlyApiClient.cs b/src/Client/TrustlyApiClient.cs index e9b9ac5..5a90223 100644 --- a/src/Client/TrustlyApiClient.cs +++ b/src/Client/TrustlyApiClient.cs @@ -33,7 +33,8 @@ public class TrustlyApiClient public event EventHandler> OnAccount; public event EventHandler> OnCancel; public event EventHandler> OnCredit; - public event EventHandler> OnDebit; + public event EventHandler> OnDefaultDebit; + public event EventHandler> OnDebit; public event EventHandler> OnPayoutConfirmation; public event EventHandler> OnPayoutFailed; public event EventHandler> OnPending; diff --git a/src/Domain/Domain.cs b/src/Domain/Domain.cs index b4f1c01..a655612 100644 --- a/src/Domain/Domain.cs +++ b/src/Domain/Domain.cs @@ -1,9 +1,8 @@ -// Generated by Omnigen @ 2024-09-10T09:36:45.343Z +// Generated by Omnigen @ 2024-09-24T11:49:54.634Z using Newtonsoft.Json; using Newtonsoft.Json.Converters; using Newtonsoft.Json.Linq; -using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Runtime.Serialization; @@ -24,6 +23,7 @@ public class WithdrawResponseData /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the request. /// /// 9594811343 + /// 9594811343 [JsonProperty("orderid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string OrderID { get; set; } @@ -55,6 +55,7 @@ public class SwishResponseData /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the request. /// /// 9594811343 + /// 9594811343 [JsonProperty("orderid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string OrderID { get; set; } @@ -110,6 +111,7 @@ public class SelectAccountResponseData /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the charge. /// /// 9594811343 + /// 9594811343 [JsonProperty("orderid")] public long OrderID { get; set; } /// @@ -174,6 +176,8 @@ public class RegisterAccountResponseData /// /// 1234567890 /// 7653385737 + /// 1234567890 + /// 7653385737 [JsonProperty("accountid")] public string AccountID { get; set; } /// @@ -208,6 +212,35 @@ public class RegisterAccountResponseData /// SPAIN /// SWEDEN /// UNITED_KINGDOM + /// AUSTRIA + /// BELGIUM + /// BULGARIA + /// CROATIA + /// CYPRUS + /// CZECH_REPUBLIC + /// DENMARK + /// ESTONIA + /// FINLAND + /// FRANCE + /// GERMANY + /// GREECE + /// HUNGARY + /// IRELAND + /// ITALY + /// LATVIA + /// LITHUANIA + /// LUXEMBOURG + /// MALTA + /// NETHERLANDS + /// NORWAY + /// POLAND + /// PORTUGAL + /// ROMANIA + /// SLOVAKIA + /// SLOVENIA + /// SPAIN + /// SWEDEN + /// UNITED_KINGDOM [JsonProperty("clearinghouse")] public string ClearingHouse { get; set; } /// @@ -215,12 +248,15 @@ public class RegisterAccountResponseData /// /// SEB /// Skandiabanken + /// SEB + /// Skandiabanken [JsonProperty("bank")] public string Bank { get; set; } /// /// A text that is safe to show the enduser for identifying the account. Do not parse this text since it will be a different format for different accounts. /// /// ***4057 + /// ***4057 [JsonProperty("descriptor")] public string Descriptor { get; set; } [JsonExtensionData] @@ -344,6 +380,8 @@ public class RecipientOrSenderInformation /// /// Date string in the ISO 8601 format (YYYY-MM-DD) /// 2014-04-01 + /// Date string in the ISO 8601 format (YYYY-MM-DD) + /// 2014-04-01 [JsonProperty("DateOfBirth")] public string DateOfBirth { get; set; } } @@ -490,6 +528,7 @@ public class RegisterAccountPayoutResponseData /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the charge. /// /// 9594811343 + /// 9594811343 [JsonProperty("orderid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public long OrderID { get; set; } @@ -564,6 +603,17 @@ public enum KYCNotificationResponseDataStatus public class KYCNotificationResponseData : NotificationResponseDataBase { + /// BGN: 100.00 + /// CZK: 100.00 + /// DKK: 100.00 + /// EUR: 100.00 + /// GBP: 100.00 + /// HRK: 100.00 + /// HUF: 100 + /// NOK: 100.00 + /// PLN: 100.00 + /// RON: 100.00 + /// SEK: 100.00 /// BGN: 100.00 /// CZK: 100.00 /// DKK: 100.00 @@ -797,6 +847,17 @@ public class GetWithdrawalsResponseDataEntry /// FAILED /// RETURNED /// CONFIRMED + /// EXECUTING + /// EXECUTED + /// PENDING + /// QUEUED + /// PREPARING + /// PREPARED + /// BOUNCED + /// ERROR + /// FAILED + /// RETURNED + /// CONFIRMED [JsonProperty("transferstate", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string Transferstate { get; set; } @@ -811,6 +872,8 @@ public class GetWithdrawalsResponseDataEntry /// /// 1234567890 /// 7653385737 + /// 1234567890 + /// 7653385737 [JsonProperty("accountid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string AccountID { get; set; } @@ -886,6 +949,7 @@ public class DirectPaymentBatchResponseData : WithRejection /// 9594811343 + /// 9594811343 [JsonProperty("orderid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string OrderID { get; set; } @@ -938,6 +1002,7 @@ public class DirectDebitResponseData : WithRejection /// 9594811343 + /// 9594811343 [JsonProperty("orderid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string OrderID { get; set; } @@ -973,6 +1038,7 @@ public class DirectDebitMandateResponseData /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the request. /// /// 9594811343 + /// 9594811343 [JsonProperty("orderid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string OrderID { get; set; } @@ -1053,6 +1119,7 @@ public class DirectCreditResponseData : WithRejection /// 9594811343 + /// 9594811343 [JsonProperty("orderid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string OrderID { get; set; } @@ -1095,6 +1162,7 @@ public class DepositResponseData /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the request. /// /// 9594811343 + /// 9594811343 [JsonProperty("orderid")] public string OrderID { get; set; } /// @@ -1256,6 +1324,7 @@ public class CreateAccountResponseData /// The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. /// /// 7653385737 + /// 7653385737 [JsonProperty("accountId")] public double AccountId { get; set; } /// @@ -1290,6 +1359,35 @@ public class CreateAccountResponseData /// SPAIN /// SWEDEN /// UNITED_KINGDOM + /// AUSTRIA + /// BELGIUM + /// BULGARIA + /// CROATIA + /// CYPRUS + /// CZECH_REPUBLIC + /// DENMARK + /// ESTONIA + /// FINLAND + /// FRANCE + /// GERMANY + /// GREECE + /// HUNGARY + /// IRELAND + /// ITALY + /// LATVIA + /// LITHUANIA + /// LUXEMBOURG + /// MALTA + /// NETHERLANDS + /// NORWAY + /// POLAND + /// PORTUGAL + /// ROMANIA + /// SLOVAKIA + /// SLOVENIA + /// SPAIN + /// SWEDEN + /// UNITED_KINGDOM [JsonProperty("clearingHouse")] public string ClearingHouse { get; set; } /// @@ -1297,12 +1395,15 @@ public class CreateAccountResponseData /// /// SEB /// Skandiabanken + /// SEB + /// Skandiabanken [JsonProperty("bank")] public string Bank { get; set; } /// /// A text that is safe to show the enduser for identifying the account. Do not parse this text since it will be a different format for different accounts. /// /// ***4057 + /// ***4057 [JsonProperty("descriptor")] public string Descriptor { get; set; } } @@ -1419,6 +1520,7 @@ public class CancelChargeResponseData : WithRejection /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the request. /// /// 9594811343 + /// 9594811343 [JsonProperty("orderid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string OrderID { get; set; } @@ -1839,6 +1941,7 @@ public class AccountLedgerResponseDataEntry /// A human friendly description of this ledger record. /// /// CLIENT_FUNDS_SWEDEN_ESSE + /// CLIENT_FUNDS_SWEDEN_ESSE [JsonProperty("transactiontype")] public string Transactiontype { get; set; } /// @@ -1855,6 +1958,7 @@ public class AccountLedgerResponseDataEntry /// An ID meaning different things for different payment methods, you probably don't need this data. /// /// 3209647863 + /// 3209647863 [JsonProperty("gluepayid")] public string Gluepayid { get; set; } } @@ -1930,6 +2034,7 @@ public class WithdrawRequestDataAttributes : AbstractRequestDataAttributes /// The email address of the end user. /// /// test@trustly.com + /// test@trustly.com [JsonProperty("Email")] public string Email { get; set; } /// @@ -1968,6 +2073,7 @@ public class WithdrawRequestDataAttributes : AbstractRequestDataAttributes /// The end-user's social security number / personal number / birth number / etc. Useful for some banks for identifying transactions and KYC/AML. If a Swedish personid ("personnummer") is provided, it will be pre-filled when the user logs in to their bank. /// /// 790131-1234 + /// 790131-1234 [JsonProperty("NationalIdentificationNumber")] public string NationalIdentificationNumber { get; set; } /// @@ -2026,6 +2132,7 @@ public class WithdrawRequestDataAttributes : AbstractRequestDataAttributes /// Recipient address street /// /// Main Street 1 + /// Main Street 1 [JsonProperty("AddressLine1")] public string AddressLine1 { get; set; } /// @@ -2038,12 +2145,14 @@ public class WithdrawRequestDataAttributes : AbstractRequestDataAttributes /// This attribute should only be used if you are unable to provide the shipping address information in the 5 separate properties: AddressCountry, AddressCity, AddressPostalCode, AddressLine1, AddressLine2 /// /// Birgerstreet 14, SE-11411, Stockholm, Sweden + /// Birgerstreet 14, SE-11411, Stockholm, Sweden [JsonProperty("Address")] public string Address { get; set; } /// /// The ExternalReference is a reference set by the merchant for any purpose and does not need to be unique for every API call. For example, it can be used for invoice references, OCR numbers and also for offering end users the option to part-pay an invoice using the same ExternalReference. The ExternalReference will be included in version 1.2 of the settlement report, ViewAutomaticSettlementDetailsCSV. /// /// 32423534523 + /// 32423534523 [JsonProperty("ExternalReference")] public string ExternalReference { get; set; } /// @@ -2083,6 +2192,7 @@ public class SwishRequestDataAttributes : AbstractRequestDataAttributes /// The Swish number of the payee. /// /// 1231181189 + /// 1231181189 [JsonProperty("MerchantSwishNumber", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string MerchantSwishNumber { get; set; } @@ -2118,6 +2228,17 @@ public class SwishRequestDataAttributes : AbstractRequestDataAttributes /// PLN /// RON /// SEK + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK [JsonProperty("Currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string Currency { get; set; } @@ -2125,6 +2246,7 @@ public class SwishRequestDataAttributes : AbstractRequestDataAttributes /// Merchant supplies a message about the payment/order. Max 50 characters. Common allowed characters are the letters a-ö, A-Ö, the numbers 0-9, and special characters !?(),.-:; /// /// Payment + /// Payment [JsonProperty("Message")] public string Message { get; set; } /// @@ -2136,6 +2258,7 @@ public class SwishRequestDataAttributes : AbstractRequestDataAttributes /// The end-user's social security number / personal number / birth number / etc. Useful for some banks for identifying transactions and KYC/AML. If a Swedish personid ("personnummer") is provided, it will be pre-filled when the user logs in to their bank. /// /// 790131-1234 + /// 790131-1234 [JsonProperty("NationalIdentificationNumber")] public string NationalIdentificationNumber { get; set; } /// @@ -2193,6 +2316,7 @@ public class SelectAccountRequestDataAttributes : AbstractRequestDataAttributes /// The email address of the end user. /// /// test@trustly.com + /// test@trustly.com [JsonProperty("Email")] public string Email { get; set; } /// @@ -2231,6 +2355,7 @@ public class SelectAccountRequestDataAttributes : AbstractRequestDataAttributes /// The end-user's social security number / personal number / birth number / etc. Useful for some banks for identifying transactions and KYC/AML. If a Swedish personid ("personnummer") is provided, it will be pre-filled when the user logs in to their bank. /// /// 790131-1234 + /// 790131-1234 [JsonProperty("NationalIdentificationNumber")] public string NationalIdentificationNumber { get; set; } /// @@ -2299,6 +2424,7 @@ public class RegisterAccountRequestDataAttributes : AbstractRequestDataAttribute /// The end-user's social security number / personal number / birth number / etc. Useful for some banks for identifying transactions and KYC/AML. If a Swedish personid ("personnummer") is provided, it will be pre-filled when the user logs in to their bank. /// /// 790131-1234 + /// 790131-1234 [JsonProperty("NationalIdentificationNumber")] public string NationalIdentificationNumber { get; set; } /// @@ -2331,12 +2457,14 @@ public class RegisterAccountRequestDataAttributes : AbstractRequestDataAttribute /// This attribute should only be used if you are unable to provide the shipping address information in the 5 separate properties: AddressCountry, AddressCity, AddressPostalCode, AddressLine1, AddressLine2 /// /// Birgerstreet 14, SE-11411, Stockholm, Sweden + /// Birgerstreet 14, SE-11411, Stockholm, Sweden [JsonProperty("Address")] public string Address { get; set; } /// /// The email address of the end user. /// /// test@trustly.com + /// test@trustly.com [JsonProperty("Email")] public string Email { get; set; } } @@ -2355,6 +2483,7 @@ public class RegisterAccountPayoutRequestDataAttributes : AbstractRequestDataAtt /// The ExternalReference is a reference set by the merchant for any purpose and does not need to be unique for every API call. For example, it can be used for invoice references, OCR numbers and also for offering end users the option to part-pay an invoice using the same ExternalReference. The ExternalReference will be included in version 1.2 of the settlement report, ViewAutomaticSettlementDetailsCSV. /// /// 32423534523 + /// 32423534523 [JsonProperty("ExternalReference")] public string ExternalReference { get; set; } /// @@ -2397,6 +2526,7 @@ public class RegisterAccountPayoutRequestDataAttributes : AbstractRequestDataAtt /// The end-user's social security number / personal number / birth number / etc. Useful for some banks for identifying transactions and KYC/AML. If a Swedish personid ("personnummer") is provided, it will be pre-filled when the user logs in to their bank. /// /// 790131-1234 + /// 790131-1234 [JsonProperty("NationalIdentificationNumber")] public string NationalIdentificationNumber { get; set; } /// @@ -2418,6 +2548,7 @@ public class RegisterAccountPayoutRequestDataAttributes : AbstractRequestDataAtt /// Recipient address street /// /// Main Street 1 + /// Main Street 1 [JsonProperty("AddressLine1")] public string AddressLine1 { get; set; } /// @@ -2430,12 +2561,14 @@ public class RegisterAccountPayoutRequestDataAttributes : AbstractRequestDataAtt /// This attribute should only be used if you are unable to provide the shipping address information in the 5 separate properties: AddressCountry, AddressCity, AddressPostalCode, AddressLine1, AddressLine2 /// /// Birgerstreet 14, SE-11411, Stockholm, Sweden + /// Birgerstreet 14, SE-11411, Stockholm, Sweden [JsonProperty("Address")] public string Address { get; set; } /// /// The email address of the end user. /// /// test@trustly.com + /// test@trustly.com [JsonProperty("Email")] public string Email { get; set; } } @@ -2446,6 +2579,7 @@ public class RefundRequestDataAttributes : AbstractRequestDataAttributes /// The ExternalReference is a reference set by the merchant for any purpose and does not need to be unique for every API call. For example, it can be used for invoice references, OCR numbers and also for offering end users the option to part-pay an invoice using the same ExternalReference. The ExternalReference will be included in version 1.2 of the settlement report, ViewAutomaticSettlementDetailsCSV. /// /// 32423534523 + /// 32423534523 [JsonProperty("ExternalReference")] public string ExternalReference { get; set; } } @@ -2457,6 +2591,8 @@ public class KYCNotificationDataAttributes : AbstractRequestDataAttributes /// /// SE198201019876 /// 19900501 + /// SE198201019876 + /// 19900501 [JsonProperty("personid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string PersonID { get; set; } @@ -2482,6 +2618,7 @@ public class KYCNotificationDataAttributes : AbstractRequestDataAttributes /// Recipient address street /// /// Main Street 1 + /// Main Street 1 [JsonProperty("street", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string Street { get; set; } @@ -2512,6 +2649,8 @@ public class ImportDirectDebitMandateRequestDataAttributes : AbstractRequestData /// /// 1234567890 /// 7653385737 + /// 1234567890 + /// 7653385737 [JsonProperty("AccountID")] public string AccountID { get; set; } /// @@ -2523,6 +2662,7 @@ public class ImportDirectDebitMandateRequestDataAttributes : AbstractRequestData /// [SEPA-DD]: The unique mandate reference. This must be unique for the end-user for you as a merchant. Format needs to follow regexp [0-9,a-z,A-Z]{10-35} /// /// 123ABC0123 + /// 123ABC0123 [JsonProperty("MerchantReference", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string MerchantReference { get; set; } @@ -2555,6 +2695,7 @@ public class ImportDirectDebitMandateRequestDataAttributes : AbstractRequestData /// The email address of the end user. /// /// test@trustly.com + /// test@trustly.com [JsonProperty("Email", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string Email { get; set; } @@ -2614,18 +2755,21 @@ public class DirectPaymentBatchRequestDataAttributes : AbstractRequestDataAttrib /// Date string in the ISO 8601 format (YYYY-MM-DD) /// /// 2014-04-01 + /// 2014-04-01 [JsonProperty("PaymentDate")] public string PaymentDate { get; set; } /// /// The uploaded unique file name on the SFTP server containing the instructions. /// /// unique-filename.csv + /// unique-filename.csv [JsonProperty("BatchFile")] public string BatchFile { get; set; } /// /// The MD5 checksum for the file /// /// 0cdf0945096283b9ba94e42150ba84d8 + /// 0cdf0945096283b9ba94e42150ba84d8 [JsonProperty("Checksum")] public string Checksum { get; set; } } @@ -2638,6 +2782,7 @@ public class DirectDebitRequestDataAttributes : AbstractRequestDataAttributes /// Date string in the ISO 8601 format (YYYY-MM-DD) /// /// 2014-04-01 + /// 2014-04-01 [JsonProperty("PaymentDate")] public string PaymentDate { get; set; } /// @@ -2656,6 +2801,8 @@ public class DirectDebitMandateRequestDataAttributes : AbstractRequestDataAttrib /// /// 1234567890 /// 7653385737 + /// 1234567890 + /// 7653385737 [JsonProperty("AccountId")] public string AccountId { get; set; } /// @@ -2667,6 +2814,7 @@ public class DirectDebitMandateRequestDataAttributes : AbstractRequestDataAttrib /// [SEPA-DD]: The unique mandate reference. This must be unique for the end-user for you as a merchant. Format needs to follow regexp [0-9,a-z,A-Z]{10-35} /// /// 123ABC0123 + /// 123ABC0123 [JsonProperty("MerchantReference", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string MerchantReference { get; set; } @@ -2696,6 +2844,7 @@ public class DirectDebitMandateRequestDataAttributes : AbstractRequestDataAttrib /// The email address of the end user. /// /// test@trustly.com + /// test@trustly.com [JsonProperty("Email", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string Email { get; set; } @@ -2743,6 +2892,7 @@ public class DirectDebitMandateRequestDataAttributes : AbstractRequestDataAttrib /// Recipient address street /// /// Main Street 1 + /// Main Street 1 [JsonProperty("AddressLine1")] public string AddressLine1 { get; set; } /// @@ -2827,6 +2977,7 @@ public class DepositRequestDataAttributes : AbstractRequestDataAttributes /// The email address of the end user. /// /// test@trustly.com + /// test@trustly.com [JsonProperty("Email", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string Email { get; set; } @@ -2866,6 +3017,7 @@ public class DepositRequestDataAttributes : AbstractRequestDataAttributes /// The end-user's social security number / personal number / birth number / etc. Useful for some banks for identifying transactions and KYC/AML. If a Swedish personid ("personnummer") is provided, it will be pre-filled when the user logs in to their bank. /// /// 790131-1234 + /// 790131-1234 [JsonProperty("NationalIdentificationNumber")] public string NationalIdentificationNumber { get; set; } /// @@ -2889,6 +3041,7 @@ public class DepositRequestDataAttributes : AbstractRequestDataAttributes /// iDeal. The iDEAL integration offered by Trustly allows for both iDEAL and Trustly payments on a single integration with all transactions visible in the same AccountLedger. To initiate a new iDEAL payment, add Method = "deposit.bank.netherlands.ideal" to the Deposit attributes. /// /// deposit.bank.netherlands.ideal + /// deposit.bank.netherlands.ideal [JsonProperty("Method")] public string Method { get; set; } /// @@ -2905,6 +3058,17 @@ public class DepositRequestDataAttributes : AbstractRequestDataAttributes /// PLN /// RON /// SEK + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK [JsonProperty("Currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string Currency { get; set; } @@ -2962,6 +3126,7 @@ public class DepositRequestDataAttributes : AbstractRequestDataAttributes /// The ExternalReference is a reference set by the merchant for any purpose and does not need to be unique for every API call. For example, it can be used for invoice references, OCR numbers and also for offering end users the option to part-pay an invoice using the same ExternalReference. The ExternalReference will be included in version 1.2 of the settlement report, ViewAutomaticSettlementDetailsCSV. /// /// 32423534523 + /// 32423534523 [JsonProperty("ExternalReference")] public string ExternalReference { get; set; } /// @@ -2990,6 +3155,8 @@ public class DepositRequestDataAttributes : AbstractRequestDataAttributes /// /// 1234567890 /// 7653385737 + /// 1234567890 + /// 7653385737 [JsonProperty("AccountId")] public string AccountId { get; set; } /// @@ -3021,12 +3188,15 @@ public class DebitRefundDirectDebitNotificationDataAttributes : AbstractRequestD /// /// 1E2FC19E5E5E4E18916609B7F8911C12 /// TRLY80494-1001 + /// 1E2FC19E5E5E4E18916609B7F8911C12 + /// TRLY80494-1001 [JsonProperty("reference")] public string Reference { get; set; } /// /// Statement that appear on the end users bank account /// /// TRLY80494-1001 + /// TRLY80494-1001 [JsonProperty("statement")] public string Statement { get; set; } } @@ -3038,12 +3208,15 @@ public class DebitDirectDebitNotificationDataAttributes : AbstractRequestDataAtt /// /// 1E2FC19E5E5E4E18916609B7F8911C12 /// TRLY80494-1001 + /// 1E2FC19E5E5E4E18916609B7F8911C12 + /// TRLY80494-1001 [JsonProperty("reference")] public string Reference { get; set; } /// /// Statement that appear on the end users bank account /// /// TRLY80494-1001 + /// TRLY80494-1001 [JsonProperty("statement")] public string Statement { get; set; } [JsonProperty("reason")] @@ -3062,12 +3235,15 @@ public class DebitDirectCreditNotificationDataAttributes : AbstractRequestDataAt /// /// 1E2FC19E5E5E4E18916609B7F8911C12 /// TRLY80494-1001 + /// 1E2FC19E5E5E4E18916609B7F8911C12 + /// TRLY80494-1001 [JsonProperty("reference")] public string Reference { get; set; } /// /// Statement that appear on the end users bank account /// /// TRLY80494-1001 + /// TRLY80494-1001 [JsonProperty("statement")] public string Statement { get; set; } [JsonProperty("reason")] @@ -3095,6 +3271,7 @@ public class CreateAccountRequestDataAttributes : AbstractRequestDataAttributes /// The end-user's social security number / personal number / birth number / etc. Useful for some banks for identifying transactions and KYC/AML. If a Swedish personid ("personnummer") is provided, it will be pre-filled when the user logs in to their bank. /// /// 790131-1234 + /// 790131-1234 [JsonProperty("NationalIdentificationNumber")] public string NationalIdentificationNumber { get; set; } /// @@ -3116,6 +3293,7 @@ public class CreateAccountRequestDataAttributes : AbstractRequestDataAttributes /// Recipient address street /// /// Main Street 1 + /// Main Street 1 [JsonProperty("AddressLine1")] public string AddressLine1 { get; set; } /// @@ -3128,12 +3306,14 @@ public class CreateAccountRequestDataAttributes : AbstractRequestDataAttributes /// This attribute should only be used if you are unable to provide the shipping address information in the 5 separate properties: AddressCountry, AddressCity, AddressPostalCode, AddressLine1, AddressLine2 /// /// Birgerstreet 14, SE-11411, Stockholm, Sweden + /// Birgerstreet 14, SE-11411, Stockholm, Sweden [JsonProperty("Address")] public string Address { get; set; } /// /// The email address of the end user. /// /// test@trustly.com + /// test@trustly.com [JsonProperty("Email")] public string Email { get; set; } } @@ -3152,6 +3332,7 @@ public class ChargeRequestDataAttributes : AbstractRequestDataAttributes /// The email address of the end user. /// /// test@trustly.com + /// test@trustly.com [JsonProperty("Email", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string Email { get; set; } @@ -3164,6 +3345,7 @@ public class ChargeRequestDataAttributes : AbstractRequestDataAttributes /// The ExternalReference is a reference set by the merchant for any purpose and does not need to be unique for every API call. For example, it can be used for invoice references, OCR numbers and also for offering end users the option to part-pay an invoice using the same ExternalReference. The ExternalReference will be included in version 1.2 of the settlement report, ViewAutomaticSettlementDetailsCSV. /// /// 32423534523 + /// 32423534523 [JsonProperty("ExternalReference")] public string ExternalReference { get; set; } /// @@ -3197,6 +3379,7 @@ public class CancelSwishNotificationDataAttributes : AbstractRequestDataAttribut /// Description of reason /// /// User Declined + /// User Declined [JsonProperty("details")] public string Details { get; set; } } @@ -3226,6 +3409,8 @@ public class CancelMandateNotificationDataAttributes : AbstractRequestDataAttrib /// /// 1234567890 /// 7653385737 + /// 1234567890 + /// 7653385737 [JsonProperty("accountid")] public string AccountID { get; set; } /// @@ -3237,6 +3422,7 @@ public class CancelMandateNotificationDataAttributes : AbstractRequestDataAttrib /// [SEPA-DD]: The unique mandate reference. This must be unique for the end-user for you as a merchant. Format needs to follow regexp [0-9,a-z,A-Z]{10-35} /// /// 123ABC0123 + /// 123ABC0123 [JsonProperty("merchantreference")] public string Merchantreference { get; set; } } @@ -3282,6 +3468,7 @@ public class AccountPayoutRequestDataAttributes : AbstractRequestDataAttributes /// The ExternalReference is a reference set by the merchant for any purpose and does not need to be unique for every API call. For example, it can be used for invoice references, OCR numbers and also for offering end users the option to part-pay an invoice using the same ExternalReference. The ExternalReference will be included in version 1.2 of the settlement report, ViewAutomaticSettlementDetailsCSV. /// /// 32423534523 + /// 32423534523 [JsonProperty("ExternalReference")] public string ExternalReference { get; set; } /// @@ -3331,6 +3518,7 @@ public class WithdrawRequestData : AbstractRequestData /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh + /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh [JsonProperty("NotificationURL", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string NotificationURL { get; set; } @@ -3345,6 +3533,7 @@ public class WithdrawRequestData : AbstractRequestData /// 12345678 + /// 12345678 [JsonProperty("MessageID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string MessageID { get; set; } @@ -3362,6 +3551,17 @@ public class WithdrawRequestData : AbstractRequestDataPLN /// RON /// SEK + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK [JsonProperty("Currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string Currency { get; set; } @@ -3373,6 +3573,7 @@ public class SwishRequestData : AbstractRequestData /// The URL to which notifications for this should be sent to. This URL should be hard to guess and not contain a ? ("question mark"). /// /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh + /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh [JsonProperty("NotificationURL")] public string NotificationURL { get; set; } /// @@ -3385,6 +3586,7 @@ public class SwishRequestData : AbstractRequestData /// Your unique ID of the transaction. /// /// 12345678 + /// 12345678 [JsonProperty("MessageID")] public string MessageID { get; set; } } @@ -3406,6 +3608,18 @@ public class SettlementReportRequestData : AbstractRequestDataPLN /// RON /// SEK + /// The ISO 4217 code of the currency. See documentation + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK [JsonProperty("Currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string Currency { get; set; } @@ -3426,6 +3640,7 @@ public class SelectAccountRequestData : AbstractRequestData /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh + /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh [JsonProperty("NotificationURL", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string NotificationURL { get; set; } @@ -3440,6 +3655,7 @@ public class SelectAccountRequestData : AbstractRequestData /// 12345678 + /// 12345678 [JsonProperty("MessageID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string MessageID { get; set; } @@ -3485,6 +3701,35 @@ public class RegisterAccountRequestData : AbstractRequestDataSPAIN /// SWEDEN /// UNITED_KINGDOM + /// AUSTRIA + /// BELGIUM + /// BULGARIA + /// CROATIA + /// CYPRUS + /// CZECH_REPUBLIC + /// DENMARK + /// ESTONIA + /// FINLAND + /// FRANCE + /// GERMANY + /// GREECE + /// HUNGARY + /// IRELAND + /// ITALY + /// LATVIA + /// LITHUANIA + /// LUXEMBOURG + /// MALTA + /// NETHERLANDS + /// NORWAY + /// POLAND + /// PORTUGAL + /// ROMANIA + /// SLOVAKIA + /// SLOVENIA + /// SPAIN + /// SWEDEN + /// UNITED_KINGDOM [JsonProperty("ClearingHouse", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string ClearingHouse { get; set; } @@ -3495,6 +3740,8 @@ public class RegisterAccountRequestData : AbstractRequestData /// Sweden: ^[0-9]{4,5}$ /// United Kingdom: ^[0-9]{6}$ + /// Sweden: ^[0-9]{4,5}$ + /// United Kingdom: ^[0-9]{6}$ [JsonProperty("BankNumber", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string BankNumber { get; set; } @@ -3532,14 +3779,45 @@ public class RegisterAccountRequestData : AbstractRequestDataSPAIN: ^ES[0-9]{22}$ /// SWEDEN:* [0-9]{1,15}$ /// UNITED_KINGDOM: ^[0-9]{8}$ - [JsonProperty("AccountNumber", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] - [Required] - public string AccountNumber { get; set; } - /// - /// First name of the person, or the name of the organization/company. - /// - [JsonProperty("Firstname", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] - [Required] + /// 6112 + /// 391124057 + /// AUSTRIA: ^AT[0-9]{18}$ + /// BELGIUM: ^BE[0-9]{14}$ + /// BULGARIA: ^BG[0-9]{2}[A-Z]{4}[0-9]{4}[0-9]{2}[A-Z0-9]{8}$ + /// CROATIA: ^HR[0-9]{2}[0-9]{7}[0-9]{10}$ + /// CYPRUS: ^CY[0-9]{10}[0-9A-Z]{16}$ + /// CZECH_REPUBLIC: ^CZ[0-9]{22}$ + /// DENMARK: ^DK[0-9]{16}$ + /// ESTONIA: ^EE[0-9]{18}$ + /// FINLAND: ^FI[0-9]{16}$ + /// FRANCE: ^FR[0-9]{12}[0-9A-Z]{11}[0-9]{2}$ + /// GERMANY: ^DE[0-9]{20}$ + /// GREECE: ^GR[0-9]{25}$ + /// HUNGARY: ^HU[0-9]{26}$ + /// IRELAND: ^IE[0-9]{2}[A-Z]{4}[0-9]{14}$ + /// ITALY: ^IT[0-9]{2}[A-Z][0-9]{10}[0-9A-Z]{12}$ + /// LATVIA: ^LV[0-9]{2}[A-Z]{4}[0-9A-Z]{13}$ + /// LITHUANIA: ^LT[0-9]{18}$ + /// LUXEMBOURG: ^LU[0-9]{18}$ + /// MALTA: ^MT[0-9]{2}[A-Z]{4}[0-9]{5}[0-9A-Z]{18}$ + /// NETHERLANDS: ^NL[0-9]{2}[A-Z]{4}[0-9]{10}$ + /// NORWAY: ^NO[0-9]{13}$ + /// POLAND: ^PL[0-9]{26}$ + /// PORTUGAL: ^PT[0-9]{23}$ + /// ROMANIA: ^RO[0-9]{2}[A-Z]{4}[0-9A-Z]{16}$ + /// SLOVAKIA: ^SK[0-9]{22}$ + /// SLOVENIA: ^SI56[0-9]{15}$ + /// SPAIN: ^ES[0-9]{22}$ + /// SWEDEN:* [0-9]{1,15}$ + /// UNITED_KINGDOM: ^[0-9]{8}$ + [JsonProperty("AccountNumber", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] + public string AccountNumber { get; set; } + /// + /// First name of the person, or the name of the organization/company. + /// + [JsonProperty("Firstname", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] + [Required] public string Firstname { get; set; } /// /// Last name of the person (NULL/empty for organization/company). @@ -3590,6 +3868,35 @@ public class RegisterAccountPayoutRequestData : AbstractRequestDataSPAIN /// SWEDEN /// UNITED_KINGDOM + /// AUSTRIA + /// BELGIUM + /// BULGARIA + /// CROATIA + /// CYPRUS + /// CZECH_REPUBLIC + /// DENMARK + /// ESTONIA + /// FINLAND + /// FRANCE + /// GERMANY + /// GREECE + /// HUNGARY + /// IRELAND + /// ITALY + /// LATVIA + /// LITHUANIA + /// LUXEMBOURG + /// MALTA + /// NETHERLANDS + /// NORWAY + /// POLAND + /// PORTUGAL + /// ROMANIA + /// SLOVAKIA + /// SLOVENIA + /// SPAIN + /// SWEDEN + /// UNITED_KINGDOM [JsonProperty("ClearingHouse", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string ClearingHouse { get; set; } @@ -3600,6 +3907,8 @@ public class RegisterAccountPayoutRequestData : AbstractRequestData /// Sweden: ^[0-9]{4,5}$ /// United Kingdom: ^[0-9]{6}$ + /// Sweden: ^[0-9]{4,5}$ + /// United Kingdom: ^[0-9]{6}$ [JsonProperty("BankNumber", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string BankNumber { get; set; } @@ -3637,6 +3946,37 @@ public class RegisterAccountPayoutRequestData : AbstractRequestDataSPAIN: ^ES[0-9]{22}$ /// SWEDEN:* [0-9]{1,15}$ /// UNITED_KINGDOM: ^[0-9]{8}$ + /// 6112 + /// 391124057 + /// AUSTRIA: ^AT[0-9]{18}$ + /// BELGIUM: ^BE[0-9]{14}$ + /// BULGARIA: ^BG[0-9]{2}[A-Z]{4}[0-9]{4}[0-9]{2}[A-Z0-9]{8}$ + /// CROATIA: ^HR[0-9]{2}[0-9]{7}[0-9]{10}$ + /// CYPRUS: ^CY[0-9]{10}[0-9A-Z]{16}$ + /// CZECH_REPUBLIC: ^CZ[0-9]{22}$ + /// DENMARK: ^DK[0-9]{16}$ + /// ESTONIA: ^EE[0-9]{18}$ + /// FINLAND: ^FI[0-9]{16}$ + /// FRANCE: ^FR[0-9]{12}[0-9A-Z]{11}[0-9]{2}$ + /// GERMANY: ^DE[0-9]{20}$ + /// GREECE: ^GR[0-9]{25}$ + /// HUNGARY: ^HU[0-9]{26}$ + /// IRELAND: ^IE[0-9]{2}[A-Z]{4}[0-9]{14}$ + /// ITALY: ^IT[0-9]{2}[A-Z][0-9]{10}[0-9A-Z]{12}$ + /// LATVIA: ^LV[0-9]{2}[A-Z]{4}[0-9A-Z]{13}$ + /// LITHUANIA: ^LT[0-9]{18}$ + /// LUXEMBOURG: ^LU[0-9]{18}$ + /// MALTA: ^MT[0-9]{2}[A-Z]{4}[0-9]{5}[0-9A-Z]{18}$ + /// NETHERLANDS: ^NL[0-9]{2}[A-Z]{4}[0-9]{10}$ + /// NORWAY: ^NO[0-9]{13}$ + /// POLAND: ^PL[0-9]{26}$ + /// PORTUGAL: ^PT[0-9]{23}$ + /// ROMANIA: ^RO[0-9]{2}[A-Z]{4}[0-9A-Z]{16}$ + /// SLOVAKIA: ^SK[0-9]{22}$ + /// SLOVENIA: ^SI56[0-9]{15}$ + /// SPAIN: ^ES[0-9]{22}$ + /// SWEDEN:* [0-9]{1,15}$ + /// UNITED_KINGDOM: ^[0-9]{8}$ [JsonProperty("AccountNumber", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string AccountNumber { get; set; } @@ -3656,6 +3996,7 @@ public class RegisterAccountPayoutRequestData : AbstractRequestData /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh + /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh [JsonProperty("NotificationURL", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string NotificationURL { get; set; } @@ -3685,6 +4026,17 @@ public class RegisterAccountPayoutRequestData : AbstractRequestDataPLN /// RON /// SEK + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK [JsonProperty("Currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string Currency { get; set; } @@ -3722,6 +4074,7 @@ public class RefundDirectDebitRequestData : AbstractRequestData /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the charge. /// /// 9594811343 + /// 9594811343 [JsonProperty("OrderID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public long OrderID { get; set; } @@ -3729,6 +4082,7 @@ public class RefundDirectDebitRequestData : AbstractRequestData /// Your unique ID of the transaction. /// /// 12345678 + /// 12345678 [JsonProperty("MessageID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string MessageID { get; set; } @@ -3752,6 +4106,17 @@ public class RefundDirectDebitRequestData : AbstractRequestData /// PLN /// RON /// SEK + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK [JsonProperty("Currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string Currency { get; set; } @@ -3922,6 +4287,7 @@ public class ImportDirectDebitMandateRequestData : AbstractRequestData /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh + /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh [JsonProperty("NotificationURL", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string NotificationURL { get; set; } @@ -3936,6 +4302,7 @@ public class ImportDirectDebitMandateRequestData : AbstractRequestData /// 12345678 + /// 12345678 [JsonProperty("MessageID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string MessageID { get; set; } @@ -3957,6 +4324,7 @@ public class GetWithdrawalsRequestData : AbstractRequestData /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the charge. /// /// 9594811343 + /// 9594811343 [JsonProperty("OrderID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public long OrderID { get; set; } @@ -3978,6 +4346,7 @@ public class DirectPaymentBatchRequestData : AbstractRequestData /// 12345678 + /// 12345678 [JsonProperty("MessageID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string MessageID { get; set; } @@ -3985,6 +4354,7 @@ public class DirectPaymentBatchRequestData : AbstractRequestData /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh + /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh [JsonProperty("NotificationURL", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string NotificationURL { get; set; } @@ -4002,6 +4372,17 @@ public class DirectPaymentBatchRequestData : AbstractRequestDataPLN /// RON /// SEK + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK [JsonProperty("Currency")] public string Currency { get; set; } /// @@ -4028,6 +4409,7 @@ public class DirectDebitRequestData : AbstractRequestData /// 12345678 + /// 12345678 [JsonProperty("MessageID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string MessageID { get; set; } @@ -4035,6 +4417,7 @@ public class DirectDebitRequestData : AbstractRequestData /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh + /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh [JsonProperty("NotificationURL", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string NotificationURL { get; set; } @@ -4043,6 +4426,8 @@ public class DirectDebitRequestData : AbstractRequestData /// 1234567890 /// 7653385737 + /// 1234567890 + /// 7653385737 [JsonProperty("AccountID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string AccountID { get; set; } @@ -4055,6 +4440,7 @@ public class DirectDebitRequestData : AbstractRequestData /// 123ABC0123 + /// 123ABC0123 [JsonProperty("MerchantReference")] public string MerchantReference { get; set; } /// @@ -4077,6 +4463,17 @@ public class DirectDebitRequestData : AbstractRequestDataPLN /// RON /// SEK + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK [JsonProperty("Currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string Currency { get; set; } @@ -4100,6 +4497,7 @@ public class DirectDebitMandateRequestData : AbstractRequestData /// 12345678 + /// 12345678 [JsonProperty("MessageID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string MessageID { get; set; } @@ -4107,6 +4505,7 @@ public class DirectDebitMandateRequestData : AbstractRequestData /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh + /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh [JsonProperty("NotificationURL", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string NotificationURL { get; set; } @@ -4135,6 +4534,7 @@ public class DirectCreditRequestData : AbstractRequestData /// 12345678 + /// 12345678 [JsonProperty("MessageID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string MessageID { get; set; } @@ -4149,6 +4549,7 @@ public class DirectCreditRequestData : AbstractRequestData /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh + /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh [JsonProperty("NotificationURL", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string NotificationURL { get; set; } @@ -4157,6 +4558,8 @@ public class DirectCreditRequestData : AbstractRequestData /// 1234567890 /// 7653385737 + /// 1234567890 + /// 7653385737 [JsonProperty("AccountID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string AccountID { get; set; } @@ -4168,6 +4571,11 @@ public class DirectCreditRequestData : AbstractRequestDatabg /// 123123 /// HANDSESS + /// 6160 + /// 6000 + /// bg + /// 123123 + /// HANDSESS [JsonProperty("BankIdentifier")] public string BankIdentifier { get; set; } /// @@ -4204,6 +4612,37 @@ public class DirectCreditRequestData : AbstractRequestDataSPAIN: ^ES[0-9]{22}$ /// SWEDEN:* [0-9]{1,15}$ /// UNITED_KINGDOM: ^[0-9]{8}$ + /// 6112 + /// 391124057 + /// AUSTRIA: ^AT[0-9]{18}$ + /// BELGIUM: ^BE[0-9]{14}$ + /// BULGARIA: ^BG[0-9]{2}[A-Z]{4}[0-9]{4}[0-9]{2}[A-Z0-9]{8}$ + /// CROATIA: ^HR[0-9]{2}[0-9]{7}[0-9]{10}$ + /// CYPRUS: ^CY[0-9]{10}[0-9A-Z]{16}$ + /// CZECH_REPUBLIC: ^CZ[0-9]{22}$ + /// DENMARK: ^DK[0-9]{16}$ + /// ESTONIA: ^EE[0-9]{18}$ + /// FINLAND: ^FI[0-9]{16}$ + /// FRANCE: ^FR[0-9]{12}[0-9A-Z]{11}[0-9]{2}$ + /// GERMANY: ^DE[0-9]{20}$ + /// GREECE: ^GR[0-9]{25}$ + /// HUNGARY: ^HU[0-9]{26}$ + /// IRELAND: ^IE[0-9]{2}[A-Z]{4}[0-9]{14}$ + /// ITALY: ^IT[0-9]{2}[A-Z][0-9]{10}[0-9A-Z]{12}$ + /// LATVIA: ^LV[0-9]{2}[A-Z]{4}[0-9A-Z]{13}$ + /// LITHUANIA: ^LT[0-9]{18}$ + /// LUXEMBOURG: ^LU[0-9]{18}$ + /// MALTA: ^MT[0-9]{2}[A-Z]{4}[0-9]{5}[0-9A-Z]{18}$ + /// NETHERLANDS: ^NL[0-9]{2}[A-Z]{4}[0-9]{10}$ + /// NORWAY: ^NO[0-9]{13}$ + /// POLAND: ^PL[0-9]{26}$ + /// PORTUGAL: ^PT[0-9]{23}$ + /// ROMANIA: ^RO[0-9]{2}[A-Z]{4}[0-9A-Z]{16}$ + /// SLOVAKIA: ^SK[0-9]{22}$ + /// SLOVENIA: ^SI56[0-9]{15}$ + /// SPAIN: ^ES[0-9]{22}$ + /// SWEDEN:* [0-9]{1,15}$ + /// UNITED_KINGDOM: ^[0-9]{8}$ [JsonProperty("AccountNumber")] public string AccountNumber { get; set; } /// @@ -4225,6 +4664,17 @@ public class DirectCreditRequestData : AbstractRequestDataPLN /// RON /// SEK + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK [JsonProperty("Currency")] public string Currency { get; set; } /// @@ -4251,6 +4701,7 @@ public class DepositRequestData : AbstractRequestData /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh + /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh [JsonProperty("NotificationURL", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string NotificationURL { get; set; } @@ -4265,6 +4716,7 @@ public class DepositRequestData : AbstractRequestData /// 12345678 + /// 12345678 [JsonProperty("MessageID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string MessageID { get; set; } @@ -4288,6 +4740,7 @@ public class DenyWithdrawalRequestData : AbstractRequestData /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the charge. /// /// 9594811343 + /// 9594811343 [JsonProperty("OrderID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public long OrderID { get; set; } @@ -4343,6 +4796,35 @@ public class CreateAccountRequestData : AbstractRequestDataSPAIN /// SWEDEN /// UNITED_KINGDOM + /// AUSTRIA + /// BELGIUM + /// BULGARIA + /// CROATIA + /// CYPRUS + /// CZECH_REPUBLIC + /// DENMARK + /// ESTONIA + /// FINLAND + /// FRANCE + /// GERMANY + /// GREECE + /// HUNGARY + /// IRELAND + /// ITALY + /// LATVIA + /// LITHUANIA + /// LUXEMBOURG + /// MALTA + /// NETHERLANDS + /// NORWAY + /// POLAND + /// PORTUGAL + /// ROMANIA + /// SLOVAKIA + /// SLOVENIA + /// SPAIN + /// SWEDEN + /// UNITED_KINGDOM [JsonProperty("ClearingHouse", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string ClearingHouse { get; set; } @@ -4353,6 +4835,8 @@ public class CreateAccountRequestData : AbstractRequestData /// Sweden: ^[0-9]{4,5}$ /// United Kingdom: ^[0-9]{6}$ + /// Sweden: ^[0-9]{4,5}$ + /// United Kingdom: ^[0-9]{6}$ [JsonProperty("BankNumber", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string BankNumber { get; set; } @@ -4390,6 +4874,37 @@ public class CreateAccountRequestData : AbstractRequestDataSPAIN: ^ES[0-9]{22}$ /// SWEDEN:* [0-9]{1,15}$ /// UNITED_KINGDOM: ^[0-9]{8}$ + /// 6112 + /// 391124057 + /// AUSTRIA: ^AT[0-9]{18}$ + /// BELGIUM: ^BE[0-9]{14}$ + /// BULGARIA: ^BG[0-9]{2}[A-Z]{4}[0-9]{4}[0-9]{2}[A-Z0-9]{8}$ + /// CROATIA: ^HR[0-9]{2}[0-9]{7}[0-9]{10}$ + /// CYPRUS: ^CY[0-9]{10}[0-9A-Z]{16}$ + /// CZECH_REPUBLIC: ^CZ[0-9]{22}$ + /// DENMARK: ^DK[0-9]{16}$ + /// ESTONIA: ^EE[0-9]{18}$ + /// FINLAND: ^FI[0-9]{16}$ + /// FRANCE: ^FR[0-9]{12}[0-9A-Z]{11}[0-9]{2}$ + /// GERMANY: ^DE[0-9]{20}$ + /// GREECE: ^GR[0-9]{25}$ + /// HUNGARY: ^HU[0-9]{26}$ + /// IRELAND: ^IE[0-9]{2}[A-Z]{4}[0-9]{14}$ + /// ITALY: ^IT[0-9]{2}[A-Z][0-9]{10}[0-9A-Z]{12}$ + /// LATVIA: ^LV[0-9]{2}[A-Z]{4}[0-9A-Z]{13}$ + /// LITHUANIA: ^LT[0-9]{18}$ + /// LUXEMBOURG: ^LU[0-9]{18}$ + /// MALTA: ^MT[0-9]{2}[A-Z]{4}[0-9]{5}[0-9A-Z]{18}$ + /// NETHERLANDS: ^NL[0-9]{2}[A-Z]{4}[0-9]{10}$ + /// NORWAY: ^NO[0-9]{13}$ + /// POLAND: ^PL[0-9]{26}$ + /// PORTUGAL: ^PT[0-9]{23}$ + /// ROMANIA: ^RO[0-9]{2}[A-Z]{4}[0-9A-Z]{16}$ + /// SLOVAKIA: ^SK[0-9]{22}$ + /// SLOVENIA: ^SI56[0-9]{15}$ + /// SPAIN: ^ES[0-9]{22}$ + /// SWEDEN:* [0-9]{1,15}$ + /// UNITED_KINGDOM: ^[0-9]{8}$ [JsonProperty("AccountNumber", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string AccountNumber { get; set; } @@ -4424,6 +4939,8 @@ public class ChargeRequestData : AbstractRequestData /// 1234567890 /// 7653385737 + /// 1234567890 + /// 7653385737 [JsonProperty("AccountID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string AccountID { get; set; } @@ -4431,6 +4948,7 @@ public class ChargeRequestData : AbstractRequestData /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh + /// https://example.com/trustly/notification/a2b63j23dj23883jhfhfh [JsonProperty("NotificationURL", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string NotificationURL { get; set; } @@ -4445,6 +4963,7 @@ public class ChargeRequestData : AbstractRequestData /// 12345678 + /// 12345678 [JsonProperty("MessageID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string MessageID { get; set; } @@ -4459,6 +4978,17 @@ public class ChargeRequestData : AbstractRequestDataPLN: 100.00 /// RON: 100.00 /// SEK: 100.00 + /// BGN: 100.00 + /// CZK: 100.00 + /// DKK: 100.00 + /// EUR: 100.00 + /// GBP: 100.00 + /// HRK: 100.00 + /// HUF: 100 + /// NOK: 100.00 + /// PLN: 100.00 + /// RON: 100.00 + /// SEK: 100.00 [JsonProperty("Amount", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string Amount { get; set; } @@ -4476,6 +5006,17 @@ public class ChargeRequestData : AbstractRequestDataPLN /// RON /// SEK + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK [JsonProperty("Currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string Currency { get; set; } @@ -4497,6 +5038,7 @@ public class CancelDirectDebitRequestData : AbstractRequestData /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the request. /// /// 9594811343 + /// 9594811343 [JsonProperty("OrderID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string OrderID { get; set; } @@ -4518,6 +5060,7 @@ public class CancelDirectDebitMandateRequestData : AbstractRequestData /// 9594811343 + /// 9594811343 [JsonProperty("OrderID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string OrderID { get; set; } @@ -4574,6 +5117,7 @@ public class ApproveWithdrawalRequestData : AbstractRequestData /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the charge. /// /// 9594811343 + /// 9594811343 [JsonProperty("OrderID", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public long OrderID { get; set; } @@ -4635,6 +5179,17 @@ public class AccountPayoutRequestData : AbstractRequestDataPLN /// RON /// SEK + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK [JsonProperty("Currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string Currency { get; set; } @@ -4656,6 +5211,7 @@ public class AccountLedgerRequestData : AbstractRequestData /// Date string in the ISO 8601 format (YYYY-MM-DD) /// /// 2014-04-01 + /// 2014-04-01 [JsonProperty("FromDate", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string FromDate { get; set; } @@ -4663,6 +5219,7 @@ public class AccountLedgerRequestData : AbstractRequestData /// Date string in the ISO 8601 format (YYYY-MM-DD) /// /// 2014-04-01 + /// 2014-04-01 [JsonProperty("ToDate", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string ToDate { get; set; } @@ -4680,6 +5237,17 @@ public class AccountLedgerRequestData : AbstractRequestData /// PLN /// RON /// SEK + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK [JsonProperty("Currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string Currency { get; set; } @@ -4706,6 +5274,7 @@ public abstract class AbstractNotificationRequestData /// The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the request. /// /// 9594811343 + /// 9594811343 [JsonProperty("orderid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string OrderID { get; set; } @@ -4713,6 +5282,7 @@ public abstract class AbstractNotificationRequestData /// Your unique ID of the transaction. /// /// 12345678 + /// 12345678 [JsonProperty("messageid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string MessageID { get; set; } @@ -4726,6 +5296,7 @@ public abstract class AbstractNotificationRequestData public class PayoutFailedNotificationData : AbstractNotificationRequestData { + /// 98.02 /// 98.02 [JsonProperty("amount", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] @@ -4744,6 +5315,17 @@ public class PayoutFailedNotificationData : AbstractNotificationRequestData /// PLN /// RON /// SEK + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK [JsonProperty("currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string Currency { get; set; } @@ -4759,6 +5341,8 @@ public class PayoutFailedNotificationData : AbstractNotificationRequestData /// /// 2014-01-30 13:28:45.652299+01 /// 2014-03-31 11:50:06.46106+00 + /// 2014-01-30 13:28:45.652299+01 + /// 2014-03-31 11:50:06.46106+00 [JsonProperty("timestamp", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string Timestamp { get; set; } @@ -4766,12 +5350,14 @@ public class PayoutFailedNotificationData : AbstractNotificationRequestData /// Short code of the error /// /// incorrect_account_number + /// incorrect_account_number [JsonProperty("errorcode")] public string Errorcode { get; set; } /// /// Description of the error /// /// Format of the account number specified is not correct + /// Format of the account number specified is not correct [JsonProperty("errormessage")] public string Errormessage { get; set; } [JsonProperty("attributes")] @@ -4790,6 +5376,7 @@ public PayoutFailedNotification() : base("payoutfailed") { } public class PayoutConfirmationNotificationData : AbstractNotificationRequestData { + /// 98.02 /// 98.02 [JsonProperty("amount", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] @@ -4808,6 +5395,17 @@ public class PayoutConfirmationNotificationData : AbstractNotificationRequestDat /// PLN /// RON /// SEK + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK [JsonProperty("currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string Currency { get; set; } @@ -4823,6 +5421,8 @@ public class PayoutConfirmationNotificationData : AbstractNotificationRequestDat /// /// 2014-01-30 13:28:45.652299+01 /// 2014-03-31 11:50:06.46106+00 + /// 2014-01-30 13:28:45.652299+01 + /// 2014-03-31 11:50:06.46106+00 [JsonProperty("timestamp", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string Timestamp { get; set; } @@ -4842,6 +5442,7 @@ public PayoutConfirmationNotification() : base("payoutconfirmation") { } public abstract class AbstractPendingNotificationData : AbstractNotificationRequestData { + /// 98.02 /// 98.02 [JsonProperty("amount", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] @@ -4860,6 +5461,17 @@ public abstract class AbstractPendingNotificationData : AbstractNotificationRequ /// PLN /// RON /// SEK + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK [JsonProperty("currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string Currency { get; set; } @@ -4868,6 +5480,8 @@ public abstract class AbstractPendingNotificationData : AbstractNotificationRequ /// /// 2014-01-30 13:28:45.652299+01 /// 2014-03-31 11:50:06.46106+00 + /// 2014-01-30 13:28:45.652299+01 + /// 2014-03-31 11:50:06.46106+00 [JsonProperty("timestamp", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string Timestamp { get; set; } @@ -4928,6 +5542,8 @@ public class PendingDirectDebitNotificationData : AbstractPendingNotificationDat /// /// 1234567890 /// 7653385737 + /// 1234567890 + /// 7653385737 [JsonProperty("accountid")] public string AccountID { get; set; } /// @@ -4977,6 +5593,7 @@ public class PendingDefaultNotificationData : AbstractPendingNotificationData public string EndUserID { get; set; } } + [JsonConverter(typeof(WrapperConverter), "Raw")] public class PendingNotificationData { private PendingDefaultNotificationData _pendingDefaultNotificationData; @@ -4985,57 +5602,57 @@ public class PendingNotificationData private PendingRefundDirectDebitNotificationData _pendingRefundDirectDebitNotificationData; private PendingDirectPaymentBatchNotificationData _pendingDirectPaymentBatchNotificationData; - public PendingNotificationData(dynamic raw) + public PendingNotificationData(JToken raw) { this.Raw = raw; } - public PendingDefaultNotificationData GetPendingDefaultNotificationData(Func transformer) + public PendingDefaultNotificationData GetPendingDefaultNotificationData(JsonSerializer transformer) { if (this._pendingDefaultNotificationData != null) { return this._pendingDefaultNotificationData; } - return this._pendingDefaultNotificationData = transformer(this.Raw); + return this._pendingDefaultNotificationData = this.Raw.ToObject(transformer); } - public PendingDirectDebitNotificationData GetPendingDirectDebitNotificationData(Func transformer) + public PendingDirectDebitNotificationData GetPendingDirectDebitNotificationData(JsonSerializer transformer) { if (this._pendingDirectDebitNotificationData != null) { return this._pendingDirectDebitNotificationData; } - return this._pendingDirectDebitNotificationData = transformer(this.Raw); + return this._pendingDirectDebitNotificationData = this.Raw.ToObject(transformer); } - public PendingDirectCreditNotificationData GetPendingDirectCreditNotificationData(Func transformer) + public PendingDirectCreditNotificationData GetPendingDirectCreditNotificationData(JsonSerializer transformer) { if (this._pendingDirectCreditNotificationData != null) { return this._pendingDirectCreditNotificationData; } - return this._pendingDirectCreditNotificationData = transformer(this.Raw); + return this._pendingDirectCreditNotificationData = this.Raw.ToObject(transformer); } - public PendingRefundDirectDebitNotificationData GetPendingRefundDirectDebitNotificationData(Func transformer) + public PendingRefundDirectDebitNotificationData GetPendingRefundDirectDebitNotificationData(JsonSerializer transformer) { if (this._pendingRefundDirectDebitNotificationData != null) { return this._pendingRefundDirectDebitNotificationData; } - return this._pendingRefundDirectDebitNotificationData = transformer(this.Raw); + return this._pendingRefundDirectDebitNotificationData = this.Raw.ToObject(transformer); } - public PendingDirectPaymentBatchNotificationData GetPendingDirectPaymentBatchNotificationData(Func transformer) + public PendingDirectPaymentBatchNotificationData GetPendingDirectPaymentBatchNotificationData(JsonSerializer transformer) { if (this._pendingDirectPaymentBatchNotificationData != null) { return this._pendingDirectPaymentBatchNotificationData; } - return this._pendingDirectPaymentBatchNotificationData = transformer(this.Raw); + return this._pendingDirectPaymentBatchNotificationData = this.Raw.ToObject(transformer); } - public dynamic Raw { get; set; } + public JToken Raw { get; set; } } public class PendingNotificationParams : JsonRpcNotificationParams @@ -5063,6 +5680,7 @@ public class AbstractKYCNotificationData : AbstractNotificationRequestData /// ***The identifier may change, hence our suggestion is to have a logic that does not include KYCEntityID /// /// 29a750aa-0bad-4a28-a42d-ffb9a690d93a + /// 29a750aa-0bad-4a28-a42d-ffb9a690d93a [JsonProperty("kycentityid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string Kycentityid { get; set; } @@ -5082,40 +5700,43 @@ public class KYCAbortNotificationData : AbstractKYCNotificationData public StringBoolean? Abort { get; set; } /// unverified /// underage + /// unverified + /// underage [JsonProperty("abortmessage", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string Abortmessage { get; set; } } + [JsonConverter(typeof(WrapperConverter), "Raw")] public class KYCNotificationData { private KYCDefaultNotificationData _kycDefaultNotificationData; private KYCAbortNotificationData _kycAbortNotificationData; - public KYCNotificationData(dynamic raw) + public KYCNotificationData(JToken raw) { this.Raw = raw; } - public KYCDefaultNotificationData GetKycDefaultNotificationData(Func transformer) + public KYCDefaultNotificationData GetKycDefaultNotificationData(JsonSerializer transformer) { if (this._kycDefaultNotificationData != null) { return this._kycDefaultNotificationData; } - return this._kycDefaultNotificationData = transformer(this.Raw); + return this._kycDefaultNotificationData = this.Raw.ToObject(transformer); } - public KYCAbortNotificationData GetKycAbortNotificationData(Func transformer) + public KYCAbortNotificationData GetKycAbortNotificationData(JsonSerializer transformer) { if (this._kycAbortNotificationData != null) { return this._kycAbortNotificationData; } - return this._kycAbortNotificationData = transformer(this.Raw); + return this._kycAbortNotificationData = this.Raw.ToObject(transformer); } - public dynamic Raw { get; set; } + public JToken Raw { get; set; } } public class KYCNotificationParams : JsonRpcNotificationParams @@ -5131,6 +5752,17 @@ public KYCNotification() : base("kyc") { } public class AbstractDebitNotificationData : AbstractNotificationRequestData where T : AbstractRequestDataAttributes { + /// BGN: 100.00 + /// CZK: 100.00 + /// DKK: 100.00 + /// EUR: 100.00 + /// GBP: 100.00 + /// HRK: 100.00 + /// HUF: 100 + /// NOK: 100.00 + /// PLN: 100.00 + /// RON: 100.00 + /// SEK: 100.00 /// BGN: 100.00 /// CZK: 100.00 /// DKK: 100.00 @@ -5159,6 +5791,17 @@ public class AbstractDebitNotificationData : AbstractNotificationRequestData /// PLN /// RON /// SEK + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK [JsonProperty("currency", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string Currency { get; set; } @@ -5174,6 +5817,8 @@ public class AbstractDebitNotificationData : AbstractNotificationRequestData /// /// 2014-01-30 13:28:45.652299+01 /// 2014-03-31 11:50:06.46106+00 + /// 2014-01-30 13:28:45.652299+01 + /// 2014-03-31 11:50:06.46106+00 [JsonProperty("timestamp", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string Timestamp { get; set; } @@ -5237,6 +5882,7 @@ public class DebitDefaultNotificationData : AbstractDebitNotificationData), "Raw")] public class DebitNotificationData { private DebitDefaultNotificationData _debitDefaultNotificationData; @@ -5244,48 +5890,48 @@ public class DebitNotificationData private DebitDirectCreditNotificationData _debitDirectCreditNotificationData; private DebitRefundDirectDebitNotificationData _debitRefundDirectDebitNotificationData; - public DebitNotificationData(dynamic raw) + public DebitNotificationData(JToken raw) { this.Raw = raw; } - public DebitDefaultNotificationData GetDebitDefaultNotificationData(Func transformer) + public DebitDefaultNotificationData GetDebitDefaultNotificationData(JsonSerializer transformer) { if (this._debitDefaultNotificationData != null) { return this._debitDefaultNotificationData; } - return this._debitDefaultNotificationData = transformer(this.Raw); + return this._debitDefaultNotificationData = this.Raw.ToObject(transformer); } - public DebitDirectDebitNotificationData GetDebitDirectDebitNotificationData(Func transformer) + public DebitDirectDebitNotificationData GetDebitDirectDebitNotificationData(JsonSerializer transformer) { if (this._debitDirectDebitNotificationData != null) { return this._debitDirectDebitNotificationData; } - return this._debitDirectDebitNotificationData = transformer(this.Raw); + return this._debitDirectDebitNotificationData = this.Raw.ToObject(transformer); } - public DebitDirectCreditNotificationData GetDebitDirectCreditNotificationData(Func transformer) + public DebitDirectCreditNotificationData GetDebitDirectCreditNotificationData(JsonSerializer transformer) { if (this._debitDirectCreditNotificationData != null) { return this._debitDirectCreditNotificationData; } - return this._debitDirectCreditNotificationData = transformer(this.Raw); + return this._debitDirectCreditNotificationData = this.Raw.ToObject(transformer); } - public DebitRefundDirectDebitNotificationData GetDebitRefundDirectDebitNotificationData(Func transformer) + public DebitRefundDirectDebitNotificationData GetDebitRefundDirectDebitNotificationData(JsonSerializer transformer) { if (this._debitRefundDirectDebitNotificationData != null) { return this._debitRefundDirectDebitNotificationData; } - return this._debitRefundDirectDebitNotificationData = transformer(this.Raw); + return this._debitRefundDirectDebitNotificationData = this.Raw.ToObject(transformer); } - public dynamic Raw { get; set; } + public JToken Raw { get; set; } } public class DebitNotificationParams : JsonRpcNotificationParams @@ -5310,12 +5956,15 @@ public class CreditSwishNotificationDataAttributes : AbstractCreditNotificationD /// /// 1E2FC19E5E5E4E18916609B7F8911C12 /// TRLY80494-1001 + /// 1E2FC19E5E5E4E18916609B7F8911C12 + /// TRLY80494-1001 [JsonProperty("reference")] public string Reference { get; set; } /// /// Payment reference, from the bank, of the payment that occurred based on the Payment request. Only available if status is PAID. /// /// 467123476 + /// 467123476 [JsonProperty("payerAlias")] public string PayerAlias { get; set; } } @@ -5327,12 +5976,15 @@ public class CreditRefundDirectDebitNotificationDataAttributes : AbstractCreditN /// /// 1E2FC19E5E5E4E18916609B7F8911C12 /// TRLY80494-1001 + /// 1E2FC19E5E5E4E18916609B7F8911C12 + /// TRLY80494-1001 [JsonProperty("reference")] public string Reference { get; set; } /// /// Statement that appear on the end users bank account /// /// TRLY80494-1001 + /// TRLY80494-1001 [JsonProperty("statement")] public string Statement { get; set; } [JsonProperty("reason")] @@ -5351,12 +6003,15 @@ public class CreditDirectDebitNotificationDataAttributes : AbstractCreditNotific /// /// 1E2FC19E5E5E4E18916609B7F8911C12 /// TRLY80494-1001 + /// 1E2FC19E5E5E4E18916609B7F8911C12 + /// TRLY80494-1001 [JsonProperty("reference")] public string Reference { get; set; } /// /// Statement that appear on the end users bank account /// /// TRLY80494-1001 + /// TRLY80494-1001 [JsonProperty("statement")] public string Statement { get; set; } } @@ -5368,12 +6023,15 @@ public class CreditDirectCreditNotificationDataAttributes : AbstractCreditNotifi /// /// 1E2FC19E5E5E4E18916609B7F8911C12 /// TRLY80494-1001 + /// 1E2FC19E5E5E4E18916609B7F8911C12 + /// TRLY80494-1001 [JsonProperty("reference")] public string Reference { get; set; } /// /// Statement that appear on the end users bank account /// /// TRLY80494-1001 + /// TRLY80494-1001 [JsonProperty("statement")] public string Statement { get; set; } } @@ -5393,6 +6051,7 @@ public class AbstractCreditNotificationData : AbstractNotificationRequestData [JsonProperty("enduserid")] public string EndUserID { get; set; } /// 98.02 + /// 98.02 [JsonProperty("amount")] public decimal Amount { get; set; } /// @@ -5409,6 +6068,17 @@ public class AbstractCreditNotificationData : AbstractNotificationRequestData /// PLN /// RON /// SEK + /// BGN + /// CZK + /// DKK + /// EUR + /// GBP + /// HRK + /// HUF + /// NOK + /// PLN + /// RON + /// SEK [JsonProperty("currency")] public string Currency { get; set; } /// @@ -5416,6 +6086,8 @@ public class AbstractCreditNotificationData : AbstractNotificationRequestData /// /// 2014-01-30 13:28:45.652299+01 /// 2014-03-31 11:50:06.46106+00 + /// 2014-01-30 13:28:45.652299+01 + /// 2014-03-31 11:50:06.46106+00 [JsonProperty("timestamp")] public string Timestamp { get; set; } [JsonProperty("attributes")] @@ -5463,6 +6135,8 @@ public class CreditDirectDebitNotificationData : AbstractCreditNotificationData< /// /// 1234567890 /// 7653385737 + /// 1234567890 + /// 7653385737 [JsonProperty("accountid")] public string AccountID { get; set; } } @@ -5497,6 +6171,7 @@ public class CreditDefaultNotificationData : AbstractCreditNotificationData), "Raw")] public class CreditNotificationData { private CreditDefaultNotificationData _creditDefaultNotificationData; @@ -5505,57 +6180,57 @@ public class CreditNotificationData private CreditRefundDirectDebitNotificationData _creditRefundDirectDebitNotificationData; private CreditSwishNotificationData _creditSwishNotificationData; - public CreditNotificationData(dynamic raw) + public CreditNotificationData(JToken raw) { this.Raw = raw; } - public CreditDefaultNotificationData GetCreditDefaultNotificationData(Func transformer) + public CreditDefaultNotificationData GetCreditDefaultNotificationData(JsonSerializer transformer) { if (this._creditDefaultNotificationData != null) { return this._creditDefaultNotificationData; } - return this._creditDefaultNotificationData = transformer(this.Raw); + return this._creditDefaultNotificationData = this.Raw.ToObject(transformer); } - public CreditDirectDebitNotificationData GetCreditDirectDebitNotificationData(Func transformer) + public CreditDirectDebitNotificationData GetCreditDirectDebitNotificationData(JsonSerializer transformer) { if (this._creditDirectDebitNotificationData != null) { return this._creditDirectDebitNotificationData; } - return this._creditDirectDebitNotificationData = transformer(this.Raw); + return this._creditDirectDebitNotificationData = this.Raw.ToObject(transformer); } - public CreditDirectCreditNotificationData GetCreditDirectCreditNotificationData(Func transformer) + public CreditDirectCreditNotificationData GetCreditDirectCreditNotificationData(JsonSerializer transformer) { if (this._creditDirectCreditNotificationData != null) { return this._creditDirectCreditNotificationData; } - return this._creditDirectCreditNotificationData = transformer(this.Raw); + return this._creditDirectCreditNotificationData = this.Raw.ToObject(transformer); } - public CreditRefundDirectDebitNotificationData GetCreditRefundDirectDebitNotificationData(Func transformer) + public CreditRefundDirectDebitNotificationData GetCreditRefundDirectDebitNotificationData(JsonSerializer transformer) { if (this._creditRefundDirectDebitNotificationData != null) { return this._creditRefundDirectDebitNotificationData; } - return this._creditRefundDirectDebitNotificationData = transformer(this.Raw); + return this._creditRefundDirectDebitNotificationData = this.Raw.ToObject(transformer); } - public CreditSwishNotificationData GetCreditSwishNotificationData(Func transformer) + public CreditSwishNotificationData GetCreditSwishNotificationData(JsonSerializer transformer) { if (this._creditSwishNotificationData != null) { return this._creditSwishNotificationData; } - return this._creditSwishNotificationData = transformer(this.Raw); + return this._creditSwishNotificationData = this.Raw.ToObject(transformer); } - public dynamic Raw { get; set; } + public JToken Raw { get; set; } } public class CreditNotificationParams : JsonRpcNotificationParams @@ -5582,6 +6257,8 @@ public class CancelSwishNotificationData : AbstractCancelNotificationData /// 2014-01-30 13:28:45.652299+01 /// 2014-03-31 11:50:06.46106+00 + /// 2014-01-30 13:28:45.652299+01 + /// 2014-03-31 11:50:06.46106+00 [JsonProperty("timestamp")] public string Timestamp { get; set; } } @@ -5688,10 +6365,13 @@ public class CancelDefaultNotificationData : AbstractCancelNotificationData /// 2014-01-30 13:28:45.652299+01 /// 2014-03-31 11:50:06.46106+00 + /// 2014-01-30 13:28:45.652299+01 + /// 2014-03-31 11:50:06.46106+00 [JsonProperty("timestamp")] public string Timestamp { get; set; } } + [JsonConverter(typeof(WrapperConverter), "Raw")] public class CancelNotificationData { private CancelDefaultNotificationData _cancelDefaultNotificationData; @@ -5702,75 +6382,75 @@ public class CancelNotificationData private CancelMandateNotificationData _cancelMandateNotificationData; private CancelDirectPaymentBatchNotificationData _cancelDirectPaymentBatchNotificationData; - public CancelNotificationData(dynamic raw) + public CancelNotificationData(JToken raw) { this.Raw = raw; } - public CancelDefaultNotificationData GetCancelDefaultNotificationData(Func transformer) + public CancelDefaultNotificationData GetCancelDefaultNotificationData(JsonSerializer transformer) { if (this._cancelDefaultNotificationData != null) { return this._cancelDefaultNotificationData; } - return this._cancelDefaultNotificationData = transformer(this.Raw); + return this._cancelDefaultNotificationData = this.Raw.ToObject(transformer); } - public CancelSwishNotificationData GetCancelSwishNotificationData(Func transformer) + public CancelSwishNotificationData GetCancelSwishNotificationData(JsonSerializer transformer) { if (this._cancelSwishNotificationData != null) { return this._cancelSwishNotificationData; } - return this._cancelSwishNotificationData = transformer(this.Raw); + return this._cancelSwishNotificationData = this.Raw.ToObject(transformer); } - public CancelDirectDebitNotificationData GetCancelDirectDebitNotificationData(Func transformer) + public CancelDirectDebitNotificationData GetCancelDirectDebitNotificationData(JsonSerializer transformer) { if (this._cancelDirectDebitNotificationData != null) { return this._cancelDirectDebitNotificationData; } - return this._cancelDirectDebitNotificationData = transformer(this.Raw); + return this._cancelDirectDebitNotificationData = this.Raw.ToObject(transformer); } - public CancelDirectCreditNotificationData GetCancelDirectCreditNotificationData(Func transformer) + public CancelDirectCreditNotificationData GetCancelDirectCreditNotificationData(JsonSerializer transformer) { if (this._cancelDirectCreditNotificationData != null) { return this._cancelDirectCreditNotificationData; } - return this._cancelDirectCreditNotificationData = transformer(this.Raw); + return this._cancelDirectCreditNotificationData = this.Raw.ToObject(transformer); } - public CancelRefundDirectDebitNotificationData GetCancelRefundDirectDebitNotificationData(Func transformer) + public CancelRefundDirectDebitNotificationData GetCancelRefundDirectDebitNotificationData(JsonSerializer transformer) { if (this._cancelRefundDirectDebitNotificationData != null) { return this._cancelRefundDirectDebitNotificationData; } - return this._cancelRefundDirectDebitNotificationData = transformer(this.Raw); + return this._cancelRefundDirectDebitNotificationData = this.Raw.ToObject(transformer); } - public CancelMandateNotificationData GetCancelMandateNotificationData(Func transformer) + public CancelMandateNotificationData GetCancelMandateNotificationData(JsonSerializer transformer) { if (this._cancelMandateNotificationData != null) { return this._cancelMandateNotificationData; } - return this._cancelMandateNotificationData = transformer(this.Raw); + return this._cancelMandateNotificationData = this.Raw.ToObject(transformer); } - public CancelDirectPaymentBatchNotificationData GetCancelDirectPaymentBatchNotificationData(Func transformer) + public CancelDirectPaymentBatchNotificationData GetCancelDirectPaymentBatchNotificationData(JsonSerializer transformer) { if (this._cancelDirectPaymentBatchNotificationData != null) { return this._cancelDirectPaymentBatchNotificationData; } - return this._cancelDirectPaymentBatchNotificationData = transformer(this.Raw); + return this._cancelDirectPaymentBatchNotificationData = this.Raw.ToObject(transformer); } - public dynamic Raw { get; set; } + public JToken Raw { get; set; } } public class CancelNotificationParams : JsonRpcNotificationParams @@ -5817,6 +6497,35 @@ public class AbstractAccountNotificationDataAttributes : AbstractRequestDataAttr /// SPAIN /// SWEDEN /// UNITED_KINGDOM + /// AUSTRIA + /// BELGIUM + /// BULGARIA + /// CROATIA + /// CYPRUS + /// CZECH_REPUBLIC + /// DENMARK + /// ESTONIA + /// FINLAND + /// FRANCE + /// GERMANY + /// GREECE + /// HUNGARY + /// IRELAND + /// ITALY + /// LATVIA + /// LITHUANIA + /// LUXEMBOURG + /// MALTA + /// NETHERLANDS + /// NORWAY + /// POLAND + /// PORTUGAL + /// ROMANIA + /// SLOVAKIA + /// SLOVENIA + /// SPAIN + /// SWEDEN + /// UNITED_KINGDOM [JsonProperty("clearinghouse")] public string ClearingHouse { get; set; } /// @@ -5824,12 +6533,15 @@ public class AbstractAccountNotificationDataAttributes : AbstractRequestDataAttr /// /// SEB /// Skandiabanken + /// SEB + /// Skandiabanken [JsonProperty("bank")] public string Bank { get; set; } /// /// A text that is safe to show the enduser for identifying the account. Do not parse this text since it will be a different format for different accounts. /// /// ***4057 + /// ***4057 [JsonProperty("descriptor")] public string Descriptor { get; set; } /// @@ -5842,12 +6554,15 @@ public class AbstractAccountNotificationDataAttributes : AbstractRequestDataAttr /// /// SE198201019876 /// 19900501 + /// SE198201019876 + /// 19900501 [JsonProperty("personid")] public string PersonID { get; set; } /// /// The name of the account holder /// /// John Doe + /// John Doe [JsonProperty("name")] public string Name { get; set; } /// @@ -5859,12 +6574,14 @@ public class AbstractAccountNotificationDataAttributes : AbstractRequestDataAttr /// The zipcode of the account holder /// /// 12345 + /// 12345 [JsonProperty("zipcode")] public string Zipcode { get; set; } /// /// The city of the account holder /// /// Examplecity + /// Examplecity [JsonProperty("city")] public string City { get; set; } } @@ -5889,12 +6606,15 @@ public class AccountMandateNotificationDataAttributes : AbstractAccountNotificat /// /// Sweden: ^[0-9]{4,5}$ /// United Kingdom: ^[0-9]{6}$ + /// Sweden: ^[0-9]{4,5}$ + /// United Kingdom: ^[0-9]{6}$ [JsonProperty("bankcode")] public string Bankcode { get; set; } /// /// Name of the account /// /// Salary account + /// Salary account [JsonProperty("accountname")] public string Accountname { get; set; } [JsonProperty("accountholders")] @@ -5907,6 +6627,11 @@ public class AccountMandateNotificationDataAttributes : AbstractAccountNotificat /// bg /// 123123 /// HANDSESS + /// 6160 + /// 6000 + /// bg + /// 123123 + /// HANDSESS [JsonProperty("bankidentifier")] public string Bankidentifier { get; set; } /// @@ -5943,6 +6668,37 @@ public class AccountMandateNotificationDataAttributes : AbstractAccountNotificat /// SPAIN: ^ES[0-9]{22}$ /// SWEDEN:* [0-9]{1,15}$ /// UNITED_KINGDOM: ^[0-9]{8}$ + /// 6112 + /// 391124057 + /// AUSTRIA: ^AT[0-9]{18}$ + /// BELGIUM: ^BE[0-9]{14}$ + /// BULGARIA: ^BG[0-9]{2}[A-Z]{4}[0-9]{4}[0-9]{2}[A-Z0-9]{8}$ + /// CROATIA: ^HR[0-9]{2}[0-9]{7}[0-9]{10}$ + /// CYPRUS: ^CY[0-9]{10}[0-9A-Z]{16}$ + /// CZECH_REPUBLIC: ^CZ[0-9]{22}$ + /// DENMARK: ^DK[0-9]{16}$ + /// ESTONIA: ^EE[0-9]{18}$ + /// FINLAND: ^FI[0-9]{16}$ + /// FRANCE: ^FR[0-9]{12}[0-9A-Z]{11}[0-9]{2}$ + /// GERMANY: ^DE[0-9]{20}$ + /// GREECE: ^GR[0-9]{25}$ + /// HUNGARY: ^HU[0-9]{26}$ + /// IRELAND: ^IE[0-9]{2}[A-Z]{4}[0-9]{14}$ + /// ITALY: ^IT[0-9]{2}[A-Z][0-9]{10}[0-9A-Z]{12}$ + /// LATVIA: ^LV[0-9]{2}[A-Z]{4}[0-9A-Z]{13}$ + /// LITHUANIA: ^LT[0-9]{18}$ + /// LUXEMBOURG: ^LU[0-9]{18}$ + /// MALTA: ^MT[0-9]{2}[A-Z]{4}[0-9]{5}[0-9A-Z]{18}$ + /// NETHERLANDS: ^NL[0-9]{2}[A-Z]{4}[0-9]{10}$ + /// NORWAY: ^NO[0-9]{13}$ + /// POLAND: ^PL[0-9]{26}$ + /// PORTUGAL: ^PT[0-9]{23}$ + /// ROMANIA: ^RO[0-9]{2}[A-Z]{4}[0-9A-Z]{16}$ + /// SLOVAKIA: ^SK[0-9]{22}$ + /// SLOVENIA: ^SI56[0-9]{15}$ + /// SPAIN: ^ES[0-9]{22}$ + /// SWEDEN:* [0-9]{1,15}$ + /// UNITED_KINGDOM: ^[0-9]{8}$ [JsonProperty("accountnumber")] public string Accountnumber { get; set; } [JsonProperty("accountsource")] @@ -5962,6 +6718,8 @@ public class AbstractAccountNotificationData : AbstractNotificationRequestDat /// /// 1234567890 /// 7653385737 + /// 1234567890 + /// 7653385737 [JsonProperty("accountid", Required = Required.Always, NullValueHandling = NullValueHandling.Include)] [Required] public string AccountID { get; set; } @@ -5995,35 +6753,36 @@ public class AccountDefaultNotificationData : AbstractAccountNotificationData), "Raw")] public class AccountNotificationData { private AccountDefaultNotificationData _accountDefaultNotificationData; private AccountMandateNotificationData _accountMandateNotificationData; - public AccountNotificationData(dynamic raw) + public AccountNotificationData(JToken raw) { this.Raw = raw; } - public AccountDefaultNotificationData GetAccountDefaultNotificationData(Func transformer) + public AccountDefaultNotificationData GetAccountDefaultNotificationData(JsonSerializer transformer) { if (this._accountDefaultNotificationData != null) { return this._accountDefaultNotificationData; } - return this._accountDefaultNotificationData = transformer(this.Raw); + return this._accountDefaultNotificationData = this.Raw.ToObject(transformer); } - public AccountMandateNotificationData GetAccountMandateNotificationData(Func transformer) + public AccountMandateNotificationData GetAccountMandateNotificationData(JsonSerializer transformer) { if (this._accountMandateNotificationData != null) { return this._accountMandateNotificationData; } - return this._accountMandateNotificationData = transformer(this.Raw); + return this._accountMandateNotificationData = this.Raw.ToObject(transformer); } - public dynamic Raw { get; set; } + public JToken Raw { get; set; } } public class AccountNotificationParams : JsonRpcNotificationParams diff --git a/src/Domain/WrapperConverter.cs b/src/Domain/WrapperConverter.cs new file mode 100644 index 0000000..bae3b78 --- /dev/null +++ b/src/Domain/WrapperConverter.cs @@ -0,0 +1,45 @@ + +using System; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Trustly.Api.Domain +{ + public class WrapperConverter : JsonConverter where T : class + { + private readonly string propertyName; + + public WrapperConverter(string propertyName) + { + this.propertyName = propertyName; + } + + public override bool CanConvert(Type objectType) + { + return objectType == typeof(T); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + var jsonObject = JToken.Load(reader); + var constructor = typeof(T).GetConstructor(new[] { typeof(JToken) }); + if (constructor == null) + { + throw new JsonSerializationException($"No 'new(JToken)' constructor found for type {typeof(T)}"); + } + + return constructor.Invoke(new object[] { jsonObject }) as T; + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + var dataProperty = value.GetType().GetProperty(this.propertyName); + if (dataProperty == null) + { + throw new JsonSerializationException($"No '{this.propertyName}' property found on type {value.GetType()}"); + } + + serializer.Serialize(writer, dataProperty.GetValue(value)); + } + } +} diff --git a/tests/Client.UnitTests/NotificationTests.cs b/tests/Client.UnitTests/NotificationTests.cs index 3b80fc8..3a463e4 100644 --- a/tests/Client.UnitTests/NotificationTests.cs +++ b/tests/Client.UnitTests/NotificationTests.cs @@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Http; using Moq; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using NUnit.Framework; using Trustly.Api.Domain; using Trustly.Api.Domain.Exceptions; @@ -56,6 +57,17 @@ public async Task TestNotificationHandlerFromRequest() Assert.That(receivedDebitNotifications, Is.EqualTo(1)); } + [Test] + public void TestUnionDeserialization() + { + var body = this.CreateMockDebitNotificationRequestBodyString("debit"); + var deserialized = JsonConvert.DeserializeObject(body); + var serializer = JsonSerializer.CreateDefault(); + var data = deserialized.Params.Data.GetDebitDefaultNotificationData(serializer); + + Assert.That(data.EndUserID, Is.EqualTo("user@email.com")); + } + [Test] public async Task TestNotificationHandlerFromMiddlewareRequest() { @@ -374,7 +386,7 @@ public class DebitIshNotificationRequest : JsonRpcNotification Date: Fri, 11 Oct 2024 11:29:54 +0200 Subject: [PATCH 6/6] 451 -> 481 --- src/Client/Client.csproj | 4 ++-- src/Domain/Domain.csproj | 2 +- tests/Client.UnitTests/Client.UnitTests.csproj | 12 +++++++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/Client/Client.csproj b/src/Client/Client.csproj index 9d3ac7c..aaa0f04 100644 --- a/src/Client/Client.csproj +++ b/src/Client/Client.csproj @@ -1,7 +1,7 @@ - netstandard2.0;net451 + netstandard2.0;net481 Trustly.Api.Client trustly-api-client @@ -25,7 +25,7 @@ - + diff --git a/src/Domain/Domain.csproj b/src/Domain/Domain.csproj index a756995..e3d9227 100644 --- a/src/Domain/Domain.csproj +++ b/src/Domain/Domain.csproj @@ -1,7 +1,7 @@ - netstandard2.0;net451 + netstandard2.0;net481 Trustly.Api.Domain trustly-api-domain diff --git a/tests/Client.UnitTests/Client.UnitTests.csproj b/tests/Client.UnitTests/Client.UnitTests.csproj index ace684c..6982b50 100644 --- a/tests/Client.UnitTests/Client.UnitTests.csproj +++ b/tests/Client.UnitTests/Client.UnitTests.csproj @@ -2,9 +2,19 @@ net481 + Trustly.Api.Client.UnitTests + + trustly-api-tests + 1.0.0 + Trustly + Trustly + ClientApi-Client-Tests + + git + https://github.com/trustly/trustly-client-net false - Trustly.Api.Client.UnitTests +