Ehsan.ZarinPal.SDK
2.0.2
dotnet add package Ehsan.ZarinPal.SDK --version 2.0.2
NuGet\Install-Package Ehsan.ZarinPal.SDK -Version 2.0.2
<PackageReference Include="Ehsan.ZarinPal.SDK" Version="2.0.2" />
<PackageVersion Include="Ehsan.ZarinPal.SDK" Version="2.0.2" />
<PackageReference Include="Ehsan.ZarinPal.SDK" />
paket add Ehsan.ZarinPal.SDK --version 2.0.2
#r "nuget: Ehsan.ZarinPal.SDK, 2.0.2"
#:package Ehsan.ZarinPal.SDK@2.0.2
#addin nuget:?package=Ehsan.ZarinPal.SDK&version=2.0.2
#tool nuget:?package=Ehsan.ZarinPal.SDK&version=2.0.2
ZarinPal .NET SDK
A comprehensive .NET SDK for integrating with ZarinPal payment gateway services. This SDK provides an easy-to-use interface for processing payments, refunds, transaction inquiries, and more.
Note: All operations can be called directly on the
zarinPalinstance (e.g.await zarinPal.CreateAsync(...)). The resource-based methods (e.g.await zarinPal.Payments.CreateAsync(...)) still work and are fully supported for backward compatibility.
Table of Contents
Target Frameworks
This SDK multi-targets .NET 8.0 and .NET Standard 2.0, making it compatible with:
- .NET 8.0+ (.NET 8, .NET 9, etc.)
- .NET Core 2.0+ / .NET 5, 6, 7
- .NET Framework 4.6.1+
Installation
To install the ZarinPal SDK :
1- Easily add it via NuGet package manager gallery by searching:
Ehsan.ZarinPal.SDK
2- Run this command:
dotnet add package Ehsan.ZarinPal.SDK
3- Or in PMC:
NuGet\Install-Package Ehsan.ZarinPal.SDK
Configuration
To use the SDK, you can configure it with Dependency Injection using IHttpClientFactory:
using ZarinPal.Extensions;
builder.Services.AddZarinPal(config =>
{
config.MerchantId = builder.Configuration["ZarinPal:MerchantId"] ?? "00000000-0000-0000-0000-000000000000";
config.AccessToken = builder.Configuration["ZarinPal:AccessToken"] ?? "";
config.Sandbox = builder.Configuration.GetValue<bool>("ZarinPal:Sandbox", true);
config.UserAgent = "MyCustomApp/v1.0"; // Optional custom user-agent
config.Timeout = TimeSpan.FromSeconds(30); // Optional timeout
});
To inject and use it in a controller or service:
using ZarinPal.Interfaces;
public class PaymentController : ControllerBase
{
private readonly IZarinPal _zarinPal;
public PaymentController(IZarinPal zarinPal)
{
_zarinPal = zarinPal;
}
}
Configuration Options
MerchantId: Your merchant ID provided by ZarinPal (UUID format)AccessToken: Access token for authentication (used for GraphQL requests)Sandbox: Whether to use the sandbox environment (default: false)UserAgent: Custom HTTP User-Agent header (default:"ZarinPalSdk/v1 (.NET)")Timeout: Timeout for HTTP requests (default: 30 seconds)
Usage
All operations are available directly on the zarinPal instance and return strongly-typed response models. All asynchronous methods accept an optional CancellationToken.
The table below maps each direct method to its equivalent resource-based method:
| Direct method | Resource-based equivalent |
|---|---|
zarinPal.CreateAsync(paymentRequest) |
zarinPal.Payments.CreateAsync(paymentRequest) |
zarinPal.CalculateFeeAsync(feeRequest) |
zarinPal.Payments.FeeCalculationAsync(feeRequest) |
zarinPal.GetRedirectUrl(authority) |
zarinPal.Payments.GetRedirectUrl(authority) |
zarinPal.VerifyAsync(verificationRequest) |
zarinPal.Verifications.VerifyAsync(verificationRequest) |
zarinPal.InquireAsync(inquiryRequest) |
zarinPal.Inquiries.InquireAsync(inquiryRequest) |
zarinPal.ReverseAsync(reversalRequest) |
zarinPal.Reversals.ReverseAsync(reversalRequest) |
zarinPal.ListTransactionsAsync(listRequest) |
zarinPal.Transactions.ListAsync(listRequest) |
zarinPal.ListUnverifiedAsync() |
zarinPal.Unverified.ListAsync() |
zarinPal.CreateRefundAsync(refundRequest) |
zarinPal.Refunds.CreateAsync(refundRequest) |
zarinPal.RetrieveRefundAsync(refundId) |
zarinPal.Refunds.RetrieveAsync(refundId) |
zarinPal.ListRefundsAsync(listRequest) |
zarinPal.Refunds.ListAsync(listRequest) |
Creating a Payment
To create a payment request:
using ZarinPal.Models;
var paymentRequest = new PaymentRequest
{
Amount = 10000, // Amount in Rials
CallbackUrl = "https://yoursite.com/callback",
Description = "Payment description",
Mobile = "09120000000", // Optional: Customer mobile number
Email = "customer@example.com" // Optional: Customer email
};
try
{
PaymentResult result = await zarinPal.CreateAsync(paymentRequest);
// Redirect user to payment gateway page
var paymentUrl = zarinPal.GetRedirectUrl(result.Authority);
}
catch (Exception ex)
{
Console.WriteLine($"Error creating payment: {ex.Message}");
}
Verifying a Payment
After a payment attempt, verify the transaction:
using ZarinPal.Models;
var verificationRequest = new VerificationRequest
{
Amount = 10000, // Amount in Rials (must match payment amount)
Authority = "A00000000000000000000000000000000000" // Authority from callback query
};
try
{
VerifyResult result = await zarinPal.VerifyAsync(verificationRequest);
if (result.Code == 100 || result.Code == 101) // Success code
{
Console.WriteLine($"Payment verified successfully. Ref ID: {result.RefId}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error verifying payment: {ex.Message}");
}
Inquiring Transaction Status
To inquire about the status of a transaction:
using ZarinPal.Models;
var inquiryRequest = new InquiryRequest
{
Authority = "A00000000000000000000000000000000000"
};
try
{
InquiryResult result = await zarinPal.InquireAsync(inquiryRequest);
Console.WriteLine($"Transaction Code: {result.Code}, Status: {result.Status}, RefId: {result.RefId}");
}
catch (Exception ex)
{
Console.WriteLine($"Error inquiring transaction: {ex.Message}");
}
Reversing a Transaction
To reverse a transaction:
using ZarinPal.Models;
var reversalRequest = new ReversalRequest
{
Authority = "A00000000000000000000000000000000000"
};
try
{
ReversalResult result = await zarinPal.ReverseAsync(reversalRequest);
Console.WriteLine($"Reversal Code: {result.Code}, Message: {result.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"Error reversing transaction: {ex.Message}");
}
Listing Transactions
To retrieve a list of transactions via GraphQL:
using ZarinPal.Models;
var transactionListRequest = new TransactionListRequest
{
TerminalId = "TERMINAL_ID",
Limit = 10,
Offset = 0
};
try
{
List<TransactionItem> items = await zarinPal.ListTransactionsAsync(transactionListRequest);
foreach (var item in items)
{
Console.WriteLine($"ID: {item.Id}, Status: {item.Status}, Amount: {item.Amount}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error listing transactions: {ex.Message}");
}
Listing Unverified Payments
To retrieve a list of unverified payments:
try
{
UnverifiedResult result = await zarinPal.ListUnverifiedAsync();
if (result.Authorities != null)
{
foreach (var item in result.Authorities)
{
Console.WriteLine($"Authority: {item.Authority}, Amount: {item.Amount}");
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Error listing unverified payments: {ex.Message}");
}
Creating a Refund
To create a refund request via GraphQL:
using ZarinPal.Models;
using ZarinPal.Enums;
var refundRequest = new RefundCreateRequest
{
SessionId = "SESSION_ID",
Amount = 1000,
Description = "Refund description",
Method = RefundMethod.PAYA,
Reason = "CUSTOMER_REQUEST"
};
try
{
RefundCreateResult result = await zarinPal.CreateRefundAsync(refundRequest);
Console.WriteLine($"Refund created with ID: {result.Id}, Amount: {result.Amount}");
}
catch (Exception ex)
{
Console.WriteLine($"Error creating refund: {ex.Message}");
}
Fee Calculation
To calculate the transaction fee before creating a payment:
using ZarinPal.Models;
var feeCalculationRequest = new FeeCalculationRequest
{
MerchantId = "YOUR_MERCHANT_ID", // Optional if configured globally
Amount = 10000, // Amount in Rials
Currency = "IRR"
};
try
{
FeeCalculationResult result = await zarinPal.CalculateFeeAsync(feeCalculationRequest);
Console.WriteLine($"Fee: {result.Fee}, FeeType: {result.FeeType}");
}
catch (Exception ex)
{
Console.WriteLine($"Error calculating fee: {ex.Message}");
}
Error Handling
The SDK throws specific exceptions for different error scenarios:
ValidationException: Thrown when input parameter validation fails.ResponseException: Thrown when HTTP or GraphQL responses contain network errors, unparseable bodies, or empty response payloads (resource methods throw instead of returning empty objects).ZarinPalApiException: Thrown when ZarinPal API returns a business error code (e.g.,code != 100and101). Contains aCodeproperty with the error code.
try
{
var result = await zarinPal.CreateAsync(paymentRequest);
}
catch (ZarinPal.Exceptions.ValidationException validationEx)
{
Console.WriteLine($"Validation error: {validationEx.Message}");
}
catch (ZarinPal.Exceptions.ZarinPalApiException apiEx)
{
Console.WriteLine($"ZarinPal API error code {apiEx.Code}: {apiEx.Message}");
}
catch (ZarinPal.Exceptions.ResponseException responseEx)
{
Console.WriteLine($"API error: {responseEx.Message}, Status Code: {responseEx.StatusCode}");
}
catch (Exception ex)
{
Console.WriteLine($"General error: {ex.Message}");
}
Sandbox Environment
For testing purposes, you can use ZarinPal's sandbox environment by setting Sandbox = true in the configuration:
var config = new Config
{
MerchantId = "YOUR_SANDBOX_MERCHANT_ID",
AccessToken = "YOUR_SANDBOX_ACCESS_TOKEN",
Sandbox = true // Use sandbox environment
};
License
This project is licensed under the MIT License - see the LICENSE.txt file for details.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Microsoft.Extensions.DependencyInjection (>= 8.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Http (>= 8.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.0)
- System.Text.Json (>= 8.0.5)
-
net8.0
- Microsoft.Extensions.DependencyInjection (>= 8.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Http (>= 8.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.