API پست ایران با دات نت

تاریخ: 1404/12/5 ساعت: 1:13 بازدید: 12

API پست ایران با دات نت چیست و چرا باید یاد بگیریم؟

اگر یک فروشگاه آنلاین دارید یا یک سیستم مدیریت سفارش می‌سازید، احتمالاً با این مشکل آشنا هستید: چطور می‌توانیم به صورت خودکار مرسوله‌های پستی را ثبت و پیگیری کنیم؟ پاسخ این سوال، استفاده از API رسمی پست جمهوری اسلامی ایران است.

پست ایران یک وب‌سرویس (Web Service) رسمی دارد که به توسعه‌دهندگان اجازه می‌دهد سیستم‌های نرم‌افزاری خود را مستقیماً به سامانه پستی متصل کنند. شما با استفاده از این API می‌توانید:

  • بارکد مرسوله تولید و ثبت کنید
  • وضعیت مرسوله را به‌صورت لحظه‌ای پیگیری کنید
  • هزینه ارسال را محاسبه کنید
  • لیست خدمات پستی موجود را دریافت کنید
  • اطلاعات آدرس و کدپستی را اعتبارسنجی کنید

در این مقاله قدم‌به‌قدم یاد می‌گیرید چطور با C# و ASP.NET به این API وصل شوید، کدهای آماده دریافت کنید و رایج‌ترین خطاها را رفع کنید.

پیش‌نیازهای اتصال به وب‌سرویس پست ایران

قبل از نوشتن حتی یک خط کد، باید چند چیز را آماده کنید. این مرحله را جدی بگیرید چون بسیاری از توسعه‌دهندگان به دلیل رد شدن همین مرحله ساعت‌ها وقت تلف می‌کنند.

۱. دریافت نام کاربری و رمز API

برای استفاده از وب‌سرویس پست ایران، باید از طریق سامانه رسمی پست ثبت‌نام کنید و Credentials دریافت کنید. این اطلاعات شامل:

  • Username: نام کاربری اختصاصی شما
  • Password: رمز عبور سرویس
  • ServiceCode: کد سرویس پستی که از آن استفاده می‌کنید

۲. ابزارهای مورد نیاز توسعه

  • Visual Studio 2019/2022 یا VS Code
  • .NET 6 / .NET 8 (توصیه شده برای پروژه‌های جدید)
  • پکیج Newtonsoft.Json یا System.Text.Json
  • ابزار تست API مثل Postman برای تست اولیه

آشنایی با ساختار API پست ایران

API پست ایران از پروتکل SOAP (Simple Object Access Protocol) و همچنین در نسخه‌های جدیدتر از REST پشتیبانی می‌کند. برای پروژه‌های دات‌نتی، کار با هر دو رویکرد امکان‌پذیر است، اما SOAP به دلیل WSDL ساختارمند، خطاهای کمتری در پیاده‌سازی ایجاد می‌کند.

متدهای اصلی وب‌سرویس پست ایران

  • PostWebService.AddParcel: ثبت مرسوله جدید و دریافت بارکد
  • PostWebService.GetParcelStatus: دریافت وضعیت مرسوله با بارکد
  • PostWebService.GetPostPrice: محاسبه هزینه ارسال بر اساس وزن و مقصد
  • PostWebService.GetCityList: دریافت لیست شهرها و کدهای پستی
  • PostWebService.ValidatePostCode: اعتبارسنجی کد پستی

پیاده‌سازی API پست ایران با C# — کد کامل و آماده

حالا وارد بخش اصلی می‌شویم. در ادامه کدهای کامل و تست‌شده برای اتصال به سرویس پستی با دات نت را می‌بینید.

مرحله اول: افزودن Service Reference

اگر از رویکرد SOAP استفاده می‌کنید، باید ابتدا WSDL پست ایران را به پروژه اضافه کنید:


// در Visual Studio:

// راست‌کلیک روی پروژه > Add > Service Reference

// آدرس WSDL پست ایران را وارد کنید

// نام فضای نام: IranPostService

مرحله دوم: مدل‌های داده (Models)


// Models/PostParcelModel.cs

public class PostParcelRequest

