Files
docs/technical/TECH-05-API-INTEGRATION.md
T
masoodafar-web 421a651975 docs: Magic Wallet + VAT 10% documentation update
- All 14 totalDoc files updated with Magic Wallet additions
- MAGIC-WALLET-PLAN.md: Phase 1-6 checklist fully marked complete
- Business docs: Magic Wallet section, commission filter, new entities
- Payment docs: VAT 9%→10%, TransactionType 14+15, ZarinPal 4th usage
- Technical docs: UserWallet fields, ClubMembershipCycle, gRPC RPCs
- Overview docs: Magic flowchart, ER diagram, changelog, glossary, roadmap
2026-02-22 20:09:01 +03:30

12 KiB
Raw Blame History

🔌 API، Protobuf و یکپارچه‌سازی خارجی

منابع ادغام‌شده: FRONTOFFICE-CMS-API-COMPATIBILITY.md, REMAINING-TASKS.md, chatika-integration.md, payment-gateway.md, club-feature-management-services.md
آخرین بروزرسانی: اسفند ۱۴۰۴ (بروزرسانی: Magic Wallet gRPC RPCs)


۱. معماری ارتباطات

┌──────────────────────────────────────────────────────────────────┐
│                    External Services                              │
│  ┌─────────┐ ┌──────────┐ ┌─────────┐ ┌─────────┐              │
│  │ ZarinPal│ │ Kavenegar│ │ DayaLoan│ │ Chatika │              │
│  │ (IPG)   │ │ (SMS)    │ │ (Loan)  │ │ (AI)    │              │
│  └────┬────┘ └────┬─────┘ └────┬────┘ └────┬────┘              │
│       │           │            │            │                    │
│  ┌────▼───────────▼────────────▼────────────▼────┐              │
│  │              CMS Microservice                  │              │
│  │    (gRPC Server + Hangfire + EF Core)          │              │
│  └────────────────┬───────────────────────────────┘              │
│                   │ gRPC (Protobuf v3)                           │
│       ┌───────────┼───────────┐                                  │
│  ┌────▼────┐ ┌────▼────┐                                        │
│  │BackOffice│ │FrontOffice│                                      │
│  │(Blazor  │ │(Blazor   │                                       │
│  │ WASM)   │ │ Server)  │                                       │
│  └─────────┘ └──────────┘                                       │
└──────────────────────────────────────────────────────────────────┘

۲. gRPC Proto Definitions

۲.۱ لیست کامل سرویس‌ها

// ===== product.proto =====
service ProductService {
    rpc GetProducts (GetProductsRequest) returns (GetProductsResponse);
    rpc GetProductById (GetProductByIdRequest) returns (ProductMessage);
    rpc CreateProduct (CreateProductRequest) returns (CreateProductResponse);
    rpc UpdateProduct (UpdateProductRequest) returns (UpdateProductResponse);
    rpc DeleteProduct (DeleteProductRequest) returns (Empty);
    rpc GetProductsPaged (GetProductsPagedRequest) returns (GetProductsPagedResponse);
}

// ===== order.proto =====
service OrderService {
    rpc CreateOrder (CreateOrderRequest) returns (CreateOrderResponse);
    rpc GetOrders (GetOrdersRequest) returns (GetOrdersResponse);
    rpc GetOrderById (GetOrderByIdRequest) returns (OrderMessage);
    rpc UpdateOrderStatus (UpdateOrderStatusRequest) returns (Empty);
}

// ===== user.proto =====
service UserService {
    rpc Register (RegisterRequest) returns (AuthResponse);
    rpc Login (LoginRequest) returns (AuthResponse);
    rpc GetProfile (GetProfileRequest) returns (UserProfileMessage);
    rpc UpdateProfile (UpdateProfileRequest) returns (Empty);
    rpc SendOtp (SendOtpRequest) returns (SendOtpResponse);
    rpc VerifyOtp (VerifyOtpRequest) returns (VerifyOtpResponse);
}

