allgram Marketplace - Enterprise-Grade Digital Commerce Platform

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.

Digital Commerce

Products, Services, Stripe Integration

Specialists Market

Find, Hire, Connect

Developer Friendly

REST API, SDKs, Comprehensive Docs

  • Quick Start Guide
  • Node.js
    Server-side implementation with Express.js, Digital Market & Specialists Market API integration

  • Swift
    iOS native development with UIKit/SwiftUI, marketplace integration and secure transactions

  • Kotlin
    Android development with Jetpack Compose, marketplace SDK and P2P commerce capabilities

  • Additional Resources
    Security, performance, API reference, and community support

  • Marketplace Services
    Explore enterprise features, pricing, and integration options
  • Licensing
    Commercial licenses, compliance, and enterprise agreements
  • Full Documentation
    Complete API reference, tutorials, and best practices

Node.js Integration

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.

  • Full API Support: Complete REST API with product management and search
  • Enterprise Security: E2EE, P2P, Stripe PCI DSS Level 1 compliance
  • Real-time Performance: WebSocket-based instant updates and notifications
  • Scalable Architecture: Built for high-load production environments
Explore Marketplace Services

// 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);
    });
                                    

Key Features & Benefits

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.

  • Product Management: Create, update, and manage digital products
  • Stripe Integration: Secure payment processing with PCI DSS compliance
  • Real-time Updates: WebSocket-based instant notifications
  • Advanced Search: Filter by type, price, and availability
View Licensing Options

Swift iOS Integration

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.

  • Native iOS Support: Full SwiftUI and UIKit compatibility
  • Specialist Search: Advanced filtering by category and location
  • Secure Communication: Direct chat creation with specialists
  • Modern Architecture: MVVM, Combine, and async/await support
Explore Marketplace 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)
    }
}
                                    

iOS Development Features

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.

  • SwiftUI Integration: Native SwiftUI components and data binding
  • Combine Framework: Reactive programming with publishers and subscribers
  • Async/Await: Modern concurrency for better performance
  • Location Services: CoreLocation integration for specialist search
View Licensing Options

Kotlin Android Integration

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.

  • Jetpack Compose: Modern declarative UI toolkit
  • WebSocket Integration: Real-time bidirectional communication
  • P2P Commerce: Direct peer-to-peer transactions
  • Android Architecture: MVVM, Repository pattern, and Coroutines
Explore Marketplace 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()
    }
}
                                    

Android Development Features

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.

  • Jetpack Compose: Modern declarative UI with Material Design 3
  • Coroutines: Asynchronous programming with structured concurrency
  • MVVM Architecture: Clean architecture with Repository pattern
  • WebSocket Integration: Real-time marketplace updates
View Licensing Options

Additional Resources & Next Steps

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.

Security & Compliance

Learn about our enterprise security features, GDPR compliance, and Stripe PCI DSS Level 1 certification.

Learn More →

Performance Optimization

Discover advanced techniques for optimizing marketplace performance and scalability.

Learn More →

API Reference

Complete API documentation with examples, error codes, and best practices.

View Docs →

Community Support

Join our developer community for support, updates, and collaboration.

Join Community →
allgram - Universal Social Platform Logo

Experience the Future of Social Communication

allgram combines messenger, social network, marketplace, and professional networking in one secure, privacy-focused platform. Download now and join millions of users worldwide.

Mobile Apps

Full-featured mobile experience with push notifications

Desktop Apps

Native desktop experience with keyboard shortcuts

Web Version

Access from any browser, no installation required

10M+ Active Users
99.9% Uptime
150+ Countries
6 Languages

Trusted & Certified

FIPS 140-2
Common Criteria EAL4+
GDPR Compliant
SOC 2 Type II

Join millions of users who trust allgram for their digital communication needs

Free forever plan No ads or tracking Instant setup