Flow-Based Charges
Create charges within a billing flow. This is useful for grouping related charges together and organizing transactions by project, customer, or use case.
Note: Billing flows with advanced flowcharts and conditions are coming soon. For simpler use cases, consider using Standalone Charges.
Endpoint
/v1/flows/{flow_id}/chargesAuthorization: Bearer <MESHPAY_API_KEY>
Content-Type: application/json
Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| flow_id | string | Yes | ID of the billing flow to create the charge in |
Request Body
| Field | Type | Required | Description | Example |
|---|---|---|---|---|
| amount | number | Required | Final amount to charge (e.g. 100 = $100.00) | 100 |
| currency | string | Required | Currency code - accepts any fiat (USD, EUR) or crypto (USDC, ETH, SOL) | USD |
| customer_ref | string | null | Optional | Your internal customer ID or reference | user_123 |
| reference | string | null | Optional | Optional reference for this charge (order ID, job ID, etc.) | order_456 |
| metadata | object | null | Optional | Free-form JSON object stored with the transaction | {"order_id": "456", "tier": "pro"} |
| receiver_config_id | string | null | Optional | ID of payment receiver config to use (overrides flow default) | config_abc123 |
| network | string | null | Optional | Blockchain network (e.g., 'solana-mainnet', 'base-mainnet') | solana-mainnet |
| asset | string | null | Optional | Asset/token (e.g., 'USDC', 'USDT') | USDC |
| pay_to_address | string | null | Optional | Wallet address to receive payment (required if network/asset provided) | 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb |
| escrow_address | string | null | Optional | Meshpay settlement wallet (required if collection_mode is 'escrow') | 0xMeshpaySettlement... |
| facilitator | string | null | Optional | Facilitator endpoint URL for payment confirmation | https://facilitator.example.com/webhook |
| max_timeout_seconds | number | null | Optional | Maximum timeout for payment in seconds (default: 60) | 60 |
| collection_mode | string | null | Optional | Collection mode: 'direct' (payments go to pay_to_address) or 'escrow' (payments go to escrow_address) | direct |
Code Examples
Basic Flow-Based Charge:
import requestsimport osflow_id = "flow_123"url = f"https://api.orvion.sh/v1/flows/{flow_id}/charges"headers = {"Authorization": f"Bearer {os.environ['MESHPAY_API_KEY']}","Content-Type": "application/json"}data = {"amount": 100,"currency": "USD","customer_ref": "user_123","reference": "order_456"}response = requests.post(url, json=data, headers=headers)transaction = response.json()print(f"Charge created in flow: {transaction['id']}")
With Custom Receiver Config:
FLOW_ID="flow_123"curl -X POST "https://api.orvion.sh/v1/flows/$FLOW_ID/charges" \-H "Authorization: Bearer $MESHPAY_API_KEY" \-H "Content-Type: application/json" \-d '{"amount": 250,"currency": "USD","customer_ref": "user_456","reference": "subscription_monthly","receiver_config_id": "config_xyz789","metadata": {"plan": "pro","billing_cycle": "monthly"}}'
Response
Returns the created transaction with x402 payment requirements. The billing_flow_id field will contain the flow ID.
{
"id": "txn_abc123",
"organization_id": "org_456",
"billing_flow_id": "flow_123",
"amount": "100.00",
"currency": "USD",
"status": "pending",
"customer_ref": "user_123",
"reference": "order_456",
"metadata": null,
"x402_requirements": {
"rail_config": {
"scheme": "exact",
"network": "solana-mainnet",
"asset": "USDC",
"pay_to_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"facilitator": "https://facilitator.example.com/webhook",
"max_timeout_seconds": 60
},
"metadata": {
"description": null,
"mime_type": "application/json",
"tags": []
},
"amount": "100.00",
"currency": "USD",
"external_ref": "billing:txn_abc123"
},
"tx_hash": null,
"confirmed_at": null,
"created_via": "api",
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-15T10:30:00Z"
}
Response Fields
id- Unique transaction identifier (e.g.,txn_abc123)organization_id- Organization that owns this transactionbilling_flow_id- The flow ID this charge belongs toamount- Charged amount (string with 2 decimal places)currency- Currency codestatus- Transaction status (pending,succeeded,failed)customer_ref- Your internal customer referencereference- Optional reference stringmetadata- Arbitrary JSON data attached to the transactionx402_requirements- Payment instructions for the buyer (see Standalone Charges)tx_hash- Transaction hash (set after payment confirmation)confirmed_at- Timestamp when payment was confirmedcreated_via- Source of creation (apiordashboard_test)created_at- Timestamp when the charge was createdupdated_at- Timestamp when the transaction was last updated
Flexible Currency Support
Charges can use any currency code — fiat (USD, EUR, GBP) or crypto (USDC, ETH, SOL, etc.).
The flow's optional accounting_currency is used only for aggregated reporting and analytics. It does not restrict what currencies charges can use.
Examples of valid charge currencies:
- Fiat:
USD,EUR,GBP,JPY - Stablecoins:
USDC,EURC,USDT - Crypto:
ETH,SOL,BTC
This flexibility enables sellers to:
- Accept payments in any currency/asset
- Configure payout preferences separately
- Track revenue in a consistent accounting currency for reports
x402 Configuration Resolution
When creating a flow-based charge, Meshpay resolves x402 payment configuration using this priority:
- Charge request x402 fields - If
network,asset, andpay_to_addressare provided directly - Receiver config - If
receiver_config_idis provided - Flow's receiver config - If the flow has a default receiver config
- Default receiver config - If a config with
is_default: trueexists - Connected Solana wallet - If you have a primary Solana wallet connected
- Error - If no configuration can be resolved
Error Codes
400 Bad Request
- Invalid request (amount ≤ 0, missing fields, invalid JSON)
- Invalid currency format
- x402 configuration required (no receiver config, default config, or connected wallet found)
escrow_addressrequired whencollection_modeisescrow
401 Unauthorized
- Invalid or missing API key
403 Forbidden
- Flow paused or not accessible to your API key's organization
404 Not Found
- Flow not found
- Receiver config not found (if
receiver_config_idprovided)
500 Internal Server Error
- Internal error (retry may succeed)
Transaction Status Lifecycle
| Status | Description |
|--------|-------------|
| pending | Charge created, x402 requirements returned, awaiting payment |
| succeeded | Payment confirmed via facilitator webhook |
| failed | Payment failed (network error, insufficient funds, etc.) |
Charges start as pending. After the buyer pays on-chain, the facilitator webhook confirms the payment and status updates to succeeded.
When to Use Flow-Based Charges
Flow-based charges are ideal when you need to:
- Group related transactions - Organize charges by project, customer, or use case
- Track aggregated metrics - View total revenue and transaction counts per flow
- Apply flow-level settings - Use flow-specific receiver configs or settings
- Prepare for advanced features - Billing flows with conditions and automations are coming soon
For simpler use cases where grouping isn't needed, Standalone Charges offer a more straightforward approach.
Best Practices
- Create flows for logical groupings - Use flows to organize charges by project, product, or customer segment
- Set flow-level receiver configs - Configure a default receiver config on the flow for consistency
- Use consistent currencies - While charges can use any currency, using consistent currencies makes reporting easier
- Use
customer_ref- Track which customer each charge belongs to - Use
referencefor traceability - Link charges to your internal order IDs, job IDs, etc. - Store context in
metadata- Include any additional data you might need later - Handle
pendingstatus - Charges start aspending, wait for webhook confirmation
Related Documentation
- Standalone Charges - Create charges without a flow
- Billing Flows - Creating and managing billing flows
- Receiver Configs - Configure where to receive payments
- Transactions - Viewing and filtering charges
- SDK Examples - Using SDKs to create charges