Square

Payment PlatformPOSRetailRestaurantBitcoinAIHardware Integration

Payment & POS Platform

Square

Overview

Square is a comprehensive payment platform integrating in-person and online payments, POS systems, and business management tools. Focused on retail, restaurants, and service businesses, it revolutionizes payment and business management for small to medium businesses through simple hardware-software integration. In 2025, Square introduces next-generation payment and business solutions including Bitcoin payment integration, AI-powered new hardware, and the Square Releases program.

Details

Founded in 2009, Square started with card reader innovation and has evolved into an integrated business platform providing payment processing, inventory management, customer management, payroll, and lending. As of 2025, it offers cutting-edge business solutions including the new Square Handheld device, Bitcoin integration for cryptocurrency payments, and AI-powered features for sales forecasting and inventory optimization.

Key Features

  • Integrated POS: Hardware-software unified POS system
  • Diverse Payment Methods: Cards, digital wallets, cash, and Bitcoin support
  • Business Management: Unified management of inventory, customers, employees, and accounting
  • Hardware Ecosystem: Square Terminal, Reader, Stand, Handheld, and more
  • Industry-Specific: Specialized solutions for restaurants, retail, beauty, and service industries
  • Financial Services: Square Capital (business funding) and banking services
  • Developer APIs: Comprehensive APIs for custom integration and app development
  • AI & Analytics: Sales forecasting, inventory optimization, and customer insights

Supported Payment Methods

  • Card Payments: Visa, Mastercard, American Express, Discover, JCB
  • Digital Wallets: Apple Pay, Google Pay, Samsung Pay
  • Cash Payments: Cash management and reporting through POS
  • Bitcoin: Integration with Square Cash App (2025 new feature)
  • Buy Now, Pay Later: Afterpay, Klarna integration
  • Gift Cards: Square's proprietary gift card system

Pros and Cons

Pros

  • Easy Setup: Plug-and-play hardware
  • Integrated Solution: Unified payment to business management
  • Transparent Pricing: Clear and predictable fee structure
  • Hardware Quality: Robust and user-friendly POS devices
  • Industry Specialization: Features tailored to specific industry needs
  • Fast Deposits: Next-business-day funding available
  • Free Plan: Basic features available at no cost

Cons

  • Transaction Fees: Per-transaction fees (sometimes higher than competitors)
  • Customization Limits: Constraints due to platform design
  • Advanced Features: Some features require paid plans
  • Regional Restrictions: Limited functionality in certain regions like Japan
  • Internet Dependency: Limited offline functionality
  • Competitive Comparison: Other platforms may be superior for specific use cases

Reference Links

Implementation Examples

1. Basic Setup

# Install Square SDK
npm install squareup

# Square Developer Dashboard Setup
# 1. Create application at https://developer.squareup.com/
# 2. Obtain Application ID and Access Token
# 3. Configure Webhook Signature Key

# Development environment Sandbox setup
export SQUARE_APPLICATION_ID="sandbox-sq0idp-xxxxx"
export SQUARE_ACCESS_TOKEN="sandbox-sq0atb-xxxxx"
export SQUARE_WEBHOOK_SIGNATURE_KEY="xxxxx"
export SQUARE_ENVIRONMENT="sandbox"  # or "production"

# Install Square CLI (development/testing)
curl -L https://github.com/square/square-cli/releases/download/v1.0.0/square-cli-linux -o square-cli
chmod +x square-cli

2. Basic Payment Processing

// Square SDK initialization
const { Client, Environment } = require('squareup');

const client = new Client({
  accessToken: process.env.SQUARE_ACCESS_TOKEN,
  environment: process.env.SQUARE_ENVIRONMENT === 'production' 
    ? Environment.Production 
    : Environment.Sandbox
});

const paymentsApi = client.paymentsApi;
const ordersApi = client.ordersApi;
const customersApi = client.customersApi;

// Basic payment processing
async function processPayment(paymentRequest) {
  try {
    // Create order
    const order = {
      order: {
        locationId: process.env.SQUARE_LOCATION_ID,
        lineItems: paymentRequest.items.map(item => ({
          name: item.name,
          quantity: item.quantity.toString(),
          basePriceMoney: {
            amount: item.price, // Amount in cents for USD
            currency: 'USD'
          }
        })),
        taxes: [
          {
            name: 'Sales Tax',
            percentage: '8.5',
            scope: 'ORDER'
          }
        ]
      }
    };

    const { result: orderResult } = await ordersApi.createOrder(order);
    const createdOrder = orderResult.order;

    // Process payment
    const payment = {
      sourceId: paymentRequest.sourceId, // Card nonce
      amountMoney: {
        amount: parseInt(createdOrder.totalMoney.amount),
        currency: 'USD'
      },
      orderId: createdOrder.id,
      autocomplete: true,
      locationId: process.env.SQUARE_LOCATION_ID,
      referenceId: paymentRequest.referenceId || `order-${Date.now()}`,
      note: paymentRequest.note || 'Payment processing',
      // Customer information
      buyerEmailAddress: paymentRequest.customerEmail,
      // Billing address
      billingAddress: {
        addressLine1: paymentRequest.billingAddress.line1,
        addressLine2: paymentRequest.billingAddress.line2,
        locality: paymentRequest.billingAddress.city,
        postalCode: paymentRequest.billingAddress.postalCode,
        country: 'US'
      }
    };

    const { result: paymentResult } = await paymentsApi.createPayment(payment);

    return {
      success: true,
      paymentId: paymentResult.payment.id,
      orderId: createdOrder.id,
      receiptNumber: paymentResult.payment.receiptNumber,
      cardDetails: paymentResult.payment.cardDetails,
      totalAmount: createdOrder.totalMoney
    };
  } catch (error) {
    console.error('Payment processing error:', error);
    return {
      success: false,
      error: error.message,
      errorCode: error.code
    };
  }
}

// Customer creation and management
async function createCustomer(customerData) {
  try {
    const customer = {
      givenName: customerData.firstName,
      familyName: customerData.lastName,
      emailAddress: customerData.email,
      phoneNumber: customerData.phone,
      address: {
        addressLine1: customerData.address.line1,
        addressLine2: customerData.address.line2,
        locality: customerData.address.city,
        postalCode: customerData.address.postalCode,
        country: 'US'
      },
      note: customerData.note || '',
      referenceId: customerData.referenceId
    };

    const { result } = await customersApi.createCustomer(customer);
    return result.customer;
  } catch (error) {
    console.error('Customer creation error:', error);
    throw error;
  }
}

// Refund processing
async function refundPayment(paymentId, refundAmount, reason) {
  try {
    const refund = {
      amountMoney: {
        amount: refundAmount,
        currency: 'USD'
      },
      paymentId: paymentId,
      reason: reason || 'Customer-requested refund'
    };

    const { result } = await paymentsApi.refundPayment(refund);
    return {
      success: true,
      refundId: result.refund.id,
      status: result.refund.status,
      refundAmount: result.refund.amountMoney
    };
  } catch (error) {
    console.error('Refund processing error:', error);
    throw error;
  }
}

3. Inventory & Product Catalog Management

// Product catalog management
const catalogApi = client.catalogApi;
const inventoryApi = client.inventoryApi;

// Product creation
async function createProduct(productData) {
  try {
    const catalogObject = {
      type: 'ITEM',
      id: `#${productData.sku}`,
      itemData: {
        name: productData.name,
        description: productData.description,
        categoryId: productData.categoryId,
        productType: 'REGULAR',
        skipModifierScreen: false,
        variations: productData.variations.map((variation, index) => ({
          type: 'ITEM_VARIATION',
          id: `#${productData.sku}_variation_${index}`,
          itemVariationData: {
            itemId: `#${productData.sku}`,
            name: variation.name,
            sku: variation.sku,
            pricingType: 'FIXED_PRICING',
            priceMoney: {
              amount: variation.price,
              currency: 'USD'
            },
            trackInventory: true,
            stockable: true
          }
        }))
      }
    };

    const upsertRequest = {
      idempotencyKey: `create-product-${Date.now()}`,
      object: catalogObject
    };

    const { result } = await catalogApi.upsertCatalogObject(upsertRequest);
    return result.catalogObject;
  } catch (error) {
    console.error('Product creation error:', error);
    throw error;
  }
}

