Skip to content

mbates/squareup

Repository files navigation

Node.js      TypeScript      Square

@bates-solutions/squareup

The modern TypeScript SDK for Square payments
Build payment backends with type-safe APIs, fluent builders, and webhook support.

License: MIT TypeScript


Stop wrestling with Square's low-level APIs. squareup gives you a simplified client API and fluent builders that make payment integration straightforward. Process payments, manage orders, handle webhooks—all with full TypeScript support and zero boilerplate.

Features

  • Simplified APIs - Less boilerplate, more productivity
  • Type-Safe - Full TypeScript support with strict types
  • Fluent Builders - Chainable order and payment construction
  • Webhook Support - Signature verification and middleware for Express/Next.js
  • Service Classes - Payments, Orders, Customers, Customer Groups, Catalog (incl. pricing rules and subscription plan listing), Inventory, Subscriptions, Invoices, Loyalty

Requirements

Dependency Version
Square SDK ^43.0.0
Node.js 22+
TypeScript 5.0+

Installation

npm install @bates-solutions/squareup square

Quick Start

Basic Usage

import { createSquareClient } from '@bates-solutions/squareup';

const client = createSquareClient({
  accessToken: process.env.SQUARE_ACCESS_TOKEN!,
  environment: 'sandbox',
});

// Process a payment
const payment = await client.payments.create({
  sourceId: 'cnon:card-nonce',
  amount: 1000, // $10.00
  currency: 'USD',
});

// Create an order with the fluent builder
const order = await client.orders.create(
  client.orders
    .builder()
    .addItem({ name: 'Coffee', quantity: 2, amount: 450 })
    .addItem({ name: 'Muffin', quantity: 1, amount: 350 })
    .build()
);

// Search recent completed orders
const { data: orders } = await client.orders.searchRecent({
  states: ['COMPLETED'],
  since: new Date(Date.now() - 60 * 60 * 1000), // last hour
});

// Manage customers
const customer = await client.customers.create({
  givenName: 'John',
  familyName: 'Doe',
  emailAddress: 'john@example.com',
});

// List customers with pagination
const page1 = await client.customers.list({ limit: 50 });
const page2 = await client.customers.list({ cursor: page1.cursor, limit: 50 });

// Search customers by name, email, company, or city
const results = await client.customers.search({ query: 'john doe' });

Webhook Handling (Express)

import express from 'express';
import { createWebhookHandler, rawBodyMiddleware } from '@bates-solutions/squareup/server';

const app = express();

// Use raw body middleware before JSON parsing for webhook routes
app.use('/webhooks/square', rawBodyMiddleware);
app.use(express.json());

const webhookHandler = createWebhookHandler({
  signatureKey: process.env.SQUARE_WEBHOOK_SIGNATURE_KEY!,
});

app.post('/webhooks/square', (req, res) => {
  const event = webhookHandler.verifyAndParse(req);

  switch (event.type) {
    case 'payment.completed':
      console.log('Payment completed:', event.data);
      break;
    case 'order.created':
      console.log('Order created:', event.data);
      break;
  }

  res.sendStatus(200);
});

Webhook Handling (Next.js)

// app/api/webhooks/square/route.ts
import { createWebhookHandler } from '@bates-solutions/squareup/server';

const webhookHandler = createWebhookHandler({
  signatureKey: process.env.SQUARE_WEBHOOK_SIGNATURE_KEY!,
});

export async function POST(request: Request) {
  const body = await request.text();
  const signature = request.headers.get('x-square-hmacsha256-signature')!;

  const event = webhookHandler.verifyAndParse(body, signature);

  // Handle the event
  console.log('Received event:', event.type);

  return new Response('OK', { status: 200 });
}

Typed Webhook Payloads

import type { PaymentWebhookEvent } from '@bates-solutions/squareup/server';
import { getOrderId, getCustomerId } from '@bates-solutions/squareup/server';

// Cast to typed event for full payload types — no `as any` needed
const event = webhookHandler.verifyAndParse(req) as PaymentWebhookEvent;
const payment = event.data.object.payment;
console.log(payment.status, payment.amount_money);

// Or use helpers to extract entity IDs from any event type
const orderId = getOrderId(event);     // works on payment, order, and refund events
const customerId = getCustomerId(event); // works on payment and customer events

Webhook Handling (AWS Lambda)

import { createLambdaWebhookHandler } from '@bates-solutions/squareup/server';

export const handler = createLambdaWebhookHandler({
  signatureKey: process.env.SQUARE_WEBHOOK_SIGNATURE_KEY!,
  handlers: {
    'payment.completed': async (event, context) => {
      // context.orderId, context.customerId auto-extracted
      await processPayment(event.data.id, context.orderId!);
    },
  },
});

Available Services

Service Description
payments Process and manage payments
orders Create and manage orders
customers Customer management
customerGroups Customer groups + group membership (gates pricing rules)
catalog Product catalog ops, incl. pricing rules and wholesale pricing
inventory Inventory tracking
subscriptions Subscription management
invoices Invoice operations
loyalty Loyalty program management
checkout Hosted checkout sessions

Utilities

import { toCents, fromCents, formatMoney } from '@bates-solutions/squareup';

toCents(10.99);           // 1099
fromCents(1099);          // 10.99
formatMoney(1099, 'USD'); // "$10.99"

Contributing

We welcome contributions! Please see our Contributing Guide for details.

License

MIT - see LICENSE for details.

About

TypeScript SDK for the Square API with simplified pagination, search, and CRUD operations

Resources

License

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors