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/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/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..d5a91b6 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
+ JToken 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 = (JToken) 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..5a90223 100644
--- a/src/Client/TrustlyApiClient.cs
+++ b/src/Client/TrustlyApiClient.cs
@@ -8,153 +8,117 @@
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 static JsonSerializerSettings DEFAULT_SERIALIZER_SETTINGS = new JsonSerializerSettings
+ {
+ NullValueHandling = NullValueHandling.Ignore
+ };
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> OnDefaultDebit;
+ 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 = TrustlyApiClient.DEFAULT_SERIALIZER_SETTINGS;
+ 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 +130,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 +147,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 +163,103 @@ 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, 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?");
}
@@ -311,22 +267,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..8b46561 100644
--- a/src/Client/TrustlyApiClientExtensions.cs
+++ b/src/Client/TrustlyApiClientExtensions.cs
@@ -1,96 +1,84 @@
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[] { '/' });
- if (string.Equals(contextPath, "trustly/notifications", StringComparison.InvariantCultureIgnoreCase))
+ if (string.Equals(contextPath, client.Settings.NotificationUrl ?? "trustly/notifications", StringComparison.InvariantCultureIgnoreCase))
{
var responseCount = 0;
- var clientCount = 0;
- foreach (var client in TrustlyApiClient.GetRegisteredClients())
+ var includeErrorMessage = false;
+
+ try
{
- clientCount++;
+ includeErrorMessage = includeErrorMessage || client.Settings.IncludeExceptionMessageInNotificationResponse;
+
await client.HandleNotificationFromRequestAsync(
request,
- onOK: async (rpcMethod, uuid) =>
- {
- 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/TrustlyApiClientSettings.cs b/src/Client/TrustlyApiClientSettings.cs
index 87abbdd..46879be 100644
--- a/src/Client/TrustlyApiClientSettings.cs
+++ b/src/Client/TrustlyApiClientSettings.cs
@@ -17,6 +17,8 @@ public class TrustlyApiClientSettings
public string Username { get; set; }
public string Password { get; set; }
+ public string NotificationUrl { get; set; }
+
public AsymmetricKeyParameter ClientPublicKey { get; internal set; }
public AsymmetricKeyParameter ClientPrivateKey { get; internal set; }
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..a655612
--- /dev/null
+++ b/src/Domain/Domain.cs
@@ -0,0 +1,6807 @@
+// Generated by Omnigen @ 2024-09-24T11:49:54.634Z
+
+using Newtonsoft.Json;
+using Newtonsoft.Json.Converters;
+using Newtonsoft.Json.Linq;
+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
+ /// 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
+ /// 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
+ /// 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
+ /// 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
+ /// 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
+ /// 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]
+ 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
+ /// 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
+ /// 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
+ /// 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
+ /// 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
+ /// 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
+ /// 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
+ /// 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
+ /// 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
+ /// 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
+ /// 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
+ /// 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
+ /// 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
+ /// 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; }
+ }
+
+ 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
+ /// 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