Build secure, scalable, and feature-rich digital commerce applications with our comprehensive marketplace API. From digital products to specialist services, from secure transactions to real-time P2P commerce.
allgram Marketplace provides enterprise-level security, Stripe integration, and seamless commerce solutions. Perfect for businesses, developers, and organizations requiring professional digital commerce platforms.
Products, Services, Stripe Integration
Find, Hire, Connect
REST API, SDKs, Comprehensive Docs
Build robust marketplace applications with Node.js and Express.js. Our comprehensive API provides both Digital Market and Specialists Market integration, Stripe payment processing, and enterprise-grade security features. Perfect for building scalable e-commerce platforms and specialist marketplace applications.
// allgram Marketplace Digital Market Integration Example
const express = require('express');
const WebSocket = require('ws');
const crypto = require('crypto');
const axios = require('axios');
const stripe = require('stripe')('your-stripe-secret-key');
class allgramMarketplaceClient {
constructor(apiKey, baseUrl = 'https://api.allgram.best') {
this.apiKey = apiKey;
this.baseUrl = baseUrl;
this.ws = null;
this.products = new Map();
this.specialists = new Map();
}
// Initialize WebSocket connection for real-time updates
async connectWebSocket() {
try {
this.ws = new WebSocket(`wss://api.allgram.best/ws/marketplace/`);
this.ws.on('open', () => {
console.log('✅ Marketplace WebSocket connected');
// Authenticate with API key
this.ws.send(JSON.stringify({
type: 'auth',
api_key: this.apiKey
}));
});
this.ws.on('message', (data) => {
this.handleWebSocketMessage(JSON.parse(data));
});
this.ws.on('error', (error) => {
console.error('WebSocket error:', error);
this.reconnect();
});
} catch (error) {
console.error('Failed to connect WebSocket:', error);
}
}
// Create a new digital product
async createProduct(name, description, type, price, isFree = false, isFreeForPremium = false, mediaContent, files) {
try {
const response = await axios.post(`${this.baseUrl}/digital_market/v1/product/create/`, {
name: name,
description: description,
type: type, // 0: background, 1: stickers, 2: reactions
amount: price * 100, // Convert to kopecks
is_free: isFree,
is_free_for_premium: isFreeForPremium,
media_content: mediaContent,
files: files
}, {
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
}
});
if (response.status === 200) {
const product = response.data;
this.products.set(product.id, product);
console.log(`✅ Product created: ${product.name}`);
return product;
}
} catch (error) {
console.error('Failed to create product:', error.response?.data || error.message);
throw error;
}
}
// Search products with filters
async searchProducts(searchTerm, filterBy, productType, skip = 0, count = 20) {
try {
const response = await axios.get(`${this.baseUrl}/digital_market/v1/search/`, {
params: {
search_term: searchTerm,
filter_by: filterBy, // 0: owned, 1: free, 2: free_for_premium
type: productType, // 0: background, 1: stickers, 2: reactions
skip: skip,
count: count
},
headers: {
'Authorization': `Bearer ${this.apiKey}`
}
});
if (response.status === 200) {
console.log(`✅ Found ${response.data.length} products`);
return response.data;
}
} catch (error) {
console.error('Failed to search products:', error.response?.data || error.message);
throw error;
}
}
// Purchase product with Stripe integration
async purchaseProduct(productId, amount, paymentMethodId) {
try {
// Create payment intent with Stripe
const paymentIntent = await stripe.paymentIntents.create({
amount: amount * 100, // Convert to cents
currency: 'usd',
payment_method: paymentMethodId,
confirm: true,
return_url: 'https://your-app.com/success'
});
if (paymentIntent.status === 'succeeded') {
// Purchase product through allgram API
const response = await axios.post(`${this.baseUrl}/digital_market/v1/product/${productId}/buy/`, {
payment_intent_id: paymentIntent.id,
amount: amount
}, {
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
}
});
if (response.status === 200) {
console.log('✅ Product purchased successfully');
return response.data;
}
}
} catch (error) {
console.error('Failed to purchase product:', error.response?.data || error.message);
throw error;
}
}
// Handle WebSocket messages
handleWebSocketMessage(message) {
if (message.content.action) {
this.handleSystemEvent(message);
} else if (message.content.product || message.content.specialist) {
this.handleMarketplaceUpdate(message);
}
}
// Handle system events
handleSystemEvent(message) {
switch (message.content.action) {
case 'product_created':
console.log(`🆕 New product: ${message.content.product.name}`);
break;
case 'product_updated':
console.log(`📝 Product updated: ${message.content.product.name}`);
break;
case 'product_purchased':
console.log(`💰 Product purchased: ${message.content.product.name}`);
break;
case 'specialist_available':
console.log(`👨💼 New specialist available: ${message.content.specialist.first_name}`);
break;
}
}
// Handle marketplace updates
handleMarketplaceUpdate(message) {
if (message.content.product) {
this.updateProductCache(message.content.product);
} else if (message.content.specialist) {
this.updateSpecialistCache(message.content.specialist);
}
}
// Update product cache
updateProductCache(product) {
this.products.set(product.id, product);
console.log(`🔄 Product cache updated: ${product.name}`);
}
// Update specialist cache
updateSpecialistCache(specialist) {
this.specialists.set(specialist.user, specialist);
console.log(`🔄 Specialist cache updated: ${specialist.first_name}`);
}
// Reconnection logic
reconnect() {
setTimeout(() => {
console.log('🔄 Attempting to reconnect...');
this.connectWebSocket();
}, 5000);
}
}
// Usage example
const marketplaceClient = new allgramMarketplaceClient('your-api-key-here');
// Initialize connection
marketplaceClient.connectWebSocket();
// Create a digital product
marketplaceClient.createProduct(
'Modern Background Pack',
'Professional backgrounds for presentations',
0, // background type
9.99,
false,
true,
[{ image: 'https://example.com/background.jpg' }],
[{ file: 'https://example.com/backgrounds.zip' }]
).then(product => {
console.log('Product created successfully:', product);
}).catch(error => {
console.error('Failed to create product:', error);
});
// Search for free backgrounds
marketplaceClient.searchProducts('background', 1, 0, 0, 10)
.then(products => {
console.log('Free backgrounds found:', products);
}).catch(error => {
console.error('Failed to search products:', error);
});
Our Node.js integration provides enterprise-grade marketplace capabilities with minimal setup. Built on proven technologies like Express.js and WebSocket, it offers exceptional performance and reliability for production applications.
Build powerful marketplace applications with Swift and SwiftUI. Our iOS SDK provides seamless integration with UIKit and SwiftUI, digital product browsing, specialist search, and secure transactions. Perfect for creating professional iOS applications for digital commerce and specialist services.
// allgram Marketplace Specialists Market iOS Integration Example
import SwiftUI
import Combine
import CoreLocation
// MARK: - Specialist Models
struct Specialist: Codable, Identifiable {
let id: String
let user: String
let firstName: String
let lastName: String
let thirdName: String
let realPhoto: String
let specialistStatus: String
let categories: [String]
let location: Location?
let rating: Double
let reviews: Int
let hourlyRate: Double?
let isAvailable: Bool
enum CodingKeys: String, CodingKey {
case id
case user
case firstName = "first_name"
case lastName = "last_name"
case thirdName = "third_name"
case realPhoto = "real_photo"
case specialistStatus = "specialist_status"
case categories
case location
case rating
case reviews
case hourlyRate = "hourly_rate"
case isAvailable = "is_available"
}
}
struct Location: Codable {
let country: String?
let state: String?
let city: String?
let coordinates: Coordinates?
}
struct Coordinates: Codable {
let latitude: Double
let longitude: Double
}
struct SpecialistCard: Codable, Identifiable {
let id: String
let specialist: Specialist
let description: String
let skills: [String]
let experience: String
let portfolio: [String]
let availability: [String]
let contactMethods: [String]
}
// MARK: - Specialists Service
class allgramSpecialistsService: ObservableObject {
@Published var specialists: [Specialist] = []
@Published var categories: [String] = []
@Published var searchResults: [Specialist] = []
@Published var isLoading = false
@Published var error: String?
private var cancellables = Set<AnyCancellable>()
private let baseURL = "https://api.allgram.best"
private let apiKey: String
init(apiKey: String) {
self.apiKey = apiKey
loadCategories()
}
// MARK: - Category Management
func loadCategories() {
guard let url = URL(string: "\(baseURL)/specialists/v1/category/list/") else { return }
var request = URLRequest(url: url)
request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
URLSession.shared.dataTaskPublisher(for: request)
.map(.data)
.decode(type: [String].self, decoder: JSONDecoder())
.receive(on: DispatchQueue.main)
.sink(
receiveCompletion: { completion in
if case .failure(let error) = completion {
self.error = error.localizedDescription
}
},
receiveValue: { categories in
self.categories = categories
}
)
.store(in: &cancellables)
}
// MARK: - Specialist Search
func searchSpecialists(
category: String? = nil,
location: Location? = nil,
name: String? = nil,
skip: Int = 0,
count: Int = 20
) {
isLoading = true
error = nil
guard let url = URL(string: "\(baseURL)/specialists/v1/search-user/") else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
var searchPayload: [String: Any] = [:]
if let category = category {
searchPayload["category_name"] = category
}
if let location = location {
searchPayload["location"] = [
"country": location.country ?? "",
"state": location.state ?? "",
"city": location.city ?? ""
]
}
if let name = name {
searchPayload["specialist_name"] = name
}
request.httpBody = try? JSONSerialization.data(withJSONObject: searchPayload)
URLSession.shared.dataTaskPublisher(for: request)
.map(.data)
.decode(type: [Specialist].self, decoder: JSONDecoder())
.receive(on: DispatchQueue.main)
.sink(
receiveCompletion: { completion in
self.isLoading = false
if case .failure(let error) = completion {
self.error = error.localizedDescription
}
},
receiveValue: { specialists in
self.searchResults = specialists
}
)
.store(in: &cancellables)
}
// MARK: - Get Specialists by Category
func getSpecialistsByCategory(_ category: String) {
isLoading = true
error = nil
guard let url = URL(string: "\(baseURL)/specialists/v1/category/\(category)/") else { return }
var request = URLRequest(url: url)
request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
URLSession.shared.dataTaskPublisher(for: request)
.map(.data)
.decode(type: [Specialist].self, decoder: JSONDecoder())
.receive(on: DispatchQueue.main)
.sink(
receiveCompletion: { completion in
self.isLoading = false
if case .failure(let error) = completion {
self.error = error.localizedDescription
}
},
receiveValue: { specialists in
self.specialists = specialists
}
)
.store(in: &cancellables)
}
// MARK: - Create Specialist Card
func createSpecialistCard(
firstName: String,
lastName: String,
thirdName: String,
description: String,
skills: [String],
experience: String,
categories: [String],
location: Location
) async throws -> SpecialistCard {
let url = URL(string: "\(baseURL)/specialists/v1/card/create/")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let cardData = [
"first_name": firstName,
"last_name": lastName,
"third_name": thirdName,
"description": description,
"skills": skills,
"experience": experience,
"categories": categories,
"location": [
"country": location.country ?? "",
"state": location.state ?? "",
"city": location.city ?? ""
]
]
request.httpBody = try JSONSerialization.data(withJSONObject: cardData)
let (data, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse,
httpResponse.statusCode == 200 else {
throw SpecialistError.serverError
}
let specialistCard = try JSONDecoder().decode(SpecialistCard.self, from: data)
return specialistCard
}
// MARK: - Create Direct Chat
func createDirectChat(with specialistUsername: String) async throws -> String {
let url = URL(string: "\(baseURL)/chats/v1/create/")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let chatData = [
"chat_name": "Chat with \(specialistUsername)",
"chat_description": "Direct communication with specialist",
"participants": [specialistUsername],
"is_secure": false,
"is_public": false,
"is_p2p": true
]
request.httpBody = try JSONSerialization.data(withJSONObject: chatData)
let (data, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse,
httpResponse.statusCode == 200 else {
throw SpecialistError.serverError
}
let chatResponse = try JSONDecoder().decode(ChatResponse.self, from: data)
return chatResponse.chatId
}
}
// MARK: - Supporting Models
struct ChatResponse: Codable {
let chatId: String
enum CodingKeys: String, CodingKey {
case chatId = "chat_id"
}
}
enum SpecialistError: Error, LocalizedError {
case serverError
case networkError
case authenticationError
var errorDescription: String? {
switch self {
case .serverError:
return "Server error occurred"
case .networkError:
return "Network connection failed"
case .authenticationError:
return "Authentication failed"
}
}
}
// MARK: - SwiftUI Views
struct SpecialistsListView: View {
@StateObject private var specialistsService = allgramSpecialistsService(apiKey: "your-api-key")
@State private var selectedCategory = "All"
@State private var searchText = ""
var body: some View {
NavigationView {
VStack {
// Category Picker
Picker("Category", selection: $selectedCategory) {
Text("All").tag("All")
ForEach(specialistsService.categories, id: .self) { category in
Text(category).tag(category)
}
}
.pickerStyle(SegmentedPickerStyle())
.padding()
// Search Bar
HStack {
Image(systemName: "magnifyingglass")
.foregroundColor(.secondary)
TextField("Search specialists...", text: $searchText)
.textFieldStyle(RoundedBorderTextFieldStyle())
Button("Search") {
specialistsService.searchSpecialists(
category: selectedCategory == "All" ? nil : selectedCategory,
name: searchText.isEmpty ? nil : searchText
)
}
.buttonStyle(.borderedProminent)
}
.padding(.horizontal)
// Results List
if specialistsService.isLoading {
ProgressView()
.scaleEffect(1.5)
.padding()
} else if let error = specialistsService.error {
VStack {
Image(systemName: "exclamationmark.triangle")
.font(.largeTitle)
.foregroundColor(.orange)
Text("Error: \(error)")
.foregroundColor(.secondary)
}
.padding()
} else {
List(specialistsService.searchResults.isEmpty ? specialistsService.specialists : specialistsService.searchResults) { specialist in
NavigationLink(destination: SpecialistDetailView(specialist: specialist, specialistsService: specialistsService)) {
SpecialistRowView(specialist: specialist)
}
}
}
}
.navigationTitle("Specialists")
.onAppear {
if selectedCategory != "All" {
specialistsService.getSpecialistsByCategory(selectedCategory)
}
}
.onChange(of: selectedCategory) { newCategory in
if newCategory != "All" {
specialistsService.getSpecialistsByCategory(newCategory)
}
}
}
}
}
struct SpecialistRowView: View {
let specialist: Specialist
var body: some View {
HStack {
AsyncImage(url: URL(string: specialist.realPhoto)) { image in
image
.resizable()
.aspectRatio(contentMode: .fill)
} placeholder: {
Image(systemName: "person.circle.fill")
.foregroundColor(.secondary)
}
.frame(width: 50, height: 50)
.clipShape(Circle())
VStack(alignment: .leading, spacing: 4) {
HStack {
Text("\(specialist.firstName) \(specialist.lastName)")
.font(.headline)
if specialist.isAvailable {
Circle()
.fill(Color.green)
.frame(width: 8, height: 8)
}
}
Text(specialist.categories.joined(separator: ", "))
.font(.subheadline)
.foregroundColor(.secondary)
HStack {
Image(systemName: "star.fill")
.foregroundColor(.yellow)
Text(String(format: "%.1f", specialist.rating))
Text("(\(specialist.reviews))")
.foregroundColor(.secondary)
}
.font(.caption)
}
Spacer()
if let hourlyRate = specialist.hourlyRate {
VStack {
Text("$")
.font(.caption)
.foregroundColor(.secondary)
Text(String(format: "%.0f", hourlyRate))
.font(.headline)
.foregroundColor(.primary)
}
}
}
.padding(.vertical, 4)
}
}
Our Swift SDK leverages the latest iOS technologies including SwiftUI, Combine, and async/await. Built with modern iOS development patterns, it provides a seamless developer experience while maintaining high performance and security standards.
Build powerful Android marketplace applications with Kotlin and Jetpack Compose. Our Android SDK provides seamless integration with modern Android development tools, real-time marketplace updates, and P2P commerce capabilities. Perfect for creating professional Android applications for digital commerce and specialist services.
// allgram Marketplace API Integration Android Example
package com.allgram.marketplace
import android.util.Log
import androidx.compose.runtime.*
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject
import java.security.MessageDigest
import javax.crypto.Cipher
import javax.crypto.spec.GCMParameterSpec
import javax.crypto.spec.SecretKeySpec
// MARK: - Data Models
data class Product(
val id: String,
val name: String,
val description: String,
val type: Int, // 0: background, 1: stickers, 2: reactions
val amount: Int,
val isFree: Boolean,
val isFreeForPremium: Boolean,
val creator: String,
val mediaContent: MediaContent,
val files: Files,
val creationDate: Long
)
data class MediaContent(
val image: String
)
data class Files(
val file: String
)
data class Specialist(
val user: String,
val firstName: String,
val lastName: String,
val thirdName: String,
val realPhoto: String,
val specialistStatus: String,
val categories: List<String>,
val location: Location?,
val rating: Double,
val reviews: Int
)
data class Location(
val country: String?,
val state: String?,
val city: String?
)
// MARK: - Marketplace Service
class allgramMarketplaceService(
private val apiKey: String,
private val baseUrl: String = "https://api.allgram.best"
) {
private val client = OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.build()
private var webSocket: WebSocket? = null
private val productCallbacks = mutableListOf<(Product) -> Unit>()
private val specialistCallbacks = mutableListOf<(Specialist) -> Unit>()
private val systemEventCallbacks = mutableListOf<(String, String) -> Unit>()
// MARK: - WebSocket Management
fun connectWebSocket() {
val request = Request.Builder()
.url("wss://api.allgram.best/ws/marketplace/")
.build()
webSocket = client.newWebSocket(request, object : WebSocketListener() {
override fun onOpen(webSocket: WebSocket, response: Response) {
Log.d("allgramMarketplace", "✅ WebSocket connected")
// Authenticate
sendWebSocketMessage(JSONObject().apply {
put("type", "auth")
put("api_key", apiKey)
}.toString())
}
override fun onMessage(webSocket: WebSocket, text: String) {
try {
val json = JSONObject(text)
handleWebSocketMessage(json)
} catch (e: Exception) {
Log.e("allgramMarketplace", "Failed to parse WebSocket message", e)
}
}
override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
Log.e("allgramMarketplace", "WebSocket failure", t)
// Attempt reconnection
CoroutineScope(Dispatchers.IO).launch {
delay(5000)
connectWebSocket()
}
}
})
}
// MARK: - Digital Market API
suspend fun createProduct(
name: String,
description: String,
type: Int,
price: Double,
isFree: Boolean = false,
isFreeForPremium: Boolean = false,
mediaContent: List<String>,
files: List<String>
): Result<Product> = withContext(Dispatchers.IO) {
try {
val requestBody = JSONObject().apply {
put("name", name)
put("description", description)
put("type", type)
put("amount", (price * 100).toInt()) // Convert to kopecks
put("is_free", isFree)
put("is_free_for_premium", isFreeForPremium)
put("media_content", JSONObject().apply {
put("image", mediaContent.firstOrNull() ?: "")
})
put("files", JSONObject().apply {
put("file", files.firstOrNull() ?: "")
})
}.toString()
val request = Request.Builder()
.url("$baseUrl/digital_market/v1/product/create/")
.post(requestBody.toRequestBody("application/json".toMediaType()))
.addHeader("Authorization", "Bearer $apiKey")
.build()
val response = client.newCall(request).execute()
if (response.isSuccessful) {
val responseBody = response.body?.string()
val productJson = JSONObject(responseBody ?: "")
val product = Product(
id = productJson.getString("id"),
name = productJson.getString("name"),
description = productJson.getString("description"),
type = productJson.getInt("type"),
amount = productJson.getInt("amount"),
isFree = productJson.getBoolean("is_free"),
isFreeForPremium = productJson.getBoolean("is_free_for_premium"),
creator = productJson.getString("creator"),
mediaContent = MediaContent(
image = productJson.getJSONObject("media_content").getString("image")
),
files = Files(
file = productJson.getJSONObject("files").getString("file")
),
creationDate = productJson.getLong("creation_date")
)
Log.d("allgramMarketplace", "✅ Product created: ${product.name}")
Result.success(product)
} else {
Log.e("allgramMarketplace", "Failed to create product: ${response.code}")
Result.failure(Exception("Server error: ${response.code}"))
}
} catch (e: Exception) {
Log.e("allgramMarketplace", "Exception creating product", e)
Result.failure(e)
}
}
// MARK: - Specialists Market API
suspend fun searchSpecialists(
category: String? = null,
location: Location? = null,
name: String? = null
): Result<List<Specialist>> = withContext(Dispatchers.IO) {
try {
val requestBody = JSONObject().apply {
if (category != null) put("category_name", category)
if (location != null) {
put("location", JSONObject().apply {
put("country", location.country ?: "")
put("state", location.state ?: "")
put("city", location.city ?: "")
})
}
if (name != null) put("specialist_name", name)
}.toString()
val request = Request.Builder()
.url("$baseUrl/specialists/v1/search-user/")
.post(requestBody.toRequestBody("application/json".toMediaType()))
.addHeader("Authorization", "Bearer $apiKey")
.build()
val response = client.newCall(request).execute()
if (response.isSuccessful) {
val responseBody = response.body?.string()
val specialistsArray = JSONObject(responseBody ?: "").getJSONArray("specialists")
val specialists = mutableListOf<Specialist>()
for (i in 0 until specialistsArray.length()) {
val specialistJson = specialistsArray.getJSONObject(i)
val specialist = Specialist(
user = specialistJson.getString("user"),
firstName = specialistJson.getString("first_name"),
lastName = specialistJson.getString("last_name"),
thirdName = specialistJson.getString("third_name"),
realPhoto = specialistJson.getString("real_photo"),
specialistStatus = specialistJson.getString("specialist_status"),
categories = specialistJson.getJSONArray("categories").let { array ->
List(array.length()) { i -> array.getString(i) }
},
location = specialistJson.optJSONObject("location")?.let { locJson ->
Location(
country = locJson.optString("country"),
state = locJson.optString("state"),
city = locJson.optString("city")
)
},
rating = specialistJson.optDouble("rating", 0.0),
reviews = specialistJson.optInt("reviews", 0)
)
specialists.add(specialist)
}
Log.d("allgramMarketplace", "✅ Found ${specialists.size} specialists")
Result.success(specialists)
} else {
Log.e("allgramMarketplace", "Failed to search specialists: ${response.code}")
Result.failure(Exception("Server error: ${response.code}"))
}
} catch (e: Exception) {
Log.e("allgramMarketplace", "Exception searching specialists", e)
Result.failure(e)
}
}
// MARK: - WebSocket Communication
private fun sendWebSocketMessage(message: String) {
webSocket?.send(message) ?: run {
Log.w("allgramMarketplace", "WebSocket not connected")
}
}
private fun handleWebSocketMessage(json: JSONObject) {
when {
json.has("action") -> {
val action = json.getString("action")
val data = json.optString("data", "")
handleSystemEvent(action, data)
}
json.has("product") -> {
val product = parseProductFromJson(json.getJSONObject("product"))
product?.let { handleProductUpdate(it) }
}
json.has("specialist") -> {
val specialist = parseSpecialistFromJson(json.getJSONObject("specialist"))
specialist?.let { handleSpecialistUpdate(it) }
}
}
}
private fun handleSystemEvent(action: String, data: String) {
Log.d("allgramMarketplace", "System event: $action with data: $data")
systemEventCallbacks.forEach { callback ->
callback(action, data)
}
}
private fun handleProductUpdate(product: Product) {
Log.d("allgramMarketplace", "Product update: ${product.name}")
productCallbacks.forEach { callback ->
callback(product)
}
}
private fun handleSpecialistUpdate(specialist: Specialist) {
Log.d("allgramMarketplace", "Specialist update: ${specialist.firstName} ${specialist.lastName}")
specialistCallbacks.forEach { callback ->
callback(specialist)
}
}
// MARK: - Callbacks
fun addProductCallback(callback: (Product) -> Unit) {
productCallbacks.add(callback)
}
fun addSpecialistCallback(callback: (Specialist) -> Unit) {
specialistCallbacks.add(callback)
}
fun addSystemEventCallback(callback: (String, String) -> Unit) {
systemEventCallbacks.add(callback)
}
// MARK: - Cleanup
fun disconnect() {
webSocket?.close(1000, "Disconnecting")
webSocket = null
}
}
// MARK: - ViewModel
class MarketplaceViewModel(
private val marketplaceService: allgramMarketplaceService
) : ViewModel() {
private val _products = MutableStateFlow<List<Product>>(emptyList())
val products: StateFlow<List<Product>> = _products.asStateFlow()
private val _specialists = MutableStateFlow<List<Specialist>>(emptyList())
val specialists: StateFlow<List<Specialist>> = _specialists.asStateFlow()
private val _isLoading = MutableStateFlow(false)
val isLoading: StateFlow<Boolean> = _isLoading.asStateFlow()
init {
setupMarketplaceService()
}
private fun setupMarketplaceService() {
marketplaceService.addProductCallback { product ->
_products.value = _products.value + product
}
marketplaceService.addSpecialistCallback { specialist ->
_specialists.value = _specialists.value + specialist
}
marketplaceService.addSystemEventCallback { action, data ->
when (action) {
"product_created" -> Log.d("MarketplaceViewModel", "New product: $data")
"specialist_available" -> Log.d("MarketplaceViewModel", "New specialist: $data")
}
}
}
fun createProduct(
name: String,
description: String,
type: Int,
price: Double,
isFree: Boolean = false,
isFreeForPremium: Boolean = false
) {
viewModelScope.launch {
_isLoading.value = true
try {
val result = marketplaceService.createProduct(
name, description, type, price, isFree, isFreeForPremium,
listOf("https://example.com/image.jpg"),
listOf("https://example.com/file.zip")
)
result.onSuccess { product ->
Log.d("MarketplaceViewModel", "Product created: ${product.name}")
}.onFailure { error ->
Log.e("MarketplaceViewModel", "Failed to create product", error)
}
} finally {
_isLoading.value = false
}
}
}
fun searchSpecialists(category: String? = null, location: Location? = null) {
viewModelScope.launch {
_isLoading.value = true
try {
val result = marketplaceService.searchSpecialists(category, location)
result.onSuccess { specialists ->
_specialists.value = specialists
}.onFailure { error ->
Log.e("MarketplaceViewModel", "Failed to search specialists", error)
}
} finally {
_isLoading.value = false
}
}
}
override fun onCleared() {
super.onCleared()
marketplaceService.disconnect()
}
}
Our Kotlin SDK leverages the latest Android technologies including Jetpack Compose, Coroutines, and modern Android architecture patterns. Built with performance and developer experience in mind, it provides a robust foundation for building scalable marketplace applications.
Ready to take your marketplace integration to the next level? Explore our comprehensive resources and advanced features to build enterprise-grade commerce applications with allgram.
Learn about our enterprise security features, GDPR compliance, and Stripe PCI DSS Level 1 certification.
Learn More →Discover advanced techniques for optimizing marketplace performance and scalability.
Learn More →Join our developer community for support, updates, and collaboration.
Join Community →allgram combines messenger, social network, marketplace, and professional networking in one secure, privacy-focused platform. Download now and join millions of users worldwide.
Join millions of users who trust allgram for their digital communication needs