Skip to content

feat(cards): bind one funding source per card - #934

Draft
whoisglover wants to merge 1 commit into
eng-11645-docs-cleanupfrom
eng-11645-funding-source
Draft

feat(cards): bind one funding source per card#934
whoisglover wants to merge 1 commit into
eng-11645-docs-cleanupfrom
eng-11645-funding-source

Conversation

@whoisglover

@whoisglover whoisglover commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Jira: ENG-11660 under ENG-11645

What this does

The cards API let a platform bind an ordered list of internal accounts to a card, and the docs said Authorization Decisioning would try them in that order. The server never did that. It pulls from one account, the oldest active binding, and a failed hold does not fall through to the next one.

This PR makes the contract match: a card has exactly one fundingSource. The fundingSources array is gone from the card resource, the create request, and the update request. Breaking change with no alias, decided by Danny on 2026-09-09.

Changes

  • Card, CardCreateRequest: fundingSource is a required string, the internal account id that funds the card.
  • CardUpdateRequest: fundingSource is an optional string that replaces the bound account. It cannot be combined with state: CLOSED. To stop spending, freeze the card.
  • GET /cards?accountId= returns cards whose fundingSource is that account.
  • The issue-a-card and update descriptions drop every mention of priority order and "at least one source".
  • The funding-sources guide is rewritten around one source per card.
  • Grid CLI: --funding-sources <list> becomes --funding-source <id> on cards create and cards update. An empty value is rejected instead of sending an empty PATCH.

What has to land with this

The server accepts the array today. The webdev change that reads fundingSource, rejects a second source, and raises FUNDING_SOURCE_INELIGIBLE as documented merges in the same window, along with the dashboard and the observatory sandbox card canary that still send the array.

Verification

make build and make lint pass. cd cli && npm test passes, 80 tests. A repo-wide grep for fundingSources, priority order, and at least one source returns only the guide's URL slug.

@vercel

vercel Bot commented Sep 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Actions Updated
grid-flow-builder Ignored Ignored Preview Sep 10, 2026 5:00pm UTC
grid-wallet-demo Ignored Ignored Preview Sep 10, 2026 5:00pm UTC

Request Review

@github-actions

github-actions Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

✱ Stainless preview builds for grid

This PR will update the grid SDKs with the following commit messages.

cli
⏳ (generating...)```
feat(cards): bind one funding source per card

**go**
⏳ (generating...)```
feat(cards): bind one funding source per card

kotlin
⏳ (generating...)```
feat(cards): bind one funding source per card

**openapi**
⏳ (generating...)```
feat(cards): bind one funding source per card

php
⏳ (generating...)```
feat(cards): bind one funding source per card

**python**
⏳ (generating...)```
feat(cards): bind one funding source per card

ruby
⏳ (generating...)```
feat(cards): bind one funding source per card

**typescript**
⏳ (generating...)```
feat(cards): bind one funding source per card

Edit this comment to update them. They will appear in their respective SDK's changelogs.

grid-typescript studio
grid-openapi studio
grid-ruby studio
grid-kotlin studio
grid-go studio
grid-python studio
grid-php studio
grid-cli studio

⏳ These are partial results; builds are still running.


This comment is auto-generated by GitHub Actions and is automatically kept up to date as you push.
If you push custom code to the preview branch, re-run this workflow to update the comment.
Last updated: 2026-09-10 17:11:43 UTC

@whoisglover

Copy link
Copy Markdown
Contributor Author

@greptile review

@greptile-apps

greptile-apps Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 3/5

The PR does not appear safe to merge until the breaking card contract receives a new API version and the remaining maxTransactionsPerDay update-contract inconsistency is resolved.

Findings

  1. P1 API version is unchanged
  2. P1 Transaction limit property missing
Fix with agent prompt
### Issue 1
openapi/components/schemas/cards/CardCreateRequest.yaml:undefined-5
This required-field rename from `fundingSources` to `fundingSource` changes the request from an array to a string, making it a breaking contract change. The repository requires breaking changes to bump `info.version` and use a matching new `servers.url`, but both remain `2025-10-13`. Existing clients using that versioned endpoint can therefore receive an incompatible contract without a new API version to migrate to.

