Marketplace API - AI Conversational Commerce
The Marketplace API provides AI-powered conversational commerce functionality enabling users to discover, search, and purchase products from multiple marketplaces (Etsy, Tokopedia) using natural language and pay with USDC cryptocurrency. Built for seamless cross-border shopping with blockchain payment integration.
🎯 What Can You Manage?
Your complete conversational commerce ecosystem with these powerful tools:
- AI Chat Assistant: Natural language product discovery powered by Groq AI (Llama 3.1 70B)
- Multi-Marketplace Search: Simultaneous product search across Etsy (USD) and Tokopedia (IDR)
- Product Normalization: Unified product schema across different marketplaces
- Order Management: Create and track orders with USDC payment integration
- Payment Tracking: Real-time blockchain payment monitoring via smart contract events
- Currency Conversion: Automatic FX conversion for IDR products to USDC
- Order History: Complete order tracking with pagination and status filtering
🧩 Your Marketplace Building Blocks
💬 Chat Operations Blocks
POST /api/marketplace/chat- Send message to AI shopping assistant (No Auth)
🔍 Search Operations Blocks
POST /api/marketplace/search- Search products across marketplaces (No Auth)
📦 Order Operations Blocks
POST /api/marketplace/orders- Create new order (Auth Required)GET /api/marketplace/orders/:order_id- Get order details (Auth Required)GET /api/marketplace/orders- Get user order history (Auth Required)
🏗️ Common Usage Patterns
Pattern 1: "I want to find products using natural language"
Chat with AI → Get product recommendations → Search products
Use: /marketplace/chat → /marketplace/search
Pattern 2: "I want to buy a product with USDC"
Search product → Create order → Pay with USDC → Track status
Use: /marketplace/search → /marketplace/orders (POST) → /marketplace/orders/:order_id (GET)
Pattern 3: "I want to see my purchase history"
Get order history → Filter by status → Check payment status
Use: /marketplace/orders (GET) with pagination
Pattern 4: "I want to shop across multiple countries"
Search Etsy (USD) + Tokopedia (IDR) → Compare prices → Order with auto FX conversion
Use: /marketplace/search with sources: ['etsy', 'tokopedia']
🔐 Authentication
Marketplace API has mixed authentication requirements:
No Authentication Required
- Chat:
/api/marketplace/chat- Public access for AI assistant - Search:
/api/marketplace/search- Public access for product search
Authentication Required
- Create Order:
/api/marketplace/orders(POST) - Get Order:
/api/marketplace/orders/:order_id(GET) - Order History:
/api/marketplace/orders(GET)
Required Headers (Auth endpoints only)
Authorization: Bearer YOUR_JWT_TOKEN
x-api-key: YOUR_API_KEY
Content-Type: application/json
Getting JWT Token
curl -X POST https://api.brdz.link/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"usernameoremail": "user@example.com",
"password": "your_password"
}'
Response:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user_id": 123,
"role": "user"
}
💬 Chat Operations
Send Message to AI Assistant
Send Message to AI Shopping Assistant
Interact with AI-powered shopping assistant using natural language. The assistant helps users discover products, provides recommendations, and guides through the purchase process. Powered by Groq AI (Llama 3.1 70B) with intent detection (SEARCH, BUY, INFO, HELP). No authentication required - public access.
Parameters
messagestringrequiredUser's message to the AI assistant
conversation_historyarrayPrevious conversation messages for context (default: [])
Request Body
{
"message": "I'm looking for handmade ceramic mugs under $30",
"conversation_history": [
{
"role": "user",
"content": "Hi, I need a gift"
},
{
"role": "assistant",
"content": "I'd be happy to help you find a gift! What kind of gift are you looking for?"
}
]
}Response
{
"success": true,
"reply": "Great! I can help you find handmade ceramic mugs. Here are some beautiful options:\n\n1. Artisan Blue Ceramic Mug - $24.99 (Etsy)\n2. Handcrafted Pottery Mug Set - $28.50 (Etsy)\n3. Rustic Stoneware Mug - $22.00 (Tokopedia - IDR 349,000)\n\nWould you like me to search for more options or provide details about any of these?",
"intent": "SEARCH",
"usage": {
"prompt_tokens": 245,
"completion_tokens": 128,
"total_tokens": 373
}
}{
"success": false,
"error": "Message required"
}{
"success": false,
"error": "Chat service unavailable",
"details": "Groq API error"
}curl -X POST https://api.brdz.link/api/marketplace/chat \
-H "Content-Type: application/json" \
-d '{
"message": "I'''m looking for handmade ceramic mugs under $30",
"conversation_history": []
}'🔍 Search Operations
Search Products Across Marketplaces
Search Products Across Multiple Marketplaces
Search for products across Etsy (USD) and Tokopedia (IDR) marketplaces. Uses AI-powered query generation to optimize search results. Products are normalized into unified schema with automatic currency conversion for IDR items. Returns sorted results with price, images, vendor info, and direct purchase links. No authentication required - public access.
Parameters
querystringrequiredSearch query (e.g., 'handmade ceramic mug')
sourcesarrayMarketplaces to search: ['etsy', 'tokopedia'] (default: ['etsy'])
limitnumberMaximum products to return (default: 10, max: 50)
Request Body
{
"query": "handmade ceramic travel mug",
"sources": [
"etsy",
"tokopedia"
],
"limit": 10
}Response
{
"success": true,
"query": "handmade ceramic travel mug",
"products": [
{
"productId": "etsy-123456",
"title": "Handmade Ceramic Travel Mug with Lid",
"description": "Beautiful handcrafted ceramic travel mug...",
"image": "https://i.etsystatic.com/...",
"images": [
"https://i.etsystatic.com/..."
],
"source": "etsy",
"url": "https://www.etsy.com/listing/123456",
"vendor": {
"name": "Etsy - PotteryShop",
"marketplace": "etsy",
"shop_name": "PotteryShop",
"shop_url": "https://www.etsy.com/shop/PotteryShop"
},
"pricing": {
"price": 28.5,
"currency": "USD",
"original_price": 28.5,
"shipping": 5,
"total": 33.5
},
"availability": "in_stock",
"metadata": {
"rating": 4.8,
"num_favorers": 1250,
"tags": [
"ceramic",
"handmade",
"travel mug"
]
}
},
{
"productId": "tokopedia-789012",
"title": "Gelas Keramik Travel Handmade Premium",
"description": "Gelas keramik travel buatan tangan...",
"image": "https://images.tokopedia.net/...",
"images": [
"https://images.tokopedia.net/..."
],
"source": "tokopedia",
"url": "https://www.tokopedia.com/...",
"vendor": {
"name": "Tokopedia - KeramikArt",
"marketplace": "tokopedia",
"shop_name": "KeramikArt",
"shop_url": "https://www.tokopedia.com/keramikart",
"shop_location": "Jakarta Selatan"
},
"pricing": {
"price": 22.15,
"currency": "USD",
"original_price": 350000,
"original_currency": "IDR",
"shipping": 0,
"total": 22.15,
"fx_rate": 15850
},
"availability": "in_stock",
"metadata": {
"rating": 4.9,
"total_sold": 342,
"stock": 45,
"condition": "new"
}
}
],
"count": 10,
"search_queries": [
"handmade ceramic travel mug",
"pottery travel cup",
"gelas keramik travel"
]
}{
"success": false,
"error": "Search query required"
}{
"success": false,
"error": "Search failed",
"details": "Scraper timeout"
}curl -X POST https://api.brdz.link/api/marketplace/search \
-H "Content-Type: application/json" \
-d '{
"query": "handmade ceramic travel mug",
"sources": ["etsy", "tokopedia"],
"limit": 10
}'📦 Order Operations
Create Order
Create Marketplace Order
Create a new marketplace order for selected product. Calculates USDC payment amount with automatic FX conversion for IDR products. Saves order to database with PENDING status. Returns payment details for blockchain transaction. Requires authentication.
Parameters
productobjectrequiredProduct details from search results
recipientobjectrequiredDelivery recipient information
wallet_addressstringrequiredUser's wallet address for payment tracking
chain_idstringBlockchain network (default: 'sepolia')
Request Body
{
"product": {
"productId": "etsy-123456",
"title": "Handmade Ceramic Travel Mug",
"description": "Beautiful handcrafted ceramic travel mug with lid",
"image": "https://i.etsystatic.com/...",
"url": "https://www.etsy.com/listing/123456",
"source": "etsy",
"vendor": {
"name": "Etsy - PotteryShop",
"marketplace": "etsy",
"shop_name": "PotteryShop",
"shop_url": "https://www.etsy.com/shop/PotteryShop"
},
"pricing": {
"price": 28.5,
"currency": "USD",
"total": 33.5,
"shipping": 5
}
},
"recipient": {
"name": "John Doe",
"phone": "+628123456789",
"address": "Jl. Sudirman No. 123, Jakarta Selatan 12190, Indonesia",
"email": "john@example.com",
"notes": "Please call before delivery"
},
"wallet_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"chain_id": "sepolia"
}Response
{
"success": true,
"order": {
"order_id": "BRDZ-1705308000000-a1b2c3d4",
"user_id": 456,
"product_data": {
"id": "etsy-123456",
"title": "Handmade Ceramic Travel Mug",
"description": "Beautiful handcrafted ceramic travel mug...",
"image": "https://i.etsystatic.com/...",
"url": "https://www.etsy.com/listing/123456",
"source": "etsy"
},
"vendor_data": {
"name": "Etsy - PotteryShop",
"marketplace": "etsy",
"shop_name": "PotteryShop",
"shop_url": "https://www.etsy.com/shop/PotteryShop"
},
"pricing_data": {
"original_price": 28.5,
"original_currency": "USD",
"usd_amount": 33.5,
"usdc_amount": 33.5,
"shipping": 5,
"total_usd": 33.5,
"fx_rate": null,
"fx_timestamp": "2024-01-15T10:00:00Z"
},
"recipient_data": {
"name": "John Doe",
"phone": "+628123456789",
"address": "Jl. Sudirman No. 123, Jakarta Selatan 12190",
"email": "john@example.com",
"notes": "Please call before delivery"
},
"payment_token": "USDC",
"token_amount": 33.5,
"fiat_amount": 28.5,
"fiat_currency": "USD",
"chain_id": "sepolia",
"wallet_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"contract_address": "0x7E93334bf4Cd3Bd15D2203D7E6d5A59A891C4a48",
"payment_status": "PENDING",
"created_at": "2024-01-15T10:00:00Z"
},
"payment_details": {
"order_id": "BRDZ-1705308000000-a1b2c3d4",
"usdc_amount": 33.5,
"contract_address": "0x7E93334bf4Cd3Bd15D2203D7E6d5A59A891C4a48",
"chain_id": "sepolia",
"wallet_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"
}
}{
"success": false,
"error": "Missing required fields: product, recipient, wallet_address"
}{
"success": false,
"error": "Authentication required"
}{
"success": false,
"error": "Failed to create order",
"details": "Database error"
}curl -X POST https://api.brdz.link/api/marketplace/orders \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"product": {
"productId": "etsy-123456",
"title": "Handmade Ceramic Travel Mug",
"description": "Beautiful handcrafted ceramic travel mug with lid",
"image": "https://i.etsystatic.com/...",
"url": "https://www.etsy.com/listing/123456",
"source": "etsy",
"vendor": {
"name": "Etsy - PotteryShop",
"marketplace": "etsy",
"shop_name": "PotteryShop",
"shop_url": "https://www.etsy.com/shop/PotteryShop"
},
"pricing": {
"price": 28.50,
"currency": "USD",
"total": 33.50,
"shipping": 5.00
}
},
"recipient": {
"name": "John Doe",
"phone": "+628123456789",
"address": "Jl. Sudirman No. 123, Jakarta Selatan 12190, Indonesia",
"email": "john@example.com",
"notes": "Please call before delivery"
},
"wallet_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"chain_id": "sepolia"
}'Get Order Details
Get Order Details by ID
Retrieve complete order details including product info, pricing, recipient data, payment status, and blockchain transaction hash. Users can only access their own orders, admins can access any order. Requires authentication.
Parameters
order_idstringrequiredOrder ID (format: BRDZ-{timestamp}-{uuid})
Response
{
"success": true,
"order": {
"order_id": "BRDZ-1705308000000-a1b2c3d4",
"user_id": 456,
"product_data": {
"id": "etsy-123456",
"title": "Handmade Ceramic Travel Mug",
"description": "Beautiful handcrafted ceramic travel mug...",
"image": "https://i.etsystatic.com/...",
"url": "https://www.etsy.com/listing/123456",
"source": "etsy"
},
"vendor_data": {
"name": "Etsy - PotteryShop",
"marketplace": "etsy",
"shop_name": "PotteryShop",
"shop_url": "https://www.etsy.com/shop/PotteryShop"
},
"pricing_data": {
"original_price": 28.5,
"original_currency": "USD",
"usd_amount": 33.5,
"usdc_amount": 33.5,
"total_usd": 33.5
},
"recipient_data": {
"name": "John Doe",
"phone": "+628123456789",
"address": "Jl. Sudirman No. 123, Jakarta Selatan 12190",
"email": "john@example.com"
},
"payment_token": "USDC",
"token_amount": 33.5,
"payment_status": "PAID",
"blockchain_tx_hash": "0xabc123...",
"created_at": "2024-01-15T10:00:00Z",
"paid_at": "2024-01-15T10:05:00Z",
"completed_at": null
}
}{
"success": false,
"error": "Authentication required"
}{
"success": false,
"error": "Access denied"
}{
"success": false,
"error": "Order not found"
}{
"success": false,
"error": "Failed to get order",
"details": "Database error"
}curl -X GET https://api.brdz.link/api/marketplace/orders/BRDZ-1705308000000-a1b2c3d4 \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY"Get User Order History
Get User Order History
Retrieve paginated order history for authenticated user. Supports filtering by payment status and pagination. Returns orders sorted by creation date (newest first). Requires authentication.
Parameters
limitnumberMaximum orders to return (default: 10, max: 100)
offsetnumberNumber of orders to skip (default: 0)
statusstringFilter by status: PENDING, PAID, COMPLETED, FAILED, CANCELLED
Response
{
"success": true,
"orders": [
{
"order_id": "BRDZ-1705308000000-a1b2c3d4",
"user_id": 456,
"product_data": {
"id": "etsy-123456",
"title": "Handmade Ceramic Travel Mug",
"image": "https://i.etsystatic.com/...",
"source": "etsy"
},
"vendor_data": {
"name": "Etsy - PotteryShop",
"marketplace": "etsy"
},
"pricing_data": {
"usdc_amount": 33.5,
"original_currency": "USD"
},
"payment_status": "PAID",
"blockchain_tx_hash": "0xabc123...",
"created_at": "2024-01-15T10:00:00Z",
"paid_at": "2024-01-15T10:05:00Z"
},
{
"order_id": "BRDZ-1705221600000-e5f6g7h8",
"user_id": 456,
"product_data": {
"id": "tokopedia-789012",
"title": "Gelas Keramik Premium",
"image": "https://images.tokopedia.net/...",
"source": "tokopedia"
},
"vendor_data": {
"name": "Tokopedia - KeramikArt",
"marketplace": "tokopedia"
},
"pricing_data": {
"usdc_amount": 22.15,
"original_currency": "IDR",
"original_price": 350000
},
"payment_status": "COMPLETED",
"blockchain_tx_hash": "0xdef456...",
"created_at": "2024-01-14T09:00:00Z",
"paid_at": "2024-01-14T09:03:00Z",
"completed_at": "2024-01-18T14:30:00Z"
}
],
"pagination": {
"total": 15,
"limit": 10,
"offset": 0,
"has_more": true
}
}{
"success": false,
"error": "Authentication required"
}{
"success": false,
"error": "Failed to get orders",
"details": "Database error"
}# Get recent orders
curl -X GET "https://api.brdz.link/api/marketplace/orders?limit=10&offset=0" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY"
# Filter by status
curl -X GET "https://api.brdz.link/api/marketplace/orders?status=PAID&limit=20" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY"🚀 Complete Shopping Workflows
Workflow 1: Conversational Product Discovery
// Complete AI-assisted shopping flow
async function conversationalShopping() {
console.log('=== AI Shopping Assistant ===\n');
const conversationHistory = [];
// Step 1: Initial conversation (no auth)
const chat1Response = await fetch('https://api.brdz.link/api/marketplace/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
message: 'I need a birthday gift for my mom'
})
});
const chat1 = await chat1Response.json();
console.log('You: I need a birthday gift for my mom');
console.log(`AI: ${chat1.reply}\n`);
conversationHistory.push(
{ role: 'user', content: 'I need a birthday gift for my mom' },
{ role: 'assistant', content: chat1.reply }
);
// Step 2: Provide more context (no auth)
const chat2Response = await fetch('https://api.brdz.link/api/marketplace/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
message: 'She loves gardening and handmade pottery',
conversation_history: conversationHistory
})
});
const chat2 = await chat2Response.json();
console.log('You: She loves gardening and handmade pottery');
console.log(`AI: ${chat2.reply}\n`);
// Step 3: AI suggests search
if (chat2.intent === 'SEARCH') {
console.log('AI detected SEARCH intent - proceeding to product search\n');
// Step 4: Search products (no auth)
const searchResponse = await fetch('https://api.brdz.link/api/marketplace/search', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
query: 'handmade pottery planter',
sources: ['etsy', 'tokopedia'],
limit: 10
})
});
const searchResults = await searchResponse.json();
console.log(`Found ${searchResults.count} products:\n`);
searchResults.products.slice(0, 3).forEach((product, index) => {
console.log(`${index + 1}. ${product.title}`);
console.log(` Price: $${product.pricing.total}`);
console.log(` Shop: ${product.vendor.shop_name}`);
console.log(` Rating: ${product.metadata?.rating || 'N/A'}\n`);
});
return searchResults;
}
return conversationHistory;
}
// Usage
await conversationalShopping();
Workflow 2: Complete Purchase Flow with Web3 Payment
// End-to-end purchase workflow with blockchain payment
async function completePurchaseFlow(searchQuery, userWalletAddress, jwtToken, apiKey) {
console.log('=== Complete Purchase Flow ===\n');
try {
// Step 1: Search products (no auth)
console.log('Step 1: Searching products...');
const searchResponse = await fetch('https://api.brdz.link/api/marketplace/search', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
query: searchQuery,
sources: ['etsy'],
limit: 5
})
});
const searchResults = await searchResponse.json();
if (searchResults.products.length === 0) {
throw new Error('No products found');
}
console.log(`Found ${searchResults.count} products\n`);
// Step 2: Select product
const selectedProduct = searchResults.products[0];
console.log('Step 2: Product selected:');
console.log(` ${selectedProduct.title}`);
console.log(` Price: $${selectedProduct.pricing.total}\n`);
// Step 3: Create order (auth required)
console.log('Step 3: Creating order...');
const orderResponse = await fetch('https://api.brdz.link/api/marketplace/orders', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${jwtToken}`,
'x-api-key': apiKey
},
body: JSON.stringify({
product: selectedProduct,
recipient: {
name: 'Jane Smith',
phone: '+628123456789',
address: 'Jl. Sudirman No. 456, Jakarta Selatan 12190, Indonesia',
email: 'jane@example.com',
notes: 'Please call before delivery'
},
wallet_address: userWalletAddress,
chain_id: 'sepolia'
})
});
const order = await orderResponse.json();
console.log(`Order created: ${order.order.order_id}`);
console.log(`Amount to pay: ${order.payment_details.usdc_amount} USDC\n`);
// Step 4: Execute blockchain payment
console.log('Step 4: Processing payment...');
// Initialize Web3
const Web3 = require('web3');
const web3 = new Web3(window.ethereum);
const BRDZ_PAYMENT_ABI = [{
inputs: [
{ type: 'address', name: 'brdzWallet' },
{ type: 'uint256', name: 'amount' },
{ type: 'string', name: 'orderId' }
],
name: 'completePayment',
outputs: [],
stateMutability: 'nonpayable',
type: 'function'
}];
const contract = new web3.eth.Contract(
BRDZ_PAYMENT_ABI,
order.payment_details.contract_address
);
const amountInWei = web3.utils.toWei(
order.payment_details.usdc_amount.toString(),
'mwei' // USDC has 6 decimals
);
const tx = await contract.methods
.completePayment(
order.payment_details.wallet_address,
amountInWei,
order.order.order_id
)
.send({ from: userWalletAddress });
console.log(`Payment TX: ${tx.transactionHash}\n`);
// Step 5: Wait for blockchain relayer to update status
console.log('Step 5: Waiting for payment confirmation...');
await new Promise(resolve => setTimeout(resolve, 5000));
// Check order status
const statusResponse = await fetch(
`https://api.brdz.link/api/marketplace/orders/${order.order.order_id}`,
{
headers: {
'Authorization': `Bearer ${jwtToken}`,
'x-api-key': apiKey
}
}
);
const orderStatus = await statusResponse.json();
console.log(`Status: ${orderStatus.order.payment_status}`);
if (orderStatus.order.blockchain_tx_hash) {
console.log(`TX Hash: ${orderStatus.order.blockchain_tx_hash}`);
}
console.log('\n=== Purchase Complete ===');
return {
order_id: order.order.order_id,
product: selectedProduct.title,
amount: order.payment_details.usdc_amount,
status: orderStatus.order.payment_status,
tx_hash: tx.transactionHash
};
} catch (error) {
console.error(`Purchase failed: ${error.message}`);
throw error;
}
}
// Usage
await completePurchaseFlow(
'handmade ceramic planter',
'0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb',
'YOUR_JWT_TOKEN',
'YOUR_API_KEY'
);
Workflow 3: Multi-Marketplace Price Comparison
// Compare prices across marketplaces
async function priceComparison(searchQuery) {
console.log(`=== Price Comparison: "${searchQuery}" ===\n`);
// Search both marketplaces (no auth)
const response = await fetch('https://api.brdz.link/api/marketplace/search', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
query: searchQuery,
sources: ['etsy', 'tokopedia'],
limit: 20
})
});
const results = await response.json();
// Separate by marketplace
const etsyProducts = results.products.filter(p => p.source === 'etsy');
const tokopediaProducts = results.products.filter(p => p.source === 'tokopedia');
console.log(`Etsy: ${etsyProducts.length} products`);
console.log(`Tokopedia: ${tokopediaProducts.length} products\n`);
// Price analysis
const getPriceStats = (products) => {
const prices = products.map(p => p.pricing.total);
return {
min: Math.min(...prices),
max: Math.max(...prices),
avg: prices.reduce((a, b) => a + b, 0) / prices.length,
count: products.length
};
};
const etsyStats = getPriceStats(etsyProducts);
const tokopediaStats = getPriceStats(tokopediaProducts);
console.log('💰 Price Analysis:');
console.log('\nEtsy (USD):');
console.log(` Min: $${etsyStats.min.toFixed(2)}`);
console.log(` Max: $${etsyStats.max.toFixed(2)}`);
console.log(` Avg: $${etsyStats.avg.toFixed(2)}`);
console.log('\nTokopedia (converted to USD):');
console.log(` Min: $${tokopediaStats.min.toFixed(2)}`);
console.log(` Max: $${tokopediaStats.max.toFixed(2)}`);
console.log(` Avg: $${tokopediaStats.avg.toFixed(2)}`);
// Best deals
const allProducts = [...etsyProducts, ...tokopediaProducts]
.sort((a, b) => a.pricing.total - b.pricing.total);
console.log('\n🏆 Top 3 Best Deals:');
allProducts.slice(0, 3).forEach((product, index) => {
console.log(`${index + 1}. ${product.title}`);
console.log(` $${product.pricing.total} (${product.source})`);
console.log(` Shop: ${product.vendor.shop_name}`);
console.log(` Rating: ${product.metadata?.rating || 'N/A'}\n`);
});
return {
etsy: etsyStats,
tokopedia: tokopediaStats,
bestDeal: allProducts[0]
};
}
// Usage
await priceComparison('ceramic coffee mug');
🌍 Supported Marketplaces & Features
Marketplace Support
Etsy (International)
- Currency: USD
- Payment: Direct USDC (1:1 conversion)
- Shipping: International
- Features: Handmade, vintage, craft supplies
- Scraping: Puppeteer with stealth plugins
- Data: Title, price, images, shop info, ratings
Tokopedia (Indonesia)
- Currency: IDR
- Payment: Auto-converted to USDC via FX service
- Shipping: Domestic Indonesia
- Features: Wide range of products
- Scraping: Puppeteer with stealth plugins
- Data: Title, price (IDR), images, shop info, location, sales
Payment Features
- Smart Contract: BRDZPayment.sol on Sepolia testnet
- Contract Address:
0x7E93334bf4Cd3Bd15D2203D7E6d5A59A891C4a48 - Payment Token: USDC (6 decimals)
- Event Monitoring: Blockchain relayer auto-listens to PaymentCompleted events
- Status Updates: Automatic order status update from PENDING to PAID
Order Processing Stages
- PENDING: Order created, awaiting payment
- PAID: Payment confirmed on blockchain
- COMPLETED: Product shipped and delivered (manual update for MVP)
- FAILED: Payment or order processing failed
- CANCELLED: Order cancelled by user or system
🔄 Complete Integration Flow Diagram
┌─────────────────────────────────────────────────────────────────┐
│ MARKETPLACE FLOW DIAGRAM │
└─────────────────────────────────────────────────────────────────┘
STEP 1: PRODUCT DISCOVERY (No Auth)
┌──────────────────────────┐
│ User opens marketplace │
└──────────┬───────────────┘
│
v
┌──────────────────────────┐
│ Chat with AI assistant │
│ POST /marketplace/chat │
└──────────┬───────────────┘
│
v
┌──────────────────────────┐
│ AI detects SEARCH intent │
└──────────┬───────────────┘
│
▼
STEP 2: PRODUCT SEARCH (No Auth)
┌──────────────────────────┐
│ Search products │
│ POST /marketplace/search │
└──────────┬───────────────┘
│
v
┌──────────────────────────┐
│ AI generates optimal │
│ search queries │
└──────────┬───────────────┘
│
v
┌──────────────────────────┐
│ Scrape Etsy + Tokopedia │
│ (Puppeteer) │
└──────────┬───────────────┘
│
v
┌──────────────────────────┐
│ Normalize products │
│ Unified schema │
└──────────┬───────────────┘
│
v
┌──────────────────────────┐
│ FX conversion for IDR │
│ (Tokopedia products) │
└──────────┬───────────────┘
│
v
┌──────────────────────────┐
│ Return sorted results │
└──────────┬───────────────┘
│
▼
STEP 3: ORDER CREATION (Auth Required)
┌──────────────────────────┐
│ User login/authenticate │
└──────────┬───────────────┘
│
v
┌──────────────────────────┐
│ User selects product │
└──────────┬───────────────┘
│
v
┌──────────────────────────┐
│ Enter recipient info │
└──────────┬───────────────┘
│
v
┌──────────────────────────┐
│ Create order │
│ POST /marketplace/orders │
└──────────┬───────────────┘
│
v
┌──────────────────────────┐
│ Calculate USDC amount │
│ (with FX for IDR) │
└──────────┬───────────────┘
│
v
┌──────────────────────────┐
│ Save to database │
│ Status: PENDING │
└──────────┬───────────────┘
│
v
┌──────────────────────────┐
│ Return payment details │
│ (contract, amount, etc) │
└──────────┬───────────────┘
│
▼
STEP 4: BLOCKCHAIN PAYMENT
┌──────────────────────────┐
│ User approves USDC spend │
│ (MetaMask/Web3) │
└──────────┬───────────────┘
│
v
┌──────────────────────────┐
│ Execute completePayment()│
│ on BRDZPayment contract │
└──────────┬───────────────┘
│
v
┌──────────────────────────┐
│ PaymentCompleted event │
│ emitted │
└──────────┬───────────────┘
│
▼
STEP 5: PAYMENT CONFIRMATION
┌──────────────────────────┐
│ Blockchain relayer │
│ listens to events │
└──────────┬───────────────┘
│
v
┌──────────────────────────┐
│ Update order status │
│ PENDING → PAID │
└──────────┬───────────────┘
│
v
┌──────────────────────────┐
│ Store blockchain TX hash │
└──────────┬───────────────┘
│
▼
STEP 6: ORDER FULFILLMENT (MVP: Manual)
┌──────────────────────────┐
│ Admin notified │
│ (console log) │
└──────────┬───────────────┘
│
v
┌──────────────────────────┐
│ Merchant contacted │
│ Product shipped │
└──────────┬───────────────┘
│
v
┌──────────────────────────┐
│ Update status │
│ PAID → COMPLETED │
└──────────┬───────────────┘
│
v
[✅ DONE]
═══════════════════════════════════════════════════════════════
USER ORDER TRACKING (Auth Required):
┌──────────────────────────┐
│ Check order status │
│ GET /orders/:order_id │
└──────────┬───────────────┘
│
v
┌──────────────────────────┐
│ View order history │
│ GET /orders │
└──────────────────────────┘
📊 Database Schema Reference
marketplace_orders Table
- order_id VARCHAR(100) PRIMARY KEY
- user_id INTEGER NOT NULL
- product_data JSONB NOT NULL
- vendor_data JSONB NOT NULL
- pricing_data JSONB NOT NULL
- recipient_data JSONB NOT NULL
- payment_status VARCHAR(20) DEFAULT 'PENDING'
- payment_token VARCHAR(20) DEFAULT 'USDC'
- token_amount DECIMAL(20, 6)
- fiat_amount DECIMAL(20, 2)
- fiat_currency VARCHAR(10)
- chain_id VARCHAR(50) DEFAULT 'sepolia'
- wallet_address VARCHAR(100)
- blockchain_tx_hash VARCHAR(100)
- contract_address VARCHAR(100) DEFAULT '0x7E93334bf4Cd3Bd15D2203D7E6d5A59A891C4a48'
- created_at TIMESTAMP DEFAULT NOW()
- paid_at TIMESTAMP
- completed_at TIMESTAMP
- search_query TEXT
- ai_conversation JSONB
⚠️ Important Notes & Warnings
This is an MVP implementation with manual fulfillment. Automated merchant notification and shipping integration are not yet implemented. Admin must manually:
- Contact merchant after payment confirmation
- Track shipping status
- Update order status to COMPLETED
Product availability is scraped in real-time but may change between search and purchase. Always verify product is still in stock on the marketplace website before finalizing order.
IDR products from Tokopedia are automatically converted to USDC using the existing FX service. Exchange rates are fetched in real-time during order creation. Rate is saved with order for reference.
Current implementation uses Sepolia testnet for USDC payments. Production deployment will use mainnet with real USDC.
Blockchain relayer automatically monitors PaymentCompleted events and updates order status. No manual intervention needed for payment confirmation.
Chat and Search endpoints are public (no auth required) to allow users to browse products before logging in. Order operations require authentication for security.
🚨 Troubleshooting Guide
Common Issues & Solutions
Issue 1: "Chat service unavailable"
Cause: Groq API error or rate limit
Solution: Check Groq API configuration and implement retry logic
Issue 2: "Search failed - scraper timeout"
Cause: Marketplace website blocking or slow response
Solution:
- Check if marketplace website is accessible
- Verify Puppeteer configuration
- Use fewer sources or reduce limit
Issue 3: "Authentication required"
Cause: Missing or invalid JWT token for order endpoints
Solution: Ensure user is logged in and token is provided in headers
Issue 4: "Payment not confirmed"
Cause: Blockchain relayer not running or event not detected
Solution:
- Check blockchain relayer is running (auto-starts in app.js)
- Verify transaction on Etherscan
- Check smart contract address matches
Issue 5: "Product price changed"
Cause: Price changed between search and order creation
Solution: Re-search product and inform user of price change
📚 API Reference Summary
Quick Reference Table
| Endpoint | Method | Auth | Description |
|---|---|---|---|
/marketplace/chat | POST | No | Send message to AI assistant |
/marketplace/search | POST | No | Search products across marketplaces |
/marketplace/orders | POST | Yes | Create new order |
/marketplace/orders/:order_id | GET | Yes | Get order details |
/marketplace/orders | GET | Yes | Get user order history |
Authentication Summary
| Endpoint Category | Auth Required | Headers Needed |
|---|---|---|
| Chat Operations | ❌ No | Content-Type only |
| Search Operations | ❌ No | Content-Type only |
| Order Operations | ✅ Yes | Authorization + x-api-key + Content-Type |
💬 Support & Feedback
For technical support, API issues, or feature requests related to Marketplace integration:
- Review the documentation above
- Check error codes and troubleshooting guide
- Test with Sepolia testnet first
- Contact Anantla technical support
- Report bugs via support channels
🚀 Roadmap & Future Features
Planned Enhancements
- Automated Fulfillment: Direct merchant API integration
- More Marketplaces: Amazon, AliExpress, Shopee support
- Advanced AI: Product recommendations, price predictions
- Multi-Chain: Support for Polygon, BSC, other EVM chains
- Fiat On-ramp: Buy USDC with credit card directly
- Order Tracking: Real-time shipping status updates
- Dispute Resolution: Built-in escrow and arbitration
- Loyalty Rewards: Cashback in USDC for purchases