Skip to content

Commit 6a584d5

Browse files
authored
Merge pull request #1 from helixge/feature/initiator
Feature/initiator
2 parents c00e4c8 + 2867dd8 commit 6a584d5

14 files changed

+162
-25
lines changed

.github/workflows/pull_request.yml

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Pull request
2+
3+
on:
4+
workflow_dispatch:
5+
pull_request:
6+
workflow_call:
7+
8+
jobs:
9+
build_and_test:
10+
name: Build and test
11+
runs-on: ubuntu-latest
12+
timeout-minutes: 5
13+
steps:
14+
- name: Checkout repo
15+
uses: actions/checkout@v3
16+
17+
- uses: actions/setup-dotnet@v3
18+
with:
19+
dotnet-version: '6'
20+
21+
- name: Build
22+
working-directory: ./Solution
23+
run: dotnet build
24+
25+
- name: Test
26+
working-directory: ./Solution
27+
run: dotnet test

README.md

+17-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# TBC Bank E-Commerce Card Payments Gateway Client (.NET Library)
22

3-
[![Version](https://helix.ge/helix-tbcbank-ecommerceclient-nuget.svg?3-2-0)](https://www.nuget.org/packages/Helix.TbcBank.EcommerceClient)
3+
[![Version](https://helix.ge/helix-tbcbank-ecommerceclient-nuget.svg?4-0-0-1)](https://www.nuget.org/packages/Helix.TbcBank.EcommerceClient)
44

55
[Helix.TbcBank.EcommerceClient](https://www.nuget.org/packages/Helix.TbcBank.EcommerceClient) is a .NET client library for using TBC Bank e-commerce visa and master card payments gateway .
66

@@ -76,7 +76,7 @@ var client = new TbcBankEcommerceClient(clientOptions);
7676
Once the transaction is registered and the corresponding ID is retrieved from TBC, call this method to retrieve URL where the user should be redirected to in order to enter card details and complete the transaction
7777

7878
* **ExecuteReoccurringTransactionAsync**
79-
If you have already successfully completed the transaction using ```RegisterTransactionAndGetReoccuringPaymentIdAsync``` method, you can execute additional transactions without the user intervention using this method.
79+
If you have already successfully completed the transaction using ```RegisterTransactionAndGetReoccuringPaymentIdAsync``` or ```RegisterPreAuthorizationAndGetReoccuringPaymentId``` methods, you can execute additional transactions without the user intervention using this method.
8080

8181
* **RegisterPreAuthorizationAsync**
8282
Use this method if you want to temporarily block the amount on the card while processing offline or asynchronous operation. ```ExecutePreAuthorizationAsync()``` method must be called to complete the transaction.
@@ -95,6 +95,20 @@ var client = new TbcBankEcommerceClient(clientOptions);
9595

9696
* **CloseBusinessDayAsync**
9797
Closes the business day for a merchant
98+
99+
* **RegisterPreAuthorizationAndGetReoccuringPaymentId**
100+
Pre-authorization is the temporary amount blocking operation, which must be followed by a pre-authorization confirmation or reversal operation. In case none of them follow, the system by default will automatically delete the blocked amount after 30 working days. The block period is regulated by the card issuer (Issuer Bank). Pre-authorization can only be completed within 30 working days, follow the next commands to clarify.
101+
102+
Register payment transaction with specified amount and save information for future transactions. This feature should be enabled by TBC. Once transaction id is retrieved, call ```GetClientRedirectUrl()``` method and navigate the user to the corresponding URL.
103+
104+
Once the operation completes you need to confirm the transaction using ```ExecutePreAuthorizationAsync()``` or reverse the transaction using ```ReverseTransactionAsync()```
105+
106+
* **ExecuteReoccurringPreAuthorizationAsync**
107+
Pre-authorization is the temporary amount blocking operation, which must be followed by a pre-authorization confirmation or reversal operation. In case none of them follow, the system by default will automatically delete the blocked amount after 30 working days. The block period is regulated by the card issuer (Issuer Bank). Pre-authorization can only be completed within 30 working days, follow the next commands to clarify.
108+
109+
If you have already successfully completed the transaction using ```RegisterTransactionAndGetReoccuringPaymentIdAsync``` or ```RegisterPreAuthorizationAndGetReoccuringPaymentId``` methods, you can execute additional transactions without the user intervention using this method.
110+
111+
Once the operation completes you need to confirm the transaction using ```ExecutePreAuthorizationAsync()``` or reverse the transaction using ```ReverseTransactionAsync()```
98112

99113
* **ExecuteCreditTransactionAsync**
100114
This feature should be enabled by TBC.
@@ -183,4 +197,4 @@ public class HomeController : Controller
183197

184198
//...other methods
185199
}
186-
````
200+
````

RELEASE-NOTES.txt

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
v4.0.0
2+
- Adding required initiator parameter introduced by the TBC regulation: When the merchant has to cut a certain amount from the client on any given date without the client's approval, it is necessary for the merchant to add an additional parameter (initiator = merchant)
3+
- Adding 'RegisterPreAuthorizationAndGetReoccuringPaymentId' method (command "d").
4+
- Adding 'ExecuteReoccurringPreAuthorizationAsync()' method (command "f").
5+
- Note: Pre-authorization is the temporary amount blocking operation, which must be followed by a pre-authorization confirmation ('ExecutePreAuthorizationAsync()', command "t") or reversal operation ('ReverseTransactionAsync()', command "r"). In case none of them follow, the system by default will automatically delete the blocked amount after 30 working days. The block period is regulated by the card issuer (Issuer Bank). Pre-authorization can only be completed within 30 working days, follow the next commands to clarify.
16
v3.2.0
27
- Optimize HTTP connection creation. Use singleton HttpClient per merchant
38
v3.1.0

Solution/TbcBank.EcommerceClient/CodesAndStatuses/CurrencyCode.cs renamed to Solution/TbcBank.EcommerceClient/EnumsAndConstants/CurrencyCode.cs

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Text;
4-
5-
namespace TbcBank.EcommerceClient
1+
namespace TbcBank.EcommerceClient
62
{
73
public enum CurrencyCode
84
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace TbcBank.EcommerceClient
2+
{
3+
public enum TransactionInitiator
4+
{
5+
Client = 1,
6+
Merchant = 2
7+
}
8+
}

Solution/TbcBank.EcommerceClient/TbcBank.EcommerceClient.csproj

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
<PackageIcon>helix.png</PackageIcon>
1616
<PackageIconUrl />
1717
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
18-
<AssemblyVersion>3.2.0.0</AssemblyVersion>
19-
<FileVersion>3.2.0.0</FileVersion>
20-
<Version>3.2.0</Version>
18+
<AssemblyVersion>4.0.0.0</AssemblyVersion>
19+
<FileVersion>4.0.0.0</FileVersion>
20+
<Version>4.0.0</Version>
2121
<Product>TBC Bank Ecommerce Card Payments Gateway Client (.NET Library)</Product>
2222
</PropertyGroup>
2323

Solution/TbcBank.EcommerceClient/TbcBankEcommerceClient.cs

+77-3
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ public async Task<RegisterTransactionResult> RegisterTransactionAndGetReoccuring
138138
/// <param name="language"></param>
139139
/// <param name="merchantTransactionId"></param>
140140
/// <returns></returns>
141-
public async Task<ExecuteReoccurringTransactionResult> ExecuteReoccurringTransactionAsync(int amount, CurrencyCode currency, string clientIpAddress, string description, string billerClientId, string language = PaymentUiLanguage.Georgian, string merchantTransactionId = null)
141+
public async Task<ExecuteReoccurringTransactionResult> ExecuteReoccurringTransactionAsync(int amount, CurrencyCode currency, string clientIpAddress, string description, string billerClientId, TransactionInitiator initiator, string language = PaymentUiLanguage.Georgian, string merchantTransactionId = null)
142142
{
143143
var options = GetActiveOptions(currency);
144144

@@ -149,12 +149,16 @@ public async Task<ExecuteReoccurringTransactionResult> ExecuteReoccurringTransac
149149
{ "currency", ((int)currency).ToString() },
150150
{ "client_ip_addr", clientIpAddress },
151151
{ "description", description },
152-
{ "desc", description },
153152
{ "language", language },
154153
{ "biller_client_id", billerClientId },
155154
{ "mrch_transaction_id", merchantTransactionId }
156155
};
157156

157+
if (initiator == TransactionInitiator.Merchant)
158+
{
159+
requestParameters.Add("initiator", "merchant");
160+
}
161+
158162
return new ExecuteReoccurringTransactionResult(await MakePostRequestAsync(requestParameters, options));
159163
}
160164

@@ -208,7 +212,6 @@ public async Task<ExecutePreAuthorizationResult> ExecutePreAuthorizationAsync(st
208212
{ "currency", ((int)currency).ToString() },
209213
{ "client_ip_addr", clientIpAddress },
210214
{ "description", description },
211-
{ "desc", description },
212215
};
213216

214217
return new ExecutePreAuthorizationResult(await MakePostRequestAsync(requestParameters, options));
@@ -315,6 +318,77 @@ public async Task<CloseBusinessDayResult> CloseBusinessDayAsync()
315318
return new CloseBusinessDayResult(await MakePostRequestAsync(requestParameters, options));
316319
}
317320

321+
/// <summary>
322+
/// Command - D
323+
/// </summary>
324+
/// <param name="currency"></param>
325+
/// <param name="clientIpAddress"></param>
326+
/// <param name="description"></param>
327+
/// <param name="recurringPaymentUniqueId"></param>
328+
/// <param name="expiryDate"></param>
329+
/// <param name="language"></param>
330+
/// <param name="merchantTransactionId"></param>
331+
/// <returns></returns>
332+
public async Task<RegisterTransactionResult> RegisterPreAuthorizationAndGetReoccuringPaymentId(int amount, CurrencyCode currency, string clientIpAddress, string description, string recurringPaymentUniqueId, DateTimeOffset? expiryDate = null, string language = PaymentUiLanguage.Georgian, string merchantTransactionId = null)
333+
{
334+
var options = GetActiveOptions(currency);
335+
336+
expiryDate = expiryDate ?? GetDefaultExpiryDate();
337+
338+
var requestParameters = new Dictionary<string, string>()
339+
{
340+
{ "command", "d" },
341+
{ "amount", amount.ToString() },
342+
{ "currency", ((int)currency).ToString() },
343+
{ "client_ip_addr", clientIpAddress },
344+
{ "description", description },
345+
{ "language", language },
346+
{ "msg_type", "DMS" },
347+
{ "biller_client_id", recurringPaymentUniqueId },
348+
{ "perspayee_expiry", expiryDate.Value.ToString("MMyy") },
349+
{ "template_type", "DMS" }
350+
};
351+
352+
return new RegisterTransactionResult(await MakePostRequestAsync(requestParameters, options));
353+
}
354+
355+
/// <summary>
356+
/// Command - F
357+
/// </summary>
358+
/// <param name="amount"></param>
359+
/// <param name="currency"></param>
360+
/// <param name="clientIpAddress"></param>
361+
/// <param name="description"></param>
362+
/// <param name="billerClientId"></param>
363+
/// <param name="language"></param>
364+
/// <param name="merchantTransactionId"></param>
365+
/// <returns></returns>
366+
public async Task<ExecuteReoccurringTransactionResult> ExecuteReoccurringPreAuthorizationAsync(int amount, CurrencyCode currency, string clientIpAddress, string description, string billerClientId, TransactionInitiator initiator, string language = PaymentUiLanguage.Georgian, string merchantTransactionId = null)
367+
{
368+
var options = GetActiveOptions(currency);
369+
370+
var requestParameters = new Dictionary<string, string>()
371+
{
372+
{ "command", "f" },
373+
{ "amount", amount.ToString() },
374+
{ "currency", ((int)currency).ToString() },
375+
{ "client_ip_addr", clientIpAddress },
376+
{ "description", description },
377+
{ "language", language },
378+
{ "biller_client_id", billerClientId },
379+
{ "mrch_transaction_id", merchantTransactionId },
380+
{ "template_type", "DMS" }
381+
};
382+
383+
if (initiator == TransactionInitiator.Merchant)
384+
{
385+
requestParameters.Add("initiator", "merchant");
386+
}
387+
388+
return new ExecuteReoccurringTransactionResult(await MakePostRequestAsync(requestParameters, options));
389+
}
390+
391+
318392
/// <summary>
319393
/// Gets redirect URL where the client should be navigated to enter card details
320394
/// </summary>

Solution/TbcBankEcommerceClientSolution.sln

+5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{87E0BC95-E
1919
EndProject
2020
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Example.WebApp", "Docs\Example.WebApp\Example.WebApp.csproj", "{204987D7-7ED0-4C7E-9876-1A073B2473CA}"
2121
EndProject
22+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DevOps", "DevOps", "{2C81DBA6-53DF-4F04-9CE1-9F3090BF44E5}"
23+
ProjectSection(SolutionItems) = preProject
24+
..\.github\workflows\pull_request.yml = ..\.github\workflows\pull_request.yml
25+
EndProjectSection
26+
EndProject
2227
Global
2328
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2429
Debug|Any CPU = Debug|Any CPU

Solution/Testing/TbcBank.EcommerceClient.TestConsoleApp/Program.cs

+19-11
Original file line numberDiff line numberDiff line change
@@ -85,17 +85,25 @@ string redirectUrl
8585
CheckTransactionResult checkTransactionAndGetReoccuringPaymentIdResult
8686
= await client.CheckTransactionResultAsync(registerTransactionAndGetReoccuringPaymentIdResult.TransactionId, ClientIpAddress);
8787

88-
ExecuteReoccurringTransactionResult executeReoccurringTransactionResult
89-
= await client.ExecuteReoccurringTransactionAsync(4, CurrencyCode.GEL, ClientIpAddress, "Test Transaction - ExecuteReoccurringTransactionAsync", billerClientId);
90-
91-
CheckTransactionResult checkExecuteReoccurringTransactionResult
92-
= await client.CheckTransactionResultAsync(executeReoccurringTransactionResult.TransactionId, ClientIpAddress);
93-
94-
ReverseTransactionResult reverseResult
95-
= await client.ReverseTransactionAsync(executeReoccurringTransactionResult.TransactionId, 1);
96-
97-
RefundTransactionResult refundResult
98-
= await client.RefundTransactionAsync(executeReoccurringTransactionResult.TransactionId, 1);
88+
ExecuteReoccurringTransactionResult executeReoccurringTransactionResultForClient
89+
= await client.ExecuteReoccurringTransactionAsync(4, CurrencyCode.GEL, ClientIpAddress, "Test Transaction - ExecuteReoccurringTransactionAsync", billerClientId, TransactionInitiator.Client);
90+
ExecuteReoccurringTransactionResult executeReoccurringTransactionResultForMerchant
91+
= await client.ExecuteReoccurringTransactionAsync(4, CurrencyCode.GEL, ClientIpAddress, "Test Transaction - ExecuteReoccurringTransactionAsync", billerClientId, TransactionInitiator.Merchant);
92+
93+
CheckTransactionResult checkExecuteReoccurringTransactionResultForClient
94+
= await client.CheckTransactionResultAsync(executeReoccurringTransactionResultForClient.TransactionId, ClientIpAddress);
95+
CheckTransactionResult checkExecuteReoccurringTransactionResultForMerchant
96+
= await client.CheckTransactionResultAsync(executeReoccurringTransactionResultForMerchant.TransactionId, ClientIpAddress);
97+
98+
ReverseTransactionResult reverseResultForClient
99+
= await client.ReverseTransactionAsync(executeReoccurringTransactionResultForClient.TransactionId, 1);
100+
ReverseTransactionResult reverseResultForMerchant
101+
= await client.ReverseTransactionAsync(executeReoccurringTransactionResultForMerchant.TransactionId, 1);
102+
103+
RefundTransactionResult refundResultForClient
104+
= await client.RefundTransactionAsync(executeReoccurringTransactionResultForClient.TransactionId, 1);
105+
RefundTransactionResult refundResultForMerchant
106+
= await client.RefundTransactionAsync(executeReoccurringTransactionResultForClient.TransactionId, 1);
99107
}
100108

101109
{

0 commit comments

Comments
 (0)