FourTwenty.LokoMerchant.Client
1.0.15
dotnet add package FourTwenty.LokoMerchant.Client --version 1.0.15
NuGet\Install-Package FourTwenty.LokoMerchant.Client -Version 1.0.15
<PackageReference Include="FourTwenty.LokoMerchant.Client" Version="1.0.15" />
<PackageVersion Include="FourTwenty.LokoMerchant.Client" Version="1.0.15" />
<PackageReference Include="FourTwenty.LokoMerchant.Client" />
paket add FourTwenty.LokoMerchant.Client --version 1.0.15
#r "nuget: FourTwenty.LokoMerchant.Client, 1.0.15"
#:package FourTwenty.LokoMerchant.Client@1.0.15
#addin nuget:?package=FourTwenty.LokoMerchant.Client&version=1.0.15
#tool nuget:?package=FourTwenty.LokoMerchant.Client&version=1.0.15
FourTwenty.LokoMerchant.Client
.NET client library for the Loko Merchant API, simplifying delivery order management, pricing queries, and webhook integration in C#.
Features
- Store Management: Update store status (pause/unpause) and manage schedules
- Webhook Management: Create, update, delete webhook subscriptions and retrieve events
- Menu Management: Import products, offers, categories, and complete menu structures
- OAuth 2.0 Authentication: Secure client credentials authentication
- Async/Await Support: Modern C# async patterns throughout
- Strongly Typed: Complete type safety with comprehensive models
- Dependency Injection: Easy integration with .NET Core DI container
Installation
Install via NuGet Package Manager:
dotnet add package FourTwenty.LokoMerchant.Client
Or via Package Manager Console in Visual Studio:
Install-Package FourTwenty.LokoMerchant.Client
Quick Start
Basic Usage
using FourTwenty.LokoMerchant.Client;
using FourTwenty.LokoMerchant.Client.Models;
// Configure HttpClient with base URL and authentication
var httpClient = new HttpClient();
httpClient.BaseAddress = new Uri("https://merchant-api.silpo.ua/");
// Add bearer token to requests (see Authentication section below)
httpClient.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "your-access-token");
// Create the client
var client = new LokoMerchantClient(httpClient);
// Use the client
await client.Store.UpdateStatus("store-id", StoreStatus.Unpause, new BranchStatusBodyRequest());
var subscriptions = await client.Webhooks.GetSubscriptions();
var importResult = await client.Menu.ImportProducts(new ImportProductRequest());
Authentication
The Loko Merchant API uses OAuth 2.0 client credentials flow. Here's how to set up authentication:
using FourTwenty.LokoMerchant.Client;
using FourTwenty.LokoMerchant.Client.Identity;
// Create identity client for authentication
var identityHttpClient = new HttpClient { BaseAddress = new Uri("https://auth.silpo.ua/") };
var identityClient = new LokoMerchantIdentityClient(identityHttpClient);
// Get access token
var config = new LokoMerchantConfig
{
ClientId = "your-client-id",
ClientSecret = "your-client-secret"
};
var tokenResponse = await identityClient.GetToken(config.ClientId, config.ClientSecret);
if (tokenResponse != null)
{
// Configure API client with the access token
var apiHttpClient = new HttpClient { BaseAddress = new Uri("https://merchant-api.silpo.ua/") };
apiHttpClient.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", tokenResponse.AccessToken);
var client = new LokoMerchantClient(apiHttpClient);
// Use the client...
}
ASP.NET Core Integration
Using Extension Methods (Recommended)
The easiest way to integrate with ASP.NET Core is using the provided extension methods:
using FourTwenty.LokoMerchant.Client.Extensions;
var builder = WebApplication.CreateBuilder(args);
// Configure Loko Merchant client with extension method
builder.Services.AddLokoMerchantClient(options =>
{
options.ClientId = builder.Configuration["LokoMerchant:ClientId"];
options.ClientSecret = builder.Configuration["LokoMerchant:ClientSecret"];
// Optional: Configure custom URLs (defaults to production)
options.IdentityBaseUrl = builder.Configuration["LokoMerchant:IdentityBaseUrl"];
options.ApiBaseUrl = builder.Configuration["LokoMerchant:ApiBaseUrl"];
});
var app = builder.Build();
Using Method Parameters for URLs (Alternative)
You can also pass URLs directly as method parameters for staging/testing environments:
builder.Services.AddLokoMerchantClient(
identityBaseUrl: "https://identity-public-qa.foodtech.team/",
apiBaseUrl: "https://global-api-qa.foodtech.team/public/merchant",
options =>
{
options.ClientId = builder.Configuration["LokoMerchant:ClientId"];
options.ClientSecret = builder.Configuration["LokoMerchant:ClientSecret"];
});
Note: Using configuration properties is the preferred approach as it's more flexible and testable.
Manual HttpClient Factory Setup
If you need more control over the configuration:
using FourTwenty.LokoMerchant.Client;
using FourTwenty.LokoMerchant.Client.Identity;
var builder = WebApplication.CreateBuilder(args);
// Configure Loko Merchant settings
builder.Services.Configure<LokoMerchantConfig>(
builder.Configuration.GetSection("LokoMerchant"));
// Register HttpClient for identity server
builder.Services.AddHttpClient<ILokoMerchantIdentityClient, LokoMerchantIdentityClient>(client =>
{
client.BaseAddress = new Uri("https://auth.silpo.ua/");
});
// Register HttpClient for API with token authentication
builder.Services.AddHttpClient<ILokoMerchantClient, LokoMerchantClient>(async (serviceProvider, client) =>
{
client.BaseAddress = new Uri("https://merchant-api.silpo.ua/");
// Get token and set authorization header
var config = serviceProvider.GetRequiredService<IOptions<LokoMerchantConfig>>().Value;
var identityClient = serviceProvider.GetRequiredService<ILokoMerchantIdentityClient>();
var tokenResponse = await identityClient.GetToken(config.ClientId, config.ClientSecret);
if (tokenResponse != null)
{
client.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", tokenResponse.AccessToken);
}
});
var app = builder.Build();
var app = builder.Build();
```csharp
using FourTwenty.LokoMerchant.Client;
using FourTwenty.LokoMerchant.Client.Identity;
var builder = WebApplication.CreateBuilder(args);
// Configure Loko Merchant settings
builder.Services.Configure<LokoMerchantConfig>(
builder.Configuration.GetSection("LokoMerchant"));
// Register HttpClient for identity server
builder.Services.AddHttpClient<ILokoMerchantIdentityClient, LokoMerchantIdentityClient>(client =>
{
client.BaseAddress = new Uri("https://auth.silpo.ua/");
});
// Register HttpClient for API with token authentication
builder.Services.AddHttpClient<ILokoMerchantClient, LokoMerchantClient>(async (serviceProvider, client) =>
{
client.BaseAddress = new Uri("https://merchant-api.silpo.ua/");
// Get token and set authorization header
var config = serviceProvider.GetRequiredService<IOptions<LokoMerchantConfig>>().Value;
var identityClient = serviceProvider.GetRequiredService<ILokoMerchantIdentityClient>();
var tokenResponse = await identityClient.GetToken(config.ClientId, config.ClientSecret);
if (tokenResponse != null)
{
client.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", tokenResponse.AccessToken);
}
});
var app = builder.Build();
Configuration (appsettings.json)
{
"LokoMerchant": {
"ClientId": "your-client-id",
"ClientSecret": "your-client-secret",
"IdentityBaseUrl": "https://auth.silpo.ua/",
"ApiBaseUrl": "https://merchant-api.silpo.ua/"
}
}
The IdentityBaseUrl and ApiBaseUrl properties are optional and will default to production URLs if not specified.
Using in Controllers
[ApiController]
[Route("api/[controller]")]
public class StoreController : ControllerBase
{
private readonly ILokoMerchantClient _lokoClient;
public StoreController(ILokoMerchantClient lokoClient)
{
_lokoClient = lokoClient;
}
[HttpPost("{storeId}/pause")]
public async Task<IActionResult> PauseStore(string storeId)
{
try
{
await _lokoClient.Store.UpdateStatus(storeId, StoreStatus.Pause, new BranchStatusBodyRequest());
return Ok();
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
[HttpPost("menu/products")]
public async Task<IActionResult> ImportProducts(ImportProductRequest request)
{
try
{
var result = await _lokoClient.Menu.ImportProducts(request);
return Ok(new { ImportId = result?.Id });
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
}
Usage Examples
Store Management
// Pause a store
await client.Store.UpdateStatus("store-123", StoreStatus.Pause, new BranchStatusBodyRequest());
// Unpause a store
await client.Store.UpdateStatus("store-123", StoreStatus.Unpause, new BranchStatusBodyRequest());
// Update store schedule
var schedules = new List<BranchDaySchedule>
{
new BranchDaySchedule
{
// Configure schedule details
}
};
await client.Store.UpdateSchedule("store-123", schedules);
// Update multiple stores' schedules
var storeSchedules = new List<BranchDayStoreSchedule>
{
new BranchDayStoreSchedule
{
// Configure store schedule details
}
};
await client.Store.UpdateStoresSchedule(storeSchedules);
Webhook Management
// Create a webhook subscription
var subscriptionRequest = new SubscriptionRequest
{
Callback = "https://your-app.com/webhooks/loko",
Events = new List<WebhookEvent> { WebhookEvent.OrderCreated, WebhookEvent.OrderStatusChanged },
CompanyIds = new List<string> { "company-123" }
};
var subscription = await client.Webhooks.CreateSubscription(subscriptionRequest);
Console.WriteLine($"Subscription created with ID: {subscription?.Id}");
Console.WriteLine($"Webhook secret: {subscription?.Secret}");
// List all subscriptions
var subscriptions = await client.Webhooks.GetSubscriptions();
foreach (var sub in subscriptions?.Items ?? Enumerable.Empty<SubscriptionResponse>())
{
Console.WriteLine($"Subscription: {sub.Id} -> {sub.Callback}");
}
// Update a subscription
var updateRequest = new SubscriptionRequest
{
Callback = "https://your-app.com/webhooks/loko-updated",
Events = new List<WebhookEvent> { WebhookEvent.OrderCreated }
};
await client.Webhooks.UpdateSubscription("subscription-id", updateRequest);
// Delete a subscription
await client.Webhooks.DeleteSubscription("subscription-id");
// Get webhook events history
var events = await client.Webhooks.GetSubscriptionEvents();
Menu Management
// Import products
var productRequest = new ImportProductRequest
{
// Configure products to import
};
var importResult = await client.Menu.ImportProducts(productRequest);
Console.WriteLine($"Import started with ID: {importResult?.Id}");
// Import offers (pricing)
var offersRequest = new ImportOffersRequest
{
// Configure offers to import
};
await client.Menu.ImportOffers(offersRequest);
// Import categories
var categories = new List<Category>
{
new Category
{
ExternalId = "cat-1",
Name = "Main Dishes",
Position = 1
},
new Category
{
ExternalId = "cat-2",
Name = "Beverages",
Position = 2,
ParentExternalId = null
}
};
await client.Menu.ImportCategories("company-123", categories);
// Import complete menu
var menuRequest = new ImportMenuRequest
{
// Configure complete menu structure
};
await client.Menu.ImportMenu("company-123", menuRequest);
// Partial menu import (updates only specific items)
var partialRequest = new PartialImportRequest
{
// Configure partial update
};
await client.Menu.PartialMenuImport(partialRequest);
Error Handling
The client includes built-in error handling. API errors are automatically processed and thrown as exceptions:
try
{
await client.Store.UpdateStatus("invalid-store-id", StoreStatus.Pause, new BranchStatusBodyRequest());
}
catch (HttpRequestException ex)
{
// Handle HTTP-related errors (network issues, API errors)
Console.WriteLine($"Request failed: {ex.Message}");
}
catch (JsonException ex)
{
// Handle JSON deserialization errors
Console.WriteLine($"Invalid response format: {ex.Message}");
}
catch (Exception ex)
{
// Handle other exceptions
Console.WriteLine($"Unexpected error: {ex.Message}");
}
API Reference
Core Interfaces
ILokoMerchantClient: Main client interface providing access to all functionalityIStoreProvider: Store management operations (status, scheduling)IWebhooksProvider: Webhook subscription managementIMenuProvider: Menu and product catalog managementIBearerTokenProvider: Token management for authentication
Models
The library includes comprehensive models for all API entities:
- Products:
BaseProduct,Product,MenuProduct - Categories:
Category,MenuProductCategory - Offers:
BaseOffer,Offer,MenuOffer - Options:
Option,OptionGroup,OptionInner - Schedules:
BranchDaySchedule,WorkSchedule - Webhooks:
SubscriptionRequest,SubscriptionResponse,WebhookEvent - Responses:
IdResponse,PagedResponse<T>,LokoAuthResponse
API Documentation
For detailed API documentation, visit: Loko Merchant API Documentation
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
For issues and questions:
- Create an issue on GitHub
- Check the API documentation
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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. |
-
net8.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.9)
- Microsoft.Extensions.Http (>= 9.0.9)
- Microsoft.Extensions.Options (>= 9.0.9)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.15 | 210 | 10/30/2025 |
| 1.0.14 | 140 | 10/17/2025 |
| 1.0.13 | 191 | 10/14/2025 |
| 1.0.12 | 197 | 10/14/2025 |
| 1.0.11 | 192 | 10/14/2025 |
| 1.0.10 | 183 | 10/14/2025 |
| 1.0.9 | 188 | 10/13/2025 |
| 1.0.8 | 191 | 10/13/2025 |
| 1.0.7 | 198 | 10/13/2025 |
| 1.0.6 | 194 | 10/9/2025 |
| 1.0.5 | 185 | 10/9/2025 |
| 1.0.4 | 190 | 10/9/2025 |
| 1.0.3 | 191 | 10/9/2025 |
| 1.0.2 | 178 | 10/9/2025 |
| 1.0.1 | 183 | 10/9/2025 |
| 1.0.0 | 187 | 9/28/2025 |