// Inventory management
async function updateInventory(catalogObjectId, quantity, locationId) {
  try {
    const change = {
      type: 'ADJUSTMENT',
      adjustment: {
        catalogObjectId: catalogObjectId,
        fromState: 'IN_STOCK',
        toState: 'IN_STOCK',
        locationId: locationId,
        quantity: quantity.toString()
      }
    };

    const inventoryChange = {
      idempotencyKey: `inventory-update-${Date.now()}`,
      changes: [change]
    };

    const { result } = await inventoryApi.batchChangeInventory(inventoryChange);
    return result.changes;
  } catch (error) {
    console.error('Inventory update error:', error);
    throw error;
  }
}

// Get inventory levels
async function getInventoryLevels(catalogObjectIds, locationIds) {
  try {
    const { result } = await inventoryApi.batchRetrieveInventoryCounts({
      catalogObjectIds: catalogObjectIds,
      locationIds: locationIds,
      states: ['IN_STOCK']
    });

    return result.counts.map(count => ({
      catalogObjectId: count.catalogObjectId,
      locationId: count.locationId,
      quantity: parseInt(count.quantity),
      state: count.state
    }));
  } catch (error) {
    console.error('Inventory retrieval error:', error);
    throw error;
  }
}

4. Order & Fulfillment Management

// Order management system
class OrderManager {
  constructor(squareClient) {
    this.ordersApi = squareClient.ordersApi;
    this.paymentsApi = squareClient.paymentsApi;
  }

  // Search orders
  async searchOrders(filters = {}) {
    try {
      const query = {
        filter: {},
        sort: {
          sortField: 'CREATED_AT',
          sortOrder: 'DESC'
        }
      };

      // Configure filters
      if (filters.locationIds) {
        query.filter.locationFilter = {
          locationIds: filters.locationIds
        };
      }

      if (filters.dateRange) {
        query.filter.dateTimeFilter = {
          createdAt: {
            startAt: filters.dateRange.startAt,
            endAt: filters.dateRange.endAt
          }
        };
      }

      if (filters.states) {
        query.filter.stateFilter = {
          states: filters.states
        };
      }

      const searchRequest = {
        query: query,
        limit: filters.limit || 50,
        returnEntries: true
      };

      const { result } = await this.ordersApi.searchOrders(searchRequest);
      return result.orders || [];
    } catch (error) {
      console.error('Order search error:', error);
      throw error;
    }
  }

  // Get order details
  async getOrderDetails(orderId) {
    try {
      const { result } = await this.ordersApi.retrieveOrder(orderId);
      return result.order;
    } catch (error) {
      console.error('Order details retrieval error:', error);
      throw error;
    }
  }

  // Update order status
  async updateOrderStatus(orderId, newState, version) {
    try {
      const updateRequest = {
        order: {
          state: newState,
          version: version
        }
      };

      const { result } = await this.ordersApi.updateOrder(orderId, updateRequest);
      return result.order;
    } catch (error) {
      console.error('Order status update error:', error);
      throw error;
    }
  }

  // Calculate shipping cost
  calculateShippingCost(order, shippingMethod) {
    const baseShipping = {
      'standard': 5.99,
      'express': 12.99,
      'overnight': 24.99
    };

    let shippingCost = baseShipping[shippingMethod] || 5.99;
    
    // Free shipping threshold
    const orderTotal = parseInt(order.totalMoney.amount) / 100; // Convert from cents
    if (orderTotal >= 75) { // Free shipping over $75
      shippingCost = 0;
    }

    return Math.round(shippingCost * 100); // Convert to cents
  }

