Accept and send payments programmatically
Create a key request from the merchant dashboard and wait for admin approval. The API Secret is shown only once when created or regenerated, so store it securely.
Choose which endpoints your API key can access. Minimum one permission required.
Test with small amounts, then scale up. Always use HTTPS.
Required Headers:
X-API-Key: oes_your_api_key_here
X-API-Secret: sk_your_secret_here
Each API key can have one or more permissions. The all permission grants full access.
| Permission | Description | Endpoints |
|---|---|---|
| payin | Create and manage payment invoices | /create-invoice, /check-status, /merchant/payins |
| payout | Create and manage payout requests | /payout/create, /merchant/payouts |
| balance | Check balance and statistics | /merchant/balance, /merchant/stats |
| all | Full access to all endpoints | All endpoints |
https://chash.app/api
All endpoints are relative to this base URL.
/create-invoice
Requires: payin
Required Headers:
Content-Type: application/json
X-API-Key: oes_your_api_key_here
X-API-Secret: sk_your_secret_here
{
"amount": 100.00,
"pay_way": "cashapp",
"customer_email": "customer@example.com",
"customer_name": "John Doe"
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| amount | numeric | ✅ Yes | Normally Min: 1, Max: 10000. eCashApp, Apple Pay and Google Pay accept only the exact preset amounts listed below. |
| pay_way | string | ✅ Yes | cashapp, ecashapp, applepay, googlepay, chime, btcpay, paypal, venmo |
| customer_email | string | ❌ No | Valid customer email, maximum 255 characters |
| customer_name | string | ❌ No | Customer name, maximum 255 characters |
| redirect_url | URL | ❌ No | HTTPS return URL after checkout, maximum 2048 characters |
Fee and net values vary according to the authenticated merchant's effective rate.
{
"success": true,
"data": {
"order_id": 123,
"order_no": "API_1788264000_abc123",
"amount": "99.99",
"fee": "14.80",
"net": "85.19",
"pay_way": "applepay",
"payment_url": "https://provider.example/checkout/xxx",
"expires_at": "2026-09-01T12:00:00Z",
"status": "processing"
}
}
{
"success": true,
"data": {
"order_id": 124,
"order_no": "API_1788264000_def456",
"amount": "100.00",
"fee": "10.30",
"net": "89.70",
"pay_way": "chime",
"manual_code": "W6X-F1",
"wallet_address": "$ExampleTag",
"checkout_url": "https://chash.app/checkout/124",
"expires_at": "2026-09-01T20:00:00Z",
"status": "pending_manual"
}
}
/check-status/{order_id}
Requires: payin
{
"success": true,
"data": {
"order_id": 123,
"order_no": "API_1788264000_abc123",
"amount": "99.99",
"real_amount": "99.99",
"fee": "14.80",
"net": "85.19",
"pay_way": "applepay",
"payment_url": "https://provider.example/checkout/xxx",
"manual_code": null,
"status": "success",
"created_at": "2026-09-01T10:00:00Z",
"success_time": "2026-09-01T10:05:00Z",
"expires_at": "2026-09-01T12:00:00Z"
}
}
/merchant/balance
Requires: balance
{
"success": true,
"data": {
"merchant_id": 123,
"merchant_name": "My Store",
"balance": "1500.00",
"bonus_balance": "50.00"
}
}
/merchant/payins
Requires: payin
Query Parameters:
?limit=20&status=success
{
"success": true,
"data": {
"total": 45,
"payins": [
{
"id": 123,
"order_no": "API_1706000000_abc123",
"amount": "100.00",
"fee": "11.00",
"net": "89.00",
"pay_way": "cashapp",
"status": "success",
"created_at": "2026-01-15 10:00:00"
}
]
}
}
/merchant/payouts
Requires: payout
Query Parameters:
?limit=20&status=approved
{
"success": true,
"data": {
"total": 12,
"payouts": [
{
"id": 456,
"transaction_id": "POU-123456",
"amount": "50.00",
"fee": "3.50",
"pay_way": "paypal_payout",
"recipient": "merchant@example.com",
"status": "approved",
"created_at": "2026-01-15 10:00:00"
}
]
}
}
/merchant/stats
Requires: balance
{
"success": true,
"data": {
"balance": "1500.00",
"bonus_balance": "50.00",
"payin": {
"total_count": 45,
"total_amount": "5000.00",
"total_success": "4500.00",
"total_pending": "500.00",
"total_failed": "0.00"
},
"payout": {
"total_count": 12,
"total_amount": "1200.00",
"total_approved": "1100.00",
"total_pending": "100.00",
"total_failed": "0.00"
}
}
}
/merchant/profile
Requires: all
{
"success": true,
"data": {
"id": 12,
"name": "Example Merchant",
"email": "merchant@example.com",
"status": "active"
}
}
/payout/create
Requires: payout
X-API-Key: oes_your_api_key
X-API-Secret: sk_your_secret
Idempotency-Key: unique_request_id_123
{
"amount": 50.00,
"pay_way": "paypal_payout",
"account_info": "merchant@example.com"
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| amount | numeric | ✅ Yes | Min: 10, Max: 5000 |
| pay_way | string | ✅ Yes | cashapp_payout, paypal_payout, ach_payout, card_payout, chime_payout |
| account_info | string | ✅ Yes | Email, tag, or handle |
{
"success": true,
"data": {
"payout_id": 456,
"transaction_id": "POU-20260901-A1B2C3D4E5F6-1788264000",
"amount": "50.00",
"fee": "3.50",
"total_deducted": "53.50",
"pay_way": "paypal_payout",
"recipient": "merchant@example.com",
"status": "pending",
"created_at": "2026-09-01 10:00:00"
}
}
This section describes the planned OESPay-to-merchant callback format. It is separate from provider callbacks received by OESPay from BTCPay Server or other payout providers.
Content-Type: application/json
X-OESPay-Event-Id: evt_01JABCDEF123456789
X-OESPay-Timestamp: 1788264000
X-OESPay-Signature: sha256=generated_hmac_signature
{
"event_id": "evt_01JABCDEF123456789",
"event": "payout.approved",
"created_at": "2026-09-01T10:00:00Z",
"data": {
"payout_id": 456,
"transaction_id": "POU-20260901-A1B2C3D4E5F6-1788264000",
"amount": "50.00",
"fee": "3.50",
"total_deducted": "53.50",
"pay_way": "paypal_payout",
"status": "approved"
}
}
Planned verification: Calculate HMAC-SHA256 over timestamp.raw_request_body using a separate webhook signing secret, then compare it with X-OESPay-Signature using a timing-safe comparison.
Acknowledgement: Return any HTTP 2xx response after safely recording the event.
Duplicate protection: Store X-OESPay-Event-Id and ignore an event that has already been processed.
Retry policy: The production retry schedule will be published when outgoing webhooks are enabled.
| Code | HTTP Status | Message |
|---|---|---|
| AUTH_001 | 401 | API key required |
| AUTH_002 | 401 | Invalid API credentials |
| AUTH_003 | 401 | API key is inactive or expired |
| AUTH_004 | 401 | Invalid API credentials |
| AUTH_005 | 403 | Request IP is not allowed |
| AUTH_006 | 403 | Permission denied for this endpoint |
| AUTH_007 | 401 | API secret required |
| AUTH_008 | 403 | Merchant account is inactive |
| AUTH_009 | 403 | API permission configuration missing |
| AUTH_010 | 401 | Merchant not authenticated |
| PAYIN_001 | 422 | Payment method is unavailable |
| PAYIN_002 | 422 | Calculated fee exceeds the invoice amount |
| PAYIN_003 | 502 | Upstream payment provider could not create the invoice |
| PAYIN_004 | 422 | Unsupported payment method |
| PAYIN_005 | 404 | Order not found for the authenticated merchant |
| PAYIN_006 | 503 | No active manual wallet is available |
| PAYIN_007 | 422 | Invalid restricted amount; response includes allowed_amounts |
| PAYOUT_002 | 500 | Temporary payout processing error. Please retry safely with the same Idempotency-Key. |
| PAYOUT_003 | 400 | Payment method not available for payout |
| PAYOUT_004 | 422 | Valid Idempotency-Key header is required |
| PAYOUT_005 | 409 | Idempotency key was already used with different payout data |
| PAYOUT_006 | 422 | Insufficient balance or merchant inactive |
| RATE_001 | 429 | Rate limit exceeded (5000/min) |
| 500 | 500 | Internal server error |
If you exceed this limit, you will receive a 429 Too Many Requests response.
Rate Limit Headers:
X-RateLimit-Limit: 5000
X-RateLimit-Remaining: 4999
X-RateLimit-Reset: 1706000000