SortSwift
Pricing
Sign InGet started
InventoryInventory OverviewBulk Lot BuilderMaster SetsChaos Sorting
Syncing
PricingSign In
SortSwift Docs
Getting Started
Core Features
Integrations & Tools
Support

Customer Order Submission

Step-by-step guide for customers submitting buylist orders through the customer portal.

Complete Submission Process


  1. Access Customer Portal: Navigate to the store's buylist customer portal (typically at a URL like buylist.[storename].com or embedded in store website)
  2. Search for Products: Use GET /api/buylist/search endpoint to find cards by name, set code, card number, or other filters
  3. Select Product: Click on a product to view details and available printings/conditions
  4. Get Pricing: System calls GET /api/buylist/get-price with productId, printing, condition, language, and storeId to fetch cash and credit prices for all conditions
  5. Add to Cart: Select condition, language, printing, quantity, and payment type (Cash, Credit, or Split)
  6. Review Cart: View all items with totals calculated based on payment types and split percentages
  7. Provide Customer Info: Enter customerName, customerEmail, customerPhone (optional), orderType (dropIn/delivery), paypalEmail (if delivery), customerAddress (if delivery), and orderNotes
  8. Submit Order: POST /api/buylist/submit-order with complete order data
  9. Receive Confirmation: Order created, orderId returned, confirmation email sent (if enabled)

Required Request Data


Required Fields:
• storeId: Store's unique identifier
• customerName: Customer's full name
• customerEmail: Customer's email address
• cart: Array of cart items (minimum 1 item required)

Optional Fields:
• customerPhone: Phone number
• orderType: 'dropIn' (default) or 'delivery'
• paypalEmail: Required if orderType='delivery'
• customerAddress: Required if orderType='delivery'
• orderNotes: Additional notes from customer
• totalCash: Pre-calculated total (system will recalculate)
• totalCredit: Pre-calculated total (system will recalculate)

Cart Item Structure


Required for Regular Items:
• productId: TCGPlayer product ID (number)
• condAbbr: Condition abbreviation (NM, LP, MP, HP, DM)
• langAbbr: Language abbreviation (EN, JP, FR, etc.)
• printing: Printing type (Normal, Foil, Holofoil, etc.)
• quantity: Number of copies (default: 1)
• paymentType: 'Cash', 'Credit', or 'Split'
• addedCashPrice: Price per unit for cash
• addedCreditPrice: Price per unit for credit

Optional Fields:
• splitPercentage: Percentage for cash (0-100) when paymentType='Split' (default: 50)
• notes: Item-specific notes
• isCustomItem: Boolean flag for custom items
• customItemData: Object with baseDescription, baseQuantity, userQuantity, baseCashPrice, baseCreditPrice (for custom items)

Server-Side Processing Steps


  1. Validation: Server validates storeId exists, customerName and customerEmail are present, cart is non-empty array
  2. Store Lookup: Finds UserModel by buylistConfig.storeId. Returns 404 if store not found or config missing
  3. Product Hydration: For regular items (not isCustomItem), fetches ProductModel records to populate cleanName, categoryId, groupId, number, groupName
  4. Split Normalization: For items with paymentType='Split', ensures splitPercentage is number (defaults to 50 if missing)
  5. Total Calculation: Computes computedTotalCash and computedTotalCredit by iterating cart:
    • Cash items: addedCashPrice × quantity
    • Credit items: addedCreditPrice × quantity
    • Split items: (addedCashPrice × quantity × splitPercentage%) + (addedCreditPrice × quantity × (100-splitPercentage)%)
  6. Budget Validation: If budgetsEnabled in store config, validates totals against remaining cash/credit budgets. Auto-adjusts payment types if one budget exhausted but other has capacity
  7. CSV Generation: Creates CSV file with columns: ProductId, TCGplayer Id, Name, Set, Number, Condition, Language, Printing, Quantity, CashPrice, CreditPrice, Notes
  8. Status Determination: Sets initial status based on:
    • POS buys: Uses req.body.status or defaults to 'approved'
    • Customer orders: Uses buylistConfig.defaultOrderStatus if set, otherwise checks autoApprove flag (true = 'approved', false = 'pending_approval')
  9. Order Creation: Creates BuylistOrder document with all fields, initial statusHistory entry, and system message: "Buylist order created with X items"
  10. Auto-Approval Handling: If status='approved', adds "Order auto-approved" message and sends customer approval email with store address
  11. Email Notifications: Sends two emails (if emailsEnabled !== false):
    • Store owner: HTML table with all items, CSV attachment, subject: "[StoreName] - New Buylist Order from [CustomerName]"
    • Customer: HTML table confirmation, subject: "Buylist Confirmation - [StoreName]"
  12. Budget Update: If budgetsEnabled, increments cashBudgetUsed and creditBudgetUsed fields in UserModel
  13. Response: Returns JSON with success: true, message, and orderId

Getting Prices for Cart Items


Before adding items to cart, customers should fetch prices using GET /api/buylist/get-price with query parameters:

  • productId: Required - TCGPlayer product ID
  • printing: Required - Printing type (Normal, Foil, etc.)
  • condition: Optional - Condition abbreviation (NM, LP, MP, HP, DM)
  • language: Optional - Language abbreviation (default: EN)
  • storeId: Optional - Store ID for store-specific pricing

Response includes:
• price.directLowPrice, lowPrice, midPrice, marketPrice, highPrice (raw TCGPlayer prices)
• price.NMFinalCash, NMFinalCredit (Near Mint prices)
• price.LPFinalCash, LPFinalCredit (Lightly Played prices)
• price.MPFinalCash, MPFinalCredit (Moderately Played prices)
• price.HPFinalCash, HPFinalCredit (Heavily Played prices)
• price.DMFinalCash, DMFinalCredit (Damaged prices)
• price.logs: Array of step-by-step pricing calculation logs (if debug mode)

Bulk Pricing: For multiple items, use POST /api/buylist/get-price/bulk with body containing array of {productId, printing, condition, language} objects. Returns array of price objects.

Getting Available Printings


Before displaying condition/printing options, fetch available printings using GET /api/buylist/available-printings?productId=[id]. Returns array of available printing objects with subTypeName and other metadata.

For bulk operations, use GET /api/buylist/available-printings/bulk?productIds=[id1,id2,id3] or POST /api/buylist/get-price/bulk to get both prices and printings together.

Error Handling


  • 400 Bad Request: Missing storeId, customerName, customerEmail, or empty cart
  • 404 Not Found: Store not found for storeId, or store configuration missing
  • 400 Budget Error: If both cash and credit budgets exhausted, returns error with cashRemaining and creditRemaining values
  • 500 Server Error: Product not found for productId, database errors, email sending failures

Successful Response


{ "success": true, "message": "Buylist order submitted successfully!", "orderId": "507f1f77bcf86cd799439011" }

The orderId can be used to view order status via GET /api/buylist/public/orders/:orderId (no auth required, uses email verification).