// ===== club.proto =====
service ClubService {
    rpc GetNetworkTree (GetNetworkTreeRequest) returns (NetworkTreeResponse);
    rpc GetBalance (GetBalanceRequest) returns (BalanceResponse);
    rpc ReadContract (ReadContractRequest) returns (ContractResponse);
    rpc RequestContractOtp (RequestOtpRequest) returns (OtpResponse);
    rpc VerifyContractOtp (VerifyOtpRequest) returns (VerifyOtpResponse);
    rpc AcceptContract (AcceptContractRequest) returns (AcceptContractResponse);
    rpc GetClubFeatures (GetFeaturesRequest) returns (FeaturesResponse);
}

// ===== payment.proto =====
service PaymentService {
    rpc CreatePayment (CreatePaymentRequest) returns (CreatePaymentResponse);
    rpc VerifyPayment (VerifyPaymentRequest) returns (VerifyPaymentResponse);
    rpc GetPaymentStatus (PaymentStatusRequest) returns (PaymentStatusResponse);
}

// ===== blog.proto =====
service BlogService {
    rpc GetPosts (GetPostsRequest) returns (GetPostsResponse);
    rpc GetPostBySlug (GetPostBySlugRequest) returns (BlogPostMessage);
    rpc CreatePost (CreatePostRequest) returns (CreatePostResponse);
    rpc UpdatePost (UpdatePostRequest) returns (Empty);
    rpc DeletePost (DeletePostRequest) returns (Empty);
}

// ===== inventory.proto =====
service InventoryService {
    rpc GetInventory (GetInventoryRequest) returns (InventoryMessage);
    rpc UpdateStock (UpdateStockRequest) returns (Empty);
    rpc GetAllInventories (GetAllRequest) returns (InventoryListResponse);
}

// ===== sitepage.proto =====
service SitePageService {
    rpc GetPage (GetPageRequest) returns (SitePageMessage);
    rpc SaveSettings (SaveSettingsRequest) returns (Empty);
    rpc GetAllPages (Empty) returns (PageListResponse);
}

// ===== file.proto =====
service FileService {
    rpc Upload (stream UploadRequest) returns (UploadResponse);
    rpc Download (DownloadRequest) returns (stream DownloadResponse);
    rpc Delete (DeleteFileRequest) returns (Empty);
}

// ===== category.proto =====
service CategoryService {
    rpc GetCategories (GetCategoriesRequest) returns (CategoryListResponse);
    rpc CreateCategory (CreateCategoryRequest) returns (CreateCategoryResponse);
    rpc UpdateCategory (UpdateCategoryRequest) returns (Empty);
}

// ===== config.proto =====
service SystemConfigService {
    rpc GetConfig (GetConfigRequest) returns (ConfigResponse);
    rpc UpdateConfig (UpdateConfigRequest) returns (Empty);
    rpc GetAllConfigs (Empty) returns (ConfigListResponse);
}

// ===== userwallet.proto ===== (NEW — Magic Wallet)
service UserWalletService {
    rpc GetCustomerWallet (GetCustomerWalletRequest) returns (GetCustomerWalletResponse);
    rpc InitiateMagicCharge (InitiateMagicChargeRequest) returns (InitiateMagicChargeResponse);
    rpc GetMagicWalletStatus (GetMagicWalletStatusRequest) returns (MagicWalletStatusResponse);
}

۲.۲ Shared Messages

// ===== common.proto =====
message PaginationState {
    int32 skip = 1;
    int32 take = 2;
}

message PaginatedResponse {
    int32 totalCount = 1;
    int32 pageSize = 2;
    int32 currentPage = 3;
}

message Empty {}

۳. External Service Integration

۳.۱ ZarinPal (پرداخت)

public class ZarinPalService : IPaymentGateway
{
    // Config
    private readonly string _merchantId;
    private readonly bool _isSandbox;
    
    // Endpoints
    const string PAYMENT_URL = "https://api.zarinpal.com/pg/v4/payment/request.json";
    const string VERIFY_URL = "https://api.zarinpal.com/pg/v4/payment/verify.json";
    const string SANDBOX_URL = "https://sandbox.zarinpal.com/pg/v4/payment/request.json";
    
    // Flow
    // 1. CreatePayment → Authority token
    // 2. Redirect → https://www.zarinpal.com/pg/StartPay/{Authority}
    // 3. Callback → VerifyPayment(Authority, Amount)
    // 4. Result → RefID (reference number)
}

