Getting Started
Welcome to the Payment Processor API documentation. This API allows you to accept cryptocurrency payments and manage payouts programmatically.
Base URL
https://api.shadowpay.world
Quick Start
To get started, you'll need:
- An api_key for authentication
- A configured wallet chain for your chosen blockchain network
Example: Create Your First Payment
curl -X POST "https://api.shadowpay.world/post_create_order" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "order_id=ORDER_001" \
-d "amount=100" \
-d "symbol=USDC" \
-d "chain=sepolia" \
-d "base_currency=EUR" \
-d "api_key=YOUR_API_KEY"
Response:
{
"payment_url": "https://shadowpay.world/d4e5f6g7-h8i9-j0k1-l2m3-n4o5p6q7r8s9"
}
Authentication
All authenticated endpoints require your API key for authentication. The API key automatically identifies your merchant account.
api_key- Your secret API key (format: sk_live_xxx or sk_test_xxx)
Create Payment Order
Creates a new cryptocurrency payment order and returns a payment URL for the customer.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
order_id |
string | ✓ | Unique identifier for this order |
amount |
string | ✓ | Payment amount in merchant's base currency (set during account creation, e.g., "100" for €100 or $100) |
symbol |
string | ✓ | Currency symbol (e.g., "USDC", "USDT") |
chain |
string | ✓ | Blockchain network (e.g., "ethereum", "sepolia", "base", "arbitrum") |
base_currency |
string | ✓ | Base fiat currency for the amount (e.g., "EUR", "USD") |
api_key |
string | ✓ | Your API key for authentication |
Example Request
curl -X POST "https://api.shadowpay.world/post_create_order" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "order_id=ORDER_12345" \
-d "amount=100.50" \
-d "symbol=USDC" \
-d "chain=ethereum" \
-d "base_currency=EUR" \
-d "api_key=sk_live_abc123xyz789"
Response
{
"payment_url": "https://shadowpay.world/a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
Error Responses
400- Invalid amount format or cryptocurrency not available401- Invalid authentication credentials404- Cryptocurrency not found500- No wallet chain configured or internal error
Get Payment Info
Retrieves detailed information about a payment, including current status, amounts, and transaction events.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
payment_id |
UUID | The unique payment identifier from the payment URL |
Example Request
curl -X GET "https://api.shadowpay.world/get_payment_infos/a1b2c3d4-e5f6-7890-abcd-ef1234567890"
Response
{
"crypto_price": 0.92,
"amount": 100.0,
"confirmed_amount": 50.0,
"received_amount": 80.0,
"expires_at": "2025-10-24T10:45:00.000Z",
"updated_at": "2025-10-24T10:35:00.000Z",
"qrcode": "data:image/png;base64,iVBORw0KGgo...",
"chain": "sepolia",
"status": "partially_received",
"payment_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"currency": "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
"symbol": "USDC",
"base_currency": "EUR",
"amount_base_currency": 92.0,
"transaction_events": [
{
"tx_hash": "0xabc123...",
"amount": 50.0,
"status": "confirmed",
"block_number": 12340,
"created_at": "2025-10-24T10:31:00.000Z",
"updated_at": "2025-10-24T10:33:00.000Z"
},
{
"tx_hash": "0xdef456...",
"amount": 30.0,
"status": "seen",
"block_number": 12341,
"created_at": "2025-10-24T10:35:00.000Z",
"updated_at": "2025-10-24T10:35:00.000Z"
}
]
}
created to pending.
Payment Status Values
The status field in the response can have one of the following values:
| Status | Description |
|---|---|
created |
Payment order created, not yet viewed by customer |
pending |
Customer viewing payment page, waiting for payment |
partially_received |
Some crypto received on blockchain, but not full amount |
received |
Full crypto amount received on blockchain (unconfirmed) |
partially_confirmed |
Some amount confirmed on blockchain |
confirmed |
Payment fully confirmed on blockchain (final state) |
expired |
Payment window expired (default: 15 minutes) |
failed |
Payment failed or cancelled |
Get Payout Info
Retrieves detailed information about a payout/withdrawal, including current status, amounts, and transaction events.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
payout_id |
UUID | The unique payout identifier returned from create withdrawal |
Example Request
curl -X GET "https://api.shadowpay.world/get_payout_infos/b1c2d3e4-f5g6-7890-hijk-lm1234567890"
Response
{
"crypto_price": 0.92,
"amount": 50.0,
"status": "confirmed",
"chain": "sepolia",
"destination_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"currency": "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
"symbol": "USDC",
"base_currency": "EUR",
"amount_base_currency": 46.0,
"tx_hash": "0xabc123def456...",
"created_at": "2025-10-24T11:00:00.000Z",
"confirmed_at": "2025-10-24T11:05:00.000Z",
"updated_at": "2025-10-24T11:05:00.000Z",
"transaction_events": [
{
"tx_hash": "0xabc123def456...",
"amount": 50.0,
"status": "confirmed",
"block_number": 12450,
"created_at": "2025-10-24T11:02:00.000Z",
"updated_at": "2025-10-24T11:05:00.000Z"
}
]
}
Payout Status Values
The status field in the response can have one of the following values:
| Status | Description |
|---|---|
pending |
Payout request created, waiting for processing |
queued |
Payout queued for execution |
sent |
Transaction sent to blockchain |
confirmed |
Transaction confirmed on blockchain (final state) |
failed |
Payout failed (check failure_reason field) |
cancelled |
Payout cancelled |
List Available Currencies
Returns a list of available cryptocurrencies with their current exchange rates and network information.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
api_key |
string | ✓ | Your API key for authentication |
Example Request
curl -X POST "https://api.shadowpay.world/post_currencies?api_key=YOUR_API_KEY"
Response
[
{
"symbol": "USDC",
"name": "USD Coin",
"network": "ethereum",
"rate": 1.00,
"deposit_address": "0x1234567890abcdef1234567890abcdef12345678",
"available": true
},
{
"symbol": "USDC",
"name": "USD Coin (Sepolia Testnet)",
"network": "sepolia",
"rate": 1.00,
"deposit_address": "0x1234567890abcdef1234567890abcdef12345678",
"available": true
},
{
"symbol": "USDT",
"name": "Tether",
"network": "ethereum",
"rate": 0.99,
"deposit_address": "0x4567890123def4567890123def4567890123def",
"available": true
}
]
symbol field contains only the currency symbol (e.g., "USDC", "USDT") without the chain. Use the network field to identify which blockchain the currency is available on. The same currency can appear multiple times with different networks.
Create Withdrawal
Creates a withdrawal request to send cryptocurrency from your merchant wallet to a specified address.
order_id will return the existing payout if it's still active.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
order_id |
string | ✓ | Unique identifier for this withdrawal order |
amount |
string | ✓ | Withdrawal amount in merchant's base currency (set during account creation, e.g., "100" for €100 or $100) |
address_to |
string | ✓ | Destination blockchain address |
chain |
string | ✓ | Blockchain network (ethereum, sepolia, arbitrum, base) |
symbol |
string | ✓ | Currency symbol (USDC, USDT) |
base_currency |
string | ✓ | Base fiat currency for the amount (e.g., "EUR", "USD") |
api_key |
string | ✓ | Your API key for authentication |
Example Request
curl -X POST "https://api.shadowpay.world/post_create_withdrawal" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "order_id=WITHDRAWAL_001" \
-d "amount=50" \
-d "address_to=0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb" \
-d "chain=sepolia" \
-d "symbol=USDC" \
-d "base_currency=EUR" \
-d "api_key=sk_live_abc123xyz789"
Response
{
"payout_id": "b1c2d3e4-f5g6-7890-hijk-lm1234567890",
"status": "pending",
"payout_type": "withdrawal",
"amount": 50.0,
"symbol": "USDC",
"chain": "sepolia",
"source_wallet_address": "0x1234567890abcdef1234567890abcdef12345678",
"destination_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"created_at": "2025-10-24T10:30:00.000Z"
}
Withdrawal Statuses
pending- Withdrawal request created, waiting for processingqueued- Withdrawal queued for executionsent- Transaction sent to blockchainconfirmed- Transaction confirmed on blockchainfailed- Withdrawal failedcancelled- Withdrawal cancelled
Webhooks
Webhooks allow you to receive real-time notifications when payment and payout events occur in your account. Instead of polling our API, webhooks push event data directly to your server.
Setup
To receive webhooks, you need to:
- Contact us to register your webhook endpoint URL
- We will generate a unique
webhook_secretfor your account - Store this secret securely - you'll use it to verify webhook authenticity
Webhook Events
We currently send webhooks for the following events:
| Event Type | Description |
|---|---|
payment.confirmed |
Payment has been fully confirmed on the blockchain |
payout.confirmed |
Payout transaction successfully completed on the blockchain |
payout.failed |
Payout transaction failed on the blockchain |
Webhook Payload Structure
Payment Webhook Example
{
"event_type": "payment.confirmed",
"event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created_at": "2024-12-03T10:30:45.123456+00:00",
"payment": {
"id": "d4e5f6g7-h8i9-j0k1-l2m3-n4o5p6q7r8s9",
"merchant_order_id": "ORDER_12345",
"crypto_amount": "100000000",
"amount_base": "100.00",
"crypto_currency": "USDC",
"base_currency": "EUR",
"status": "confirmed",
"created_at": "2024-12-03T10:15:30.000000+00:00",
"crypto_amount_paid": "100000000",
"amount_base_paid": "100.00"
}
}
Payout Webhook Example
{
"event_type": "payout.confirmed",
"event_id": "b2c3d4e5-f6g7-8901-bcde-f12345678901",
"created_at": "2024-12-03T11:45:20.123456+00:00",
"metadata": {
"tx_hash": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"block_number": 12345678,
"confirmed_at": "2024-12-03T11:45:15.000000+00:00"
},
"payout": {
"id": "e5f6g7h8-i9j0-k1l2-m3n4-o5p6q7r8s9t0",
"merchant_reference_id": "PAYOUT_456",
"payout_type": "withdrawal",
"crypto_amount": "50000000",
"crypto_currency": "USDC",
"amount_base": "50.00",
"base_currency": "EUR",
"status": "confirmed",
"created_at": "2024-12-03T11:30:15.000000+00:00",
"destination_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"
}
}
Webhook Security
All webhook requests include cryptographic signatures to verify their authenticity. This prevents spoofing and ensures the request genuinely comes from Shadow Pay.
Signature Headers
Each webhook request includes two security headers:
X-Webhook-Timestamp- Unix timestamp when the webhook was sentX-Webhook-Signature- HMAC-SHA256 signature of the payload
Signature Verification Process
To verify a webhook is authentic:
- Extract
X-Webhook-TimestampandX-Webhook-Signaturefrom headers - Reconstruct the signed message:
{timestamp}.{json_payload} - Compute HMAC-SHA256 using your webhook secret:
HMAC-SHA256(message, webhook_secret) - Compare the computed signature with the received signature using a timing-safe comparison
# Signature verification logic
message = f"{timestamp}.{json.dumps(payload, separators=(',', ':'), sort_keys=True)}"
expected_signature = hmac.new(webhook_secret, message.encode('utf-8'), hashlib.sha256).hexdigest()
is_valid = hmac.compare_digest(expected_signature, received_signature)
Retry Behavior
If your endpoint is unavailable or returns an error, we will automatically retry the webhook delivery:
- Retry Schedule: 30s, 1m, 2m, 4m, 8m, 16m, 32m, 64m, 112.5m (total ~4 hours)
- Maximum Attempts: 10 retries
- Success Codes: 200-299 HTTP status codes
- Permanent Failures: 400, 401, 403, 404, 410, 422 (no retries)
- Transient Failures: 5xx errors, timeouts, connection errors (will retry)
Idempotency
Each webhook has a unique event_id. We guarantee at-least-once delivery, so you may receive duplicate webhooks. Use the event_id to make your webhook handling idempotent and prevent duplicate processing.
Testing Webhooks
During development:
- Use tools like ngrok to expose your local server
- Implement signature verification before deploying to production
- Contact support to trigger test webhook events
Error Handling
The API uses standard HTTP response codes to indicate success or failure.
HTTP Status Codes
| Code | Description |
|---|---|
200 |
Success - Request completed successfully |
400 |
Bad Request - Invalid parameters or request format |
401 |
Unauthorized - Invalid or missing authentication credentials |
404 |
Not Found - Payment, order, or cryptocurrency not found |
500 |
Internal Server Error - Something went wrong on the server |
Error Response Format
{
"detail": "Invalid authentication credentials"
}
Common Error Examples
Authentication Error (401)
{
"detail": "Invalid authentication credentials"
}
Payment Not Found (404)
{
"detail": "Payment a1b2c3d4-e5f6-7890-abcd-ef1234567890 not found"
}
Invalid Amount (400)
{
"detail": "Invalid amount format"
}