Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,5 @@ jobs:
- name: Install dependencies
run: npm ci

- name: Install mint
run: npm i -g mint

- name: Lint
run: make lint
52 changes: 41 additions & 11 deletions mintlify/openapi.yaml

Large diffs are not rendered by default.

37 changes: 19 additions & 18 deletions mintlify/snippets/cards/embedded-wallet-funding.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ curl -X POST "$GRID_BASE_URL/cards" \
The card's `currency` is `USD`. The wallet holds USDB, which Grid converts
1:1, so a $12.50 authorization pulls 12.50 USDB.

The card comes back in `status: "PROCESSING"` and activates through the
The card comes back in `status: "PROCESSING"` and moves to `PENDING_AUTH` through the
`CARD.STATUS_CHANGE` webhook as described in
[Issuing cards](/cards/card-management/issuing-cards). An `ACTIVE` card with
no active delegated key declines every authorization, so complete the next
section before you show the card to the cardholder.
[Issuing cards](/cards/card-management/issuing-cards). Complete the next
section to authorize funding and activate the card before you show it to
the cardholder.

Set `maxSpendPerTransaction` and `maxSpendPerDay`. Spend controls work the same
way for a wallet-funded card as for any other card: the values on the card cap
Expand Down Expand Up @@ -231,29 +231,30 @@ Two behaviors differ from a custodial funding source:

## What fails without an active key

Grid checks for the delegated key when it goes to sign the pull, not before.
If the card's funding source has no `ACTIVE` key (never created, still
`PENDING`, or revoked), the signing step fails and Grid declines the
authorization. Nothing is pulled from the wallet.
If an otherwise enabled card's funding source has no `ACTIVE` key (never
created, still `PENDING`, or revoked), the provisioned card is `PENDING_AUTH` with
`statusReason: "DELEGATION_REQUIRED"`. Grid declines new synchronous
authorizations before pulling funds from the wallet.

The card transaction is recorded with `status: "DECLINED"` and
`cardDeclinedReason: "OTHER"`, and a `CARD_TRANSACTION.DECLINED` webhook
fires. The decline does not name the missing key, so check for it directly
when you investigate a declined card funded from a wallet:
`cardDeclinedReason: "CARD_NOT_ACTIVE"`, and a `CARD_TRANSACTION.DECLINED`
webhook fires. Check the card's `statusReason` and its funding source's
delegated keys when you investigate a pending wallet-funded card:

```bash
curl -X GET "$GRID_BASE_URL/auth/delegated-keys?fundingSourceId=CardFundingSource:019542f5-b3e7-1d02-0000-000000000011" \
-u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET"
```

An empty `data` array, or one with no `ACTIVE` entry, means every
authorization on that card declines until the cardholder completes the
three-leg flow again.
An empty `data` array, or one with no `ACTIVE` entry, means the cardholder
must complete the three-leg flow, including both signed retries. Once the
new key is `ACTIVE`, the pending card becomes `ACTIVE` automatically and
emits `CARD.STATUS_CHANGE`.

The same decline path applies when the cardholder revokes the key: the card
stays `ACTIVE`, and every authorization declines. To stop a card from
spending without touching the key, freeze it with `PATCH /cards/{id}` and
`status: "FROZEN"`.
Revoking the required key moves an active card to `PENDING_AUTH` and emits
`CARD.STATUS_CHANGE`. Processing, frozen, and closed cards retain their
status. To stop a card from spending without touching the key, freeze it
with `PATCH /cards/{id}` and `status: "FROZEN"`.

## Manage the key

Expand Down
8 changes: 8 additions & 0 deletions mintlify/snippets/cards/funding-sources.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,11 @@ curl -X PATCH "$GRID_BASE_URL/cards/Card:019542f5-b3e7-1d02-0000-000000000010" \

To permanently retire a card, close it with `PATCH /cards/{id}` and
`status: "CLOSED"`.

## Funding authorization and readiness

Replacing USD funding with a USDB Embedded Wallet without an active
delegated key moves an active card to `PENDING_AUTH`. Complete all signed retries
of `POST /auth/delegated-keys` to restore `ACTIVE`. A key for another card or
funding source does not authorize this binding. Frozen and closed cards
retain their status.
8 changes: 8 additions & 0 deletions mintlify/snippets/cards/implementation-overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,11 @@ When you're ready to go live:
Contact your Lightspark representative to enable Production card
issuance and finalize issuer activations.
</Check>

## USDB funding authorization

A provisioned card funded by a USDB Embedded Wallet is `PENDING_AUTH` until all
signed retries of `POST /auth/delegated-keys` are complete. Successful
delegation restores `ACTIVE`; funding changes or key revocation can return
an active card to `PENDING_AUTH`. Frozen and closed cards keep their status when
delegation completes.
3 changes: 2 additions & 1 deletion mintlify/snippets/cards/intro.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ See [Card PINs](/cards/card-management/pins) to let cardholders set, change, or

## Card lifecycle at a glance

A card moves through five states:
A card moves through six states:

| State | Meaning |
|-------|---------|
| `PENDING_KYC` | Cardholder has not finished KYC; the card cannot transact yet. |
| `PROCESSING` | Card has been requested and is being provisioned with the issuer. |
| `PENDING_AUTH` | Issuer provisioning is complete; USDB Embedded Wallet funding requires delegated signing authorization. |
| `ACTIVE` | Card is live and can authorize transactions. |
| `FROZEN` | Card is temporarily disabled. New authorizations are declined; in-flight settlements continue. |
| `CLOSED` | Card is permanently closed. Terminal, irreversible. |
Expand Down
25 changes: 22 additions & 3 deletions mintlify/snippets/cards/issuing-cards.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,19 @@ spending-limit units.
## The lifecycle

```text
PROCESSING ──► ACTIVE ◄──► FROZEN
│
└──► CLOSED
USD: PROCESSING ──► ACTIVE ◄──► FROZEN

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.

hmm, this is missing PENDING_KYC?

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.

or maybe we remove PENDING_KYC and make sure its represented as a statusReason?

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.

Also just curious but what if it needs KYC AND delegation. Are we sure this will still work properly in that case?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yea if we need KYC and delegation, we are in PROCESSING status because something still needs to be done on our side. If:
- KYC completes, status moves to PENDING
- Delegation completes, status moces to PROCESSING

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

PROCESSING is also the status when KYC needs to be approved on our side

│ │
└───────────┴──► CLOSED

USDB: PROCESSING ──► PENDING_AUTH ◄──► ACTIVE ◄──► FROZEN
│ │ │
└─────────────────┴───────────┴──► CLOSED
```

| State | When you see it |
|-------|-----------------|
| `PROCESSING` | Returned synchronously from `POST /cards`. The card cannot transact yet. |
| `PENDING_AUTH` | The issuer has provisioned the card, but its USDB Embedded Wallet funding source has no active delegated key. Complete delegated-key setup. |
| `ACTIVE` | Issuer provisioned the card. Reached via `CARD.STATUS_CHANGE` webhook. |
| `FROZEN` | You called `PATCH /cards/{id}` with `status: "FROZEN"`. |
| `CLOSED` | You called `PATCH /cards/{id}` with `status: "CLOSED"`. Terminal. |
Expand All @@ -60,6 +65,20 @@ issuer provisions the card asynchronously; on success a
`CARD.STATUS_CHANGE` webhook fires with the activated `Card` resource
including the populated `last4`, `expMonth`, and `expYear`.

For USDB Embedded Wallet funding without an active delegated key, the
provisioning webhook reports `PENDING_AUTH` with `statusReason: "DELEGATION_REQUIRED"`.
Complete all three calls to `POST /auth/delegated-keys`, including both signed
retries. When the final retry returns an `ACTIVE` delegated key, the pending
card becomes `ACTIVE` automatically and emits `CARD.STATUS_CHANGE`.

USD funding does not require delegation. If delegation completes before
provisioning, the card can go directly from `PROCESSING` to `ACTIVE`.

Replacing USD funding with USDB lacking an active key can move an active
card back to `PENDING_AUTH`. Switching back to USD, or completing delegation,
restores readiness. Revoking the required key also moves an active card to
`PENDING_AUTH`. Frozen and closed cards retain their status.

## Revealing the PAN

To show the cardholder their full PAN, CVV, and expiry, request a
Expand Down
8 changes: 8 additions & 0 deletions mintlify/snippets/cards/quickstart.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,11 @@ event model.
You've issued a card, watched it activate, and driven an over-auth
transaction through pull and clearing.
</Check>

## USDB funding authorization

A provisioned card funded by a USDB Embedded Wallet is `PENDING_AUTH` until all
signed retries of `POST /auth/delegated-keys` are complete. Successful
delegation restores `ACTIVE`; funding changes or key revocation can return
an active card to `PENDING_AUTH`. Frozen and closed cards keep their status when
delegation completes.
5 changes: 3 additions & 2 deletions mintlify/snippets/cards/webhooks.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ lifecycle.

| Type | Fires on |
|------|----------|
| `CARD.STATUS_CHANGE` | `PROCESSING → ACTIVE`, `→ CLOSED (ISSUER_REJECTED)`, and every subsequent `ACTIVE ⇄ FROZEN` and `→ CLOSED` transition. |
| `CARD.STATUS_CHANGE` | `PROCESSING → ACTIVE / PENDING_AUTH`, `ACTIVE ⇄ PENDING_AUTH`, `→ CLOSED (ISSUER_REJECTED)`, and every subsequent `ACTIVE ⇄ FROZEN`, `PENDING_AUTH → FROZEN`, and `→ CLOSED` transition. |
| `CARD.PIN_STATUS_CHANGE` | Grid records a new PIN status, such as `NOT_SET → OK`, `OK → BLOCKED`, or `BLOCKED → OK`. |
| `CARD_TRANSACTION.AUTHORIZED` | An authorization is approved and a hold is placed on the funding source. |
| `CARD_TRANSACTION.PARTIALLY_SETTLED` | A clearing posted, but more are still expected. |
Expand Down Expand Up @@ -64,7 +64,8 @@ activation after issuance:

Common branches to handle in your consumer:

- `status: "ACTIVE"` after `PROCESSING` — the card is live. To reveal
- `status: "PENDING_AUTH"` — complete delegated-key setup for the funding source.
- `status: "ACTIVE"` after `PROCESSING` or `PENDING_AUTH` — the card is live. To reveal
the full card details, request a reveal with
`POST /cards/{id}/reveal` right before rendering its short-lived
`panEmbedUrl` in an iframe — webhook payloads never carry a reveal
Expand Down
Loading
Loading