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
15 changes: 15 additions & 0 deletions api-features/payee-destinations.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,28 @@ ERC20 token contract address (EVM `0x...` or Tron `T...` format).
Chain ID for the receiving network (e.g., `8453` for Base, `1` for Ethereum).
</ParamField>

<ParamField body="accessPolicy" type="object">
Optional KYT (Know Your Transaction) compliance policy applied to payments into this destination. When set, every payer wallet that connects to a payment link backed by this destination is screened before the payment can proceed. See [Compliance-gated payments](/use-cases/compliance-gated-payments) for the full guide.

| Sub-field | Type | Description |
| --- | --- | --- |
| `mode` | `"off"` \| `"kyt_all_wallets"` | `off` (default): no screening. `kyt_all_wallets`: every payer wallet is screened. |
| `hideUntilApproved` | `boolean` | When `true`, payment metadata is hidden in the payer UI until the wallet passes screening. |
| `hidePayeeAddress` | `boolean` | When `true`, the payee address is masked in the payer UI (no copy / no explorer link). |
</ParamField>
Comment on lines +96 to +104
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 The accessPolicy sub-fields are documented as a plain Markdown table inside the ParamField body. Per the AGENTS.md style guide, nested object properties should use the Expandable component with nested ParamField entries for consistent, scannable API docs.

Suggested change
<ParamField body="accessPolicy" type="object">
Optional KYT (Know Your Transaction) compliance policy applied to payments into this destination. When set, every payer wallet that connects to a payment link backed by this destination is screened before the payment can proceed. See [Compliance-gated payments](/use-cases/compliance-gated-payments) for the full guide.
| Sub-field | Type | Description |
| --- | --- | --- |
| `mode` | `"off"` \| `"kyt_all_wallets"` | `off` (default): no screening. `kyt_all_wallets`: every payer wallet is screened. |
| `hideUntilApproved` | `boolean` | When `true`, payment metadata is hidden in the payer UI until the wallet passes screening. |
| `hidePayeeAddress` | `boolean` | When `true`, the payee address is masked in the payer UI (no copy / no explorer link). |
</ParamField>
<ParamField body="accessPolicy" type="object">
Optional KYT (Know Your Transaction) compliance policy applied to payments into this destination. When set, every payer wallet that connects to a payment link backed by this destination is screened before the payment can proceed. See [Compliance-gated payments](/use-cases/compliance-gated-payments) for the full guide.
<Expandable title="accessPolicy fields">
<ParamField body="mode" type='"off" | "kyt_all_wallets"'>
`off` (default): no screening. `kyt_all_wallets`: every payer wallet is screened.
</ParamField>
<ParamField body="hideUntilApproved" type="boolean">
When `true`, payment metadata is hidden in the payer UI until the wallet passes screening.
</ParamField>
<ParamField body="hidePayeeAddress" type="boolean">
When `true`, the payee address is masked in the payer UI (no copy / no explorer link).
</ParamField>
</Expandable>
</ParamField>

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!