  // Order fulfillment
  async fulfillOrder(orderId, fulfillmentData) {
    try {
      const fulfillment = {
        type: fulfillmentData.type || 'SHIPMENT',
        state: 'PREPARED',
        shipmentDetails: {
          recipient: fulfillmentData.recipient,
          carrier: fulfillmentData.carrier,
          shippingNote: fulfillmentData.shippingNote,
          trackingNumber: fulfillmentData.trackingNumber,
          expectedShippedAt: fulfillmentData.expectedShippedAt
        }
      };

      const updateRequest = {
        order: {
          fulfillments: [fulfillment],
          version: fulfillmentData.orderVersion
        }
      };

      const { result } = await this.ordersApi.updateOrder(orderId, updateRequest);
      return result.order;
    } catch (error) {
      console.error('Order fulfillment error:', error);
      throw error;
    }
  }
}

5. Hardware Integration & POS Implementation

// Square POS API integration (for terminals)
class SquarePOSIntegration {
  constructor(applicationId, locationId) {
    this.applicationId = applicationId;
    this.locationId = locationId;
  }

  // Square POS app integration
  generatePOSURL(transactionData) {
    const baseUrl = 'square-commerce-v1://payment/create';
    const params = new URLSearchParams({
      'data': JSON.stringify({
        client_id: this.applicationId,
        version: '1.3',
        notes: transactionData.notes || '',
        amount_money: {
          amount: transactionData.amount,
          currency_code: 'USD'
        },
        callback_url: transactionData.callbackUrl,
        version: '1.3',
        options: {
          supported_tender_types: [
            'CREDIT_CARD',
            'CASH',
            'OTHER'
          ]
        }
      })
    });

    return `${baseUrl}?${params.toString()}`;
  }

  // Hardware event handling
  async handleHardwareEvent(eventType, eventData) {
    switch (eventType) {
      case 'CARD_INSERTED':
        return await this.processCardPayment(eventData);
      case 'CASH_DRAWER_OPENED':
        return await this.recordCashDrawerEvent(eventData);
      case 'RECEIPT_PRINTED':
        return await this.confirmReceiptPrint(eventData);
      default:
        console.log(`Unhandled hardware event: ${eventType}`);
    }
  }

  // Square Terminal API (2025 new feature)
  async sendTerminalCommand(deviceId, command) {
    try {
      const terminalApi = client.terminalApi;
      
      const terminalCheckout = {
        amountMoney: {
          amount: command.amount,
          currency: 'USD'
        },
        deviceOptions: {
          deviceId: deviceId,
          skipReceiptScreen: command.skipReceipt || false,
          collectSignature: command.collectSignature || true
        },
        note: command.note || 'Terminal payment',
        orderId: command.orderId
      };

      const { result } = await terminalApi.createTerminalCheckout(terminalCheckout);
      return result.checkout;
    } catch (error) {
      console.error('Terminal command error:', error);
      throw error;
    }
  }
}

// Restaurant-specific POS functionality
class RestaurantPOS {
  constructor(squareClient, locationId) {
    this.ordersApi = squareClient.ordersApi;
    this.paymentsApi = squareClient.paymentsApi;
    this.locationId = locationId;
  }

  // Table order management
  async createTableOrder(tableNumber, items, customerId = null) {
    try {
      const order = {
        locationId: this.locationId,
        referenceId: `table-${tableNumber}-${Date.now()}`,
        source: {
          name: `Table ${tableNumber}`
        },
        lineItems: items.map(item => ({
          name: item.name,
          quantity: item.quantity.toString(),
          basePriceMoney: {
            amount: item.price,
            currency: 'USD'
          },
          modifiers: item.modifiers || [],
          note: item.specialRequests || ''
        })),
        serviceCharges: [
          {
            name: 'Service Charge',
            percentage: '18.0',
            calculationPhase: 'SUBTOTAL_PHASE'
          }
        ],
        metadata: {
          tableNumber: tableNumber.toString(),
          orderType: 'DINE_IN',
          customerId: customerId
        }
      };

      const { result } = await this.ordersApi.createOrder({ order });
      return result.order;
    } catch (error) {
      console.error('Table order creation error:', error);
      throw error;
    }
  }

