Skip to content

Commit

Permalink
Add ZarinpalCurrency option ✅
Browse files Browse the repository at this point in the history
  • Loading branch information
MehdiMst00 committed Dec 21, 2023
1 parent 1613870 commit 880a3ee
Show file tree
Hide file tree
Showing 10 changed files with 190 additions and 97 deletions.
45 changes: 36 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Zarinpal payment gateway for Asp.Net Core
1. Download and install package from [NuGet](https://www.nuget.org/packages/Zarinpal.AspNetCore) or [GitHub](https://github.com/MehdiMst00/Zarinpal.AspNetCore)

```
PM> Install-Package Zarinpal.AspNetCore -Version 3.0.0
PM> Install-Package Zarinpal.AspNetCore -Version 3.1.0
```

2. Use `AddZarinpal` to add needed services to service container.
Expand All @@ -23,9 +23,10 @@ builder.Services.AddZarinpal(options =>
{
options.MerchantId = "xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx";
options.ZarinpalMode = ZarinpalMode.Sandbox;
options.Currency = ZarinpalCurrency.IRT;
});
```
`Note:` If you bind options from appsettings.json [See sample](https://github.com/MehdiMst00/Zarinpal.AspNetCore/blob/master/samples/Zarinpal.AspNetCore.Sample/appsettings.json)
`Note:` If you bind options from appsettings.json [See sample](https://github.com/MehdiMst00/Zarinpal.AspNetCore/blob/net8.0/samples/Zarinpal.AspNetCore.Sample/appsettings.json)

3. Inject `IZarinpalService` to your controller

Expand All @@ -45,8 +46,21 @@ public class MyController : Controller

## Request Payment
```c#
// Amount For Original Payment Is In Rial
var request = new ZarinpalRequestDTO(5000, "خرید",
int toman = 5000;
int rial = toman.TomanToRial(); // If store your price in toman you can use TomanToRial extension
/*
* Pay atttention: Currency is important, default is IRR (Rial)
*
* Here we set it to Toman (IRT)
"Zarinpal": {
...
"Currency": "IRT", // IRR - IRT
...
}
*/

var request = new ZarinpalRequestDTO(toman, "خرید",
"https://localhost:7219/Home/VerifyPayment",
"[email protected]", "09123456789");

Expand Down Expand Up @@ -74,10 +88,22 @@ public async Task<IActionResult> VerifyPayment()
// Check 'Status' and 'Authority' query param so zarinpal sent for us
if (HttpContext.IsValidZarinpalVerifyQueries())
{
// If store your price in toman you can use TomanToRial extension
int toman = 500;
var verify = new ZarinpalVerifyDTO(toman.TomanToRial(),
HttpContext.GetZarinpalAuthorityQuery());
int toman = 5000;
int rial = toman.TomanToRial(); // If store your price in toman you can use TomanToRial extension
/*
* Pay atttention: Currency is important, default is IRR (Rial)
*
* Here we set it to toman (IRT)
"Zarinpal": {
...
"Currency": "IRT", // IRR - IRT
...
}
*/

var verify = new ZarinpalVerifyDTO(toman,
HttpContext.GetZarinpalAuthorityQuery()!);

var response = await _zarinpalService.VerifyAsync(verify);

Expand Down Expand Up @@ -111,13 +137,14 @@ public async Task<IActionResult> VerifyPayment()
- In sandbox use amount in `Toman`

## What is `IAdvancedZarinpalService`?
- If you wanna use 'UnVerified' or 'Refund'(Coming soon) method, you must inject `IAdvancedZarinpalService` to service container. (Automatically not injected)
- If you wanna use 'UnVerified' method, you must inject `IAdvancedZarinpalService` to service container. (Automatically not injected)
- So let's come back into `Program.cs` and edit it (Or Set it in `appsettings.json` like [sample](https://github.com/MehdiMst00/Zarinpal.AspNetCore/blob/master/samples/Zarinpal.AspNetCore.Sample/appsettings.json)):
```c#
builder.Services.AddZarinpal(options =>
{
options.MerchantId = "xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx";
options.ZarinpalMode = ZarinpalMode.Original;
options.Currency = ZarinpalCurrency.IRT;
options.UseAdvanced = true;
});
```
Expand Down
177 changes: 101 additions & 76 deletions samples/Zarinpal.AspNetCore.Sample/Controllers/HomeController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,105 +3,130 @@
using Zarinpal.AspNetCore.Extensions;
using Zarinpal.AspNetCore.Interfaces;

namespace Zarinpal.AspNetCore.Sample.Controllers
namespace Zarinpal.AspNetCore.Sample.Controllers;

public class HomeController : Controller
{
public class HomeController : Controller
private readonly IZarinpalService _zarinpalService;
private readonly IAdvancedZarinpalService _advancedZarinpalService;

public HomeController(IZarinpalService zarinpalService,
IAdvancedZarinpalService advancedZarinpalService)
{
private readonly IZarinpalService _zarinpalService;
private readonly IAdvancedZarinpalService _advancedZarinpalService;
_zarinpalService = zarinpalService;
_advancedZarinpalService = advancedZarinpalService;
}

public HomeController(IZarinpalService zarinpalService,
IAdvancedZarinpalService advancedZarinpalService)
{
_zarinpalService = zarinpalService;
_advancedZarinpalService = advancedZarinpalService;
public IActionResult Index()
{
return View();
}

[HttpPost, ValidateAntiForgeryToken]
public async Task<IActionResult> RequestPayment()
{
int toman = 5000;
int rial = toman.TomanToRial(); // If store your price in toman you can use TomanToRial extension

/*
* Pay atttention: Currency is important, default is IRR (Rial)
*
* Here we set it to toman (IRT)
"Zarinpal": {
...
"Currency": "IRT", // IRR - IRT
...
}
*/

var request = new ZarinpalRequestDTO(toman, "خرید",
"https://localhost:7219/Home/VerifyPayment",
"[email protected]", "09123456789");

public IActionResult Index()
var result = await _zarinpalService.RequestAsync(request);

if (result.Data != null)
{
return View();
// You can store or log zarinpal data in database
string authority = result.Data.Authority;
int code = result.Data.Code;
int fee = result.Data.Fee;
string feeType = result.Data.FeeType;
string message = result.Data.Message;
}

[HttpPost, ValidateAntiForgeryToken]
public async Task<IActionResult> RequestPayment()
if (result.IsSuccessStatusCode)
return Redirect(result.RedirectUrl);

//if (result.StatusCode == ZarinpalStatusCode.St100)
//{
// // if you want see status message
// var message = result.StatusCode.Value.GetStatusCodeMessage();
// // Do Something
//}

return RedirectToAction("Index");
}

[HttpGet]
public async Task<IActionResult> VerifyPayment()
{
// Check 'Status' and 'Authority' query param so zarinpal sent for us
if (HttpContext.IsValidZarinpalVerifyQueries())
{
var request = new ZarinpalRequestDTO(5000, "خرید",
"https://localhost:7219/Home/VerifyPayment",
"[email protected]", "09123456789");
int toman = 5000;
int rial = toman.TomanToRial(); // If store your price in toman you can use TomanToRial extension

/*
* Pay atttention: Currency is important, default is IRR (Rial)
*
* Here we set it to toman (IRT)
"Zarinpal": {
...
"Currency": "IRT", // IRR - IRT
...
}
*/

var result = await _zarinpalService.RequestAsync(request);
var verify = new ZarinpalVerifyDTO(toman,
HttpContext.GetZarinpalAuthorityQuery()!);

if (result.Data != null)
var response = await _zarinpalService.VerifyAsync(verify);

if (response.Data != null)
{
// You can store or log zarinpal data in database
string authority = result.Data.Authority;
int code = result.Data.Code;
int fee = result.Data.Fee;
string feeType = result.Data.FeeType;
string message = result.Data.Message;
ulong refId = response.Data.RefId;
int fee = response.Data.Fee;
string feeType = response.Data.FeeType;
int code = response.Data.Code;
string cardHash = response.Data.CardHash;
string cardPan = response.Data.CardPan;
}

if (result.IsSuccessStatusCode)
return Redirect(result.RedirectUrl);
if (response.IsSuccessStatusCode)
{
// Do Somethings...
ViewData["RefId"] = response.RefId;
}

//if (result.StatusCode == ZarinpalStatusCode.St100)
//if (response.StatusCode == ZarinpalStatusCode.St100)
//{
// // if you want see status message
// var message = result.StatusCode.Value.GetStatusCodeMessage();
// var message = response.StatusCode.Value.GetStatusCodeMessage();
// // Do Something
//}

return RedirectToAction("Index");
return View(response.IsSuccessStatusCode);
}

[HttpGet]
public async Task<IActionResult> VerifyPayment()
{
// Check 'Status' and 'Authority' query param so zarinpal sent for us
if (HttpContext.IsValidZarinpalVerifyQueries())
{
// If store your price in toman you can use TomanToRial extension
int toman = 500;
var verify = new ZarinpalVerifyDTO(toman.TomanToRial(),
HttpContext.GetZarinpalAuthorityQuery()!);

var response = await _zarinpalService.VerifyAsync(verify);

if (response.Data != null)
{
// You can store or log zarinpal data in database
ulong refId = response.Data.RefId;
int fee = response.Data.Fee;
string feeType = response.Data.FeeType;
int code = response.Data.Code;
string cardHash = response.Data.CardHash;
string cardPan = response.Data.CardPan;
}

if (response.IsSuccessStatusCode)
{
// Do Somethings...
ViewData["RefId"] = response.RefId;
}

//if (response.StatusCode == ZarinpalStatusCode.St100)
//{
// // if you want see status message
// var message = response.StatusCode.Value.GetStatusCodeMessage();
// // Do Something
//}

return View(response.IsSuccessStatusCode);
}

return View(false);
}
return View(false);
}

[HttpGet]
public async Task<IActionResult> UnVerifiedPayments()
{
var result = await _advancedZarinpalService.UnVerifiedAsync();
return View(result);
}
[HttpGet]
public async Task<IActionResult> UnVerifiedPayments()
{
var result = await _advancedZarinpalService.UnVerifiedAsync();
return View(result);
}
}
4 changes: 3 additions & 1 deletion samples/Zarinpal.AspNetCore.Sample/Program.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Zarinpal.AspNetCore.Consts;
using Zarinpal.AspNetCore.Enums;
using Zarinpal.AspNetCore.Extensions;
using Zarinpal.AspNetCore.Models;

var builder = WebApplication.CreateBuilder(args);

Expand All @@ -17,6 +18,7 @@
//{
// options.MerchantId = "xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx";
// options.ZarinpalMode = ZarinpalMode.Original;
// options.Currency = ZarinpalCurrency.IRT;
// options.UseAdvanced = true;
//});

Expand Down
1 change: 1 addition & 0 deletions samples/Zarinpal.AspNetCore.Sample/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"Zarinpal": {
"MerchantId": "xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx",
"ZarinpalMode": "Sandbox", // Original - Sandbox
"Currency": "IRT", // IRR - IRT
"UseAdvanced": true
}
}
7 changes: 7 additions & 0 deletions src/Zarinpal.AspNetCore/Consts/ZarinpalCurrency.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Zarinpal.AspNetCore.Consts;

public static class ZarinpalCurrency
{
public const string IRR = nameof(IRR);
public const string IRT = nameof(IRT);
}
3 changes: 2 additions & 1 deletion src/Zarinpal.AspNetCore/GlobalUsings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
global using System.Net.Http.Json;
global using System.Text.Json;
global using System.Text.Json.Nodes;
global using Zarinpal.AspNetCore.Consts;
global using Zarinpal.AspNetCore.DTOs;
global using Zarinpal.AspNetCore.Enums;
global using Zarinpal.AspNetCore.Exceptions;
Expand All @@ -17,4 +18,4 @@
global using Zarinpal.AspNetCore.Models;
global using Zarinpal.AspNetCore.Models.Internal.Original;
global using Zarinpal.AspNetCore.Models.Internal.Sandbox;
global using Zarinpal.AspNetCore.Utilities;
global using Zarinpal.AspNetCore.Utilities;
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public async Task<ZarinpalRequestResultDTO> RequestAsync(ZarinpalRequestDTO requ
Amount = request.Amount,
Description = request.Description,
VerifyCallbackUrl = request.VerifyCallbackUrl,
Currency = _zarinpalOptions.Currency,
Email = !string.IsNullOrEmpty(request.Email) ? request.Email : "",
Mobile = !string.IsNullOrEmpty(request.Mobile) ? request.Mobile : "",
});
Expand Down
Loading

0 comments on commit 880a3ee

Please sign in to comment.