{

public string SenderName { get; set; }

public string SenderAddress { get; set; }

public string SenderPostCode { get; set; }

public string SenderTel { get; set; }

public string ReceiverName { get; set; }

public string ReceiverAddress { get; set; }

public string ReceiverPostCode { get; set; }

public string ReceiverTel { get; set; }

public decimal Weight { get; set; } // وزن به گرم

public string ServiceType { get; set; } // نوع سرویس: پیشتاز، ویژه، …

public decimal CODAmount { get; set; } // مبلغ پرداخت در مقصد

public string Description { get; set; }

}

public class PostParcelResponse

{

public bool IsSuccess { get; set; }

public string Barcode { get; set; }

public string TrackingCode { get; set; }

public string ErrorMessage { get; set; }

public decimal PostPrice { get; set; }

}

مرحله سوم: سرویس اتصال به API


// Services/IranPostService.cs

using System.Net.Http;

using System.Text;

using System.Text.Json;

public class IranPostApiService

{

private readonly HttpClient _httpClient;

private readonly string _username;

private readonly string _password;

private readonly string _baseUrl = “https://www.post.ir/api/”;

public IranPostApiService(HttpClient httpClient, IConfiguration config)

{

_httpClient = httpClient;

_username = config[“IranPost:Username”];

_password = config[“IranPost:Password”];

}

// متد احراز هویت و دریافت Token

public async Task GetAuthTokenAsync()

{

var authData = new

{

username = _username,

password = _password

};

var content = new StringContent(

JsonSerializer.Serialize(authData),

Encoding.UTF8,

“application/json”

);

var response = await _httpClient.PostAsync($“{_baseUrl}auth/token”, content);

if (response.IsSuccessStatusCode)

{

var result = await response.Content.ReadAsStringAsync();

var tokenData = JsonSerializer.Deserialize(result);

return tokenData?.Token;

}

throw new Exception($“خطا در احراز هویت: {response.StatusCode}”);

}

// متد ثبت مرسوله

public async Task AddParcelAsync(PostParcelRequest request)

{

try

{

var token = await GetAuthTokenAsync();

_httpClient.DefaultRequestHeaders.Authorization =

new System.Net.Http.Headers.AuthenticationHeaderValue(“Bearer”, token);

var content = new StringContent(

JsonSerializer.Serialize(request),

Encoding.UTF8,

“application/json”

);

var response = await _httpClient.PostAsync($“{_baseUrl}parcel/add”, content);

var responseBody = await response.Content.ReadAsStringAsync();

if (response.IsSuccessStatusCode)

{

var result = JsonSerializer.Deserialize(responseBody);

result.IsSuccess = true;

return result;

}

return new PostParcelResponse

{

IsSuccess = false,

ErrorMessage = $“کد خطا: {response.StatusCode} - {responseBody}”

};

}

catch (Exception ex)

{

return new PostParcelResponse

{

IsSuccess = false,

ErrorMessage = $“خطای سیستمی: {ex.Message}”

};

}

}

// متد پیگیری مرسوله

public async Task TrackParcelAsync(string barcode)

{

var token = await GetAuthTokenAsync();

_httpClient.DefaultRequestHeaders.Authorization =

new System.Net.Http.Headers.AuthenticationHeaderValue(“Bearer”, token);

var response = await _httpClient

.GetAsync($“{_baseUrl}parcel/track/{barcode}”);

if (response.IsSuccessStatusCode)

{

var result = await response.Content.ReadAsStringAsync();

return JsonSerializer.Deserialize(result);

}

throw new Exception($“مرسوله با بارکد {barcode} یافت نشد.”);

}

// متد محاسبه هزینه ارسال

public async Task CalculatePostPriceAsync(

string originPostCode,

string destPostCode,

decimal weightInGrams,

string serviceType)

{

var token = await GetAuthTokenAsync();

_httpClient.DefaultRequestHeaders.Authorization =

new System.Net.Http.Headers.AuthenticationHeaderValue(“Bearer”, token);

var queryString = $“origin={originPostCode}&dest={destPostCode}” +

$“&weight={weightInGrams}&service={serviceType}”;

var response = await _httpClient

.GetAsync($“{_baseUrl}price/calculate?{queryString}”);

if (response.IsSuccessStatusCode)

{

var result = await response.Content.ReadAsStringAsync();

var priceData = JsonSerializer.Deserialize(result);

return priceData?.Price ?? 0;

}

throw new Exception(“خطا در محاسبه هزینه ارسال”);

}

}

مرحله چهارم: تنظیمات appsettings.json


{

“IranPost”: {

“Username”: “your_username_here”,

“Password”: “your_password_here”,

“ServiceCode”: “your_service_code”,

“BaseUrl”: “https://www.post.ir/api/”

}

}

مرحله پنجم: ثبت سرویس در Program.cs


// Program.cs (.NET 6+)

builder.Services.AddHttpClient(client =>

{

client.BaseAddress = new Uri(builder.Configuration[“IranPost:BaseUrl”]);

client.Timeout = TimeSpan.FromSeconds(30);

client.DefaultRequestHeaders.Add(“Accept”, “application/json”);

});

// یا با Policy (توصیه شده برای Production)

builder.Services.AddHttpClient()

.AddTransientHttpErrorPolicy(p =>

p.WaitAndRetryAsync(3, _ => TimeSpan.FromMilliseconds(600)));

استفاده در Controller — نمونه کامل


// Controllers/ShippingController.cs

[ApiController]

[Route(“api/[controller]”)]

public class ShippingController : ControllerBase

{

private readonly IranPostApiService _postService;

private readonly ILogger _logger;

public ShippingController(

IranPostApiService postService,

ILogger logger)

{

_postService = postService;

_logger = logger;

}

[HttpPost(“register”)]

public async Task RegisterParcel([FromBody] PostParcelRequest model)

{

if (!ModelState.IsValid)

return BadRequest(ModelState);

var result = await _postService.AddParcelAsync(model);

if (result.IsSuccess)

{

_logger.LogInformation(

“مرسوله با بارکد {Barcode} ثبت شد”, result.Barcode);

return Ok(result);

}

_logger.LogError(“خطا در ثبت مرسوله: {Error}”, result.ErrorMessage);

return BadRequest(result.ErrorMessage);

}

[HttpGet(“track/{barcode}”)]

public async Task TrackParcel(string barcode)

{

if (string.IsNullOrWhiteSpace(barcode))

return BadRequest(“بارکد نمی‌تواند خالی باشد”);

var status = await _postService.TrackParcelAsync(barcode);

return Ok(status);

}

[HttpGet(“price”)]

public async Task GetPostPrice(

[FromQuery] string origin,

[FromQuery] string dest,

[FromQuery] decimal weight,

[FromQuery] string service = “normal”)

{

var price = await _postService

.CalculatePostPriceAsync(origin, dest, weight, service);

return Ok(new { Price = price, Currency = “ریال” });

}

}

رایج‌ترین خطاها در API پست ایران و راه حل آن‌ها

بر اساس تجربه توسعه‌دهندگان ایرانی، این خطاها بیشترین تکرار را دارند:

خطای ۴۰۱ - Unauthorized

علت: نام کاربری یا رمز عبور اشتباه است یا Token منقضی شده.

راه‌حل: مطمئن شوید Credentials را درست از پنل پست دریافت کرده‌اید. Token را قبل از هر درخواست تجدید کنید.

خطای ۴۰۰ - Bad Request روی کدپستی

علت: کدپستی وارد شده معتبر نیست یا فرمت آن اشتباه است.

راه‌حل: کدپستی باید دقیقاً ۱۰ رقم باشد. از متد ValidatePostCode برای اعتبارسنجی قبل از ارسال استفاده کنید.

خطای Timeout در محیط Production

علت: سرورهای پست ایران گاهی کند پاسخ می‌دهند.

راه‌حل: از Retry Policy استفاده کنید (نمونه کد در Program.cs بالا) و Timeout را به ۴۵ ثانیه تنظیم کنید.

مشکل SSL Certificate در دات نت


// فقط در محیط Development - هرگز در Production استفاده نکنید!

builder.Services.AddHttpClient()

.ConfigurePrimaryHttpMessageHandler(() =>

new HttpClientHandler

{

ServerCertificateCustomValidationCallback =

HttpClientHandler.DangerousAcceptAnyServerCertificateValidator

});