  // Kitchen display order formatting
  formatKitchenDisplay(order) {
    return {
      orderId: order.id,
      tableNumber: order.metadata?.tableNumber,
      orderTime: order.createdAt,
      items: order.lineItems.map(item => ({
        name: item.name,
        quantity: item.quantity,
        modifiers: item.modifiers?.map(mod => mod.name),
        specialRequests: item.note,
        status: 'PENDING' // PENDING, PREPARING, READY
      })),
      totalItems: order.lineItems.length,
      estimatedTime: this.calculateCookingTime(order.lineItems)
    };
  }

  // Cooking time calculation
  calculateCookingTime(lineItems) {
    const baseTimes = {
      'Salad': 5,
      'Soup': 10,
      'Pasta': 15,
      'Pizza': 20,
      'Steak': 25
    };

    let maxTime = 0;
    lineItems.forEach(item => {
      const itemTime = baseTimes[item.name] || 10;
      maxTime = Math.max(maxTime, itemTime);
    });

    return maxTime;
  }
}

6. 2025 New Features: Bitcoin & AI Integration

// Bitcoin payment integration (2025 new feature)
class BitcoinPaymentService {
  constructor(squareClient) {
    this.paymentsApi = squareClient.paymentsApi;
    this.customersApi = squareClient.customersApi;
  }

  // Bitcoin payment processing
  async processBitcoinPayment(paymentRequest) {
    try {
      // Bitcoin payment via Square Cash App integration
      const payment = {
        sourceId: paymentRequest.bitcoinSourceId,
        amountMoney: {
          amount: paymentRequest.amount,
          currency: 'USD'
        },
        locationId: process.env.SQUARE_LOCATION_ID,
        note: 'Bitcoin payment',
        // Bitcoin-specific settings
        cashDetails: {
          buyerSuppliedMoney: {
            amount: paymentRequest.bitcoinAmount,
            currency: 'BTC'
          }
        },
        metadata: {
          paymentType: 'BITCOIN',
          exchangeRate: paymentRequest.btcToUsdRate,
          bitcoinAddress: paymentRequest.bitcoinAddress
        }
      };

      const { result } = await this.paymentsApi.createPayment(payment);
      
      return {
        success: true,
        paymentId: result.payment.id,
        bitcoinAmount: paymentRequest.bitcoinAmount,
        usdAmount: paymentRequest.amount,
        exchangeRate: paymentRequest.btcToUsdRate,
        transactionHash: result.payment.metadata?.transactionHash
      };
    } catch (error) {
      console.error('Bitcoin payment error:', error);
      throw error;
    }
  }

  // Bitcoin exchange rate retrieval
  async getBitcoinExchangeRate() {
    try {
      // Using Square Cash App API or external exchange API
      const response = await fetch('https://api.cashapp.com/v1/bitcoin/rate');
      const data = await response.json();
      
      return {
        btcToUsd: data.rate,
        timestamp: data.timestamp,
        source: 'cash_app'
      };
    } catch (error) {
      console.error('Bitcoin exchange rate error:', error);
      throw error;
    }
  }
}

// AI Analytics & Prediction (2025 new feature)
class AIAnalyticsService {
  constructor(squareClient) {
    this.ordersApi = squareClient.ordersApi;
    this.catalogApi = squareClient.catalogApi;
    this.customersApi = squareClient.customersApi;
  }

