Server-Side Integration
Target URL Verification
When users access your PayGate, Sigwei forwards paid requests to your target URL with authentication headers. You have two authentication modes to choose from.
Payment Headers
All proxied requests include these payment headers, regardless of authentication mode:
X-Payment: Base64-encoded payment authorization data (contains payer address, amount, nonce, signature, etc.)X-Payment-Response: Base64-encoded settlement response from blockchain (contains transaction hash, network, success status)
These headers allow your target server to:
Verify the payment independently if desired
Track which wallet paid for the request
Link requests to on-chain transactions
Implement custom payment verification logic
HMAC Mode (Recommended)
When headerAuthMode is set to "hmac" (default), Sigwei adds an HMAC signature for secure authentication:
Signature Computation: HMAC-SHA256(X-Payment + "|" + X-Payment-Response, secret)
The signature proves the request came from Sigwei and includes valid payment data.
// Node.js example - HMAC verification
const crypto = require('crypto');
app.get('/api/data', (req, res) => {
const xPayment = req.headers['x-payment'];
const xPaymentResponse = req.headers['x-payment-response'];
const signatureHeader = req.headers['sigwei-auth-signature'];
const secret = process.env.SIGWEI_SECRET; // From your paygate settings
if (!xPayment || !xPaymentResponse) {
return res.status(401).json({ error: 'Missing payment headers' });
}
if (!signatureHeader) {
return res.status(401).json({ error: 'Missing authentication signature' });
}
// Construct message from payment headers
const message = xPayment + '|' + xPaymentResponse;
// Verify HMAC signature
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(message)
.digest('base64');
if (signatureHeader !== expectedSignature) {
return res.status(403).json({ error: 'Invalid signature' });
}
// Optional: Decode and verify payment data independently
const paymentData = JSON.parse(Buffer.from(xPayment, 'base64').toString());
const settlementData = JSON.parse(Buffer.from(xPaymentResponse, 'base64').toString());
console.log('Paid by:', paymentData.payload.authorization.from);
console.log('Transaction:', settlementData.transaction);
res.json({ data: 'Your protected data' });
});Plaintext Mode (Simple)
When headerAuthMode is set to "plaintext", Sigwei adds a simple secret header:
// Node.js example - Plaintext verification
app.get('/api/data', (req, res) => {
const expectedSecret = process.env.SIGWEI_SECRET; // From your paygate settings
if (req.headers['sigwei-secret'] !== expectedSecret) {
return res.status(403).json({ error: 'Unauthorized' });
}
res.json({ data: 'Your protected data' });
});Why Authentication Matters
Security Issue: x-payment headers can be recreated from blockchain transaction data. Anyone could theoretically access protected PayGates by reconstructing payment headers from public blockchain transactions.
Solution: Enable requireAuth: true on PayGates. This ensures only the original payer (verified by wallet signature) can access content, even if someone else copies the payment header.
Why Sigwei Secret is Crucial
The Problem: Without verification, anyone could bypass your PayGate by calling your API directly, avoiding payment entirely.
The Solution: Sigwei Secret ensures requests come from legitimate paying users via Sigwei's proxy:
You set the secret when creating the PayGate or generate via API
Every paid request includes authentication headers
Your backend rejects requests without valid authentication
Direct API access is blocked, payments are enforced
Backend Implementation
Python Example
import hmac
import hashlib
import base64
import json
import os
from flask import Flask, request, jsonify
app = Flask(__name__)
def verify_hmac_request(request):
x_payment = request.headers.get('x-payment')
x_payment_response = request.headers.get('x-payment-response')
signature_header = request.headers.get('sigwei-auth-signature')
secret = os.environ.get('SIGWEI_SECRET')
if not x_payment or not x_payment_response:
return False, None, None
if not signature_header:
return False, None, None
# Construct message from payment headers
message = x_payment + '|' + x_payment_response
# Verify HMAC signature
expected_signature = base64.b64encode(
hmac.new(secret.encode(), message.encode(), hashlib.sha256).digest()
).decode()
if signature_header != expected_signature:
return False, None, None
# Optional: Decode payment data for additional verification
payment_data = json.loads(base64.b64decode(x_payment))
settlement_data = json.loads(base64.b64decode(x_payment_response))
return True, payment_data, settlement_data
@app.route('/api/data')
def get_data():
verified, payment_data, settlement_data = verify_hmac_request(request)
if not verified:
return jsonify({'error': 'Unauthorized'}), 403
# Optional: Log payment information
if payment_data:
print(f"Paid by: {payment_data['payload']['authorization']['from']}")
print(f"Transaction: {settlement_data['transaction']}")
return jsonify({'data': 'Your protected data'})Managing Secrets
Get or Regenerate Secret
# Get current secret for a PayGate
curl -X GET http://localhost:8080/api/v1/paygates/123 \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
# Regenerate secret (generates new random secret)
curl -X PATCH http://localhost:8080/api/v1/paygates/123/secret \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"sigweiSecret": ""}'
# Set custom secret
curl -X PATCH http://localhost:8080/api/v1/paygates/123/secret \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"sigweiSecret": "your-custom-secret"}'Request Timeouts & Size Limits
Sigwei enforces timeout and response size limits to prevent abuse and manage infrastructure costs.
Timeout Configuration
Default: 10 minutes (600 seconds)
The proxy timeout determines how long Sigwei will wait for your target URL to respond. This generous default supports:
AI endpoints (OpenAI, Claude, etc.)
Long-running computations
Large data processing
When requests timeout:
Client receives 502 Bad Gateway
Metrics are still captured for analytics
Credits are consumed (payment was made, timeout is server-side)
Best Practices:
Design APIs to respond within 10 minutes when possible
Use async patterns for longer operations (webhook callbacks)
Return processing IDs immediately, fetch results later
Consider chunking large responses
Response Size Limits
Default: 10MB (10,485,760 bytes)
Sigwei blocks responses exceeding this limit to prevent egress bandwidth abuse on hosting infrastructure.
When size limit exceeded:
Request blocked with 502 Bad Gateway
Warning logged with actual size and limit
Metrics captured showing blocked request
Credits are consumed (payment was made, size limit is protective)
Handling Large Responses:
For responses larger than 10MB, use File PayGates instead:
Upload files to Sigwei's storage (R2)
Users get presigned download URLs
No bandwidth cost to Sigwei (direct R2 → user)
Better user experience for large files
Example - Wrong way (proxy large data):
# ❌ This will hit the 10MB limit
curl -X POST https://402ify.com/api/v1/paygates \
-H "Authorization: Bearer $JWT_TOKEN" \
-d '{
"targetURL": "https://api.example.com/export/csv",
"price": 100000,
"resourceType": "url"
}'Example - Right way (use file PayGate):
# ✓ Use file PayGates for large content
curl -X POST https://402ify.com/api/v1/paygates \
-H "Authorization: Bearer $JWT_TOKEN" \
-F "price=100000" \
-F "resourceType=file" \
-F "file=@large-dataset.csv"API Design Recommendations
For API Providers:
Paginate large datasets - Return data in chunks
Stream processing - Use streaming responses where possible
Compression - gzip/brotli compress responses
Async patterns - Return job IDs for long operations
Example - Pagination:
{
"data": [...],
"pagination": {
"page": 1,
"limit": 100,
"total": 5000,
"nextPage": "/api/data?page=2"
}
}Security Best Practices
Store secrets securely: Use environment variables or key management systems
Validate every request: Check authentication headers on all protected endpoints
Use HMAC mode: More secure than plaintext for production environments
Rotate secrets regularly: Update PayGate secrets periodically via API
Log access attempts: Monitor for unauthorized patterns and failed authentications
Rate limiting: Implement rate limiting on your target URLs to prevent abuse
Response size awareness: Design APIs to stay under 10MB or use file PayGates for larger content
Last updated