# Payment Source

URL: /business/nouns/payment-source · Id: `noun:payment-source`

> A Payment Source is a card, bank debit or wallet a Customer saves with a Startup, held at Stripe and charged for Orders and Invoices.

A Payment Source is a card, bank debit or wallet a [Customer](/business/nouns/customer) saves with a [Startup](/business/nouns/startup), held at Stripe and charged for [Orders](/business/nouns/order) and [Invoices](/business/nouns/invoice).

## Properties
| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `kind` | `string` | Yes | How it pays: a card, a bank debit from the Customer’s account, or a wallet on the Customer’s phone or browser. |
| `label` | `string` | Yes | What the Customer sees, such as the card brand and last four digits; never the full number. |
| `expiresOn` | `date` | No | When a card expires; the billing portal asks for a new one 30 days before. |
| `default` | `boolean` | No | True for the one Payment Source that new Invoices and renewals charge. |
| `removedAt` | `datetime` | No | When the Customer removed it; nothing charges it after, and the record stays. |

## Object
```json
{
  "$id": "https://api.sb/kilnbakery.com/payment-sources/payment_source_1",
  "$type": "PaymentSource",
  "kind": "card",
  "label": "Visa 4242",
  "expiresOn": "2026-10-22",
  "default": true,
  "removedAt": "2026-10-22T12:00:00Z"
}
```

## Relationships
- <a id="rel-saved-by"></a>A Payment Source **is saved by** one [Customer](/business/nouns/customer): a [Customer](/business/nouns/customer) saves the Payment Sources its [Orders](/business/nouns/order), [Subscriptions](/business/nouns/subscription) and [Invoices](/business/nouns/invoice) charge; each belongs to one [Startup](/business/nouns/startup) and never moves to a sibling. `savedBy`, inverse [`saves`](/business/nouns/customer#rel-saves).

## Verbs
| Verb | Description | Subject | Event | Class |
| --- | --- | --- | --- | --- |
| [PaymentSource.add](/business/nouns/payment-source/add) | Add saves a new Payment Source for a Customer through Stripe’s embedded form on the Startup’s Domain, and can make it the default. | [Billing Specialist](/agents/finance/billing-specialist) | [`PaymentSource.added`](/business/events/PaymentSource.added) | Two-way: `try`, `send`, `do` |
| [PaymentSource.remove](/business/nouns/payment-source/remove) | Remove detaches a saved Payment Source so nothing charges it again, and keeps the record. | [Billing Specialist](/agents/finance/billing-specialist) | [`PaymentSource.removed`](/business/events/PaymentSource.removed) | Two-way: `try`, `send`, `do` |
| <a id="get"></a>[PaymentSource.get](/business/nouns/payment-source/get) | Returns one Payment Source by id. Inherited from [Noun](/business/nouns/noun). | None. | None. | Read: `try`, `do` |
| <a id="list"></a>[PaymentSource.list](/business/nouns/payment-source/list) | Returns Payment Sources, newest first, one page at a time. Inherited from [Noun](/business/nouns/noun). | None. | None. | Read: `try`, `do` |
| <a id="update"></a>[PaymentSource.update](/business/nouns/payment-source/update) | Changes the given properties of a Payment Source. Inherited from [Noun](/business/nouns/noun). | None. | `PaymentSource.updated` | Two-way: `try`, `send`, `do` |

## Permissions
Which Access level may call each Verb. One-way Verbs wait their delay window.

| Operation | `owner` | `admin` | `member` | `viewer` |
| --- | --- | --- | --- | --- |
| `PaymentSource.get` | Yes | Yes | Yes | Yes |
| `PaymentSource.list` | Yes | Yes | Yes | Yes |
| `PaymentSource.update` | Yes | Yes | Yes | No |
| `PaymentSource.add` | Yes | Yes | Yes | No |
| `PaymentSource.remove` | Yes | Yes | Yes | No |

## Call it

**Ask**

```text
Add the latest payment source with a customer.
```

**API**

```bash
curl -X POST https://api.sb/petpantry.shop/payment-sources/add \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"customer":"customer_1","kind":"card"}'
```

```json
{
  "api": "https://api.sb/petpantry.shop",
  "paymentSource": {
    "$id": "https://api.sb/petpantry.shop/payment-sources/payment_source_1",
    "$type": "PaymentSource",
    "kind": "card",
    "label": "Visa 4242"
  },
  "action": {
    "$id": "https://api.sb/petpantry.shop/actions/action_1",
    "operation": "PaymentSource.add",
    "status": "done"
  },
  "links": {
    "self": "https://api.sb/petpantry.shop/actions/action_1"
  }
}
```

**SDK**

```ts
import { $ } from 'startup-builder'

const paymentSource = await $.PaymentSource.add({ customer: 'customer_1', kind: 'card' })
```

**CLI**

```bash
npx startup-builder do PaymentSource.add --json '{"customer":"customer_1","kind":"card"}'
```

**MCP**

```json
{
  "name": "do",
  "arguments": {
    "code": "return await $.PaymentSource.add({ customer: 'customer_1', kind: 'card' })"
  }
}
```

## Example
A clinic on shiftnote.app saves a card ending 4242 as its default Payment Source and a bank debit as a backup. When the card expires, its renewal fails, and adding a new card in the [Portal](/business/nouns/portal) pays the open [Invoice](/business/nouns/invoice) at once.