بهترین شیوه‌ها (Best Practices) برای استفاده از API پست در محیط Production

  • Caching توکن: توکن احراز هویت را Cache کنید تا در هر درخواست دوباره لاگین نکنید. از IMemoryCache یا IDistributedCache استفاده کنید.
  • Retry Policy: حتماً از Polly برای مدیریت خطاهای شبکه استفاده کنید.
  • لاگ‌گیری: تمام درخواست‌ها و پاسخ‌ها را لاگ کنید تا بتوانید مشکلات را ردیابی کنید.
  • اطلاعات حساس: Username و Password را هیچ‌وقت در کد قرار ندهید. از Secret Manager یا متغیرهای محیطی استفاده کنید.
  • تست محیط: ابتدا در محیط Sandbox/Test پست ایران پیاده‌سازی را تست کنید.

🚀 می‌خواهید سایت شما در صفحه اول گوگل باشد؟

پیاده‌سازی API پست ایران فقط یک قدم از راه‌اندازی یک فروشگاه موفق است. اما بدون سئوی حرفه‌ای، هیچ‌کس سایت شما را پیدا نمی‌کند و این تلاش‌ها به هدر می‌رود.

آیا می‌خواهید سایت شما هم مثل رقبا در صفحه اول گوگل باشد و زنگ‌خورهایتان چند برابر شود؟ سئوی سایت خود را به متخصصان ما بسپارید.

📞 همین حالا برای مشاوره رایگان با ما تماس بگیرید:
09190994063  |  09376846692

اتصال به وب‌سرویس SOAP پست ایران — رویکرد کلاسیک

برخی سیستم‌های قدیمی‌تر هنوز از پروتکل SOAP استفاده می‌کنند. برای دات نت، کار با SOAP هم بسیار ساده است:


// استفاده از Connected Service / WSDL

// بعد از اضافه کردن Service Reference، کد به این شکل می‌شود:

using IranPostService; // namespace ایجاد شده توسط Visual Studio

public class SoapPostService

{

public async Task AddParcelViaSoapAsync(PostParcelRequest request)

{

var client = new PostWebServiceClient(

PostWebServiceClient.EndpointConfiguration.PostWebServiceSoap

);

var soapRequest = new AddParcelRequest

{

Username = “your_username”,

Password = “your_password”,

ReceiverName = request.ReceiverName,

ReceiverAddress = request.ReceiverAddress,

ReceiverPostCode = request.ReceiverPostCode,

Weight = (int)request.Weight,

ServiceType = request.ServiceType

};

var response = await client.AddParcelAsync(soapRequest);

if (response.ResultCode == “0”)

return response.Barcode;

throw new Exception($“خطای پست: {response.ResultDescription}”);

}

}

پیاده‌سازی Cache توکن با IMemoryCache


public class IranPostApiService

{

private readonly IMemoryCache _cache;

private const string TOKEN_CACHE_KEY = “IranPost_AuthToken”;

public IranPostApiService(HttpClient httpClient,

IConfiguration config, IMemoryCache cache)

{

_httpClient = httpClient;

_cache = cache;

// …

}

public async Task GetAuthTokenWithCacheAsync()

{

if (_cache.TryGetValue(TOKEN_CACHE_KEY, out string cachedToken))

return cachedToken;

var freshToken = await GetAuthTokenAsync();

// توکن را برای ۲۳ ساعت Cache کنید (معمولاً توکن‌ها ۲۴ ساعت اعتبار دارند)

_cache.Set(TOKEN_CACHE_KEY, freshToken, TimeSpan.FromHours(23));

return freshToken;

}

}

💡 نکته مهم برای فروشگاه‌های آنلاین

اگر فروشگاه اینترنتی دارید و می‌خواهید ارسال پست را کاملاً اتوماتیک کنید، علاوه بر پیاده‌سازی API، باید سایت شما در گوگل دیده شود تا اصلاً سفارشی وجود داشته باشد! سئوی سایت شما مستقیماً روی تعداد سفارش‌هایتان تأثیر می‌گذارد. برای مشاوره رایگان با شماره‌های 09190994063 یا 09376846692 تماس بگیرید.

تست واحد (Unit Test) برای سرویس پست ایران


// Tests/IranPostServiceTests.cs

using Moq;

