Skip to content

docs: publish payment destination + secure payment link integration guide#82

Open
AllenAJ wants to merge 1 commit intoRequestNetwork:mainfrom
AllenAJ:docs/public-payment-destination-link-guide
Open

docs: publish payment destination + secure payment link integration guide#82
AllenAJ wants to merge 1 commit intoRequestNetwork:mainfrom
AllenAJ:docs/public-payment-destination-link-guide

Conversation

@AllenAJ
Copy link

@AllenAJ AllenAJ commented Mar 23, 2026

Summary

  • Port internal Notion guide into public Mintlify docs
  • Added end-to-end flow: wallet sign-in, payment destination, client ID, webhooks, secure payment link creation, optional status check
  • Linked existing webhook/auth references to avoid duplication

Why

Integration partners currently need manual access to internal docs. This makes onboarding self-serve in public docs.

Test plan

  • Previewed page locally with Mintlify
  • Verified links and rendering

Closes #81

@greptile-apps
Copy link

greptile-apps bot commented Mar 23, 2026

Greptile Summary

This PR replaces the previous "Quick start"-style secure payments guide with a comprehensive end-to-end onboarding walkthrough covering wallet sign-in, payment destination creation, Client ID generation, webhook setup, and secure payment link creation. The rewrite is well-structured and meaningfully improves self-serve discoverability for integration partners.

Key findings:

  • destinationId naming inconsistency (P1): Step 2 labels the value returned by Dashboard as destinationId (equated to humanReadableInteropAddress), then tells users to "Save it for Step 5." Step 5 defines the API field destinationId as humanReadableInteropAddress:tokenAddress — a composite that includes the token address. A reader who saves the Step 2 value and uses it directly in the Step 5 API call will submit an incomplete identifier. The distinction between the two should be made explicit.
  • Flow diagram missing Step 6 (P2): The ASCII art overview diagram documents only 5 steps; the optional "Check payment status" Step 6 is absent from the diagram.
  • <Steps> component not used (P2): AGENTS.md requires Mintlify's <Steps>/<Step> components for numbered sequential procedures. All sub-instruction lists in Steps 1–5 use plain Markdown numbered lists instead.
  • <RequestExample> / <ResponseExample> / <ParamField> not used (P2): AGENTS.md requires these components for API endpoint documentation. Request/response examples and parameter tables throughout the guide use plain code blocks and Markdown tables instead.

Confidence Score: 3/5

  • Hold for the destinationId naming inconsistency — users who follow the guide literally may submit malformed API requests.
  • One concrete content bug (the destinationId Step 2 vs Step 5 mismatch) directly affects the primary user path: a developer who saves what Step 2 calls destinationId and passes it straight into the Step 5 API request body will receive an error because the token address is missing. This breaks the main flow. The remaining issues are style-guide compliance items that do not affect functionality but should be addressed to maintain docs consistency.
  • api-features/secure-payment-integration-guide.mdx — specifically the destinationId description in Step 2 (line 75) and its relationship to the construction instructions in Step 5 (lines 194–212).

Important Files Changed

Filename Overview
api-features/secure-payment-integration-guide.mdx Complete rewrite of the integration guide as an end-to-end onboarding flow; contains a key naming inconsistency for destinationId between Step 2 and Step 5 that could cause API call failures, plus the flow diagram is missing Step 6 and several sections don't use the required Mintlify components (<Steps>, <RequestExample>, <ParamField>).

Sequence Diagram

sequenceDiagram
    actor Dev as Developer
    participant Dash as Dashboard<br/>(dashboard.request.network)
    participant Auth as Auth API<br/>(auth.request.network)
    participant Portal as Portal<br/>(portal.request.network)
    participant API as Request API<br/>(api.request.network)

    Dev->>Dash: Sign in with wallet (Step 1)
    Dash-->>Dev: wallet session cookie (session_token)

    Dev->>Dash: Create payment destination (Step 2)
    Dash-->>Dev: humanReadableInteropAddress (destinationId)

    Dev->>Auth: POST /v1/client-ids (Step 3)
    Auth-->>Dev: clientId

    Dev->>Portal: Configure webhook endpoint (Step 4)
    Portal-->>Dev: webhook signing secret

    Dev->>API: POST /v2/secure-payments<br/>x-client-id: clientId<br/>destinationId: humanReadableInteropAddress:tokenAddress (Step 5)
    API-->>Dev: requestIds, securePaymentUrl, token

    Dev->>Dev: Share securePaymentUrl with payer

    Portal-->>Dev: Webhook event (payment.confirmed / payment.partial)

    opt Step 6 – optional polling
        Dev->>API: GET /v2/request/{requestId}
        API-->>Dev: hasBeenPaid, txHash
    end
Loading

Reviews (1): Last reviewed commit: "docs: publish end-to-end payment destina..." | Re-trigger Greptile

Comment on lines +75 to +81
Dashboard returns a `destinationId` (also shown as `humanReadableInteropAddress`). Save it for Step 5.

The `destinationId` follows ERC-7828 format:

```text
{walletAddress}@eip155:{chainId}#{checksum}
```
Copy link

Choose a reason for hiding this comment

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

P1 destinationId definition inconsistency between Step 2 and Step 5

Step 2 tells readers that Dashboard returns a destinationId which is the same as humanReadableInteropAddress (ERC-7828 format, e.g. {walletAddress}@eip155:{chainId}#{checksum}), and instructs them to "Save it for Step 5."

However, Step 5's "Constructing destinationId" section defines the destinationId field used in the API call as a composite value: {humanReadableInteropAddress}:{tokenAddress}. A user who blindly reuses the destinationId saved in Step 2 will submit an incomplete identifier (missing :{tokenAddress}) and the API call will fail.

The fix is to clarify in Step 2 that what Dashboard returns is the humanReadableInteropAddress portion only, and that the full destinationId for the API is humanReadableInteropAddress:tokenAddress (constructed in Step 5):

Suggested change
Dashboard returns a `destinationId` (also shown as `humanReadableInteropAddress`). Save it for Step 5.
The `destinationId` follows ERC-7828 format:
```text
{walletAddress}@eip155:{chainId}#{checksum}
```
Dashboard returns a `humanReadableInteropAddress`. Save it; you will combine it with a token address in Step 5 to form the full `destinationId`.
The `humanReadableInteropAddress` follows ERC-7828 format:

Comment on lines +17 to +45
```text
┌──────────────────────┐
│ 1. Sign in with │ dashboard.request.network
│ wallet │
└──────────┬───────────┘
┌──────────────────────┐
│ 2. Create Payee │ dashboard.request.network
│ Destination │
└──────────┬───────────┘
┌──────────────────────┐
│ 3. Create Client ID │ auth.request.network/open-api
│ (Auth API) │
└──────────┬───────────┘
┌──────────────────────┐
│ 4. Set up Webhook │ portal.request.network
└──────────┬───────────┘
┌──────────────────────┐
│ 5. Create Secure │ api.request.network/open-api
│ Payment (link) │
└──────────────────────┘
```
Copy link

Choose a reason for hiding this comment

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

P2 Flow diagram omits Step 6

The ASCII art diagram lists 5 steps, but the guide documents 6 steps (Step 6: "Check payment status" is optional but still part of the flow). Consider adding it with an "(optional)" label to match the rest of the guide, or noting in the diagram that Step 6 is optional:

Suggested change
```text
┌──────────────────────┐
│ 1. Sign in with │ dashboard.request.network
│ wallet │
└──────────┬───────────┘
┌──────────────────────┐
│ 2. Create Payee │ dashboard.request.network
│ Destination │
└──────────┬───────────┘
┌──────────────────────┐
│ 3. Create Client ID │ auth.request.network/open-api
│ (Auth API) │
└──────────┬───────────┘
┌──────────────────────┐
│ 4. Set up Webhook │ portal.request.network
└──────────┬───────────┘
┌──────────────────────┐
│ 5. Create Secure │ api.request.network/open-api
│ Payment (link) │
└──────────────────────┘
```
```text
┌──────────────────────┐
│ 1. Sign in with │ dashboard.request.network
│ wallet │
└──────────┬───────────┘
┌──────────────────────┐
│ 2. Create Payee │ dashboard.request.network
│ Destination │
└──────────┬───────────┘
┌──────────────────────┐
│ 3. Create Client ID │ auth.request.network/open-api
│ (Auth API) │
└──────────┬───────────┘
┌──────────────────────┐
│ 4. Set up Webhook │ portal.request.network
└──────────┬───────────┘
┌──────────────────────┐
│ 5. Create Secure │ api.request.network/open-api
│ Payment (link) │
└──────────┬───────────┘
┌──────────────────────┐
│ 6. Check Payment │ api.request.network/open-api
│ Status (opt.) │
└──────────────────────┘

Comment on lines +57 to +73
## Step 1: Sign in with wallet

1. Go to [dashboard.request.network](https://dashboard.request.network/).
2. Connect your EVM wallet and sign the authentication message.
3. Keep this session active for the next steps.

<Warning>
Wallet sessions expire after around 15 minutes. If your session expires, sign in again from Dashboard.
</Warning>

## Step 2: Create a payment destination

A payment destination registers where you receive payments, by linking your wallet address to a token on a chain.

1. In Dashboard, navigate to payment destination setup.
2. Select chain and token.
3. Confirm creation.
Copy link

Choose a reason for hiding this comment

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

P2 Use <Steps> component for numbered procedures

The AGENTS.md style guide says: "Use Steps for procedures and sequential instructions." The sub-instruction lists within each step section (e.g. "1. Go to …", "2. Connect …", "3. Keep …" in Step 1 and similar patterns in Steps 2–5) should use Mintlify's <Steps> / <Step> components instead of plain numbered Markdown lists. This applies consistently across Steps 1 through 5 in the file.

Example for Step 1:

<Steps>
  <Step title="Navigate to Dashboard">
    Go to [dashboard.request.network](https://dashboard.request.network/).
  </Step>
  <Step title="Connect your wallet">
    Connect your EVM wallet and sign the authentication message.
  </Step>
  <Step title="Keep session active">
    Keep this session active for the next steps.
  </Step>
</Steps>

The same pattern applies at lines 71–73 (Step 2), 104–106 (Step 3), 155–157 (Step 4), and 179–181 (Step 5).

Context Used: AGENTS.md (source)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment on lines +183 to +226
```json
{
"requests": [
{
"requestIds": [
"01e273ecc29d4b526df3a0f1f05ffc59372af8752c2b678096e49ac270416a7cdb"
],
"securePaymentUrl": "https://secure.request.network/?token=01ABC123DEF456GHI789JKL",
"token": "01ABC123DEF456GHI789JKL"
"destinationId": "0x6923831ACf5c327260D7ac7C9DfF5b1c3cB3C7D7@eip155:11155111#1f969856:0x370DE27fdb7D1Ff1e1BaA7D11c5820a324Cf623C",
"amount": "1"
}
```
</ResponseExample>
</Step>

<Step title="Persist payment mapping in your database">
Store at least:
- your internal metadata
- returned `requestIds`
- `token`
- `securePaymentUrl`

This mapping lets you reconcile webhook events back to your internal records.
</Step>

<Step title="Redirect payer to secure page">
Redirect in the same tab or open the secure URL in a new tab.
</Step>

<Step title="Process webhook events and update order status">
Handle payment events from webhooks and update your order/payment state from those events.
</Step>
</Steps>

## Integration pattern: generated URL + redirect

### Backend example (Node.js/Express)

```javascript server.js
import express from "express";

const app = express();
app.use(express.json());

app.post("/api/checkout/secure-payment", async (req, res) => {
const { orderId, payee, amount, currencyId } = req.body;

const apiResponse = await fetch("https://api.request.network/v2/secure-payments", {
method: "POST",
headers: {
"x-api-key": process.env.REQUEST_API_KEY,
"content-type": "application/json",
},
body: JSON.stringify({
requests: [
{
payee,
amount,
invoiceCurrency: currencyId,
paymentCurrency: currencyId,
},
],
}),
});

if (!apiResponse.ok) {
const errorBody = await apiResponse.text();
return res.status(apiResponse.status).json({ error: errorBody });
}

const securePayment = await apiResponse.json();

// Persist in your DB
// Example payload:
// {
// orderId,
// requestIds: securePayment.requestIds,
// token: securePayment.token,
// securePaymentUrl: securePayment.securePaymentUrl,
// status: "pending"
// }

return res.status(200).json({
orderId,
securePaymentUrl: securePayment.securePaymentUrl,
});
});
]
}
```

### Constructing `destinationId`

`destinationId` is:

```text
{humanReadableInteropAddress}:{tokenAddress}
```

### Frontend redirect examples
Example:

<CodeGroup>
```javascript Same tab
window.location.href = securePaymentUrl;
```text
0x6923831ACf5c327260D7ac7C9DfF5b1c3cB3C7D7@eip155:11155111#1f969856:0x370DE27fdb7D1Ff1e1BaA7D11c5820a324Cf623C
└──────────── humanReadableInteropAddress ─────────────────┘ └──────────── tokenAddress ──────────────────────┘
```

```javascript New tab
window.open(securePaymentUrl, "_blank", "noopener,noreferrer");
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `requests` | `array` | Yes | Array of payment request items |
| `requests[].destinationId` | `string` | Yes | Composite ID `humanReadableInteropAddress:tokenAddress` |
| `requests[].amount` | `string` | Yes | Human-readable amount (for example `"10"`) |
| `feePercentage` | `string` | No | Fee percentage 0-100; if set, `feeAddress` is required |
| `feeAddress` | `string` | No | Fee recipient address |

**Example response**

```json 201 Created
{
"requestIds": [
"01de2a889ee629c15b71b5d7964e3a7e87638c886be75bf1b9d2c1fbe64cf855fb"
],
"securePaymentUrl": "https://pay.request.network/?token=01KJRA0M9QG8MA4X887908T8A4",
"token": "01KJRA0M9QG8MA4X887908T8A4"
}
Copy link

Choose a reason for hiding this comment

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

P2 Use <RequestExample> / <ResponseExample> for API endpoint documentation

AGENTS.md states: "Use RequestExample/ResponseExample specifically for API endpoint documentation" and "Use ParamField for API parameters, ResponseField for API responses."

The request body (lines 183–192) and its response (lines 219–227) are presented as plain code blocks with a Markdown table for parameters. The same pattern occurs for the Client ID response (lines 131–147) and the status-check response (lines 251–270). Replacing these with <RequestExample>, <ResponseExample>, and <ParamField> / <ResponseField> components will keep the guide consistent with the rest of the docs and provide a richer interactive rendering. This pattern also appears at the Step 3 response (lines 131–147) and Step 6 response examples (lines 251–270).

Context Used: AGENTS.md (source)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

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.

Documentation - Pay-in integration guide for Dashboard, API, and Secure Payment Page

1 participant