A lightweight REST API for creating and managing cryptocurrency payment orders.
Authenticate with an API key, create an order, and poll for confirmation.
BTC · ETH · LTC · SOL · BCH · BNB · DOGE · TRX · XRP · XMR
01
Overview
The DESTROY.WTF API is a RESTful JSON service for creating cryptocurrency
payment orders, polling their status, and managing the order lifecycle. All
endpoints accept and return JSON over HTTPS.
QS
Quick start
Create a $25 BTC payment order with a single request:
Merchant requests are authenticated with an API key. Generate one from the
Dashboard after creating an account. Send the key in the
JSON body for POST requests, or as a query parameter on endpoints
that support GET. Query strings are convenient for server-side
integrations but may appear in proxy logs and browser history, so prefer
POST when possible.
Keep your API key secret — never expose it in client-side code or
public repositories. Before creating orders, configure payout addresses for
each cryptocurrency in the Dashboard; the gateway
will not process payments without them.
End-to-end flow for accepting a cryptocurrency payment.
01
Create an order
POST to /api/order/create with the USD amount, crypto type, and your API key. You receive a payment address and a hosted payment-page URL.
02
Direct the customer
Redirect to the payment_gateway_url, or display the address and amount in your own checkout UI.
03
Poll for status
Call /api/order/status periodically. Status progresses from PENDING → CONFIRMING → COMPLETED.
04
Receive payout
Once confirmed, funds are forwarded to your configured payout address. The merchant_txid field returns the payout transaction ID.
There is no webhook system — poll /api/order/status to
detect completion. The return_url is a customer-facing link
shown on the hosted payment page after they pay.
04
Endpoints
Five endpoints cover the full payment lifecycle: create, look up, update,
cancel, and discover available networks.
Endpoint
Create Order
POST/api/order/createAPI key
Creates a new cryptocurrency payment order. Returns a unique
crypto_address to receive payment, the expected
crypto_amount (locked at the current price), and a hosted
payment-page URL you can redirect customers to.
Request body 4
api_keystringRequired
Your API key (UUID v4).
amount_usdfloatRequired
Invoice amount in USD. Min 0.50, max 2000.
crypto_typestringOptional
Cryptocurrency to accept. Defaults to LTC.
return_urlstringOptional
URL displayed on the payment page for the customer to return to your site after paying.
Response fields 10
order_idstring
Unique order identifier (UUID v4).
crypto_amountstring
Amount the customer must send, formatted to 10 decimal places.
Retrieves the current status and details of an order. Public lookups
only need order_id. Merchants can also pass
api_key to verify ownership. Also accepts POST
with a JSON body.
Parameters 2
order_idstringRequired
The order UUID to look up.
api_keystringOptional
If provided, the API key must own the order.
Response fields 6
paidbool
Whether the order has been fully paid.
tx_idstring
Incoming transaction IDs (comma-separated), or "N/A".
Actual USD value received based on crypto received.
GET/api/order/status?order_id=ORDER_ID// Or POST with JSON body:POST/api/order/statusContent-Type: application/json
{
"order_id": "550e8400-e29b-41d4-a716-446655440000",
"api_key": "your-api-key"
}
Switches the cryptocurrency type for an existing unpaid order. A new
payment address is issued and the crypto amount is re-priced at the
current rate. The USD amount remains unchanged.
Request body 3
order_idstringRequired
The order UUID to update.
crypto_typestringRequired
New cryptocurrency to switch the order to.
api_keystringOptional
Your API key. If provided, must match the order's owning key.
Orders that have received any payment (paid_usd > 0)
cannot be updated. The previous payment address is replaced —
funds sent to the old address after the switch will still be
detected, but the order now expects the new crypto type.
{
"success": true,
"message": "Order cancelled successfully",
"order_id": "550e8400-...",
"status": "CANCELED",
// ... full order fields
}
Endpoint
List Cryptocurrencies
GET/api/cryptoPublic
Returns the supported cryptocurrencies and their current USD prices,
plus the percent change over three rolling windows
(5m, 6h, 24h). When the
server has been running for less than a window, that window's
window_seconds reflects the actual history available;
if no history exists yet, the window is omitted. Pass an
api_key to filter to only the cryptos configured
for that key.
Parameters 1
api_keystringOptional
If provided, filters to only cryptos configured for this key.
GET/api/crypto// Or filter by API key:GET/api/crypto?api_key=YOUR_API_KEY
{
"success": true,
"supported": {
"BTC": 97591.23,
"ETH": 3282.45,
"LTC": 128.45,
"SOL": 195.67,
// ... all configured cryptos
},
"changes": {
"BTC": {
"5m": { "pct": 0.12, "window_seconds": 300 },
"6h": { "pct": 0.85, "window_seconds": 21600 },
"24h": { "pct": 1.23, "window_seconds": 86400 }
},
// ... pct is signed (positive = up); window_seconds is the actual
// history age used, which may be smaller than the window target right
// after a restart
}
}
05
Order Statuses
An order progresses through these statuses during its lifecycle. A payment is
considered sufficient when it reaches at least 94% of the expected crypto
amount.
PENDING
Order created, awaiting payment from the customer.
PARTIAL PAYMENT
Payment received but below the 94% threshold of the expected amount.
CONFIRMING
Payment at or above the threshold detected, awaiting blockchain confirmation.
COMPLETED
Payment fully confirmed. Payout to merchant will be processed automatically.
CANCELED
Order was cancelled via API or admin action. Only possible before payment.
Once an order reaches COMPLETED, the gateway automatically
processes payouts. Check withdrawn and
merchant_txid to confirm the payout has been sent.
06
Error Handling
All error responses follow a consistent JSON shape. The HTTP status code is
200 for business-logic errors (invalid parameters, not found) and
429 for rate-limited requests.
The API enforces rate limits per IP address to protect against abuse. Authenticated
users with a valid session receive a higher limit.
Default limit
5 / sec
Unauthenticated requests
Authenticated limit
15 / sec
Logged-in users with a valid session
Block duration
30 sec
Wait before retrying
Status code
429
Too Many Requests
If you sit behind Cloudflare, the real client IP is read from the
CF-Connecting-IP header. Implement exponential backoff in your
polling logic to stay within limits.
08
Code Examples
End-to-end examples covering order creation and status polling.
import requests, time
API_KEY = "your-api-key"
BASE_URL = "https://destroy.wtf"# 1. Create an order
resp = requests.post(f"{BASE_URL}/api/order/create", json={
"api_key": API_KEY,
"amount_usd": 25.00,
"crypto_type": "BTC",
"return_url": "https://your.shop/success",
}).json()
order_id = resp["order_id"]
print(f"Pay: {resp['payment_gateway_url']}")
# 2. Poll until COMPLETEDwhile True:
status = requests.get(
f"{BASE_URL}/api/order/status",
params={"order_id": order_id, "api_key": API_KEY},
).json()
print(f"Status: {status['status']}")
if status["status"] == "COMPLETED":
print(f"Paid! TX: {status['tx_id']}")
breakif status["status"] == "CANCELED":
print("Order was cancelled.")
break
time.sleep(15)
# Create an order
curl -X POST "https://destroy.wtf/api/order/create" \
-H "Content-Type: application/json" \
-d '{
"api_key": "your-api-key",
"amount_usd": 25.00,
"crypto_type": "BTC"
}'# Check order status
curl -X POST "https://destroy.wtf/api/order/status" \
-H "Content-Type: application/json" \
-d '{"order_id":"ORDER_ID","api_key":"your-api-key"}'# Cancel an order
curl -X POST "https://destroy.wtf/api/order/cancel" \
-H "Content-Type: application/json" \
-d '{"api_key":"your-api-key","order_id":"ORDER_ID"}'
The gateway can push lifecycle events to an HTTPS endpoint you control. Manage
endpoints from the Webhooks tab in your Dashboard. Each
event is delivered as a JSON POST signed with a per-endpoint HMAC
secret.
Event types 7
order.created
A new order was created.
order.status_changed
Status transitioned — payload includes old_status and status.
order.updated
Order details refreshed.
order.payout_review
Payout flagged for manual review.
order.payout_review_cleared
An admin cleared the review flag.
order.payout_indeterminateAdmin-only
XMR payout returned an indeterminate RPC result.
order.payout_stuckAdmin-only
XMR payout has been indeterminate for over an hour.
Non-2xx responses (or timeouts) are retried up to 8 times with exponential
backoff starting at 30 seconds and doubling each attempt (cap ~64 minutes).
After 8 failed attempts the delivery is marked exhausted. After
20 consecutive failures across any deliveries the endpoint auto-disables
— re-enable it from the Dashboard once your receiver is fixed.
Best practices. Respond within 5 seconds — defer
slow work to a background queue. Treat X-Gateway-Event-Id as
the idempotency key and store seen IDs so retries are no-ops. Always
verify the signature before reading the body.