  // Sales revenue prediction
  async predictSalesRevenue(locationId, days = 30) {
    try {
      // Get historical sales data
      const historicalData = await this.getHistoricalSales(locationId, 90);
      
      // Machine learning model prediction (using Square AI service)
      const prediction = await this.callSquareAI('sales_prediction', {
        historicalData: historicalData,
        predictionDays: days,
        seasonalFactors: await this.getSeasonalFactors(),
        externalFactors: await this.getExternalFactors()
      });

      return {
        predictedRevenue: prediction.revenue,
        confidence: prediction.confidence,
        factors: prediction.influencingFactors,
        dailyBreakdown: prediction.dailyPredictions
      };
    } catch (error) {
      console.error('Sales prediction error:', error);
      throw error;
    }
  }

  // Inventory optimization AI
  async optimizeInventory(locationId) {
    try {
      const [currentInventory, salesVelocity, seasonalTrends] = await Promise.all([
        this.getCurrentInventoryLevels(locationId),
        this.getSalesVelocity(locationId),
        this.getSeasonalTrends(locationId)
      ]);

      const optimization = await this.callSquareAI('inventory_optimization', {
        currentInventory,
        salesVelocity,
        seasonalTrends,
        leadTimes: await this.getSupplierLeadTimes(),
        storageCapacity: await this.getStorageCapacity(locationId)
      });

      return {
        recommendations: optimization.restockSuggestions,
        overstockAlerts: optimization.overstockItems,
        understockAlerts: optimization.understockItems,
        optimalOrderQuantities: optimization.orderQuantities,
        costSavings: optimization.projectedSavings
      };
    } catch (error) {
      console.error('Inventory optimization error:', error);
      throw error;
    }
  }

  // Square AI API call (2025 new feature)
  async callSquareAI(model, data) {
    try {
      const response = await fetch('https://ai.squareup.com/v1/predict', {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${process.env.SQUARE_ACCESS_TOKEN}`,
          'Content-Type': 'application/json',
          'Square-Version': '2025-01-01'
        },
        body: JSON.stringify({
          model: model,
          input: data,
          location_id: process.env.SQUARE_LOCATION_ID
        })
      });

      if (!response.ok) {
        throw new Error(`Square AI API error: ${response.statusText}`);
      }

      return await response.json();
    } catch (error) {
      console.error('Square AI API error:', error);
      throw error;
    }
  }

  // Customer behavior analysis
  async analyzeCustomerBehavior(customerId) {
    try {
      const customerData = await this.getCustomerData(customerId);
      
      const analysis = await this.callSquareAI('customer_analysis', {
        transactionHistory: customerData.orders,
        visitFrequency: customerData.visitPattern,
        purchasePreferences: customerData.preferences,
        seasonalBehavior: customerData.seasonality
      });

      return {
        lifetimeValue: analysis.clv,
        churnRisk: analysis.churnProbability,
        nextPurchasePrediction: analysis.nextPurchase,
        recommendedProducts: analysis.productRecommendations,
        optimalContactTime: analysis.engagementTiming,
        loyaltyScore: analysis.loyaltyIndex
      };
    } catch (error) {
      console.error('Customer behavior analysis error:', error);
      throw error;
    }
  }
}

// Square Releases integration (2025 new feature)
class SquareReleasesIntegration {
  constructor(squareClient) {
    this.client = squareClient;
  }

  // Enable beta features
  async enableBetaFeature(featureName) {
    try {
      const response = await fetch('https://api.squareup.com/v1/releases/enable', {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${process.env.SQUARE_ACCESS_TOKEN}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          feature: featureName,
          location_id: process.env.SQUARE_LOCATION_ID
        })
      });

      return await response.json();
    } catch (error) {
      console.error('Beta feature enablement error:', error);
      throw error;
    }
  }

  // Get available features
  async getAvailableFeatures() {
    try {
      const response = await fetch('https://api.squareup.com/v1/releases/available', {
        headers: {
          'Authorization': `Bearer ${process.env.SQUARE_ACCESS_TOKEN}`
        }
      });

      return await response.json();
    } catch (error) {
      console.error('Available features retrieval error:', error);
      throw error;
    }
  }
}