From 41f2e6ed454e7124d49765a89732a89aa11fbc2e Mon Sep 17 00:00:00 2001 From: Olorunfemi Davis Date: Thu, 22 Feb 2024 13:01:43 +0100 Subject: [PATCH 1/6] Improve TransactionResponseModel.cs --- .../Transactions/TransactionResponseModel.cs | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/PayStackDotNetSDK/Models/Transactions/TransactionResponseModel.cs b/PayStackDotNetSDK/Models/Transactions/TransactionResponseModel.cs index cd05a37..595b432 100644 --- a/PayStackDotNetSDK/Models/Transactions/TransactionResponseModel.cs +++ b/PayStackDotNetSDK/Models/Transactions/TransactionResponseModel.cs @@ -37,6 +37,8 @@ public class Log public class Authorization { + public string brand { get; set; } + public string account_name { get; set; } public string authorization_code { get; set; } public string card_type { get; set; } public string last4 { get; set; } @@ -52,6 +54,11 @@ public class Authorization public class Customer { + public string phone { get; set; } + public Metadata metadata { get; set; } + public string risk_action { get; set; } + public object international_format_phone { get; set; } + public int id { get; set; } public string customer_code { get; set; } public string first_name { get; set; } @@ -61,6 +68,23 @@ public class Customer public class Data { + public long id { get; set; } + public string receipt_number { get; set; } + public object paid_at { get; set; } + public DateTime created_at { get; set; } + public Fees_Split fees_split { get; set; } + public object plan { get; set; } + //public Split split { get; set; } + public object order_id { get; set; } + public object paidAt { get; set; } + public DateTime createdAt { get; set; } + public int requested_amount { get; set; } + public object pos_transaction_data { get; set; } + public object source { get; set; } + public object fees_breakdown { get; set; } + //public Plan_Object plan_object { get; set; } + public Subaccount subaccount { get; set; } + public int amount { get; set; } public string currency { get; set; } public DateTime transaction_date { get; set; } @@ -77,4 +101,37 @@ public class Data public Authorization authorization { get; set; } public Customer customer { get; set; } } + + public class Subaccount + { + public int id { get; set; } + public string subaccount_code { get; set; } + public string business_name { get; set; } + public string description { get; set; } + public object primary_contact_name { get; set; } + public object primary_contact_email { get; set; } + public object primary_contact_phone { get; set; } + public object metadata { get; set; } + public int percentage_charge { get; set; } + public string settlement_bank { get; set; } + public int bank_id { get; set; } + public string account_number { get; set; } + public string currency { get; set; } + public bool active { get; set; } + } + + public class Fees_Split + { + public int paystack { get; set; } + public int integration { get; set; } + public int subaccount { get; set; } + public Fees_Split_Params _params { get; set; } + } + + public class Fees_Split_Params + { + public string bearer { get; set; } + public string transaction_charge { get; set; } + public string percentage_charge { get; set; } + } } From bec437d7e9e23659f0284d7d1c26fdd6c9576adc Mon Sep 17 00:00:00 2001 From: Olorunfemi Davis Date: Thu, 22 Feb 2024 13:05:24 +0100 Subject: [PATCH 2/6] Update nuget version --- PayStackDotNetSDK/PayStackDotNetSDK.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PayStackDotNetSDK/PayStackDotNetSDK.csproj b/PayStackDotNetSDK/PayStackDotNetSDK.csproj index b738d45..0fe9d6f 100644 --- a/PayStackDotNetSDK/PayStackDotNetSDK.csproj +++ b/PayStackDotNetSDK/PayStackDotNetSDK.csproj @@ -7,7 +7,7 @@ MIT License true true - 1.4.4-rc + 1.4.5-rc huygensoft.com https://github.com/fzany/PayStackDotNetSDK https://res.cloudinary.com/booksrite/image/upload/v1528391286/favicon.png From 020f7c3753fd757277c63123745b86b152548c42 Mon Sep 17 00:00:00 2001 From: Abubakar Imam Date: Thu, 9 Oct 2025 05:27:35 +0100 Subject: [PATCH 3/6] Fix build issue coming from varying .net framwork in the csproj files --- ConsoleApp1/ConsoleApp1.csproj | 4 +- ConsoleApp1/packages.config | 2 +- PayStackDotNetSDK.sln | 10 +- .../Models/Paystack.Net.Models.csproj | 79 ++----- PayStackDotNetSDK/PayStackDotNetSDK.csproj | 8 +- PayStackDotNetSDK/paystack_logo.png | Bin 0 -> 2429 bytes Tester.Console/Program.cs | 21 +- Tester.Console/Properties/AssemblyInfo.cs | 36 --- Tester.Console/Tester.Console.csproj | 89 +++----- Tester.Console/packages.config | 2 +- Tester.Web/Default.aspx | 8 - Tester.Web/Default.aspx.cs | 210 ------------------ Tester.Web/Default.aspx.designer.cs | 33 --- Tester.Web/Helpers/Credential.cs | 12 - Tester.Web/Properties/AssemblyInfo.cs | 35 --- Tester.Web/Store.Master | 19 -- Tester.Web/Store.Master.cs | 17 -- Tester.Web/Store.Master.designer.cs | 35 --- Tester.Web/Tester.Web.csproj | 152 ------------- Tester.Web/Web.Debug.config | 30 --- Tester.Web/Web.Release.config | 31 --- Tester.Web/Web.config | 25 --- Tester.Web/packages.config | 6 - 23 files changed, 68 insertions(+), 796 deletions(-) create mode 100644 PayStackDotNetSDK/paystack_logo.png delete mode 100644 Tester.Console/Properties/AssemblyInfo.cs delete mode 100644 Tester.Web/Default.aspx delete mode 100644 Tester.Web/Default.aspx.cs delete mode 100644 Tester.Web/Default.aspx.designer.cs delete mode 100644 Tester.Web/Helpers/Credential.cs delete mode 100644 Tester.Web/Properties/AssemblyInfo.cs delete mode 100644 Tester.Web/Store.Master delete mode 100644 Tester.Web/Store.Master.cs delete mode 100644 Tester.Web/Store.Master.designer.cs delete mode 100644 Tester.Web/Tester.Web.csproj delete mode 100644 Tester.Web/Web.Debug.config delete mode 100644 Tester.Web/Web.Release.config delete mode 100644 Tester.Web/Web.config delete mode 100644 Tester.Web/packages.config diff --git a/ConsoleApp1/ConsoleApp1.csproj b/ConsoleApp1/ConsoleApp1.csproj index 1f03cef..e68750f 100644 --- a/ConsoleApp1/ConsoleApp1.csproj +++ b/ConsoleApp1/ConsoleApp1.csproj @@ -34,8 +34,8 @@ 4 - - ..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll + + ..\packages\Newtonsoft.Json.13.0.4\lib\net45\Newtonsoft.Json.dll diff --git a/ConsoleApp1/packages.config b/ConsoleApp1/packages.config index 5762754..8f8cd00 100644 --- a/ConsoleApp1/packages.config +++ b/ConsoleApp1/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/PayStackDotNetSDK.sln b/PayStackDotNetSDK.sln index 2c842a1..3232cad 100644 --- a/PayStackDotNetSDK.sln +++ b/PayStackDotNetSDK.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27703.2000 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.36401.2 d17.14 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PayStackDotNetSDK", "PayStackDotNetSDK\PayStackDotNetSDK.csproj", "{BA52829E-D8D3-47F6-B1F8-07582AE28A62}" EndProject @@ -14,8 +14,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tester.Console", "Tester.Console\Tester.Console.csproj", "{AD1C115C-81CD-47DC-A00A-254D3C0BC50C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tester.Web", "Tester.Web\Tester.Web.csproj", "{7350CA94-174B-4A46-9233-F0FE35899CBD}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApp1", "ConsoleApp1\ConsoleApp1.csproj", "{679344EB-BD1B-4302-B002-0A3F6FD792C6}" EndProject Global @@ -32,10 +30,6 @@ Global {AD1C115C-81CD-47DC-A00A-254D3C0BC50C}.Debug|Any CPU.Build.0 = Debug|Any CPU {AD1C115C-81CD-47DC-A00A-254D3C0BC50C}.Release|Any CPU.ActiveCfg = Release|Any CPU {AD1C115C-81CD-47DC-A00A-254D3C0BC50C}.Release|Any CPU.Build.0 = Release|Any CPU - {7350CA94-174B-4A46-9233-F0FE35899CBD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7350CA94-174B-4A46-9233-F0FE35899CBD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7350CA94-174B-4A46-9233-F0FE35899CBD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7350CA94-174B-4A46-9233-F0FE35899CBD}.Release|Any CPU.Build.0 = Release|Any CPU {679344EB-BD1B-4302-B002-0A3F6FD792C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {679344EB-BD1B-4302-B002-0A3F6FD792C6}.Debug|Any CPU.Build.0 = Debug|Any CPU {679344EB-BD1B-4302-B002-0A3F6FD792C6}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/PayStackDotNetSDK/Models/Paystack.Net.Models.csproj b/PayStackDotNetSDK/Models/Paystack.Net.Models.csproj index b911262..8a19484 100644 --- a/PayStackDotNetSDK/Models/Paystack.Net.Models.csproj +++ b/PayStackDotNetSDK/Models/Paystack.Net.Models.csproj @@ -1,61 +1,18 @@ - - - - - Debug - AnyCPU - {F12518F2-AEEE-4A9B-89BF-D7E1D4E04209} - Library - Properties - PayStackDotNetSDK.Models - PayStackDotNetSDK.Models - v4.6 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + netstandard2.0 + PayStackDotNetSDK.Models + PayStackDotNetSDK.Models + latest + + + true + enable + + + + + + + diff --git a/PayStackDotNetSDK/PayStackDotNetSDK.csproj b/PayStackDotNetSDK/PayStackDotNetSDK.csproj index 0fe9d6f..2956bbb 100644 --- a/PayStackDotNetSDK/PayStackDotNetSDK.csproj +++ b/PayStackDotNetSDK/PayStackDotNetSDK.csproj @@ -1,4 +1,4 @@ - + netstandard2.0 @@ -21,7 +21,7 @@ true snupkg MIT - favicon.png + paystack_logo.png README.md @@ -31,7 +31,7 @@ - + True \ @@ -43,7 +43,7 @@ - + diff --git a/PayStackDotNetSDK/paystack_logo.png b/PayStackDotNetSDK/paystack_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..2fc4c94433e54a36362afbcbdceb1c45da971f14 GIT binary patch literal 2429 zcmai$2Rqw~0*C*xCGY8qvHn_azsttI zvV}3VF$BcafYNE8{0pdr0f?&tm#zaPb3o}VAgTeBG1!DvLB$JzrXxs1TO?-?k~79) z5zH6W0QtikoZ1as)Bt3S04^9v_$o+D8{ktC_DTl{DzMl_0#F2-uo_={BTz8`D478g zDuO9=K=K;EuLTGpS&J4~E5?BYt;Nkelf+%wpST%8xjX$$pMHc;>EF*fcDQDLa0^G?tLfTD+dabgq~^?s+WJK<1e8(Zj8G1yp}h1=lY-}X@}l-`h2k6O z3&q9)(-*8Uq^m>yfklfdyU9-Y7;;z>C$k*5-Af=x+=jQag(%DED#4UK8yU>L*%*ewT{_I*EY+Cr!5xZty5*T5 z#cmHWRK3B*{4%hn1mjStq0 zB4{1JPyLKb@+kmyQf&>B0@p>aZV8{W_*ozNrJZ^HEIglP|98+$7rCRkQyF`O_tgn| zY_91+1=;G&)?IvB`Uum48r9MuD&)zubyxO3WTBAzICtc^w7>((m2vfTLL8m0g*=@6 z(7o_>VPSy~spC0Tb6wewTPkHzaCHCVEbhkua;brt{rLE-ZR8&ZE;SRM+Oen8*gLa=pycZKf4^yzPuWYuQnD2g7{vykU3x3*< z_b<^<_N3)|80lZ}@^I`i$pBKxoW=Vw-B*Xl9TW{jQE(mz!4+gIorP%aDw=Q8PiaoS zSb@p-y{HEU3u2jwW5R4Z!7|k!e+ucXZ&zT*;UvtOw}%cSy_m&jVdR;9_N`#>42s>D zv}LZG&&gBzu}0nU&eAzEi6TK@DQwHrC zZQ;$dTeH#gQ;m#QdhE2$vc&bgN@Amj#UIYL*4U_5RX6-Otz!EeoXY`B66#lDo9fOA7hAw&+TIH;DI{3?D_@7MYnwm*Qrb)$~2~SDq zzSxYDJlifTt!rEq^<8&tI!>)yy&HhsJYHMcyPiK`8l7xaxq*N5=NS#coE-ib)Hb*L z^3s%=Wus={YzWkk2~}yU1B1VMb*N68>ItTiPWgM(y_sdaJI`C1FN-_XX@e+2A6TMWb*)Z?_dUb72H1_~kYQ%b z<|0{PwGY^79gH+0h5Xj0r2boaRheOTBgfeC-Ak>G<95gQ@DfwL#n3jgo4r_=z2)L) zONWfWV?*wTAqBCu;OIKoNe3CMPa^NOzR30K~q4d9|yt`#*AX*8+%8?oQsMV?s&dv4b0>?Dt_N69K5@K$}afoM8N_~rXX ztS#%w+xBYI?|<6ujrQ7tr$silv}9rHt_Chxu|`;Y>S>#}C&yRQ*yA-QvTKGNQK#Ar z)(^ft@mo%si=^|GFxPIMdzu`yN^AUOoBcu&9n=NagcYX0TQ4@zs3f{S;y)1TE)cBr zxo_pp;mP(RD9wx-obmSuL8@$`VR3VT$6r|UvEUDUQyX*%k}XzsX0yO|=eNa;$rnw1 zrie|WO-t<3>z}7>O~##3_K<88EkUSyr4lpa|9Vok&kvGZ2$Q2=id70tTp6BFgMKYrnS!QNL!;qZ#h)5 zOKk5>;HBPpP9s$VTt&SIRM(xY9TQc^8c$k@*B~-TXtp4zucJH>^Vo7>i?a#nEwAup40b*}> zXZQm_$D{jvo&*%bE0{+-B8-Q32shDR^0w&IkvOv?m+gdfC!MY?7kJ@MjvcU${f#r^ z@4N?y+Wt;&CMh=chA4vVGaN;Ku_}7x)^~9Fy0k%L8FVLgYhe4-q+95zZbFQ_6;V8c zwa*J_P7gZx?#2ExmneX67Y(RIwu=v(tb8cc2#tE{{syfuaO;LT7wc&Uv2$TQjEfD$ e_rF=r*}c|FD5U^lNjjs6cNX?U6d literal 0 HcmV?d00001 diff --git a/Tester.Console/Program.cs b/Tester.Console/Program.cs index cd529bf..7888540 100644 --- a/Tester.Console/Program.cs +++ b/Tester.Console/Program.cs @@ -1,22 +1,31 @@ using PayStackDotNetSDK.Methods.Transactions; -using System.Web.Script.Serialization; +using Newtonsoft.Json; // ✅ modern JSON serializer namespace Tester.Console { class Program { - static void Main(string[] args) + static async Task Main(string[] args) { - System.Console.WriteLine(""); + System.Console.WriteLine("🔍 Verifying Paystack transaction..."); + await VerifyTransaction(); + System.Console.WriteLine("✅ Done. Press any key to exit..."); + System.Console.ReadKey(); } - private static async void VerifyTransaction() + + private static async Task VerifyTransaction() { var paystackTransactionAPI = new PaystackTransaction("apikey/secret/key"); + var response = await paystackTransactionAPI.VerifyTransaction("T262788937392358"); - var json = new JavaScriptSerializer().Serialize(response); - //contentDiv.InnerText = json; + + // ✅ Serialize the response object to JSON string + var json = JsonConvert.SerializeObject(response, Formatting.Indented); + + // ✅ Print to console instead of web element + System.Console.WriteLine(json); } } } diff --git a/Tester.Console/Properties/AssemblyInfo.cs b/Tester.Console/Properties/AssemblyInfo.cs deleted file mode 100644 index ec71cd3..0000000 --- a/Tester.Console/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Tester.Console")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Tester.Console")] -[assembly: AssemblyCopyright("Copyright © 2018")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("ad1c115c-81cd-47dc-a00a-254d3c0bc50c")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Tester.Console/Tester.Console.csproj b/Tester.Console/Tester.Console.csproj index 81ee2e0..e2a292d 100644 --- a/Tester.Console/Tester.Console.csproj +++ b/Tester.Console/Tester.Console.csproj @@ -1,64 +1,25 @@ - - - - - Debug - AnyCPU - {AD1C115C-81CD-47DC-A00A-254D3C0BC50C} - Exe - Tester.Console - Tester.Console - v4.8 - 512 - true - - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll - - - - - - - - - - - - - - - - - - - - - - {BA52829E-D8D3-47F6-B1F8-07582AE28A62} - PayStackDotNetSDK - - - - \ No newline at end of file + + + + net8.0 + + Exe + Tester.Console + Tester.Console + enable + enable + + + + + + + + + + + + + + + diff --git a/Tester.Console/packages.config b/Tester.Console/packages.config index 5762754..8f8cd00 100644 --- a/Tester.Console/packages.config +++ b/Tester.Console/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/Tester.Web/Default.aspx b/Tester.Web/Default.aspx deleted file mode 100644 index 09144dd..0000000 --- a/Tester.Web/Default.aspx +++ /dev/null @@ -1,8 +0,0 @@ -<%@ Page Title="" Language="C#" MasterPageFile="~/Store.Master" AutoEventWireup="true" Async="true" CodeBehind="Default.aspx.cs" Inherits="Tester.Web.Default" %> - - - - - -
-
diff --git a/Tester.Web/Default.aspx.cs b/Tester.Web/Default.aspx.cs deleted file mode 100644 index d995bb5..0000000 --- a/Tester.Web/Default.aspx.cs +++ /dev/null @@ -1,210 +0,0 @@ -using System; -using System.Collections.Generic; -using PayStackDotNetSDK.Methods.Transactions; -using Tester.Web.Helpers; -using PayStackDotNetSDK.Models.Transactions; -using PayStackDotNetSDK.Methods.Banks; -using PayStackDotNetSDK.Methods.Customers; -using Newtonsoft.Json; -using System.Web.Script.Serialization; - -namespace Tester.Web -{ - public partial class Default : System.Web.UI.Page - { - protected void Page_Load(object sender, EventArgs e) - { - - } - protected void ActionBusson_ServerClick(object sender, EventArgs e) - { - //InitializeTransaction2(); - //GetAllBanks(); - VerifyTransaction(); - //TransactionListing(); - // TransactionListing2(); - } - /// - /// Implements simple InitializeTransaction with basic parameters - /// - protected async void InitializeTransaction() - { - var paystackTransactionAPI = new PaystackTransaction(Credential.Key); - var response = await paystackTransactionAPI.InitializeTransaction("email@email.com", 1000000); - if (response.status) - { - Response.AddHeader("Access-Control-Allow-Origin", "*"); - Response.AppendHeader("Access-Control-Allow-Origin", "*"); - Response.Redirect(response.data.authorization_url); //Redirects your browser to the secure URL - } - else //not successful - { - //Do something else with the info. - contentDiv.InnerText = response.message; - } - } - /// - /// Implements simple InitializeTransaction with full parameters - /// - protected async void InitializeTransaction2() - { - var paystackTransactionAPI = new PaystackTransaction(Credential.Key); - var response = await paystackTransactionAPI.InitializeTransaction(new TransactionRequestModel() { firstName = "Olorunfemi", callback_url= "http://localhost:60441/Default.aspx", lastName = "Ajibulu", amount = 1000000, currency = PayStackDotNetSDK.Helpers.Constants.Currency.Naira, email = "email@email.com", metadata = new PayStackDotNetSDK.Models.Transactions.Metadata() { referrer = "email@email.com" }, transaction_charge = 4000 }); - if (response.status) - { - Response.AddHeader("Access-Control-Allow-Origin", "*"); - Response.AppendHeader("Access-Control-Allow-Origin", "*"); - Response.Redirect(response.data.authorization_url); //Redirects your browser to the secure URL - } - else //not successful - { - //Do something else with the info. - } - } - - protected async void VerifyTransaction() - { - var paystackTransactionAPI = new PaystackTransaction("apikey/secret/key"); - var response = await paystackTransactionAPI.VerifyTransaction("T262788937392358"); - var json = new JavaScriptSerializer().Serialize(response); - contentDiv.InnerText = json; - } - /// - /// Implementation with basic parameters - /// - protected async void TransactionListing() - { - var paystackTransactionAPI = new PaystackTransaction(Credential.Key); - var response = await paystackTransactionAPI.ListTransactions(); - var json = new JavaScriptSerializer().Serialize(response); - contentDiv.InnerText = json; - } - /// - /// Implementation with full parameters - /// - protected async void TransactionListing2() - { - var paystackTransactionAPI = new PaystackTransaction(Credential.Key); - var response = await paystackTransactionAPI.ListTransactions(new TransactionListRequestModel() { from = DateTime.UtcNow.AddDays(-10), to = DateTime.UtcNow, perPage = 50, status = PayStackDotNetSDK.Helpers.Constants.Transaction.Status.Success }); - var json = new JavaScriptSerializer().Serialize(response); - contentDiv.InnerText = json; - } - - protected async void FetchTransaction() - { - var paystackTransactionAPI = new PaystackTransaction(Credential.Key); - var response = await paystackTransactionAPI.FetchTransaction(345); - } - /// - /// Implementation with basic parameters - /// - protected async void ChargeAuthorization() - { - var paystackTransactionAPI = new PaystackTransaction(Credential.Key); - var response = await paystackTransactionAPI.ChargeAuthorization("authorization_code", "email@email.com", 7000); - } - /// - /// Implementation with full parameters - /// - protected async void ChargeAuthorization2() - { - var paystackTransactionAPI = new PaystackTransaction(Credential.Key); - var response = await paystackTransactionAPI.ChargeAuthorization(new TransactionRequestModel() { firstName = "firstname" }); - } - protected async void ViewTransactionTimelines() - { - var paystackTransactionAPI = new PaystackTransaction(Credential.Key); - var response = await paystackTransactionAPI.TransactionTimeline("referenceOrID"); - } - /// - /// Implementation with basic parameters - /// - protected async void TransactionTotals() - { - var paystackTransactionAPI = new PaystackTransaction(Credential.Key); - var response = await paystackTransactionAPI.TransactionTotals(); - } - /// - /// Implementation with full parameters - /// - protected async void TransactionTotals2() - { - var paystackTransactionAPI = new PaystackTransaction(Credential.Key); - var response = await paystackTransactionAPI.TransactionTotals(new TransactionTotalsRequestModel() { }); - } - /// - /// Implementation with basic parameters - /// - protected async void ExportTransactions() - { - var connectionInstance = new PaystackTransaction(Credential.Key); - var response = await connectionInstance.ExportTransactions(); - } - /// - /// Implementation with full parameters - /// - protected async void ExportTransactions2() - { - var connectionInstance = new PaystackTransaction(Credential.Key); - var response = await connectionInstance.ExportTransactions(new ExportRequestModel() { from = DateTime.UtcNow.AddDays(-15) }); - } - /// - /// Implementation with basic parameters - /// - protected async void RequestReauthorization() - { - var connectionInstance = new PaystackTransaction(Credential.Key); - var response = await connectionInstance.RequestReAuthorization("authorization_code", "email@email.com", 4000); - } - /// - /// Implementation with full parameters - /// - protected async void RequestReauthorization2() - { - var connectionInstance = new PaystackTransaction(Credential.Key); - var response = await connectionInstance.RequestReAuthorization(new RequestReAuthorizationRequestModel() { amount = 4000, authorization_code = "authorization_code", currency = PayStackDotNetSDK.Helpers.Constants.Currency.Naira, email = "email@email.com", reference = "reference", metadata = new RequestReAuthorizationMetadata() { custom_fields = new List() { new RequestReAuthorizationCustomField() { display_name = "display_name", value = "value", variable_name = "variable_name" } } } }); - } - /// - /// Implementation with basic parameters - /// - protected async void CheckAuthorization() - { - var connectionInstance = new PaystackTransaction(Credential.Key); - var response = await connectionInstance.CheckAuthorization("authorization_code", "email@email.com", 4000); - } - /// - /// Implementation with optional parameters - /// - protected async void CheckAuthorization2() - { - var connectionInstance = new PaystackTransaction(Credential.Key); - var response = await connectionInstance.CheckAuthorization("authorization_code", "email@email.com", 4000, PayStackDotNetSDK.Helpers.Constants.Currency.Naira); - } - /// - /// Get all Nigerian Banks on Paystack API - /// - protected async void GetAllBanks() - { - string cre = Credential.Key; - var connectionInstance = new PaystackListedBanks(Credential.Key); - var response = await connectionInstance.ListBanks(); - var json = new JavaScriptSerializer().Serialize(response); - contentDiv.InnerText = json; - } - /// - /// Fetch Transaction - /// - protected async void FetchTransaction2() - { - var connectionInstance = new PaystackTransaction(Credential.Key); - var response = await connectionInstance.FetchTransaction(345); - } - protected async void CreateCustomer() - { - var connectionInstance = new PaystackCustomer(Credential.Key); - //var response = await connectionInstance.FetchTransaction(345); - } - - } - -} \ No newline at end of file diff --git a/Tester.Web/Default.aspx.designer.cs b/Tester.Web/Default.aspx.designer.cs deleted file mode 100644 index 01d5fb2..0000000 --- a/Tester.Web/Default.aspx.designer.cs +++ /dev/null @@ -1,33 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Tester.Web { - - - public partial class Default { - - /// - /// ActionBusson control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.HtmlControls.HtmlButton ActionBusson; - - /// - /// contentDiv control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.HtmlControls.HtmlGenericControl contentDiv; - } -} diff --git a/Tester.Web/Helpers/Credential.cs b/Tester.Web/Helpers/Credential.cs deleted file mode 100644 index af0d632..0000000 --- a/Tester.Web/Helpers/Credential.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; - -namespace Tester.Web.Helpers -{ - public class Credential - { - public static string Key = Environment.GetEnvironmentVariable("paystackkey"); - } -} \ No newline at end of file diff --git a/Tester.Web/Properties/AssemblyInfo.cs b/Tester.Web/Properties/AssemblyInfo.cs deleted file mode 100644 index 6a1126a..0000000 --- a/Tester.Web/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Tester.Web")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Tester.Web")] -[assembly: AssemblyCopyright("Copyright © 2018")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("7350ca94-174b-4a46-9233-f0fe35899cbd")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Tester.Web/Store.Master b/Tester.Web/Store.Master deleted file mode 100644 index dbaf1eb..0000000 --- a/Tester.Web/Store.Master +++ /dev/null @@ -1,19 +0,0 @@ -<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Store.master.cs" Inherits="Tester.Web.Store" %> - - - - - - - - - - -
-
- - -
-
- - diff --git a/Tester.Web/Store.Master.cs b/Tester.Web/Store.Master.cs deleted file mode 100644 index ddc67eb..0000000 --- a/Tester.Web/Store.Master.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; -using System.Web.UI; -using System.Web.UI.WebControls; - -namespace Tester.Web -{ - public partial class Store : System.Web.UI.MasterPage - { - protected void Page_Load(object sender, EventArgs e) - { - - } - } -} \ No newline at end of file diff --git a/Tester.Web/Store.Master.designer.cs b/Tester.Web/Store.Master.designer.cs deleted file mode 100644 index 51e4b46..0000000 --- a/Tester.Web/Store.Master.designer.cs +++ /dev/null @@ -1,35 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Tester.Web -{ - - - public partial class Store - { - - /// - /// form1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.HtmlControls.HtmlForm form1; - - /// - /// ContentPlaceHolder1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.ContentPlaceHolder ContentPlaceHolder1; - } -} diff --git a/Tester.Web/Tester.Web.csproj b/Tester.Web/Tester.Web.csproj deleted file mode 100644 index 913e999..0000000 --- a/Tester.Web/Tester.Web.csproj +++ /dev/null @@ -1,152 +0,0 @@ - - - - - - Debug - AnyCPU - - - 2.0 - {7350CA94-174B-4A46-9233-F0FE35899CBD} - {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} - Library - Properties - Tester.Web - Tester.Web - v4.8 - true - - - - - - - - - - - - true - full - false - bin\ - DEBUG;TRACE - prompt - 4 - - - true - pdbonly - true - bin\ - TRACE - prompt - 4 - - - - - ..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll - - - - - - - - - - - - - - - - - - - - ..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.8\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll - - - - - - - - - Default.aspx - ASPXCodeBehind - - - Default.aspx - - - - - Store.Master - ASPXCodeBehind - - - Store.Master - - - - - - - Web.config - - - Web.config - - - - - {BA52829E-D8D3-47F6-B1F8-07582AE28A62} - PayStackDotNetSDK - - - - 10.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - - - - - - True - True - 60441 - / - http://localhost:60449/ - True - http://localhost:60449/ - False - False - - - False - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - \ No newline at end of file diff --git a/Tester.Web/Web.Debug.config b/Tester.Web/Web.Debug.config deleted file mode 100644 index fae9cfe..0000000 --- a/Tester.Web/Web.Debug.config +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/Tester.Web/Web.Release.config b/Tester.Web/Web.Release.config deleted file mode 100644 index da6e960..0000000 --- a/Tester.Web/Web.Release.config +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/Tester.Web/Web.config b/Tester.Web/Web.config deleted file mode 100644 index ad3af92..0000000 --- a/Tester.Web/Web.config +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Tester.Web/packages.config b/Tester.Web/packages.config deleted file mode 100644 index 0053bfb..0000000 --- a/Tester.Web/packages.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From d1d70634acbcd9a9ef714e9831c015698764b22d Mon Sep 17 00:00:00 2001 From: Abubakar Imam Date: Thu, 9 Oct 2025 15:48:12 +0100 Subject: [PATCH 4/6] Fix refund model and metadata model --- .../InitializeTransactionBuilder.cs | 58 ++++++++++++++++ .../BuilderHelper/MetadataBuilder.cs | 29 ++++++++ PayStackDotNetSDK/Models/Metadata.cs | 32 +++++++-- .../Refunds/CreateRefundResponseModel.cs | 23 +------ .../Refunds/FetchRefundResponseModel.cs | 24 ------- .../Models/Refunds/ListRefundResponseModel.cs | 33 ++++------ .../Models/Refunds/commonRefundModel.cs | 66 +++++++++++++++++++ .../Transactions/TransactionResponseModel.cs | 10 +-- Tester.Console/Program.cs | 66 ++++++++++++++----- 9 files changed, 251 insertions(+), 90 deletions(-) create mode 100644 PayStackDotNetSDK/BuilderHelper/InitializeTransactionBuilder.cs create mode 100644 PayStackDotNetSDK/BuilderHelper/MetadataBuilder.cs create mode 100644 PayStackDotNetSDK/Models/Refunds/commonRefundModel.cs diff --git a/PayStackDotNetSDK/BuilderHelper/InitializeTransactionBuilder.cs b/PayStackDotNetSDK/BuilderHelper/InitializeTransactionBuilder.cs new file mode 100644 index 0000000..9ab77dd --- /dev/null +++ b/PayStackDotNetSDK/BuilderHelper/InitializeTransactionBuilder.cs @@ -0,0 +1,58 @@ +using PayStackDotNetSDK.Models; +using PayStackDotNetSDK.Models.Transactions; +using System; + +namespace PayStackDotNetSDK.Builders +{ + public class InitializeTransactionBuilder + { + private readonly TransactionRequestModel _request = new TransactionRequestModel(); + + public InitializeTransactionBuilder WithEmail(string email) + { + _request.email = email; + return this; + } + + public InitializeTransactionBuilder WithAmount(int amount) + { + _request.amount = amount; + return this; + } + + public InitializeTransactionBuilder WithReference(string reference) + { + _request.reference = reference; + return this; + } + + public InitializeTransactionBuilder WithCurrency(string currency) + { + _request.currency = currency; + return this; + } + + public InitializeTransactionBuilder WithCallbackUrl(string callbackUrl) + { + _request.callback_url = callbackUrl; + return this; + } + + public InitializeTransactionBuilder WithMetadata(Action metadataBuilderAction) + { + var builder = new MetadataBuilder(); + metadataBuilderAction(builder); + _request.metadata = builder.Build(); + return this; + } + + public TransactionRequestModel Build() + { + if (string.IsNullOrWhiteSpace(_request.email)) + throw new InvalidOperationException("Email is required for a Paystack transaction."); + if (_request.amount <= 0) + throw new InvalidOperationException("Amount must be greater than zero."); + return _request; + } + } +} diff --git a/PayStackDotNetSDK/BuilderHelper/MetadataBuilder.cs b/PayStackDotNetSDK/BuilderHelper/MetadataBuilder.cs new file mode 100644 index 0000000..7f0cb09 --- /dev/null +++ b/PayStackDotNetSDK/BuilderHelper/MetadataBuilder.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using PayStackDotNetSDK.Models; + +namespace PayStackDotNetSDK.Builders +{ + public class MetadataBuilder + { + private readonly Metadata _metadata = new Metadata(); + + public MetadataBuilder AddField(string key, object value) + { + _metadata.AdditionalData[key] = Newtonsoft.Json.Linq.JToken.FromObject(value); + return this; + } + + public MetadataBuilder AddCustomField(string displayName, string variableName, string value) + { + _metadata.CustomFields.Add(new CustomField + { + DisplayName = displayName, + VariableName = variableName, + Value = value + }); + return this; + } + + public Metadata Build() => _metadata; + } +} diff --git a/PayStackDotNetSDK/Models/Metadata.cs b/PayStackDotNetSDK/Models/Metadata.cs index d577796..1afda40 100644 --- a/PayStackDotNetSDK/Models/Metadata.cs +++ b/PayStackDotNetSDK/Models/Metadata.cs @@ -1,16 +1,38 @@ -using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System.Collections.Generic; namespace PayStackDotNetSDK.Models { public class Metadata { - public List custom_fields { get; set; } = null; + [JsonProperty("custom_fields")] + public List CustomFields { get; set; } = new List(); + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } = new Dictionary(); } + public class CustomField { - public string display_name { get; set; } = null; - public string variable_name { get; set; } = null; - public string value { get; set; } = null; + [JsonProperty("display_name")] + public string DisplayName { get; set; } + + [JsonProperty("variable_name")] + public string VariableName { get; set; } + + [JsonProperty("value")] + public string Value { get; set; } + // ✅ Add this constructor + + public CustomField() { } + + public CustomField(string displayName, string variableName, string value) + { + DisplayName = displayName; + VariableName = variableName; + Value = value; + } + } } diff --git a/PayStackDotNetSDK/Models/Refunds/CreateRefundResponseModel.cs b/PayStackDotNetSDK/Models/Refunds/CreateRefundResponseModel.cs index 8c559d5..82da673 100644 --- a/PayStackDotNetSDK/Models/Refunds/CreateRefundResponseModel.cs +++ b/PayStackDotNetSDK/Models/Refunds/CreateRefundResponseModel.cs @@ -6,26 +6,7 @@ public class CreateRefundResponseModel { public bool status { get; set; } public string message { get; set; } - public Data data { get; set; } - } - public class Data - { - public int dispute { get; set; } - public int transaction { get; set; } - public string currency { get; set; } - public int amount { get; set; } - public string channel { get; set; } - public string customer_note { get; set; } - public string merchant_note { get; set; } - public int integration { get; set; } - public string domain { get; set; } - public string status { get; set; } - public string refunded_by { get; set; } - public DateTime refunded_at { get; set; } - public DateTime expected_at { get; set; } - public bool fully_deducted { get; set; } - public int id { get; set; } - public DateTime createdAt { get; set; } - public DateTime updatedAt { get; set; } + public RefundData data { get; set; } } + } diff --git a/PayStackDotNetSDK/Models/Refunds/FetchRefundResponseModel.cs b/PayStackDotNetSDK/Models/Refunds/FetchRefundResponseModel.cs index 60715c1..8b7efe2 100644 --- a/PayStackDotNetSDK/Models/Refunds/FetchRefundResponseModel.cs +++ b/PayStackDotNetSDK/Models/Refunds/FetchRefundResponseModel.cs @@ -8,29 +8,5 @@ public class FetchRefundResponseModel public string message { get; set; } public RefundData data { get; set; } } - public class RefundData - { - public int integration { get; set; } - public int transaction { get; set; } - public int dispute { get; set; } - public object settlement { get; set; } - public string domain { get; set; } - public int amount { get; set; } - public object deducted_amount { get; set; } - public bool fully_deducted { get; set; } - public string currency { get; set; } - public string channel { get; set; } - public string status { get; set; } - public string refunded_by { get; set; } - public DateTime refunded_at { get; set; } - public DateTime expected_at { get; set; } - public string customer_note { get; set; } - public string merchant_note { get; set; } - public object bank_reference { get; set; } - public int id { get; set; } - public DateTime createdAt { get; set; } - public DateTime updatedAt { get; set; } - } - } diff --git a/PayStackDotNetSDK/Models/Refunds/ListRefundResponseModel.cs b/PayStackDotNetSDK/Models/Refunds/ListRefundResponseModel.cs index 784e150..549b41f 100644 --- a/PayStackDotNetSDK/Models/Refunds/ListRefundResponseModel.cs +++ b/PayStackDotNetSDK/Models/Refunds/ListRefundResponseModel.cs @@ -7,35 +7,31 @@ public class ListRefundResponseModel { public bool status { get; set; } public string message { get; set; } - public List data { get; set; } - public Meta meta { get; set; } + public List data { get; set; } + public RefundListMeta meta { get; set; } } - public class Refund + + public class RefundListData { public int integration { get; set; } - public string domain { get; set; } public int transaction { get; set; } - public int dispute { get; set; } - public int amount { get; set; } + public object dispute { get; set; } + public object settlement { get; set; } + public int id { get; set; } + public string domain { get; set; } public string currency { get; set; } - public string channel { get; set; } - public object deducted_amount { get; set; } - public int fully_deducted { get; set; } + public int amount { get; set; } public string status { get; set; } + public object refunded_at { get; set; } public string refunded_by { get; set; } - public DateTime refunded_at { get; set; } - public DateTime expected_at { get; set; } - public object settlement { get; set; } public string customer_note { get; set; } public string merchant_note { get; set; } - public object bank_reference { get; set; } - public int id { get; set; } - public DateTime created_at { get; set; } - public DateTime updated_at { get; set; } - public int is_deleted { get; set; } + public int deducted_amount { get; set; } + public bool fully_deducted { get; set; } + public DateTime createdAt { get; set; } } - public class Meta + public class RefundListMeta { public int total { get; set; } public int skipped { get; set; } @@ -43,5 +39,4 @@ public class Meta public int page { get; set; } public int pageCount { get; set; } } - } diff --git a/PayStackDotNetSDK/Models/Refunds/commonRefundModel.cs b/PayStackDotNetSDK/Models/Refunds/commonRefundModel.cs new file mode 100644 index 0000000..b61977b --- /dev/null +++ b/PayStackDotNetSDK/Models/Refunds/commonRefundModel.cs @@ -0,0 +1,66 @@ +using System; + +namespace PayStackDotNetSDK.Models.Refunds +{ + public class RefundData + { + public RefundTransaction transaction { get; set; } + public int integration { get; set; } + public int deducted_amount { get; set; } + public string channel { get; set; } + public string merchant_note { get; set; } + public string customer_note { get; set; } + public string status { get; set; } + public string refunded_by { get; set; } + public DateTime expected_at { get; set; } + public string currency { get; set; } + public string domain { get; set; } + public int amount { get; set; } + public bool fully_deducted { get; set; } + public int id { get; set; } + public DateTime createdAt { get; set; } + public DateTime updatedAt { get; set; } + } + + public class RefundTransaction + { + public int id { get; set; } + public string domain { get; set; } + public string reference { get; set; } + public int amount { get; set; } + public DateTime paid_at { get; set; } + public string channel { get; set; } + public string currency { get; set; } + public RefundAuthorization authorization { get; set; } + public RefundCustomer customer { get; set; } + public RefundPlan plan { get; set; } + public RefundSubaccount subaccount { get; set; } + public RefundSplit split { get; set; } + public string order_id { get; set; } + public DateTime paidAt { get; set; } + public object pos_transaction_data { get; set; } + public object source { get; set; } + public object fees_breakdown { get; set; } + } + + public class RefundAuthorization + { + public string exp_month { get; set; } + public string exp_year { get; set; } + public string account_name { get; set; } + } + + public class RefundCustomer + { + public string international_format_phone { get; set; } + } + + public class RefundPlan { } + + public class RefundSplit { } + + public class RefundSubaccount + { + public string currency { get; set; } + } +} diff --git a/PayStackDotNetSDK/Models/Transactions/TransactionResponseModel.cs b/PayStackDotNetSDK/Models/Transactions/TransactionResponseModel.cs index 595b432..a2c8062 100644 --- a/PayStackDotNetSDK/Models/Transactions/TransactionResponseModel.cs +++ b/PayStackDotNetSDK/Models/Transactions/TransactionResponseModel.cs @@ -10,10 +10,10 @@ public class TransactionResponseModel public Data data { get; set; } } - public class Metadata - { - public string referrer { get; set; } - } + //public class Metadata + //{ + // public string referrer { get; set; } + //} public class History { @@ -55,7 +55,7 @@ public class Authorization public class Customer { public string phone { get; set; } - public Metadata metadata { get; set; } + public Metadata metadata { get; set; } = new Metadata(); public string risk_action { get; set; } public object international_format_phone { get; set; } diff --git a/Tester.Console/Program.cs b/Tester.Console/Program.cs index 7888540..3d8ee1a 100644 --- a/Tester.Console/Program.cs +++ b/Tester.Console/Program.cs @@ -1,31 +1,65 @@ -using PayStackDotNetSDK.Methods.Transactions; -using Newtonsoft.Json; // ✅ modern JSON serializer +using PayStackDotNetSDK.Methods.Refunds; +using PayStackDotNetSDK.Methods.Transactions; +using PayStackDotNetSDK.Models; +using PayStackDotNetSDK.Models.Transactions; +using System; +using System.Threading.Tasks; -namespace Tester.Console +namespace Tester.ConsoleApp { class Program { + private static readonly string secretKey = "sk_test_f20e1eae3d1ebed0f3ecf3285daeb17d8ebf6535"; + static async Task Main(string[] args) { - System.Console.WriteLine("🔍 Verifying Paystack transaction..."); + Console.WriteLine("=== Paystack SDK Test ===\n"); - await VerifyTransaction(); + var paystack = new PaystackTransaction(secretKey); - System.Console.WriteLine("✅ Done. Press any key to exit..."); - System.Console.ReadKey(); - } + // Step 1: Initialize transaction with metadata + var metadata = new Metadata + { + CustomFields = new System.Collections.Generic.List + { + new CustomField("Customer ID", "CUST-2345", "12345"), + new CustomField("Referrer", "Twitter Campaign", "Twitter") + } + }; - private static async Task VerifyTransaction() - { - var paystackTransactionAPI = new PaystackTransaction("apikey/secret/key"); - var response = await paystackTransactionAPI.VerifyTransaction("T262788937392358"); + var response = await paystack.InitializeTransaction(new TransactionRequestModel + { + email = "customer@example.com", + amount = 10000, // ₦100 + metadata = metadata + }); + + Console.WriteLine("\n=== Initialize Response ==="); + Console.WriteLine($"Status: {response.status}"); + Console.WriteLine($"Auth URL: {response.data.authorization_url}"); + Console.WriteLine($"Reference: {response.data.reference}"); + + Console.WriteLine("\nOpen the authorization URL to complete the payment..."); + Console.ReadLine(); + + // Step 2: Verify transaction + var verifyResponse = await paystack.VerifyTransaction(response.data.reference); + Console.WriteLine("\n=== Verify Response ==="); + Console.WriteLine($"Status: {verifyResponse.status}"); + Console.WriteLine($"Amount: {verifyResponse.data.amount}"); + Console.WriteLine($"Customer Email: {verifyResponse.data.customer.email}"); + + // Step 3: Refund transaction + var refundInstance = new PaystackRefund(secretKey); + var refundResponse = await refundInstance.CreateRefund(verifyResponse.data.reference); - // ✅ Serialize the response object to JSON string - var json = JsonConvert.SerializeObject(response, Formatting.Indented); + Console.WriteLine("\n=== Refund Response ==="); + Console.WriteLine($"Status: {refundResponse.status}"); + Console.WriteLine($"Message: {refundResponse.message}"); - // ✅ Print to console instead of web element - System.Console.WriteLine(json); + Console.WriteLine("\n✅ SDK Test Completed — Press any key to exit..."); + Console.ReadKey(); } } } From 848d062c86e61a26cbb6a1bda67b96d21e5aaeb4 Mon Sep 17 00:00:00 2001 From: Abubakar Imam Date: Thu, 9 Oct 2025 21:32:10 +0100 Subject: [PATCH 5/6] fix error with metadata builder method and tested both the metadata and refund --- PayStackDotNetSDK/BuilderHelper/MetadataBuilder.cs | 9 +++------ PayStackDotNetSDK/Models/Metadata.cs | 2 +- .../Models/Refunds/CreateRefundRequestModel.cs | 2 +- .../Models/Refunds/ListRefundResponseModel.cs | 8 ++++---- PayStackDotNetSDK/Models/Refunds/commonRefundModel.cs | 10 +++++----- .../Models/Transactions/TransactionRequestModel.cs | 4 ++-- .../Models/Transactions/TransactionResponseModel.cs | 6 +++--- 7 files changed, 19 insertions(+), 22 deletions(-) diff --git a/PayStackDotNetSDK/BuilderHelper/MetadataBuilder.cs b/PayStackDotNetSDK/BuilderHelper/MetadataBuilder.cs index 7f0cb09..4537a2c 100644 --- a/PayStackDotNetSDK/BuilderHelper/MetadataBuilder.cs +++ b/PayStackDotNetSDK/BuilderHelper/MetadataBuilder.cs @@ -15,15 +15,12 @@ public MetadataBuilder AddField(string key, object value) public MetadataBuilder AddCustomField(string displayName, string variableName, string value) { - _metadata.CustomFields.Add(new CustomField - { - DisplayName = displayName, - VariableName = variableName, - Value = value - }); + // ✅ Correct usage of constructor + _metadata.CustomFields.Add(new CustomField(displayName, variableName, value)); return this; } public Metadata Build() => _metadata; } + } diff --git a/PayStackDotNetSDK/Models/Metadata.cs b/PayStackDotNetSDK/Models/Metadata.cs index 1afda40..ed6bfe0 100644 --- a/PayStackDotNetSDK/Models/Metadata.cs +++ b/PayStackDotNetSDK/Models/Metadata.cs @@ -25,7 +25,7 @@ public class CustomField public string Value { get; set; } // ✅ Add this constructor - public CustomField() { } + //public CustomField() { } public CustomField(string displayName, string variableName, string value) { diff --git a/PayStackDotNetSDK/Models/Refunds/CreateRefundRequestModel.cs b/PayStackDotNetSDK/Models/Refunds/CreateRefundRequestModel.cs index ba5afb1..bb82bc8 100644 --- a/PayStackDotNetSDK/Models/Refunds/CreateRefundRequestModel.cs +++ b/PayStackDotNetSDK/Models/Refunds/CreateRefundRequestModel.cs @@ -11,7 +11,7 @@ public class CreateRefundRequestModel /// /// amount(optional) : How much in kobo to be refunded to the customer.Amount is optional(defaults to original transaction amount) and cannot be more than the original transaction amount. /// - public int amount { get; set; } + public long amount { get; set; } /// /// currency: Three-letter ISO currency /// diff --git a/PayStackDotNetSDK/Models/Refunds/ListRefundResponseModel.cs b/PayStackDotNetSDK/Models/Refunds/ListRefundResponseModel.cs index 549b41f..ffac88d 100644 --- a/PayStackDotNetSDK/Models/Refunds/ListRefundResponseModel.cs +++ b/PayStackDotNetSDK/Models/Refunds/ListRefundResponseModel.cs @@ -13,14 +13,14 @@ public class ListRefundResponseModel public class RefundListData { - public int integration { get; set; } - public int transaction { get; set; } + public long integration { get; set; } + public long transaction { get; set; } public object dispute { get; set; } public object settlement { get; set; } - public int id { get; set; } + public long id { get; set; } public string domain { get; set; } public string currency { get; set; } - public int amount { get; set; } + public long amount { get; set; } public string status { get; set; } public object refunded_at { get; set; } public string refunded_by { get; set; } diff --git a/PayStackDotNetSDK/Models/Refunds/commonRefundModel.cs b/PayStackDotNetSDK/Models/Refunds/commonRefundModel.cs index b61977b..1205841 100644 --- a/PayStackDotNetSDK/Models/Refunds/commonRefundModel.cs +++ b/PayStackDotNetSDK/Models/Refunds/commonRefundModel.cs @@ -5,7 +5,7 @@ namespace PayStackDotNetSDK.Models.Refunds public class RefundData { public RefundTransaction transaction { get; set; } - public int integration { get; set; } + public long integration { get; set; } public int deducted_amount { get; set; } public string channel { get; set; } public string merchant_note { get; set; } @@ -15,19 +15,19 @@ public class RefundData public DateTime expected_at { get; set; } public string currency { get; set; } public string domain { get; set; } - public int amount { get; set; } + public long amount { get; set; } public bool fully_deducted { get; set; } - public int id { get; set; } + public long id { get; set; } public DateTime createdAt { get; set; } public DateTime updatedAt { get; set; } } public class RefundTransaction { - public int id { get; set; } + public long id { get; set; } public string domain { get; set; } public string reference { get; set; } - public int amount { get; set; } + public long amount { get; set; } public DateTime paid_at { get; set; } public string channel { get; set; } public string currency { get; set; } diff --git a/PayStackDotNetSDK/Models/Transactions/TransactionRequestModel.cs b/PayStackDotNetSDK/Models/Transactions/TransactionRequestModel.cs index fdd16fe..d848358 100644 --- a/PayStackDotNetSDK/Models/Transactions/TransactionRequestModel.cs +++ b/PayStackDotNetSDK/Models/Transactions/TransactionRequestModel.cs @@ -12,7 +12,7 @@ public class TransactionRequestModel /// /// (required) - Amount in kobo /// - public int amount { get; set; } + public long amount { get; set; } /// /// The code for the subaccount that owns the payment. /// @@ -48,7 +48,7 @@ public class TransactionRequestModel /// /// Stringified JSON object. Add a custom_fields attribute which has an array of objects if you would like the fields to be added to your transaction when displayed on the dashboard. /// - public Metadata metadata { get; set; } = null; + public Metadata metadata { get; set; } = new Metadata(); public string currency { get; set; } = Constants.Currency.Naira; public string firstName { get; set; } = null; public string lastName { get; set; } = null; diff --git a/PayStackDotNetSDK/Models/Transactions/TransactionResponseModel.cs b/PayStackDotNetSDK/Models/Transactions/TransactionResponseModel.cs index a2c8062..57b0900 100644 --- a/PayStackDotNetSDK/Models/Transactions/TransactionResponseModel.cs +++ b/PayStackDotNetSDK/Models/Transactions/TransactionResponseModel.cs @@ -59,7 +59,7 @@ public class Customer public string risk_action { get; set; } public object international_format_phone { get; set; } - public int id { get; set; } + public long id { get; set; } public string customer_code { get; set; } public string first_name { get; set; } public string last_name { get; set; } @@ -85,7 +85,7 @@ public class Data //public Plan_Object plan_object { get; set; } public Subaccount subaccount { get; set; } - public int amount { get; set; } + public long amount { get; set; } public string currency { get; set; } public DateTime transaction_date { get; set; } public string status { get; set; } @@ -104,7 +104,7 @@ public class Data public class Subaccount { - public int id { get; set; } + public long id { get; set; } public string subaccount_code { get; set; } public string business_name { get; set; } public string description { get; set; } From 5e24b2e4ef388f93c33b00d7462765b07d9894db Mon Sep 17 00:00:00 2001 From: Abubakar Imam Date: Thu, 9 Oct 2025 21:43:55 +0100 Subject: [PATCH 6/6] Added a readme sample of metadata implementation --- README.md | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8880b09..5e7bce8 100644 --- a/README.md +++ b/README.md @@ -231,7 +231,49 @@ using PayStackDotNetSDK.Models.Transactions; var connectionInstance = new PaystackTransaction(Credential.Key); var response = await connectionInstance.CheckAuthorization("authorization_code", "email@email.com", 4000, PayStackDotNetSDK.Helpers.Constants.Currency.Naira); } - + + + #### Initialize Transaction with Metadata + + /// + /// Implementation using the Metadata Builder + /// + protected async void InitializeTransactionWithMetadata() + { + var paystack = new PaystackTransaction(Credential.Key); + + // Build metadata using the builder pattern + var meta = new MetadataBuilder() + .AddField("cart_id", 398) + .AddField("promo_code", "WELCOME50") + .AddCustomField("Invoice ID", "invoice_id", "INV001") + .AddCustomField("Cart Items", "cart_items", "3 bananas, 12 mangoes") + .Build(); + + // Build transaction request with metadata + var transactionRequest = new InitializeTransactionBuilder() + .WithEmail("user@example.com") + .WithAmount(10000) + .WithReference("TXN-001") + .WithCurrency("NGN") + .WithCallbackUrl("https://yourapp.com/payment/callback") + .WithMetadata(meta) + .Build(); + + // Initialize transaction + var response = await paystack.InitializeTransaction(transactionRequest); + + if (response.status) + { + // Redirect to authorization URL on success + Response.Redirect(response.data.authorization_url); + } + else + { + // Handle unsuccessful initialization + } + } + ### Customers