diff --git a/.nuget/nuget.exe b/.nuget/nuget.exe new file mode 100644 index 0000000..ed048fe Binary files /dev/null and b/.nuget/nuget.exe differ diff --git a/PAYNLSDK/API/Alliance/AddBankAccount/AddBankAccountResult.cs b/PAYNLSDK/API/Alliance/AddBankAccount/AddBankAccountResult.cs new file mode 100644 index 0000000..6a83a4e --- /dev/null +++ b/PAYNLSDK/API/Alliance/AddBankAccount/AddBankAccountResult.cs @@ -0,0 +1,16 @@ +using Newtonsoft.Json; + +namespace PAYNLSDK.API.Alliance.AddBankAccount +{ + /// + /// Result class for AddBankAccount call + /// + public class AddBankAccountResult : ResponseBase + { + /// + /// The URL to redirect the user to for iDEAL verification + /// + [JsonProperty("issuerUrl")] + public string IssuerUrl { get; set; } + } +} diff --git a/PAYNLSDK/API/Alliance/AddBankAccount/Request.cs b/PAYNLSDK/API/Alliance/AddBankAccount/Request.cs new file mode 100644 index 0000000..db45591 --- /dev/null +++ b/PAYNLSDK/API/Alliance/AddBankAccount/Request.cs @@ -0,0 +1,75 @@ +using System.Collections.Specialized; +using PAYNLSDK.Exceptions; +using PAYNLSDK.Utilities; + +namespace PAYNLSDK.API.Alliance.AddBankAccount +{ + /// + /// Request to add a bank account for a merchant with iDEAL verification + /// + public class Request : RequestBase + { + /// + protected override int Version => 7; + /// + protected override string Controller => "Alliance"; + /// + protected override string Method => "addBankaccount"; + + /// + /// The merchant ID + /// + public string MerchantId { get; set; } + + /// + /// The URL to redirect the user to after the iDEAL verification is completed + /// + public string ReturnUrl { get; set; } + + /// + /// Optional: the bank ID, if omitted, the user will be asked for the bank + /// + public string BankId { get; set; } + + /// + /// Optional: the ID of the payment profile (standard iDEAL) + /// + public string PaymentOptionId { get; set; } + + /// + public override NameValueCollection GetParameters() + { + if (ParameterValidator.IsEmpty(MerchantId)) + { + throw new PayNlException("MerchantId is required"); + } + if (ParameterValidator.IsEmpty(ReturnUrl)) + { + throw new PayNlException("ReturnUrl is required"); + } + + var retval = new NameValueCollection + { + { "merchantId", MerchantId }, + { "returnUrl", ReturnUrl } + }; + + if (!string.IsNullOrEmpty(BankId)) + { + retval.Add("bankId", BankId); + } + if (!string.IsNullOrEmpty(PaymentOptionId)) + { + retval.Add("paymentOptionId", PaymentOptionId); + } + + return retval; + } + + /// + protected override void PrepareAndSetResponse() + { + // do nothing + } + } +} diff --git a/PAYNLSDK/API/Alliance/AddClearing/AddClearingResult.cs b/PAYNLSDK/API/Alliance/AddClearing/AddClearingResult.cs new file mode 100644 index 0000000..a4e0e9e --- /dev/null +++ b/PAYNLSDK/API/Alliance/AddClearing/AddClearingResult.cs @@ -0,0 +1,13 @@ +namespace PAYNLSDK.API.Alliance.AddClearing +{ + /// + /// Result class for AddClearing call + /// + public class AddClearingResult : ResponseBase + { + /// + /// Returns true if clearing was successfully added + /// + public bool Success => Request?.Result == true; + } +} diff --git a/PAYNLSDK/API/Alliance/AddClearing/Request.cs b/PAYNLSDK/API/Alliance/AddClearing/Request.cs new file mode 100644 index 0000000..bf041e7 --- /dev/null +++ b/PAYNLSDK/API/Alliance/AddClearing/Request.cs @@ -0,0 +1,65 @@ +using System.Collections.Specialized; +using PAYNLSDK.Exceptions; +using PAYNLSDK.Utilities; + +namespace PAYNLSDK.API.Alliance.AddClearing +{ + /// + /// Request to add clearing for a merchant + /// + public class Request : RequestBase + { + /// + protected override int Version => 4; + /// + protected override string Controller => "Merchant"; + /// + protected override string Method => "addClearing"; + + /// + /// The amount in cents + /// + public int Amount { get; set; } + + /// + /// The merchant ID (optional) + /// + public string MerchantId { get; set; } + + /// + /// The content category ID (optional) + /// + public string ContentCategoryId { get; set; } + + /// + public override NameValueCollection GetParameters() + { + if (Amount <= 0) + { + throw new PayNlException("Amount is required and must be greater than 0"); + } + + var retval = new NameValueCollection + { + { "amount", Amount.ToString() } + }; + + if (!string.IsNullOrEmpty(MerchantId)) + { + retval.Add("merchantId", MerchantId); + } + if (!string.IsNullOrEmpty(ContentCategoryId)) + { + retval.Add("contentCategoryId", ContentCategoryId); + } + + return retval; + } + + /// + protected override void PrepareAndSetResponse() + { + // do nothing + } + } +} diff --git a/PAYNLSDK/API/Alliance/AddDocument/AddDocumentResult.cs b/PAYNLSDK/API/Alliance/AddDocument/AddDocumentResult.cs new file mode 100644 index 0000000..182d55c --- /dev/null +++ b/PAYNLSDK/API/Alliance/AddDocument/AddDocumentResult.cs @@ -0,0 +1,22 @@ +using Newtonsoft.Json; + +namespace PAYNLSDK.API.Alliance.AddDocument +{ + /// + /// Result class for AddDocument call + /// + public class AddDocumentResult : ResponseBase + { + /// + /// Returns true if document was successfully uploaded + /// + [JsonProperty("result")] + public bool Result { get; set; } + + /// + /// Document ID if successful + /// + [JsonProperty("documentId")] + public string DocumentId { get; set; } + } +} diff --git a/PAYNLSDK/API/Alliance/AddDocument/Request.cs b/PAYNLSDK/API/Alliance/AddDocument/Request.cs new file mode 100644 index 0000000..cda12a2 --- /dev/null +++ b/PAYNLSDK/API/Alliance/AddDocument/Request.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using PAYNLSDK.Exceptions; +using PAYNLSDK.Utilities; + +namespace PAYNLSDK.API.Alliance.AddDocument +{ + /// + /// Request to upload a document + /// + public class Request : RequestBase + { + /// + protected override int Version => 1; + /// + protected override string Controller => "Document"; + /// + protected override string Method => "add"; + + /// + /// The document ID + /// + public string DocumentId { get; set; } + + /// + /// The filename + /// + public string Filename { get; set; } + + /// + /// Base64 encoded document content(s) + /// + public List Content { get; set; } = new List(); + + /// + /// Add base64 encoded content + /// + /// Base64 encoded document content + public void AddContent(string base64Content) + { + Content.Add(base64Content); + } + + /// + public override NameValueCollection GetParameters() + { + if (ParameterValidator.IsEmpty(DocumentId)) + { + throw new PayNlException("DocumentId is required"); + } + if (ParameterValidator.IsEmpty(Filename)) + { + throw new PayNlException("Filename is required"); + } + if (Content == null || Content.Count == 0) + { + throw new PayNlException("Content is required"); + } + + var retval = new NameValueCollection + { + { "documentId", DocumentId }, + { "filename", Filename } + }; + + if (Content.Count == 1) + { + retval.Add("documentFile", Content[0]); + } + else + { + for (int i = 0; i < Content.Count; i++) + { + retval.Add($"documentFile[{i}]", Content[i]); + } + } + + return retval; + } + + /// + protected override void PrepareAndSetResponse() + { + // do nothing + } + } +} diff --git a/PAYNLSDK/API/Alliance/DisablePaymentOption/DisablePaymentOptionResult.cs b/PAYNLSDK/API/Alliance/DisablePaymentOption/DisablePaymentOptionResult.cs new file mode 100644 index 0000000..874b09e --- /dev/null +++ b/PAYNLSDK/API/Alliance/DisablePaymentOption/DisablePaymentOptionResult.cs @@ -0,0 +1,13 @@ +namespace PAYNLSDK.API.Alliance.DisablePaymentOption +{ + /// + /// Result class for DisablePaymentOption call + /// + public class DisablePaymentOptionResult : ResponseBase + { + /// + /// Returns true if the payment option was successfully disabled + /// + public bool Success => Request?.Result == true; + } +} diff --git a/PAYNLSDK/API/Alliance/DisablePaymentOption/Request.cs b/PAYNLSDK/API/Alliance/DisablePaymentOption/Request.cs new file mode 100644 index 0000000..3335fe5 --- /dev/null +++ b/PAYNLSDK/API/Alliance/DisablePaymentOption/Request.cs @@ -0,0 +1,56 @@ +using System.Collections.Specialized; +using PAYNLSDK.Exceptions; +using PAYNLSDK.Utilities; + +namespace PAYNLSDK.API.Alliance.DisablePaymentOption +{ + /// + /// Request to disable a payment option for a service + /// + public class Request : RequestBase + { + /// + protected override int Version => 4; + /// + protected override string Controller => "Service"; + /// + protected override string Method => "disablePaymentOption"; + + /// + /// The service ID + /// + public string ServiceId { get; set; } + + /// + /// The payment profile ID (payment method ID) + /// + public string PaymentProfileId { get; set; } + + /// + public override NameValueCollection GetParameters() + { + if (ParameterValidator.IsEmpty(ServiceId)) + { + throw new PayNlException("ServiceId is required"); + } + if (ParameterValidator.IsEmpty(PaymentProfileId)) + { + throw new PayNlException("PaymentProfileId is required"); + } + + var retval = new NameValueCollection + { + { "serviceId", ServiceId }, + { "paymentProfileId", PaymentProfileId } + }; + + return retval; + } + + /// + protected override void PrepareAndSetResponse() + { + // do nothing + } + } +} diff --git a/PAYNLSDK/API/Alliance/EnablePaymentOption/EnablePaymentOptionResult.cs b/PAYNLSDK/API/Alliance/EnablePaymentOption/EnablePaymentOptionResult.cs new file mode 100644 index 0000000..8d35d2a --- /dev/null +++ b/PAYNLSDK/API/Alliance/EnablePaymentOption/EnablePaymentOptionResult.cs @@ -0,0 +1,13 @@ +namespace PAYNLSDK.API.Alliance.EnablePaymentOption +{ + /// + /// Result class for EnablePaymentOption call + /// + public class EnablePaymentOptionResult : ResponseBase + { + /// + /// Returns true if the payment option was successfully enabled + /// + public bool Success => Request?.Result == true; + } +} diff --git a/PAYNLSDK/API/Alliance/EnablePaymentOption/Request.cs b/PAYNLSDK/API/Alliance/EnablePaymentOption/Request.cs new file mode 100644 index 0000000..81f473b --- /dev/null +++ b/PAYNLSDK/API/Alliance/EnablePaymentOption/Request.cs @@ -0,0 +1,70 @@ +using System.Collections.Generic; +using System.Collections.Specialized; +using PAYNLSDK.Exceptions; +using PAYNLSDK.Utilities; + +namespace PAYNLSDK.API.Alliance.EnablePaymentOption +{ + /// + /// Request to enable a payment option for a service + /// + public class Request : RequestBase + { + /// + protected override int Version => 4; + /// + protected override string Controller => "Service"; + /// + protected override string Method => "enablePaymentOption"; + + /// + /// The service ID + /// + public string ServiceId { get; set; } + + /// + /// The payment profile ID (payment method ID) + /// + public string PaymentProfileId { get; set; } + + /// + /// Optional: settings for the payment option + /// + public Dictionary Settings { get; set; } + + /// + public override NameValueCollection GetParameters() + { + if (ParameterValidator.IsEmpty(ServiceId)) + { + throw new PayNlException("ServiceId is required"); + } + if (ParameterValidator.IsEmpty(PaymentProfileId)) + { + throw new PayNlException("PaymentProfileId is required"); + } + + var retval = new NameValueCollection + { + { "serviceId", ServiceId }, + { "paymentProfileId", PaymentProfileId } + }; + + if (Settings != null && Settings.Count > 0) + { + foreach (var setting in Settings) + { + retval.Add($"settings[{setting.Key}]", setting.Value); + } + } + + return retval; + } + + /// + protected override void PrepareAndSetResponse() + { + // do nothing + } + } +} diff --git a/PAYNLSDK/API/Alliance/GetAvailablePaymentOptions/GetAvailablePaymentOptionsResult.cs b/PAYNLSDK/API/Alliance/GetAvailablePaymentOptions/GetAvailablePaymentOptionsResult.cs new file mode 100644 index 0000000..06ba20c --- /dev/null +++ b/PAYNLSDK/API/Alliance/GetAvailablePaymentOptions/GetAvailablePaymentOptionsResult.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace PAYNLSDK.API.Alliance.GetAvailablePaymentOptions +{ + /// + /// Result class for GetAvailablePaymentOptions call + /// + public class GetAvailablePaymentOptionsResult : ResponseBase + { + /// + /// List of available payment options + /// + [JsonProperty("paymentOptions")] + public List PaymentOptions { get; set; } = new List(); + } + + /// + /// Payment option information + /// + public class PaymentOption + { + /// + /// Payment option ID + /// + [JsonProperty("id")] + public string Id { get; set; } + + /// + /// Payment option name + /// + [JsonProperty("name")] + public string Name { get; set; } + + /// + /// Whether the payment option is enabled + /// + [JsonProperty("enabled")] + public bool Enabled { get; set; } + } +} diff --git a/PAYNLSDK/API/Alliance/GetAvailablePaymentOptions/Request.cs b/PAYNLSDK/API/Alliance/GetAvailablePaymentOptions/Request.cs new file mode 100644 index 0000000..aa0885c --- /dev/null +++ b/PAYNLSDK/API/Alliance/GetAvailablePaymentOptions/Request.cs @@ -0,0 +1,41 @@ +using System.Collections.Specialized; +using PAYNLSDK.Exceptions; +using PAYNLSDK.Utilities; + +namespace PAYNLSDK.API.Alliance.GetAvailablePaymentOptions +{ + /// + /// Request to get available payment options for a service + /// + public class Request : RequestBase + { + /// + protected override int Version => 4; + /// + protected override string Controller => "Service"; + /// + protected override string Method => "getAvailablePaymentOptions"; + + /// + /// The service ID + /// + public string ServiceId { get; set; } + + /// + public override NameValueCollection GetParameters() + { + if (ParameterValidator.IsEmpty(ServiceId)) + { + throw new PayNlException("ServiceId is required"); + } + var retval = new NameValueCollection { { "serviceId", ServiceId } }; + return retval; + } + + /// + protected override void PrepareAndSetResponse() + { + // do nothing + } + } +} diff --git a/PAYNLSDK/API/Alliance/GetCategories/GetCategoriesResult.cs b/PAYNLSDK/API/Alliance/GetCategories/GetCategoriesResult.cs new file mode 100644 index 0000000..d8d0a0b --- /dev/null +++ b/PAYNLSDK/API/Alliance/GetCategories/GetCategoriesResult.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace PAYNLSDK.API.Alliance.GetCategories +{ + /// + /// Result class for GetCategories call + /// + public class GetCategoriesResult : ResponseBase + { + /// + /// List of categories + /// + [JsonProperty("categories")] + public List Categories { get; set; } = new List(); + } + + /// + /// Category information + /// + public class Category + { + /// + /// Category ID + /// + [JsonProperty("id")] + public string Id { get; set; } + + /// + /// Category name + /// + [JsonProperty("name")] + public string Name { get; set; } + + /// + /// Category description + /// + [JsonProperty("description")] + public string Description { get; set; } + } +} diff --git a/PAYNLSDK/API/Alliance/GetCategories/Request.cs b/PAYNLSDK/API/Alliance/GetCategories/Request.cs new file mode 100644 index 0000000..3574ed9 --- /dev/null +++ b/PAYNLSDK/API/Alliance/GetCategories/Request.cs @@ -0,0 +1,39 @@ +using System.Collections.Specialized; + +namespace PAYNLSDK.API.Alliance.GetCategories +{ + /// + /// Request to get website categories + /// + public class Request : RequestBase + { + /// + protected override int Version => 4; + /// + protected override string Controller => "Service"; + /// + protected override string Method => "getCategories"; + + /// + /// Optional: filter by payment option ID + /// + public string PaymentOptionId { get; set; } + + /// + public override NameValueCollection GetParameters() + { + var retval = new NameValueCollection(); + if (!string.IsNullOrEmpty(PaymentOptionId)) + { + retval.Add("paymentOptionId", PaymentOptionId); + } + return retval; + } + + /// + protected override void PrepareAndSetResponse() + { + // do nothing + } + } +} diff --git a/PAYNLSDK/API/Alliance/GetMerchants/GetMerchantsResult.cs b/PAYNLSDK/API/Alliance/GetMerchants/GetMerchantsResult.cs new file mode 100644 index 0000000..14788d4 --- /dev/null +++ b/PAYNLSDK/API/Alliance/GetMerchants/GetMerchantsResult.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace PAYNLSDK.API.Alliance.GetMerchants +{ + /// + /// Result class for GetMerchants call + /// + public class GetMerchantsResult : ResponseBase + { + /// + /// List of merchants + /// + [JsonProperty("merchants")] + public List Merchants { get; set; } = new List(); + } + + /// + /// Merchant information + /// + public class MerchantInfo + { + /// + /// Merchant ID + /// + [JsonProperty("merchantId")] + public string MerchantId { get; set; } + + /// + /// Merchant name + /// + [JsonProperty("merchantName")] + public string MerchantName { get; set; } + + /// + /// Merchant state + /// + [JsonProperty("state")] + public string State { get; set; } + } +} diff --git a/PAYNLSDK/API/Alliance/GetMerchants/Request.cs b/PAYNLSDK/API/Alliance/GetMerchants/Request.cs new file mode 100644 index 0000000..6093ac1 --- /dev/null +++ b/PAYNLSDK/API/Alliance/GetMerchants/Request.cs @@ -0,0 +1,39 @@ +using System.Collections.Specialized; + +namespace PAYNLSDK.API.Alliance.GetMerchants +{ + /// + /// Request to get a list of merchants + /// + public class Request : RequestBase + { + /// + protected override int Version => 7; + /// + protected override string Controller => "Alliance"; + /// + protected override string Method => "getMerchants"; + + /// + /// Filter by state: new, accepted or deleted + /// + public string State { get; set; } + + /// + public override NameValueCollection GetParameters() + { + var retval = new NameValueCollection(); + if (!string.IsNullOrEmpty(State)) + { + retval.Add("state", State); + } + return retval; + } + + /// + protected override void PrepareAndSetResponse() + { + // do nothing + } + } +} diff --git a/PAYNLSDK/API/Alliance/MarkReady/MarkReadyResult.cs b/PAYNLSDK/API/Alliance/MarkReady/MarkReadyResult.cs new file mode 100644 index 0000000..bf2cb5c --- /dev/null +++ b/PAYNLSDK/API/Alliance/MarkReady/MarkReadyResult.cs @@ -0,0 +1,13 @@ +namespace PAYNLSDK.API.Alliance.MarkReady +{ + /// + /// Result class for MarkReady call + /// + public class MarkReadyResult : ResponseBase + { + /// + /// Returns true if the merchant was successfully marked as ready + /// + public bool Success => Request?.Result == true; + } +} diff --git a/PAYNLSDK/API/Alliance/MarkReady/Request.cs b/PAYNLSDK/API/Alliance/MarkReady/Request.cs new file mode 100644 index 0000000..4cfc539 --- /dev/null +++ b/PAYNLSDK/API/Alliance/MarkReady/Request.cs @@ -0,0 +1,41 @@ +using System.Collections.Specialized; +using PAYNLSDK.Exceptions; +using PAYNLSDK.Utilities; + +namespace PAYNLSDK.API.Alliance.MarkReady +{ + /// + /// Request to mark a merchant as ready + /// + public class Request : RequestBase + { + /// + protected override int Version => 4; + /// + protected override string Controller => "Merchant"; + /// + protected override string Method => "markReady"; + + /// + /// The merchant ID to mark as ready + /// + public string MerchantId { get; set; } + + /// + public override NameValueCollection GetParameters() + { + if (ParameterValidator.IsEmpty(MerchantId)) + { + throw new PayNlException("MerchantId is required"); + } + var retval = new NameValueCollection { { "merchantId", MerchantId } }; + return retval; + } + + /// + protected override void PrepareAndSetResponse() + { + // do nothing + } + } +} diff --git a/PAYNLSDK/API/Alliance/SetPackage/Request.cs b/PAYNLSDK/API/Alliance/SetPackage/Request.cs new file mode 100644 index 0000000..fbe9bcb --- /dev/null +++ b/PAYNLSDK/API/Alliance/SetPackage/Request.cs @@ -0,0 +1,54 @@ +using System.Collections.Specialized; +using PAYNLSDK.Exceptions; +using PAYNLSDK.Utilities; + +namespace PAYNLSDK.API.Alliance.SetPackage +{ + /// + /// Request to set package for a merchant + /// + public class Request : RequestBase + { + /// + protected override int Version => 7; + /// + protected override string Controller => "Alliance"; + /// + protected override string Method => "setPackage"; + + /// + /// The merchant ID + /// + public string MerchantId { get; set; } + + /// + /// The package name (e.g. "Alliance" or "AlliancePlus") + /// + public string Package { get; set; } + + /// + public override NameValueCollection GetParameters() + { + if (ParameterValidator.IsEmpty(MerchantId)) + { + throw new PayNlException("MerchantId is required"); + } + if (ParameterValidator.IsEmpty(Package)) + { + throw new PayNlException("Package is required"); + } + var retval = new NameValueCollection + { + { "merchantId", MerchantId }, + { "package", Package } + }; + return retval; + } + + /// + protected override void PrepareAndSetResponse() + { + // do nothing + } + } +} diff --git a/PAYNLSDK/API/Alliance/SetPackage/SetPackageResult.cs b/PAYNLSDK/API/Alliance/SetPackage/SetPackageResult.cs new file mode 100644 index 0000000..76a2617 --- /dev/null +++ b/PAYNLSDK/API/Alliance/SetPackage/SetPackageResult.cs @@ -0,0 +1,13 @@ +namespace PAYNLSDK.API.Alliance.SetPackage +{ + /// + /// Result class for SetPackage call + /// + public class SetPackageResult : ResponseBase + { + /// + /// Returns true if the package was successfully set + /// + public bool Success => Request?.Result == true; + } +} diff --git a/PAYNLSDK/API/Alliance/Suspend/Request.cs b/PAYNLSDK/API/Alliance/Suspend/Request.cs new file mode 100644 index 0000000..18bb7dc --- /dev/null +++ b/PAYNLSDK/API/Alliance/Suspend/Request.cs @@ -0,0 +1,41 @@ +using System.Collections.Specialized; +using PAYNLSDK.Exceptions; +using PAYNLSDK.Utilities; + +namespace PAYNLSDK.API.Alliance.Suspend +{ + /// + /// Request to suspend a merchant + /// + public class Request : RequestBase + { + /// + protected override int Version => 7; + /// + protected override string Controller => "Alliance"; + /// + protected override string Method => "suspend"; + + /// + /// The merchant ID to suspend + /// + public string MerchantId { get; set; } + + /// + public override NameValueCollection GetParameters() + { + if (ParameterValidator.IsEmpty(MerchantId)) + { + throw new PayNlException("MerchantId is required"); + } + var retval = new NameValueCollection { { "merchantId", MerchantId } }; + return retval; + } + + /// + protected override void PrepareAndSetResponse() + { + // do nothing + } + } +} diff --git a/PAYNLSDK/API/Alliance/Suspend/SuspendResult.cs b/PAYNLSDK/API/Alliance/Suspend/SuspendResult.cs new file mode 100644 index 0000000..77fa2db --- /dev/null +++ b/PAYNLSDK/API/Alliance/Suspend/SuspendResult.cs @@ -0,0 +1,13 @@ +namespace PAYNLSDK.API.Alliance.Suspend +{ + /// + /// Result class for Suspend call + /// + public class SuspendResult : ResponseBase + { + /// + /// Returns true if the merchant was successfully suspended + /// + public bool Success => Request?.Result == true; + } +} diff --git a/PAYNLSDK/API/Alliance/Unsuspend/Request.cs b/PAYNLSDK/API/Alliance/Unsuspend/Request.cs new file mode 100644 index 0000000..aef8071 --- /dev/null +++ b/PAYNLSDK/API/Alliance/Unsuspend/Request.cs @@ -0,0 +1,41 @@ +using System.Collections.Specialized; +using PAYNLSDK.Exceptions; +using PAYNLSDK.Utilities; + +namespace PAYNLSDK.API.Alliance.Unsuspend +{ + /// + /// Request to unsuspend a merchant + /// + public class Request : RequestBase + { + /// + protected override int Version => 7; + /// + protected override string Controller => "Alliance"; + /// + protected override string Method => "unsuspend"; + + /// + /// The merchant ID to unsuspend + /// + public string MerchantId { get; set; } + + /// + public override NameValueCollection GetParameters() + { + if (ParameterValidator.IsEmpty(MerchantId)) + { + throw new PayNlException("MerchantId is required"); + } + var retval = new NameValueCollection { { "merchantId", MerchantId } }; + return retval; + } + + /// + protected override void PrepareAndSetResponse() + { + // do nothing + } + } +} diff --git a/PAYNLSDK/API/Alliance/Unsuspend/UnsuspendResult.cs b/PAYNLSDK/API/Alliance/Unsuspend/UnsuspendResult.cs new file mode 100644 index 0000000..d6fc91c --- /dev/null +++ b/PAYNLSDK/API/Alliance/Unsuspend/UnsuspendResult.cs @@ -0,0 +1,13 @@ +namespace PAYNLSDK.API.Alliance.Unsuspend +{ + /// + /// Result class for Unsuspend call + /// + public class UnsuspendResult : ResponseBase + { + /// + /// Returns true if the merchant was successfully unsuspended + /// + public bool Success => Request?.Result == true; + } +} diff --git a/PAYNLSDK/Alliance.cs b/PAYNLSDK/Alliance.cs index f986c74..f175db6 100644 --- a/PAYNLSDK/Alliance.cs +++ b/PAYNLSDK/Alliance.cs @@ -47,5 +47,89 @@ public API.Alliance.AddInvoice.AddInvoiceResult AddInvoice(API.Alliance.AddInvoi var response = _webClient.PerformRequest(request); return Newtonsoft.Json.JsonConvert.DeserializeObject(response); } + + /// + public API.Alliance.GetMerchants.GetMerchantsResult GetMerchants(API.Alliance.GetMerchants.Request request) + { + var response = _webClient.PerformRequest(request); + return Newtonsoft.Json.JsonConvert.DeserializeObject(response); + } + + /// + public API.Alliance.Suspend.SuspendResult Suspend(API.Alliance.Suspend.Request request) + { + var response = _webClient.PerformRequest(request); + return Newtonsoft.Json.JsonConvert.DeserializeObject(response); + } + + /// + public API.Alliance.Unsuspend.UnsuspendResult Unsuspend(API.Alliance.Unsuspend.Request request) + { + var response = _webClient.PerformRequest(request); + return Newtonsoft.Json.JsonConvert.DeserializeObject(response); + } + + /// + public API.Alliance.SetPackage.SetPackageResult SetPackage(API.Alliance.SetPackage.Request request) + { + var response = _webClient.PerformRequest(request); + return Newtonsoft.Json.JsonConvert.DeserializeObject(response); + } + + /// + public API.Alliance.MarkReady.MarkReadyResult MarkReady(API.Alliance.MarkReady.Request request) + { + var response = _webClient.PerformRequest(request); + return Newtonsoft.Json.JsonConvert.DeserializeObject(response); + } + + /// + public API.Alliance.AddClearing.AddClearingResult AddClearing(API.Alliance.AddClearing.Request request) + { + var response = _webClient.PerformRequest(request); + return Newtonsoft.Json.JsonConvert.DeserializeObject(response); + } + + /// + public API.Alliance.AddBankAccount.AddBankAccountResult AddBankAccount(API.Alliance.AddBankAccount.Request request) + { + var response = _webClient.PerformRequest(request); + return Newtonsoft.Json.JsonConvert.DeserializeObject(response); + } + + /// + public API.Alliance.GetCategories.GetCategoriesResult GetCategories(API.Alliance.GetCategories.Request request) + { + var response = _webClient.PerformRequest(request); + return Newtonsoft.Json.JsonConvert.DeserializeObject(response); + } + + /// + public API.Alliance.GetAvailablePaymentOptions.GetAvailablePaymentOptionsResult GetAvailablePaymentOptions(API.Alliance.GetAvailablePaymentOptions.Request request) + { + var response = _webClient.PerformRequest(request); + return Newtonsoft.Json.JsonConvert.DeserializeObject(response); + } + + /// + public API.Alliance.EnablePaymentOption.EnablePaymentOptionResult EnablePaymentOption(API.Alliance.EnablePaymentOption.Request request) + { + var response = _webClient.PerformRequest(request); + return Newtonsoft.Json.JsonConvert.DeserializeObject(response); + } + + /// + public API.Alliance.DisablePaymentOption.DisablePaymentOptionResult DisablePaymentOption(API.Alliance.DisablePaymentOption.Request request) + { + var response = _webClient.PerformRequest(request); + return Newtonsoft.Json.JsonConvert.DeserializeObject(response); + } + + /// + public API.Alliance.AddDocument.AddDocumentResult AddDocument(API.Alliance.AddDocument.Request request) + { + var response = _webClient.PerformRequest(request); + return Newtonsoft.Json.JsonConvert.DeserializeObject(response); + } } } diff --git a/PAYNLSDK/IAlliance.cs b/PAYNLSDK/IAlliance.cs index a7131de..03ddabb 100644 --- a/PAYNLSDK/IAlliance.cs +++ b/PAYNLSDK/IAlliance.cs @@ -32,5 +32,89 @@ public interface IAlliance /// The request. /// API.Alliance.AddInvoice.AddInvoiceResult. API.Alliance.AddInvoice.AddInvoiceResult AddInvoice(API.Alliance.AddInvoice.Request request); + + /// + /// Get a list of merchants + /// + /// The request. + /// API.Alliance.GetMerchants.GetMerchantsResult. + API.Alliance.GetMerchants.GetMerchantsResult GetMerchants(API.Alliance.GetMerchants.Request request); + + /// + /// Suspend a merchant + /// + /// The request. + /// API.Alliance.Suspend.SuspendResult. + API.Alliance.Suspend.SuspendResult Suspend(API.Alliance.Suspend.Request request); + + /// + /// Unsuspend a merchant + /// + /// The request. + /// API.Alliance.Unsuspend.UnsuspendResult. + API.Alliance.Unsuspend.UnsuspendResult Unsuspend(API.Alliance.Unsuspend.Request request); + + /// + /// Set package for a merchant + /// + /// The request. + /// API.Alliance.SetPackage.SetPackageResult. + API.Alliance.SetPackage.SetPackageResult SetPackage(API.Alliance.SetPackage.Request request); + + /// + /// Mark a merchant as ready + /// + /// The request. + /// API.Alliance.MarkReady.MarkReadyResult. + API.Alliance.MarkReady.MarkReadyResult MarkReady(API.Alliance.MarkReady.Request request); + + /// + /// Add clearing for a merchant + /// + /// The request. + /// API.Alliance.AddClearing.AddClearingResult. + API.Alliance.AddClearing.AddClearingResult AddClearing(API.Alliance.AddClearing.Request request); + + /// + /// Add bank account for a merchant with iDEAL verification + /// + /// The request. + /// API.Alliance.AddBankAccount.AddBankAccountResult. + API.Alliance.AddBankAccount.AddBankAccountResult AddBankAccount(API.Alliance.AddBankAccount.Request request); + + /// + /// Get website categories + /// + /// The request. + /// API.Alliance.GetCategories.GetCategoriesResult. + API.Alliance.GetCategories.GetCategoriesResult GetCategories(API.Alliance.GetCategories.Request request); + + /// + /// Get available payment options for a service + /// + /// The request. + /// API.Alliance.GetAvailablePaymentOptions.GetAvailablePaymentOptionsResult. + API.Alliance.GetAvailablePaymentOptions.GetAvailablePaymentOptionsResult GetAvailablePaymentOptions(API.Alliance.GetAvailablePaymentOptions.Request request); + + /// + /// Enable a payment option for a service + /// + /// The request. + /// API.Alliance.EnablePaymentOption.EnablePaymentOptionResult. + API.Alliance.EnablePaymentOption.EnablePaymentOptionResult EnablePaymentOption(API.Alliance.EnablePaymentOption.Request request); + + /// + /// Disable a payment option for a service + /// + /// The request. + /// API.Alliance.DisablePaymentOption.DisablePaymentOptionResult. + API.Alliance.DisablePaymentOption.DisablePaymentOptionResult DisablePaymentOption(API.Alliance.DisablePaymentOption.Request request); + + /// + /// Upload a document + /// + /// The request. + /// API.Alliance.AddDocument.AddDocumentResult. + API.Alliance.AddDocument.AddDocumentResult AddDocument(API.Alliance.AddDocument.Request request); } } diff --git a/PayNLSdk.Tests/AllianceTests.cs b/PayNLSdk.Tests/AllianceTests.cs index 18af285..1a0f2c9 100644 --- a/PayNLSdk.Tests/AllianceTests.cs +++ b/PayNLSdk.Tests/AllianceTests.cs @@ -123,6 +123,352 @@ public void AddInvoice_ShouldReturnReferenceId() result.ToString().ShouldContain("INV-1"); } + [Fact] + public void GetMerchants_ShouldReturnListOfMerchants() + { + // Arrange + var rawResponse = """ + { + "request": { + "result": true, + "errorId": null, + "errorMessage": null + }, + "merchants": [ + { + "merchantId": "M-1", + "merchantName": "Merchant One", + "state": "accepted" + }, + { + "merchantId": "M-2", + "merchantName": "Merchant Two", + "state": "new" + } + ] + } + """; + var client = CreateClient(rawResponse); + var alliance = new Alliance(client); + + // Act + var result = alliance.GetMerchants(new PAYNLSDK.API.Alliance.GetMerchants.Request()); + + // Assert + result.Merchants.Count.ShouldBe(2); + result.Merchants[0].MerchantId.ShouldBe("M-1"); + result.Merchants[0].MerchantName.ShouldBe("Merchant One"); + result.Merchants[0].State.ShouldBe("accepted"); + } + + [Fact] + public void Suspend_ShouldReturnSuccess() + { + // Arrange + var rawResponse = """ + { + "request": { + "result": true, + "errorId": null, + "errorMessage": null + } + } + """; + var client = CreateClient(rawResponse); + var alliance = new Alliance(client); + + // Act + var result = alliance.Suspend(new PAYNLSDK.API.Alliance.Suspend.Request { MerchantId = "M-4" }); + + // Assert + result.Success.ShouldBeTrue(); + } + + [Fact] + public void Unsuspend_ShouldReturnSuccess() + { + // Arrange + var rawResponse = """ + { + "request": { + "result": true, + "errorId": null, + "errorMessage": null + } + } + """; + var client = CreateClient(rawResponse); + var alliance = new Alliance(client); + + // Act + var result = alliance.Unsuspend(new PAYNLSDK.API.Alliance.Unsuspend.Request { MerchantId = "M-4" }); + + // Assert + result.Success.ShouldBeTrue(); + } + + [Fact] + public void SetPackage_ShouldReturnSuccess() + { + // Arrange + var rawResponse = """ + { + "request": { + "result": true, + "errorId": null, + "errorMessage": null + } + } + """; + var client = CreateClient(rawResponse); + var alliance = new Alliance(client); + + // Act + var result = alliance.SetPackage(new PAYNLSDK.API.Alliance.SetPackage.Request + { + MerchantId = "M-4", + Package = "AlliancePlus" + }); + + // Assert + result.Success.ShouldBeTrue(); + } + + [Fact] + public void MarkReady_ShouldReturnSuccess() + { + // Arrange + var rawResponse = """ + { + "request": { + "result": true, + "errorId": null, + "errorMessage": null + } + } + """; + var client = CreateClient(rawResponse); + var alliance = new Alliance(client); + + // Act + var result = alliance.MarkReady(new PAYNLSDK.API.Alliance.MarkReady.Request { MerchantId = "M-4" }); + + // Assert + result.Success.ShouldBeTrue(); + } + + [Fact] + public void AddClearing_ShouldReturnSuccess() + { + // Arrange + var rawResponse = """ + { + "request": { + "result": true, + "errorId": null, + "errorMessage": null + } + } + """; + var client = CreateClient(rawResponse); + var alliance = new Alliance(client); + + // Act + var result = alliance.AddClearing(new PAYNLSDK.API.Alliance.AddClearing.Request + { + Amount = 1000, + MerchantId = "M-4" + }); + + // Assert + result.Success.ShouldBeTrue(); + } + + [Fact] + public void AddBankAccount_ShouldReturnIssuerUrl() + { + // Arrange + var rawResponse = """ + { + "request": { + "result": true, + "errorId": null, + "errorMessage": null + }, + "issuerUrl": "https://example.com/ideal" + } + """; + var client = CreateClient(rawResponse); + var alliance = new Alliance(client); + + // Act + var result = alliance.AddBankAccount(new PAYNLSDK.API.Alliance.AddBankAccount.Request + { + MerchantId = "M-4", + ReturnUrl = "https://example.com/return" + }); + + // Assert + result.IssuerUrl.ShouldBe("https://example.com/ideal"); + } + + [Fact] + public void GetCategories_ShouldReturnListOfCategories() + { + // Arrange + var rawResponse = """ + { + "request": { + "result": true, + "errorId": null, + "errorMessage": null + }, + "categories": [ + { + "id": "1", + "name": "Category 1", + "description": "Description 1" + }, + { + "id": "2", + "name": "Category 2", + "description": "Description 2" + } + ] + } + """; + var client = CreateClient(rawResponse); + var alliance = new Alliance(client); + + // Act + var result = alliance.GetCategories(new PAYNLSDK.API.Alliance.GetCategories.Request()); + + // Assert + result.Categories.Count.ShouldBe(2); + result.Categories[0].Id.ShouldBe("1"); + result.Categories[0].Name.ShouldBe("Category 1"); + } + + [Fact] + public void GetAvailablePaymentOptions_ShouldReturnListOfOptions() + { + // Arrange + var rawResponse = """ + { + "request": { + "result": true, + "errorId": null, + "errorMessage": null + }, + "paymentOptions": [ + { + "id": "10", + "name": "iDEAL", + "enabled": true + }, + { + "id": "436", + "name": "Bancontact", + "enabled": false + } + ] + } + """; + var client = CreateClient(rawResponse); + var alliance = new Alliance(client); + + // Act + var result = alliance.GetAvailablePaymentOptions( + new PAYNLSDK.API.Alliance.GetAvailablePaymentOptions.Request { ServiceId = "SL-1000-2000" }); + + // Assert + result.PaymentOptions.Count.ShouldBe(2); + result.PaymentOptions[0].Id.ShouldBe("10"); + result.PaymentOptions[0].Name.ShouldBe("iDEAL"); + result.PaymentOptions[0].Enabled.ShouldBeTrue(); + } + + [Fact] + public void EnablePaymentOption_ShouldReturnSuccess() + { + // Arrange + var rawResponse = """ + { + "request": { + "result": true, + "errorId": null, + "errorMessage": null + } + } + """; + var client = CreateClient(rawResponse); + var alliance = new Alliance(client); + + // Act + var result = alliance.EnablePaymentOption(new PAYNLSDK.API.Alliance.EnablePaymentOption.Request + { + ServiceId = "SL-1000-2000", + PaymentProfileId = "10" + }); + + // Assert + result.Success.ShouldBeTrue(); + } + + [Fact] + public void DisablePaymentOption_ShouldReturnSuccess() + { + // Arrange + var rawResponse = """ + { + "request": { + "result": true, + "errorId": null, + "errorMessage": null + } + } + """; + var client = CreateClient(rawResponse); + var alliance = new Alliance(client); + + // Act + var result = alliance.DisablePaymentOption(new PAYNLSDK.API.Alliance.DisablePaymentOption.Request + { + ServiceId = "SL-1000-2000", + PaymentProfileId = "10" + }); + + // Assert + result.Success.ShouldBeTrue(); + } + + [Fact] + public void AddDocument_ShouldReturnSuccess() + { + // Arrange + var rawResponse = """ + { + "result": true, + "documentId": "D-1234-5678" + } + """; + var client = CreateClient(rawResponse); + var alliance = new Alliance(client); + var request = new PAYNLSDK.API.Alliance.AddDocument.Request + { + DocumentId = "D-1234-5678", + Filename = "test.pdf" + }; + request.AddContent("base64encodedcontent"); + + // Act + var result = alliance.AddDocument(request); + + // Assert + result.Result.ShouldBeTrue(); + result.DocumentId.ShouldBe("D-1234-5678"); + } + private static IClient CreateClient(string rawResponse) { var client = Substitute.For();