using Xunit;

public class IranPostServiceTests

{

[Fact]

public async Task AddParcel_WithValidData_ShouldReturnBarcode()

{

// Arrange

var mockHttpClient = new Mock();

// … تنظیم Mock

var service = new IranPostApiService(mockHttpClient.Object,

mockConfig.Object, mockCache.Object);

var request = new PostParcelRequest

{

SenderName = “علی محمدی”,

SenderPostCode = “1234567890”,

ReceiverName = “رضا احمدی”,

ReceiverPostCode = “9876543210”,

Weight = 500

};

// Act

var result = await service.AddParcelAsync(request);

// Assert

Assert.True(result.IsSuccess);

Assert.NotNull(result.Barcode);

}

}

جمع‌بندی

اتصال به API پست ایران با دات نت با رعایت ساختار صحیح، کاری نسبتاً ساده است. در این مقاله یاد گرفتیم:

  • چطور احراز هویت کنیم و توکن دریافت کنیم
  • چطور مرسوله ثبت کنیم و بارکد دریافت کنیم
  • چطور پیگیری مرسوله را پیاده‌سازی کنیم
  • چطور هزینه ارسال را به صورت داینامیک محاسبه کنیم
  • رایج‌ترین خطاها و راه‌حل‌های عملی آن‌ها

سوالات متداول درباره API پست ایران با دات نت

۱. آیا API پست ایران رایگان است؟

استفاده از API پست ایران نیازمند عقد قرارداد با اداره پست است. برای مشتریان عمده و فروشگاه‌های اینترنتی، پست ایران امکان دسترسی به وب‌سرویس را فراهم می‌کند. هزینه‌ها بسته به حجم ارسال و نوع قرارداد متفاوت است. برای اطلاعات دقیق‌تر با اداره پست منطقه خود تماس بگیرید.

۲. آیا می‌توان از API پست ایران در ASP.NET Core 8 استفاده کرد؟

بله، کاملاً امکان‌پذیر است. کدهای نشان داده شده در این مقاله با .NET 6، .NET 7 و .NET 8 سازگار هستند. فقط کافی است پکیج‌های مربوطه را نصب کنید و از IHttpClientFactory استفاده کنید که در Program.cs توضیح داده شد.

۳. چطور می‌توانم پیگیری بارکد پست ایران را به سایتم اضافه کنم؟

با استفاده از متد TrackParcelAsync که در این مقاله معرفی شد، می‌توانید یک صفحه پیگیری مرسوله در سایت خود بسازید. کافی است شماره بارکد مرسوله را از کاربر بگیرید، به API بفرستید و نتیجه را نمایش دهید. این کار با یک Controller Action و یک View ساده در ASP.NET MVC انجام می‌شود.

۴. تفاوت SOAP و REST در API پست ایران چیست؟ کدام را انتخاب کنم؟

پست ایران هر دو پروتکل را پشتیبانی می‌کند. برای پروژه‌های جدید با .NET 6 به بالا، REST API توصیه می‌شود چون سبک‌تر، سریع‌تر و debug کردنش آسان‌تر است. اگر سیستم قدیمی دارید که از SOAP استفاده می‌کند، می‌توانید با Connected Service در Visual Studio به سادگی WSDL را import کنید.

۵. آیا می‌توانم API پست ایران را با WooCommerce یا فروشگاه وردپرسی استفاده کنم؟

اگر سایت شما وردپرس است، نیاز به دات نت ندارید. اما اگر بک‌اند جداگانه‌ای با ASP.NET دارید که به وردپرس متصل است، کاملاً می‌توانید از این کدها استفاده کنید. همچنین پلاگین‌های اختصاصی وردپرس برای پست ایران هم وجود دارند که نیازی به کدنویسی ندارند.

۶. اگر سرور پست ایران Down بود، چطور سایتم را مدیریت کنم؟

این یک نگرانی رایج است. توصیه می‌شود از Circuit Breaker Pattern با Polly استفاده کنید. همچنین سفارش‌های دریافتی را ابتدا در Database ذخیره کنید و بعد به صورت Background Job به API پست بفرستید. این رویکرد مقاومت سیستم شما در برابر خطاهای خارجی را بسیار بالا می‌برد.