Skip to content
Open
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
35 changes: 35 additions & 0 deletions mintlify/platform-overview/core-concepts/quote-system.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,41 @@ curl -X POST https://api.lightspark.com/grid/2025-10-13/quotes/Quote:abc123/exec
}
```

### Strong Customer Authentication (EU Customers)

For customers in regions where Strong Customer Authentication (SCA) is required (e.g., EU), quotes may enter a `PENDING_AUTHORIZATION` status with an `scaChallenge` object. The customer must authorize the challenge before the quote can be executed.

**Quote response with SCA challenge:**

```json
{
"id": "Quote:019542f5-b3e7-1d02-0000-000000000050",
"status": "PENDING_AUTHORIZATION",
"scaChallenge": {
"id": "ScaChallenge:...",
"expiresAt": "2025-10-03T12:05:00Z",
"factor": "SMS_OTP",
"availableFactors": ["SMS_OTP", "PASSKEY"],
"purpose": "PAYOUT"
}
}
```

To authorize the quote, call `POST /quotes/{quoteId}/authorize` with the appropriate proof:

```bash
curl -X POST https://api.lightspark.com/grid/2025-10-13/quotes/Quote:abc123/authorize \
-u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" \
-H "Content-Type: application/json" \
-d '{"code": "123456"}'
```

<Note>
Multiple authorizations may be required in sequence (e.g., currency conversion + payout). After each authorization, check the quote status — if still `PENDING_AUTHORIZATION`, authorize the next challenge.
</Note>

For JIT-funded quotes, `paymentInstructions` are withheld until all SCA challenges are satisfied.

### Execution Timing

<Tabs>
Expand Down
10 changes: 10 additions & 0 deletions mintlify/platform-overview/core-concepts/transaction-lifecycle.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ A single `status` field represents whether the transaction reached its destinati
| Status | Description |
|--------|-------------|
| **PENDING** | Quote is pending confirmation |
| **PENDING_AUTHORIZATION** | Awaiting Strong Customer Authentication. Only occurs for customers in regions where SCA is required (e.g., EU); authorize the transaction's `scaChallenge` to proceed. |

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 Misleading field reference — scaChallenge lives on the quote, not the transaction

The description says "authorize the transaction's scaChallenge", but the only authorize endpoint documented is POST /quotes/{quoteId}/authorize, and the scaChallenge object is shown on the quote response (in quote-system.mdx). A developer who receives an OUTGOING_PAYMENT.PENDING_AUTHORIZATION webhook has a transaction ID, not a quote ID — the status table should either reference the quote's scaChallenge and mention using the quoteId field, or a webhook payload example for this event should be added showing how to obtain the quote ID needed to call /quotes/{quoteId}/authorize.

Prompt To Fix With AI
This is a comment left during a code review.
Path: mintlify/platform-overview/core-concepts/transaction-lifecycle.mdx
Line: 124

Comment:
**Misleading field reference — `scaChallenge` lives on the quote, not the transaction**

The description says "authorize the transaction's `scaChallenge`", but the only authorize endpoint documented is `POST /quotes/{quoteId}/authorize`, and the `scaChallenge` object is shown on the quote response (in `quote-system.mdx`). A developer who receives an `OUTGOING_PAYMENT.PENDING_AUTHORIZATION` webhook has a transaction ID, not a quote ID — the status table should either reference the quote's `scaChallenge` and mention using the `quoteId` field, or a webhook payload example for this event should be added showing how to obtain the quote ID needed to call `/quotes/{quoteId}/authorize`.

How can I resolve this? If you propose a fix, please make it concise.

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.

@claude fix this one.

| **EXPIRED** | Quote wasn't executed before the expiry window |
| **PROCESSING** | Executing the quote after receiving funds (checking internal balances, or push/pull to/from external account) |
| **COMPLETED** | Payout successfully reached the destination account |
Expand All @@ -135,6 +136,9 @@ A single `status` field represents whether the transaction reached its destinati
```mermaid
stateDiagram-v2
[*] --> PENDING : Quote created
PENDING --> PENDING_AUTHORIZATION : SCA required (EU)
PENDING_AUTHORIZATION --> PROCESSING : Authorized
PENDING_AUTHORIZATION --> EXPIRED : Challenge expired
PENDING --> PROCESSING : Quote confirmed, funds received
PENDING --> EXPIRED : Quote expired before execution
PROCESSING --> COMPLETED : Payout reached destination
Expand Down Expand Up @@ -190,6 +194,7 @@ Outgoing payment webhooks use the format `OUTGOING_PAYMENT.<STATUS>`. The webhoo
| Event | Description |
|-------|-------------|
| `OUTGOING_PAYMENT.PENDING` | Transaction created, quote pending confirmation |
| `OUTGOING_PAYMENT.PENDING_AUTHORIZATION` | Awaiting Strong Customer Authentication (EU customers only) |

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.

P2 Missing webhook payload example for PENDING_AUTHORIZATION

The Example Payloads tabs include PENDING, COMPLETED, FAILED, and REFUND_COMPLETED, but there is no tab for PENDING_AUTHORIZATION. Without a concrete payload example, developers cannot see what fields (e.g., quoteId, scaChallenge) are available in the webhook body — which is critical for knowing how to retrieve the SCA challenge and call POST /quotes/{quoteId}/authorize.

Context Used: mintlify/AGENTS.md (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: mintlify/platform-overview/core-concepts/transaction-lifecycle.mdx
Line: 197

Comment:
**Missing webhook payload example for `PENDING_AUTHORIZATION`**

The Example Payloads tabs include PENDING, COMPLETED, FAILED, and REFUND_COMPLETED, but there is no tab for `PENDING_AUTHORIZATION`. Without a concrete payload example, developers cannot see what fields (e.g., `quoteId`, `scaChallenge`) are available in the webhook body — which is critical for knowing how to retrieve the SCA challenge and call `POST /quotes/{quoteId}/authorize`.

**Context Used:** mintlify/AGENTS.md ([source](https://app.greptile.com/lightspark/github/lightsparkdev/grid-api/-/custom-context?memory=51934046-75fb-42d3-9870-f42d61cb60e3))

How can I resolve this? If you propose a fix, please make it concise.

| `OUTGOING_PAYMENT.PROCESSING` | Quote confirmed, payout in progress |
| `OUTGOING_PAYMENT.COMPLETED` | Payout reached destination |
| `OUTGOING_PAYMENT.FAILED` | Payout failed |
Expand Down Expand Up @@ -270,6 +275,11 @@ app.post('/webhooks/grid', async (req, res) => {
const { data, type } = req.body;

switch (type) {
case 'OUTGOING_PAYMENT.PENDING_AUTHORIZATION':
// EU customers only: prompt user to complete SCA challenge
await notifyCustomer(data.customerId, 'Authorization required to complete payment.');
break;

case 'OUTGOING_PAYMENT.COMPLETED':
await notifyCustomer(data.customerId, 'Payment delivered!');
break;
Expand Down
Loading