### Issue 2
openapi/components/schemas/cards/CardUpdateRequest.yaml:3-5
`CardUpdateRequest` still lists `maxTransactionsPerDay` as an accepted update, and the PATCH examples send it, but the request schema does not define that property. Generated clients and schema validators therefore cannot represent this documented transaction-limit update.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

  • Replaces fundingSources with fundingSource across card resources, create and update requests, examples, webhooks, and guides.
  • Updates Grid CLI card options and validates empty funding-source identifiers locally.
  • Aligns list filtering and card terminology around customerId and the single bound account.
  • Adds CARD to the shared transaction-type enum to match the existing card-transaction union.
  • The previously reported API-version issue remains outstanding.
  • The previously reported transaction-limit schema inconsistency remains: CardUpdateRequest still claims maxTransactionsPerDay is accepted and an example still sends it, while the property is absent.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart LR
    CLI[Grid CLI<br/>--funding-source] --> Create[POST /cards]
    CLI --> Update[PATCH /cards/:id]
    Create --> Card[Card.fundingSource]
    Update --> Card
    Card --> Account[One InternalAccount]
    Card --> List[GET /cards?accountId=...]
    Card --> Webhook[Card state webhook payload]
Loading

Reviews (3) · Last reviewed commit: "feat(cards): bind one funding source per..."

- customerId
- form
- fundingSources
- fundingSource

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 API version is unchanged

This required-field rename from fundingSources to fundingSource changes the request from an array to a string, making it a breaking contract change. The repository requires breaking changes to bump info.version and use a matching new servers.url, but both remain 2025-10-13. Existing clients using that versioned endpoint can therefore receive an incompatible contract without a new API version to migrate to.

Context Used: CLAUDE.md (source)

Knowledge Base Used: Grid API contract

Prompt To Fix With AI
This is a comment left during a code review.
Path: openapi/components/schemas/cards/CardCreateRequest.yaml
Line: 5

Comment:
**API version is unchanged**

This required-field rename from `fundingSources` to `fundingSource` changes the request from an array to a string, making it a breaking contract change. The repository requires breaking changes to bump `info.version` and use a matching new `servers.url`, but both remain `2025-10-13`. Existing clients using that versioned endpoint can therefore receive an incompatible contract without a new API version to migrate to.

**Context Used:** CLAUDE.md ([source](https://github.com/lightsparkdev/grid-api/blob/main/CLAUDE.md))

**Knowledge Base Used:** [Grid API contract](https://app.greptile.com/lightspark/-/custom-context/knowledge-base/lightsparkdev/grid-api/-/docs/api-contract.md)

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Comment thread cli/src/commands/cards.ts Outdated
@whoisglover
whoisglover force-pushed the eng-11645-funding-source branch from 165dda9 to 262c543 Compare September 10, 2026 15:46
@whoisglover

Copy link
Copy Markdown
Contributor Author

@greptile review

Comment on lines 3 to 5
Update request for `PATCH /cards/{id}`. At least one of `state`,
`fundingSources`, `maxSpendPerTransaction`, `maxSpendPerDay`, or
`fundingSource`, `maxSpendPerTransaction`, `maxSpendPerDay`, or
`maxTransactionsPerDay` must be supplied. `state`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Transaction limit property missing

CardUpdateRequest still lists maxTransactionsPerDay as an accepted update, and the PATCH examples send it, but the request schema does not define that property. Generated clients and schema validators therefore cannot represent this documented transaction-limit update.

Prompt To Fix With AI
This is a comment left during a code review.
Path: openapi/components/schemas/cards/CardUpdateRequest.yaml
Line: 3-5

Comment:
**Transaction limit property missing**

`CardUpdateRequest` still lists `maxTransactionsPerDay` as an accepted update, and the PATCH examples send it, but the request schema does not define that property. Generated clients and schema validators therefore cannot represent this documented transaction-limit update.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

@whoisglover
whoisglover force-pushed the eng-11645-funding-source branch from 262c543 to acbe107 Compare September 10, 2026 16:57
@whoisglover
whoisglover changed the base branch from eng-11645-customer-id to eng-11645-docs-cleanup September 10, 2026 16:58
@whoisglover
whoisglover force-pushed the eng-11645-funding-source branch from acbe107 to 49981f9 Compare September 10, 2026 16:59
@whoisglover

Copy link
Copy Markdown
Contributor Author

@greptile review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant