Alternative Payments Customers

SkillCommerce & finance

Alternative Payments customers and their users: customer fields and status, the customer/user relationship, MSP client onboarding, and the destructive archive operation that requires confirmation.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Alternative Payments Customers skill

What this skill tells your AI

The instructions your AI receives, as published by wyre-ai/msp-claude-plugins in msp-claude-plugins/alternative-payments/alternative-payments/skills/customers/SKILL.md and read by ahel’s review.

Overview

Customers are the foundational entity in Alternative Payments — every invoice, payment request, transaction, and payout traces back to a customer. For MSPs, a customer is typically a managed services client (a business you bill on a recurring or project basis). Each customer can have one or more users — the individual contacts at that business who receive invoices and pay them.

This skill covers the read + safe-write customer surface: listing, retrieving, and creating customers, adding users, and archiving (a destructive operation). There is no direct money-movement operation here.

Anti-triggers

  • The same client in the accounting ledger — an Alternative Payments customer is a billing target on the payment rail with no GL contact record; use xero-contacts or qbo-customers.
  • The same client in the CRM — use hubspot-companies or salesbuildr-companies-contacts.
  • Billing that customer — use alternative-payments-invoicing.

Core Concepts

Customers and Users

EntityDescriptionMSP Example
CustomerA business you bill"Acme Corp"
UserA contact at that business"billing@acme.com"

A customer is created first; users are then attached under /customers/{id}/users. Invoices and payment requests reference the customer.

Customer Status

StatusDescription
activeNormal, billable customer (default)
archivedHidden from default lists; preserved for history

Archiving is performed with DELETE /customers/{id} — it does not hard-delete the record. Treat it as destructive and confirm before running it.

Field Reference

Customer Fields

FieldTypeRequiredDescription
idstringSystemAuto-generated unique identifier
namestringYesBusiness/company name
emailstringNoPrimary billing email
phonestringNoPrimary phone number
external_idstringNoYour PSA/internal reference for cross-linking
addressobjectNoBilling address (line1, city, region, postal_code, country)
statusstringRead-onlyactive or archived
created_atdatetimeRead-onlyCreation timestamp

User Fields

FieldTypeRequiredDescription
idstringSystemAuto-generated unique identifier
first_namestringYesUser first name
last_namestringYesUser last name
emailstringYesUser email address
phonestringNoUser phone number

API Patterns

All requests carry a bearer token (Authorization: Bearer <token>). See Alternative Payments API Patterns for the OAuth2 client-credentials token flow, the 5 req/sec rate limit, and cursor pagination.

List Customers

curl -s "https://public-api.alternativepayments.io/customers?limit=100" \
  -H "Authorization: Bearer ${TOKEN}"

Responses are cursor-paginated — items are in data[] with a next_cursor / has_more indicator. Pass after=<cursor> to fetch the next page.

curl -s "https://public-api.alternativepayments.io/customers?limit=100&after=cursor_abc" \
  -H "Authorization: Bearer ${TOKEN}"

Get a Single Customer

curl -s "https://public-api.alternativepayments.io/customers/${CUSTOMER_ID}" \
  -H "Authorization: Bearer ${TOKEN}"

Create a Customer

curl -s -X POST "https://public-api.alternativepayments.io/customers" \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Corp",
    "email": "billing@acme.com",
    "phone": "+1-217-555-0123",
    "external_id": "MSP-ACME-001",
    "address": {
      "line1": "123 Main Street",
      "city": "Springfield",
      "region": "IL",
      "postal_code": "62704",
      "country": "US"
    }
  }'

List a Customer's Users

curl -s "https://public-api.alternativepayments.io/customers/${CUSTOMER_ID}/users?limit=100" \
  -H "Authorization: Bearer ${TOKEN}"

Add a User to a Customer

curl -s -X POST "https://public-api.alternativepayments.io/customers/${CUSTOMER_ID}/users" \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "first_name": "Jordan",
    "last_name": "Lee",
    "email": "jordan.lee@acme.com",
    "phone": "+1-217-555-0144"
  }'

Archive a Customer (Destructive — Confirm First)

DELETE /customers/{id} archives the customer. Always confirm with the user before running it, and verify there are no outstanding invoices first.

curl -s -X DELETE "https://public-api.alternativepayments.io/customers/${CUSTOMER_ID}" \
  -H "Authorization: Bearer ${TOKEN}"

A 204 No Content indicates success.

JavaScript Example

async function createCustomer(token, customer) {
  const res = await fetch('https://public-api.alternativepayments.io/customers', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(customer)
  });
  const text = await res.text();
  if (!res.ok) throw new Error(`Create customer failed (${res.status}): ${text}`);
  return JSON.parse(text);
}

Common Workflows

MSP Client Onboarding

  1. Create the customer with company name, billing email, and your PSA id in external_id
  2. Add billing users so invoices reach the right contacts
  3. Create the first invoice (see Invoicing)
async function onboardClient(token, client) {
  const customer = await createCustomer(token, {
    name: client.companyName,
    email: client.billingEmail,
    external_id: client.psaId
  });

  for (const u of client.contacts) {
    await fetch(
      `https://public-api.alternativepayments.io/customers/${customer.id}/users`,
      {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${token}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(u)
      }
    );
  }
  return customer;
}

Client Offboarding

  1. Verify no outstanding invoices (see Payments & Payouts)
  2. Confirm with the operator — archiving is destructive
  3. Archive with DELETE /customers/{id}

Cross-Reference with a PSA

Store your PSA/internal client id in external_id, then filter or match on it when reconciling Alternative Payments activity against your billing system.

Error Handling

CodeMeaningAction
201Customer/user createdProcess response
204ArchivedTreat as success
400 / 422Validation errorInspect the errors array; fix the request
401UnauthorizedRefresh token, retry once
404Customer not foundVerify the customer id
429Rate limitedBack off (Retry-After), retry

Best Practices

  1. Set external_id — map to your PSA client id for clean reconciliation.
  2. Add at least one user — invoices and payment links need a recipient.
  3. Confirm before archivingDELETE is destructive; check for open invoices first.
  4. Paginate with cursors — loop on has_more / next_cursor for large lists.
  5. Stay under 5 req/sec — batch onboarding loops should pace their requests.

Endpoint Reference

EndpointMethodDescription
/customersGETList customers (cursor-paginated)
/customersPOSTCreate a customer
/customers/{id}GETGet a single customer
/customers/{id}DELETEArchive a customer (destructive)
/customers/{id}/usersGETList a customer's users
/customers/{id}/usersPOSTAdd a user to a customer

Related Skills

Signals

GitHub stars
45
Forks
24
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
alternative-payments-customers
Source
github.com/wyre-ai/msp-claude-plugins