diff --git a/mintlify/openapi.yaml b/mintlify/openapi.yaml index 9beb0ec9..1290b4eb 100644 --- a/mintlify/openapi.yaml +++ b/mintlify/openapi.yaml @@ -7030,7 +7030,7 @@ paths: type: string get: summary: Get a card - description: Retrieve a card by its system-generated id. + description: Retrieve a card by its system-generated id. This is the only endpoint that returns a populated `panEmbedUrl` — a fresh, short-lived signed URL is minted on each call. Fetch the card right before rendering the PAN-reveal iframe. operationId: getCardById tags: - Cards @@ -8566,7 +8566,7 @@ webhooks: last4: '4242' expMonth: 12 expYear: 2029 - panEmbedUrl: https://embed.lithic.com/iframe/...?t=... + panEmbedUrl: null fundingSources: - InternalAccount:019542f5-b3e7-1d02-0000-000000000002 currency: USD @@ -8586,6 +8586,7 @@ webhooks: state: CLOSED stateReason: ISSUER_REJECTED form: VIRTUAL + panEmbedUrl: null fundingSources: - InternalAccount:019542f5-b3e7-1d02-0000-000000000002 currency: USD @@ -8607,6 +8608,7 @@ webhooks: last4: '4242' expMonth: 12 expYear: 2029 + panEmbedUrl: null fundingSources: - InternalAccount:019542f5-b3e7-1d02-0000-000000000002 currency: USD @@ -12321,7 +12323,7 @@ components: - SAVINGS bankName: type: string - description: The name of the bank + description: The name of the beneficiary's bank minLength: 1 maxLength: 255 example: Banco GYT Continental @@ -19693,9 +19695,11 @@ components: description: Card expiration year (four digits). example: 2029 panEmbedUrl: - type: string + type: + - string + - 'null' format: uri - description: URL of the card processor's iframe that securely displays the PAN, CVV, and expiry to the cardholder. The full PAN and CVV never cross Grid's servers — render this URL in an iframe in your client to reveal card details. + description: Signed URL of the card processor's iframe that securely displays the PAN, CVV, and expiry to the cardholder. The full PAN and CVV never cross Grid's servers — render this URL in an iframe in your client to reveal card details. Populated ONLY on `GET /cards/{id}`; null on list, create, and update responses and in webhook payloads. The URL is short-lived (expires within minutes), so fetch the card right before rendering the iframe and never cache the URL. example: https://embed.lithic.com/iframe/...?t=... fundingSources: type: array diff --git a/mintlify/snippets/cards/issuing-cards.mdx b/mintlify/snippets/cards/issuing-cards.mdx index f0c36bbd..aaf8f335 100644 --- a/mintlify/snippets/cards/issuing-cards.mdx +++ b/mintlify/snippets/cards/issuing-cards.mdx @@ -54,17 +54,32 @@ issuance is gated on KYC up front. `POST /cards` returns immediately with `state: "PROCESSING"`. The issuer provisions the card asynchronously; on success a `CARD.STATE_CHANGE` webhook fires with the activated `Card` resource -including the populated `last4`, `expMonth`, `expYear`, and -`panEmbedUrl`. +including the populated `last4`, `expMonth`, and `expYear`. If the issuer rejects provisioning, the same webhook fires with `state: "CLOSED"` and `stateReason: "ISSUER_REJECTED"`. That card is terminal — issue a new one with a fresh `platformCardId` to retry. +## Revealing the PAN + +To show the cardholder their full PAN, CVV, and expiry, fetch the +single card right before rendering: + +```bash +curl -X GET "$GRID_BASE_URL/cards/Card:019542f5-b3e7-1d02-0000-000000000010" \ + -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" +``` + +The response includes a `panEmbedUrl` — a signed URL for the card +processor's iframe that renders the full credentials directly to the +cardholder. The full PAN and CVV never cross your servers or Grid's. + -Render `panEmbedUrl` in an iframe in your client to display the full -PAN, CVV, and expiry to the cardholder. The full credentials never -cross your servers. +`panEmbedUrl` is populated **only** on `GET /cards/{id}` — it is null +on list, create, and update responses and in webhook payloads. The URL +is short-lived (it expires within minutes), so fetch the card each time +the cardholder asks to reveal their details, immediately before +rendering the iframe. Don't cache or store the URL. ## Errors to handle diff --git a/mintlify/snippets/cards/quickstart.mdx b/mintlify/snippets/cards/quickstart.mdx index 459fdc21..5fbd6f34 100644 --- a/mintlify/snippets/cards/quickstart.mdx +++ b/mintlify/snippets/cards/quickstart.mdx @@ -70,7 +70,7 @@ for the full table. When activation completes, a "last4": "4242", "expMonth": 12, "expYear": 2029, - "panEmbedUrl": "https://embed.lithic.com/iframe/...?t=...", + "panEmbedUrl": null, "fundingSources": [ "InternalAccount:019542f5-b3e7-1d02-0000-000000000002" ], @@ -84,9 +84,11 @@ for the full table. When activation completes, a ``` -Render `panEmbedUrl` in an iframe in your client to display the full -PAN, CVV, and expiry to the cardholder. The full card credentials never -cross your servers. +To display the full PAN, CVV, and expiry to the cardholder, fetch +`GET /cards/{id}` and render the returned `panEmbedUrl` in an iframe. +The URL is short-lived and populated only on the single-card GET (it's +null in webhook payloads), so fetch it right before rendering. The full +card credentials never cross your servers. ## Simulate an authorization diff --git a/mintlify/snippets/cards/terminology.mdx b/mintlify/snippets/cards/terminology.mdx index db888832..eeb73669 100644 --- a/mintlify/snippets/cards/terminology.mdx +++ b/mintlify/snippets/cards/terminology.mdx @@ -60,4 +60,6 @@ high-urgency reconciliation alerts and are surfaced as `panEmbedUrl` on the `Card` resource is the issuer's iframe URL that renders the full PAN, CVV, and expiry directly to the cardholder. Render it in an iframe in your client; the full credentials never cross -{` `}Grid's servers. +{` `}Grid's servers. The URL is short-lived and populated only on +`GET /cards/{id}` — fetch the card right before rendering the iframe +rather than caching the URL. diff --git a/mintlify/snippets/cards/webhooks.mdx b/mintlify/snippets/cards/webhooks.mdx index da0f8cd0..2b5340ad 100644 --- a/mintlify/snippets/cards/webhooks.mdx +++ b/mintlify/snippets/cards/webhooks.mdx @@ -47,7 +47,7 @@ activation after issuance: "last4": "4242", "expMonth": 12, "expYear": 2029, - "panEmbedUrl": "https://embed.lithic.com/iframe/...?t=...", + "panEmbedUrl": null, "fundingSources": [ "InternalAccount:019542f5-b3e7-1d02-0000-000000000002" ], @@ -62,8 +62,10 @@ activation after issuance: Common branches to handle in your consumer: -- `state: "ACTIVE"` after `PROCESSING` — the card is live; surface - `panEmbedUrl` to the cardholder. +- `state: "ACTIVE"` after `PROCESSING` — the card is live. To reveal + the full card details, fetch `GET /cards/{id}` right before rendering + its short-lived `panEmbedUrl` in an iframe — the field is always null + in webhook payloads. - `state: "CLOSED"`, `stateReason: "ISSUER_REJECTED"` — the issuer rejected provisioning; offer to issue a new card. - `state: "FROZEN"` / `state: "ACTIVE"` — reflect the freeze toggle in diff --git a/openapi.yaml b/openapi.yaml index 9beb0ec9..1290b4eb 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -7030,7 +7030,7 @@ paths: type: string get: summary: Get a card - description: Retrieve a card by its system-generated id. + description: Retrieve a card by its system-generated id. This is the only endpoint that returns a populated `panEmbedUrl` — a fresh, short-lived signed URL is minted on each call. Fetch the card right before rendering the PAN-reveal iframe. operationId: getCardById tags: - Cards @@ -8566,7 +8566,7 @@ webhooks: last4: '4242' expMonth: 12 expYear: 2029 - panEmbedUrl: https://embed.lithic.com/iframe/...?t=... + panEmbedUrl: null fundingSources: - InternalAccount:019542f5-b3e7-1d02-0000-000000000002 currency: USD @@ -8586,6 +8586,7 @@ webhooks: state: CLOSED stateReason: ISSUER_REJECTED form: VIRTUAL + panEmbedUrl: null fundingSources: - InternalAccount:019542f5-b3e7-1d02-0000-000000000002 currency: USD @@ -8607,6 +8608,7 @@ webhooks: last4: '4242' expMonth: 12 expYear: 2029 + panEmbedUrl: null fundingSources: - InternalAccount:019542f5-b3e7-1d02-0000-000000000002 currency: USD @@ -12321,7 +12323,7 @@ components: - SAVINGS bankName: type: string - description: The name of the bank + description: The name of the beneficiary's bank minLength: 1 maxLength: 255 example: Banco GYT Continental @@ -19693,9 +19695,11 @@ components: description: Card expiration year (four digits). example: 2029 panEmbedUrl: - type: string + type: + - string + - 'null' format: uri - description: URL of the card processor's iframe that securely displays the PAN, CVV, and expiry to the cardholder. The full PAN and CVV never cross Grid's servers — render this URL in an iframe in your client to reveal card details. + description: Signed URL of the card processor's iframe that securely displays the PAN, CVV, and expiry to the cardholder. The full PAN and CVV never cross Grid's servers — render this URL in an iframe in your client to reveal card details. Populated ONLY on `GET /cards/{id}`; null on list, create, and update responses and in webhook payloads. The URL is short-lived (expires within minutes), so fetch the card right before rendering the iframe and never cache the URL. example: https://embed.lithic.com/iframe/...?t=... fundingSources: type: array diff --git a/openapi/components/schemas/cards/Card.yaml b/openapi/components/schemas/cards/Card.yaml index 10ac4aca..5f77387e 100644 --- a/openapi/components/schemas/cards/Card.yaml +++ b/openapi/components/schemas/cards/Card.yaml @@ -51,13 +51,18 @@ properties: description: Card expiration year (four digits). example: 2029 panEmbedUrl: - type: string + type: + - string + - 'null' format: uri description: >- - URL of the card processor's iframe that securely displays the PAN, CVV, - and expiry to the cardholder. The full PAN and CVV never cross Grid's - servers — render this URL in an iframe in your client to reveal card - details. + Signed URL of the card processor's iframe that securely displays the + PAN, CVV, and expiry to the cardholder. The full PAN and CVV never + cross Grid's servers — render this URL in an iframe in your client to + reveal card details. Populated ONLY on `GET /cards/{id}`; null on + list, create, and update responses and in webhook payloads. The URL + is short-lived (expires within minutes), so fetch the card right + before rendering the iframe and never cache the URL. example: https://embed.lithic.com/iframe/...?t=... fundingSources: type: array diff --git a/openapi/components/schemas/common/GtqAccountInfoBase.yaml b/openapi/components/schemas/common/GtqAccountInfoBase.yaml index 8cf8e1be..250c9925 100644 --- a/openapi/components/schemas/common/GtqAccountInfoBase.yaml +++ b/openapi/components/schemas/common/GtqAccountInfoBase.yaml @@ -22,7 +22,7 @@ properties: - SAVINGS bankName: type: string - description: The name of the bank + description: The name of the beneficiary's bank minLength: 1 maxLength: 255 example: Banco GYT Continental diff --git a/openapi/paths/cards/cards_{id}.yaml b/openapi/paths/cards/cards_{id}.yaml index 4aa75103..ff74cd02 100644 --- a/openapi/paths/cards/cards_{id}.yaml +++ b/openapi/paths/cards/cards_{id}.yaml @@ -7,7 +7,11 @@ parameters: type: string get: summary: Get a card - description: Retrieve a card by its system-generated id. + description: >- + Retrieve a card by its system-generated id. This is the only endpoint + that returns a populated `panEmbedUrl` — a fresh, short-lived signed + URL is minted on each call. Fetch the card right before rendering the + PAN-reveal iframe. operationId: getCardById tags: - Cards diff --git a/openapi/webhooks/card-state-change.yaml b/openapi/webhooks/card-state-change.yaml index da96c3bb..679fd812 100644 --- a/openapi/webhooks/card-state-change.yaml +++ b/openapi/webhooks/card-state-change.yaml @@ -58,7 +58,7 @@ post: last4: '4242' expMonth: 12 expYear: 2029 - panEmbedUrl: https://embed.lithic.com/iframe/...?t=... + panEmbedUrl: null fundingSources: - InternalAccount:019542f5-b3e7-1d02-0000-000000000002 currency: USD @@ -78,6 +78,7 @@ post: state: CLOSED stateReason: ISSUER_REJECTED form: VIRTUAL + panEmbedUrl: null fundingSources: - InternalAccount:019542f5-b3e7-1d02-0000-000000000002 currency: USD @@ -99,6 +100,7 @@ post: last4: '4242' expMonth: 12 expYear: 2029 + panEmbedUrl: null fundingSources: - InternalAccount:019542f5-b3e7-1d02-0000-000000000002 currency: USD