External Payments API
The External Payments API allows you to create payment prompts programmatically from your backend. When a payment is created, you receive a checkout URL to redirect your customer.
Authentication
All API requests require HTTP Basic Authentication using your Client ID and API Key:
Authorization: Basic base64(clientId:apiKey)
The credentials must belong to a Merchant Admin user with an active account. See Prerequisites for details on obtaining and using your credentials.
Create Payment Prompt
Creates a new payment prompt and returns a checkout URL.
Endpoint: POST /external/payments/prompt
Headers:
Header |
Required |
Description |
|---|---|---|
|
Yes |
Must be |
|
Yes |
Basic authentication (Base64 encoded |
Request Body:
Payer Options:
customer: The customer pays the network fee (added to the payment amount)merchant: You absorb the network fee (deducted from your settlement)
Warning
Every blockchain ID in the blockchainIds array must have a payment address configured for your merchant account. If any of the requested blockchains are missing a payment address, the request will be rejected. Use GET /external/blockchains/active to check which blockchains are available, and configure payment addresses in your merchant dashboard.
Example Request:
curl -X POST https://api.miraclecash.info/external/payments/prompt \
-H "Content-Type: application/json" \
-H "Authorization: Basic $(echo -n 'your_client_id:your_api_key' | base64)" \
-d '{
"amount": 100.50,
"blockchainIds": ["eth"],
"payer": "customer",
"note": "Order #12345",
"redirectUrl": "https://shop.example.com/order/12345/complete"
}'
Example Response:
{
"prompt": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"amount": 103.52,
"commissionAmount": "3.02",
"status": "pending",
"sessionStatus": "pending",
"expiresAt": "2025-01-29T14:30:00.000Z",
"createdAt": "2025-01-28T14:30:00.000Z",
"redirectUrl": "https://shop.example.com/order/12345/complete"
},
"checkoutUrl": "https://checkout.miraclepay.com/?sessionId=550e8400-e29b-41d4-a716-446655440000"
}
Response Fields:
Field |
Type |
Description |
|---|---|---|
|
string |
Unique payment prompt ID (UUID) |
|
number |
Final amount including commission (if payer is customer) |
|
string |
Commission fee amount in USD |
|
string |
Payment status: |
|
string |
Checkout session status: |
|
string |
ISO 8601 timestamp when payment expires (24 hours) |
|
string |
ISO 8601 timestamp when payment was created |
|
string or null |
The redirect URL provided in the request, or |
|
string |
URL to redirect the customer for payment |
Get Payment Status
Retrieves the current status of a payment prompt.
Endpoint: GET /external/payments/prompt/:id
Headers:
Header |
Required |
Description |
|---|---|---|
|
Yes |
Basic authentication (Base64 encoded |
Path Parameters:
Parameter |
Type |
Description |
|---|---|---|
|
string |
The payment prompt UUID |
Example Request:
curl -X GET https://api.miraclecash.info/external/payments/prompt/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Basic $(echo -n 'your_client_id:your_api_key' | base64)"
Example Response:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"blockchainId": "eth",
"status": "successful",
"createdAt": "2025-01-28T14:30:00.000Z"
}
Payment Status Values:
Status |
Description |
|---|---|
|
Payment initiated, awaiting customer action |
|
Payment confirmed on the blockchain |
|
Payment failed (e.g., insufficient funds) |
|
Customer did not complete payment within 24 hours |
|
Payment was cancelled |
Error Responses
HTTP Status Codes:
Error Response Format:
{
"statusCode": 401,
"message": "Invalid client ID",
"error": "Unauthorized"
}
Integration Examples
Node.js / TypeScript
import axios from 'axios';
const MIRACLEPAY_CLIENT_ID = process.env.MIRACLEPAY_CLIENT_ID;
const MIRACLEPAY_API_KEY = process.env.MIRACLEPAY_API_KEY;
const MIRACLEPAY_BASE_URL = 'https://api.miraclecash.info';
// Create Basic Auth header
const authHeader = `Basic ${Buffer.from(`${MIRACLEPAY_CLIENT_ID}:${MIRACLEPAY_API_KEY}`).toString('base64')}`;
interface CreatePaymentResponse {
prompt: {
id: string;
amount: number;
status: string;
createdAt: string;
};
checkoutUrl: string;
}
async function createPayment(
amount: number,
blockchainIds: string[],
note?: string,
redirectUrl?: string
): Promise<CreatePaymentResponse> {
const response = await axios.post<CreatePaymentResponse>(
`${MIRACLEPAY_BASE_URL}/external/payments/prompt`,
{
amount,
blockchainIds,
payer: 'customer',
note,
redirectUrl,
},
{
headers: {
'Content-Type': 'application/json',
'Authorization': authHeader,
},
}
);
return response.data;
}
async function getPaymentStatus(promptId: string) {
const response = await axios.get(
`${MIRACLEPAY_BASE_URL}/external/payments/prompt/${promptId}`,
{
headers: {
'Authorization': authHeader,
},
}
);
return response.data;
}
// Usage
async function handleCheckout(orderId: string, amount: number) {
const returnUrl = `https://shop.example.com/orders/${orderId}/complete`;
const payment = await createPayment(amount, ['eth'], `Order #${orderId}`, returnUrl);
// Store prompt.id in your database linked to the order
await savePaymentToOrder(orderId, payment.prompt.id);
// Redirect customer to checkout
return { redirectUrl: payment.checkoutUrl };
}
Best Practices
Store payment IDs: Always save the
prompt.idin your database linked to the corresponding order for reconciliation.Handle errors gracefully: Implement retry logic with exponential backoff for transient failures.
Validate amounts: Ensure payment amounts are valid numbers with up to 2 decimal places.
Test first: Always test your integration using testnet blockchain IDs before going live.
Do not trust the redirect: When using
redirectUrl, the customer is redirected with?promptId=...&status=...query parameters. Never use these parameters as proof of payment. Always verify the payment status server-side viaGET /external/payments/prompt/:idbefore fulfilling orders.Configure allowed redirect domains: Before using
redirectUrl, you must add the domain to your allowed redirect domains list in the MiraclePay dashboard. Only fully qualified domain names (e.g.,shop.example.com) are allowed, up to 20 domains maximum.
Allowed Redirect Domains
For security reasons, redirect URLs are validated against an allowlist of domains configured in your merchant account.
Dashboard Configuration:
Configure your allowed redirect domains in the MiraclePay merchant dashboard under Developer Settings. Each domain must be a valid fully qualified domain name (FQDN).
Example allowed domains:
shop.example.comstore.mysite.comcheckout.yourdomain.com
Limits:
Maximum 20 domains per merchant account
Only FQDNs are accepted (no paths, protocols, or wildcards)
The hostname of your
redirectUrlmust exactly match one of the configured domains