Payment Receiver Configs
Payment Receiver Configs specify where and how you want to receive payments. They are separate from billing flows, allowing you to reuse payment settings across multiple flows or provide them when creating charges.
Why Receiver Configs?
Billing flows are logical groupings for charges (e.g., "Image API Usage", "Premium Feature X"). They don't need to know payment details.
Receiver configs are your payment preferences:
- Which blockchain network (e.g.,
solana-mainnet) - Which asset (e.g.,
USDC) - Which wallet address receives payments
- Escrow settings, facilitator URLs, timeouts
This separation allows:
- Flexibility: Use different payment configs per charge without changing flows
- Reusability: Create configs once, use across multiple flows
- Simplicity: Create flows without payment setup complexity
- Multiple wallets: Have different configs for different wallets (even same network/asset)
Key Concepts
Multiple Configs Per Organization
You can create multiple receiver configs for the same network and asset. For example:
- "Main Wallet" -
solana-mainnet/USDC→0xMain... - "Treasury Wallet" -
solana-mainnet/USDC→0xTreasury... - "Operations Wallet" -
solana-mainnet/USDC→0xOps...
Each config has a friendly name, so you can choose which one to use when creating charges.
Default Config
You can mark one config as default (is_default: true). If you don't specify a config when creating a charge, the default will be used automatically.
Fallback Chain
When creating a charge, Meshpay resolves x402 configuration using this priority:
- Charge request x402 fields (if provided directly)
- Receiver config (if
receiver_config_idprovided) - Default receiver config (if
is_default: trueexists) - Connected Solana wallet (if user has primary wallet connected)
- Error (require x402 configuration)
This means you can:
- Provide payment details directly per charge
- Reference a specific receiver config
- Rely on your default config
- Use your connected wallet automatically (for Solana users)
Creating a Receiver Config
Via API
/v1/billing/receiver-configsRequest Body:
| Field | Type | Required | Description | Example |
|---|---|---|---|---|
| name | string | Required | User-friendly name (e.g., 'Main Wallet', 'Treasury Wallet') | Main Wallet |
| network | string | Required | Blockchain network (e.g., 'solana-mainnet', 'base-mainnet') | solana-mainnet |
| asset | string | Required | Asset/token (e.g., 'USDC', 'USDT') | USDC |
| pay_to_address | string | Required | Wallet address to receive payments | 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb |
| escrow_address | string | Optional | Meshpay settlement wallet (required if collection_mode is 'escrow') | 0x... |
| facilitator | string | Optional | Facilitator endpoint URL for payment confirmation | https://facilitator.example.com/webhook |
| max_timeout_seconds | integer | Optional | Maximum timeout for payment (default: 60) | 60 |
| collection_mode | string | Optional | Collection mode: 'direct' (payments go to your wallet) or 'escrow' (payments go to Meshpay settlement wallet) | direct |
| is_default | boolean | Optional | Set as default config for organization (default: false) | — |
Example:
import requestsimport osurl = "https://api.orvion.sh/v1/billing/receiver-configs"headers = {"Authorization": f"Bearer {os.environ['MESHPAY_API_KEY']}","Content-Type": "application/json"}data = {"name": "Main Wallet","network": "solana-mainnet","asset": "USDC","pay_to_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb","facilitator": "https://facilitator.example.com/webhook","max_timeout_seconds": 60,"collection_mode": "direct","is_default": True}response = requests.post(url, json=data, headers=headers)config = response.json()
Response:
{
"id": "config_abc123",
"organization_id": "org_xyz",
"name": "Main Wallet",
"network": "solana-mainnet",
"asset": "USDC",
"pay_to_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"escrow_address": null,
"facilitator": "https://facilitator.example.com/webhook",
"max_timeout_seconds": 60,
"collection_mode": "direct",
"is_default": true,
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-15T10:30:00Z"
}
Using Receiver Configs When Creating Charges
When creating a charge, you have three options:
Option 1: Use Receiver Config ID
Reference a specific receiver config:
curl -X POST "https://api.orvion.sh/v1/flows/flow_123/charges" \-H "Authorization: Bearer $MESHPAY_API_KEY" \-H "Content-Type: application/json" \-d '{"amount": 100,"currency": "USD","receiver_config_id": "config_abc123"}'
Option 2: Provide x402 Fields Directly
Provide payment details directly in the charge request:
curl -X POST "https://api.orvion.sh/v1/flows/flow_123/charges" \-H "Authorization: Bearer $MESHPAY_API_KEY" \-H "Content-Type: application/json" \-d '{"amount": 100,"currency": "USD","network": "solana-mainnet","asset": "USDC","pay_to_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"}'
Option 3: Use Default Config or Connected Wallet
Don't provide any payment config - Meshpay will:
- Use your default receiver config (if
is_default: trueexists) - Or use your connected Solana wallet (if you have one)
- Or return an error
curl -X POST "https://api.orvion.sh/v1/flows/flow_123/charges" \-H "Authorization: Bearer $MESHPAY_API_KEY" \-H "Content-Type: application/json" \-d '{"amount": 100,"currency": "USD"}'
Managing Receiver Configs
List All Configs
/v1/billing/receiver-configsReturns all receiver configs for your organization, sorted by default first, then by creation date.
Get a Config
/v1/billing/receiver-configs/{config_id}Update a Config
/v1/billing/receiver-configs/{config_id}All fields are optional. If you set is_default: true, any existing default will be cleared.
Delete a Config
/v1/billing/receiver-configs/{config_id}Note: Deleting a config doesn't affect existing charges or transactions. Only future charges that reference this config will fail.
Fallback Chain Explained
When you create a charge without specifying payment configuration, Meshpay uses this fallback chain:
┌─────────────────────────────────────┐
│ Create Charge │
│ (no payment config provided) │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 1. Check charge request │
│ x402 fields provided? │
└──────────────┬──────────────────────┘
│ No
▼
┌─────────────────────────────────────┐
│ 2. Check receiver_config_id │
│ provided in charge request? │
└──────────────┬──────────────────────┘
│ No
▼
┌─────────────────────────────────────┐
│ 3. Check default receiver config │
│ (is_default: true) exists? │
└──────────────┬──────────────────────┘
│ No
▼
┌─────────────────────────────────────┐
│ 4. Check connected Solana wallet │
│ (only if user_id available) │
│ → Use: solana-mainnet/USDC/ │
│ primary wallet address │
└──────────────┬──────────────────────┘
│ No
▼
┌─────────────────────────────────────┐
│ 5. Error: x402 config required │
└─────────────────────────────────────┘
Collection Modes
Direct Mode
Configuration:
{
"collection_mode": "direct",
"pay_to_address": "0xYourWallet..."
}
Flow:
- Payments go directly to your
pay_to_address - No escrow wallet needed
- Faster settlement
- Simpler flow
Use when: You want payments to go directly to your wallet without escrow.
Escrow Mode
Configuration:
{
"collection_mode": "escrow",
"pay_to_address": "0xYourWallet...",
"escrow_address": "0xMeshpaySettlement..."
}
Flow:
- Payments go to Meshpay
escrow_addressfirst - Funds are then distributed according to payout splits
- Required for complex payout logic or splits
Use when: You need escrow, splits, or complex payout distribution.
Note: escrow_address is required when collection_mode is escrow.
Best Practices
1. Create Named Configs
Give your configs descriptive names that indicate their purpose:
- ✅ "Main Wallet" - Clear purpose
- ✅ "Treasury Wallet" - Indicates use case
- ✅ "Operations USDC" - Includes asset info
- ❌ "Config 1" - Not descriptive
- ❌ "Wallet" - Too generic
2. Set a Default Config
Mark your most commonly used config as default:
{
"name": "Main Wallet",
"is_default": true,
...
}
This allows you to create charges without specifying payment config.
3. Use Connected Wallets
If you're using Solana, connect your wallet in the dashboard. This enables automatic fallback to your primary wallet when no config is provided.
4. Multiple Configs for Same Network/Asset
You can have multiple configs for the same network/asset combo:
- "Main Wallet" -
solana-mainnet/USDC→0xMain... - "Treasury Wallet" -
solana-mainnet/USDC→0xTreasury...
Choose which one to use per charge via receiver_config_id.
5. Per-Charge Override
You can override config settings per charge by providing x402 fields directly:
{
"amount": 100,
"currency": "USD",
"receiver_config_id": "config_abc123",
"pay_to_address": "0xDifferentWallet..." // Override pay_to_address
}
Examples
Example 1: Simple Setup with Default Config
Step 1: Create a default receiver config
POST /v1/billing/receiver-configs
{
"name": "Main Wallet",
"network": "solana-mainnet",
"asset": "USDC",
"pay_to_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"is_default": true
}
Step 2: Create charges without payment config
POST /v1/flows/flow_123/charges
{
"amount": 100,
"currency": "USD"
}
The charge will automatically use your default config.
Example 2: Multiple Wallets, Choose Per Charge
Step 1: Create multiple configs
POST /v1/billing/receiver-configs
{
"name": "Main Wallet",
"network": "solana-mainnet",
"asset": "USDC",
"pay_to_address": "0xMain...",
"is_default": true
}
POST /v1/billing/receiver-configs
{
"name": "Treasury Wallet",
"network": "solana-mainnet",
"asset": "USDC",
"pay_to_address": "0xTreasury...",
"is_default": false
}
Step 2: Use specific config per charge
POST /v1/flows/flow_123/charges
{
"amount": 100,
"currency": "USD",
"receiver_config_id": "config_treasury" // Use treasury wallet
}
Example 3: Override Config Per Charge
POST /v1/flows/flow_123/charges
{
"amount": 100,
"currency": "USD",
"receiver_config_id": "config_abc123",
"pay_to_address": "0xOverride..." // Override the config's address
}
Error Handling
Missing Escrow Address
If collection_mode is escrow but escrow_address is missing:
{
"detail": "escrow_address is required for escrow collection mode"
}
Solution: Provide escrow_address when creating or updating a config with collection_mode: "escrow".
No x402 Configuration Found
If you create a charge without payment config and no fallback is available:
{
"detail": "x402 configuration required. Provide x402 fields in charge request, receiver_config_id, create a default receiver config, or connect a Solana wallet."
}
Solution:
- Create a default receiver config
- Or provide x402 fields in the charge request
- Or connect a Solana wallet (for automatic fallback)
Related Documentation
- Billing Flows - Creating and managing billing flows
- Charges API - Creating charges with payment config
- Wallets - Connecting and managing wallets