```json Response (201)
{
"id": "01HXEXAMPLE123",
"destinationId": "0x6923...C7D7@eip155:8453#ABCD1234:0x8335...2913",
"walletAddress": "0x6923831ACf5c327260D7ac7C9DfF5b1c3cB3C7D7",
"tokenAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"chainId": 8453,
"accessPolicy": {
"mode": "kyt_all_wallets",
"hideUntilApproved": true,
"hidePayeeAddress": true
},
"binaryInteropAddress": "0x...",
"humanReadableInteropAddress": "0x6923...C7D7@eip155:8453#ABCD1234",
"claimed": true,
Expand Down
3 changes: 2 additions & 1 deletion docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@
"use-cases/programmatic-payment-links",
"use-cases/multi-chain-checkout",
"use-cases/batch-payouts",
"use-cases/webhook-reconciliation"
"use-cases/webhook-reconciliation",
"use-cases/compliance-gated-payments"
]
}
]
Expand Down
6 changes: 6 additions & 0 deletions tools/secure-payments.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@ Tron is fully supported as both a **source** and a **destination** for single-re
**Multi-recipient Tron Secure Payments are not supported.** A Secure Payment link with multiple `requests[]` entries pointing at Tron destinations is rejected at creation time with a 400. EVM batches up to 200 payees per link work as expected.
</Warning>

## Compliance-gated payments (KYT)

When the merchant has enabled a Know Your Transaction policy on the receiving destination, the secure payment app screens the connected wallet before showing payment options. Wallets that fail the screen see a policy-failure view and cannot reach the sign step. Optional privacy flags can also keep the payment amount and the payee address masked until the screening passes.

See [Compliance-gated payments](/use-cases/compliance-gated-payments) for the merchant-side configuration.

## Smart accounts (gasless on EVM)

For supported EVM destinations, Secure Payment can route payments through an [Account Abstraction](https://www.alchemy.com/overviews/what-is-account-abstraction) smart account so the payer doesn't need to hold gas-token balance. The flow is invisible to the payer beyond a slightly different transaction signature step. The integration uses Pimlico for bundling and Alchemy gas policies for sponsorship — see [Secure payment pages](/api-features/secure-payment-pages#smart-account-payments) for the full spec.
Expand Down
112 changes: 112 additions & 0 deletions use-cases/compliance-gated-payments.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
---
title: "Compliance-gated payments (KYT)"
description: "Screen every payer wallet for sanctions and risk before accepting a payment. Built into payment destinations — opt-in per receiving route."
---

## What you'll build

A receiving setup where every wallet that tries to pay you is screened against sanctions and risk lists before the payment can settle. If a wallet fails screening, the payment is blocked — the payer never reaches the sign step. You configure this **per payment destination**, so you can keep some flows compliance-gated and others permissive.

**Audience:** regulated fintech, marketplaces with compliance obligations, B2B platforms with KYC/AML requirements, any merchant who needs to refuse payments from sanctioned or high-risk addresses.

This is a **Know Your Transaction (KYT)** policy, not a Know Your Customer (KYC) flow. There's no document upload or identity verification on the payer side — just a wallet-address screening.

## How it works

When you create a payment destination via the [Auth API](https://auth.request.network/open-api/#tag/payee-destination), you can attach a **payment access policy** that turns KYT screening on for that destination:

1. Payer opens your payment link.
2. Before the payment options view loads, Request Network's compliance gate screens the connected wallet (and, for smart-account payments, the parent EOA as well).
3. If the screening **passes**, the payment continues normally.
4. If the screening **fails**, the secure payment page shows a policy-failure view and the payer cannot reach the sign step.
Comment on lines +18 to +21
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 The "How it works" section uses a plain numbered list for a sequential, step-by-step procedure. AGENTS.md calls for the <Steps> Mintlify component for "procedures and sequential instructions" to get consistent styling and scannability.

Suggested change
1. Payer opens your payment link.
2. Before the payment options view loads, Request Network's compliance gate screens the connected wallet (and, for smart-account payments, the parent EOA as well).
3. If the screening **passes**, the payment continues normally.
4. If the screening **fails**, the secure payment page shows a policy-failure view and the payer cannot reach the sign step.
<Steps>
<Step title="Payer opens your payment link" />
<Step title="Wallet screening">
Before the payment options view loads, Request Network's compliance gate screens the connected wallet (and, for smart-account payments, the parent EOA as well).
</Step>
<Step title="Screening passes">
The payment continues normally.
</Step>
<Step title="Screening fails">
The secure payment page shows a policy-failure view and the payer cannot reach the sign step.
</Step>
</Steps>

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!


You can also choose how much information is visible to the payer until the wallet has passed screening — see [Privacy options](#privacy-options) below.

## Configure a KYT-gated destination

Pass an `accessPolicy` object when creating a payee destination:

```bash
curl -X POST "https://auth.request.network/v1/payee-destination" \
-H "Cookie: session=YOUR_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"tokenAddress": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"chainId": 1,
"accessPolicy": {
"mode": "kyt_all_wallets",
"hideUntilApproved": true,
"hidePayeeAddress": true
}
}'
```

| Field | Type | Description |
| --- | --- | --- |
| `mode` | `"off"` \| `"kyt_all_wallets"` | `off` is the default (no screening). `kyt_all_wallets` screens every payer wallet that connects. |
| `hideUntilApproved` | `boolean` | When `true`, the payment metadata (amount, currency, recipient) is hidden until the payer's wallet has passed screening. |
| `hidePayeeAddress` | `boolean` | When `true`, the payee wallet address is masked throughout the payer flow — no ENS resolution, no copy button, no explorer link. |

Both privacy flags are independent of `mode` — you can show payment details upfront and still gate the actual payment behind screening, or hide everything until the gate clears.

<Note>
Existing payment destinations without an `accessPolicy` keep behaving exactly as before — there is no implicit screening. KYT only activates when you opt a destination in.
</Note>

## Privacy options

`hideUntilApproved` and `hidePayeeAddress` solve two different concerns:

- **`hideUntilApproved`** — useful when the payment terms themselves are sensitive (commercial pricing, B2B contracts). The payer connects a wallet, gets screened, and only sees the amount/recipient if their wallet clears.
- **`hidePayeeAddress`** — useful when you want to keep your receiving wallet from being scraped and re-used by the payer outside this payment flow. The payer can still pay (the secure payment app builds the transaction with the real address), but they don't see the address copy/explorer-link affordances.

You can combine both for the strictest setup, or use either independently.

## What payers experience

| Scenario | Payer view |
| --- | --- |
| Wallet passes screening | Standard payment flow — connect, pick chain/token, sign. |
| Wallet fails screening | Policy-failure view; sign button is disabled. The payer is told the payment cannot proceed and to contact you for an alternative. |
| Screening in progress | Brief loading state between wallet connect and payment options view. |

For **smart-account payments** on EVM, the gate screens both the connected EOA and the smart-account wallet — both must pass before payment proceeds.

## Update or remove a policy

Change the policy on an existing destination by re-issuing the create call (the active destination is updated in place) or by calling `PUT /v1/payee-destination`:

```bash
curl -X PUT "https://auth.request.network/v1/payee-destination" \
-H "Cookie: session=YOUR_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"tokenAddress": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"chainId": 1,
"accessPolicy": { "mode": "off", "hideUntilApproved": false, "hidePayeeAddress": false }
}'
```

Setting `mode: "off"` reverts the destination to standard, unscreened behavior. Existing payment links you've already created against that destination will use whatever policy is in effect at the moment a payer connects.

## When KYT screening doesn't replace your own checks

KYT screens individual **wallet addresses** against external sanctions and risk lists. It does not:

- Verify payer identity (use KYC tooling for that).
- Prove origin of funds — addresses can pass screening but still be linked to off-platform behavior you'd flag yourself.
- Replace transaction-monitoring on your side after the fact.

Treat KYT as a first-line filter that blocks the most obvious cases, layered with whatever else your compliance program requires.

## Related

<CardGroup cols={2}>
<Card title="Payee destinations" href="/api-features/payee-destinations" icon="location-dot">
Full payee-destination reference, including the `accessPolicy` field.
</Card>

<Card title="Quickstart" href="/use-cases/quickstart" icon="rocket">
The end-to-end flow this fits into.
</Card>
</CardGroup>
2 changes: 1 addition & 1 deletion use-cases/welcome.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ mode: "frame"
href="/use-cases/no-code-payment-links"
icon="briefcase"
>
No-code links, programmatic links, multi-chain checkout, batch payouts, webhook reconciliation.
No-code links, programmatic links, multi-chain checkout, batch payouts, webhook reconciliation, KYT-screened payments.
</Card>

<Card
Expand Down