۳.۲ Kavenegar (SMS)

public class KavenegarService : ISmsService
{
    // Templates — فقط یک تمپلیت در کد موجود است
    const string OTP_TEMPLATE = "Afrino";  // تنها تمپلیت استفاده‌شده
    // Sender: "1000001110100"
    
    // Rate Limiting
    // ۱ SMS per phone per 60 seconds
    // ۵ SMS per phone per hour
    // ۲۰ SMS per phone per day
    
    public async Task SendOtpAsync(string phone, string code)
    {
        await _api.VerifyLookup(phone, code, OTP_TEMPLATE);
    }
}

۳.۳ Daya Loan (وام)

public class DayaLoanService : ILoanService
{
    // Hangfire job — هر ۲۰ دقیقه (*/20 * * * *)
    // Polly retry: 3 attempts, exponential backoff (2s, 4s, 8s)
    // Mock mode for staging (auto-approve)
    
    public async Task<LoanResult> RequestLoanAsync(Guid userId, decimal amount)
    {
        if (_options.UseMock)
            return LoanResult.Approved(amount);
            
        var response = await _httpClient.PostAsync(
            $"{_baseUrl}/api/loans/request",
            new { UserId = userId, Amount = amount });
        
        return MapResponse(response);
    }
}

۳.۴ Chatika (AI)

public class ChatikaService : IAiChatService
{
    // Hangfire job — هر ۵ دقیقه
    // Polly retry: 3 attempts
    // Only for active club members
    
    public async Task<string> GetResponseAsync(string userMessage)
    {
        var response = await _httpClient.PostAsync(
            $"{_baseUrl}/api/chat",
            new { Message = userMessage });
        
        return response.Content.ReadAsStringAsync();
    }
}

۴. API Compatibility Layer

۴.۱ FrontOffice Service Pattern

// هر سرویس در FrontOffice یک wrapper بر gRPC client است
public class ProductService : IProductService
{
    private readonly ProductServiceClient _client;
    
    public ProductService(ProductServiceClient client)
    {
        _client = client;
    }
    
    public async Task<ProductListResult> GetProductsPagedAsync(
        int skip, int take, Guid? categoryId = null, string? search = null)
    {
        try
        {
            var request = new GetProductsPagedRequest {
                Pagination = new PaginationState { Skip = skip, Take = take },
                CategoryId = categoryId?.ToString() ?? "",
                SearchTerm = search ?? ""
            };
            
            var response = await _client.GetProductsPagedAsync(request);
            
            return new ProductListResult(
                response.Products.Select(MapToDto).ToList(),
                response.TotalCount);
        }
        catch (RpcException ex) when (ex.StatusCode == StatusCode.Unavailable)
        {
            // CMS is down — show cached data or error
            throw new ServiceUnavailableException("CMS service unavailable");
        }
    }
}

۴.۲ Error Handling

gRPC Status HTTP Equivalent Handling
OK 200 Return data
NotFound 404 Show "not found" message
InvalidArgument 400 Show validation errors
Unauthenticated 401 Redirect to login
PermissionDenied 403 Show "access denied"
Unavailable 503 Show "service down"
Internal 500 Show generic error

۵. Proto Package Distribution

flowchart TD
    A["CMS/src/Protos/*.proto"] --> B["pack-protos.sh"]
    B --> C["Foursat.CMSMicroservice.Protobuf.nupkg\nv1.0.x"]
    C --> D["Push to BaGet / Nexus"]
    D --> E["BackOffice\nPackageReference"]
    D --> F["FrontOffice\nProjectReference ✅"]

⚠️ FrontOffice از NuGet package به ProjectReference مستقیم سوییچ شده (برای دسترسی به پروتوهای جدید Magic Wallet)


۶. Remaining Tasks / Integration Gaps

آیتم اولویت وضعیت
Product Bundle API Medium Proto + Handler needed
Manual Payment API Low Design only
SignalR for Chatika Low Replace polling
File upload streaming Done
Blog search Done
Inventory autocomplete Done
Lazy load pagination Done
Rate limiting (API level) Medium
API versioning Low