Accept stablecoin payments on Solana. with one simple API.
Create a hosted checkout for USDC payments on Solana Devnet. No SDK required.
MardiPay is currently available on Solana Devnet using Devnet USDC.
curl -X POST https://mardipay.in/api/v1/payment_intents \
-H "Authorization: Bearer mp_test_xxx" \
-H "Content-Type: application/json" \
-d '{
"amount": "5.00",
"currency": "USDC",
"description": "MardiPay Cap",
"image_url": "https://example.com/cap.png"
}'Get started
Everything you need to create your first payment.
Get an API key
Create a free Devnet API key from your MardiPay dashboard.
Create a payment
Create a Payment Intent using the API and receive a hosted checkout URL.
Send customers to checkout
Redirect your customer to the checkout URL returned by MardiPay.
How MardiPay works
The entire payment lifecycle in one simple synchronous loop.
Quickstart
Complete your first end-to-end USDC payment in under two minutes.
1Obtain your Devnet API key
Go to your Merchant Dashboard under the API Keys tab. Click Generate Key to get your test key formatted as mp_test_xxx.
2Create a Payment Intent
Send a POST request with the amount and optional item details:
curl -X POST https://mardipay.in/api/v1/payment_intents \
-H "Authorization: Bearer mp_test_xxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order_123" \
-d '{
"amount": "5.00",
"currency": "USDC",
"description": "MardiPay Cap",
"image_url": "https://example.com/cap.png",
"metadata": {
"order_id": "order_123"
}
}'3Redirect customer to checkout_url
The API response contains a hosted URL formatted as https://mardipay.in/checkout/pi_xxx. Send your buyer to this page to complete payment via Solana Pay QR or MardiPay Sol ID.
4Verify payment confirmation
Check the payment status by polling the intent endpoint:
curl https://mardipay.in/api/v1/payment_intents/pi_123 \
-H "Authorization: Bearer mp_test_xxx"/api/v1/payment_intents
Create a payment intent and receive a hosted checkout URL.
Authorization: Bearer mp_test_xxxRequest Body
| Field | Type | Description |
|---|---|---|
| amount * | String | The exact amount to charge in USDC (e.g. "5.00" or "25.00"). |
| currency * | String | Currently "USDC". |
| description | String | Optional product name or payment description displayed on the hosted checkout. |
| image_url | String | Optional image URL rendered on the hosted checkout page. |
| metadata | Object | Optional key-value object (max 4KB) for custom order references (e.g. {"order_id": "123"}). |
curl -X POST https://mardipay.in/api/v1/payment_intents \
-H "Authorization: Bearer mp_test_xxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order_123" \
-d '{
"amount": "5.00",
"currency": "USDC",
"description": "MardiPay Cap",
"image_url": "https://example.com/cap.png",
"metadata": {
"order_id": "order_123"
}
}'{
"id": "pi_k39f9a2",
"object": "payment_intent",
"amount": "5.00",
"currency": "USDC",
"status": "created",
"checkout_url": "https://mardipay.in/checkout/pi_k39f9a2",
"payment_reference": "7dK9...Wp2",
"description": "MardiPay Cap",
"image_url": "https://example.com/cap.png",
"metadata": {
"order_id": "order_123"
},
"created_at": 1790000000000,
"expires_at": 1790000300000
}/api/v1/payment_intents/:id
Retrieve the current status of a payment.
curl https://mardipay.in/api/v1/payment_intents/pi_123 \
-H "Authorization: Bearer mp_test_xxx"{
"id": "pi_123",
"object": "payment_intent",
"amount": "5.00",
"currency": "USDC",
"status": "confirmed",
"checkout_url": "https://mardipay.in/checkout/pi_123",
"tx_signature": "5abc...421",
"payer": "7xyz...891",
"created_at": 1790000000000,
"confirmed_at": 1790000020000
}Payment Statuses
| Status | Meaning |
|---|---|
| created | Payment intent created; waiting for customer to visit checkout. |
| processing | Payer initiated approval or transaction is broadcasting on Solana. |
| confirmed | USDC transfer verified onchain on Solana Devnet. Payment succeeded. |
| expired | The 5-minute checkout countdown expired before payment was verified. |
| failed | Transaction failed on Solana. |
| cancelled | The customer cancelled the checkout session. |
Customize Checkout
MardiPay hosted checkout is completely dynamic. The developer controls the item name, amount, product image, and metadata directly through the Payment Intent request.
{
"amount": "25.00",
"currency": "USDC",
"description": "Premium Hoodie",
"image_url": "https://example.com/hoodie.png",
"metadata": {
"order_id": "ORDER-123",
"size": "L"
}
}- description becomes the product title.
- amount is formatted prominently in USDC.
- image_url is rendered as the product avatar.
- metadata is preserved on the payment record.
Idempotency
Use an idempotency key to safely retry requests without creating duplicate payments.
Idempotency-Key: <unique_order_identifier>If a network error or server timeout occurs during payment intent creation, safely resend the same request with the exact same Idempotency-Key.
MardiPay recognizes the key, skips duplicate intent creation, and immediately returns the previously created Payment Intent and checkout URL.
API Errors
All error responses use standard HTTP status codes and a consistent JSON format:
{
"error": {
"type": "invalid_request",
"code": "invalid_amount",
"message": "Amount must be greater than 0."
}
}Error Codes
| Code | HTTP Status | Description |
|---|---|---|
| invalid_request | 400 | Malformed JSON payload or missing required parameter. |
| invalid_amount | 400 | Amount is missing or not a positive number string. |
| invalid_currency | 400 | Unsupported token currency. Only USDC is valid on Devnet. |
| invalid_api_key | 401 | API key is missing, inactive, or revoked. |
| payment_intent_not_found | 404 | No payment intent exists with the provided ID. |
| rate_limit_exceeded | 429 | Request rate exceeded 60 requests per minute limit. |
| internal_error | 500 | Unexpected server error while processing the request. |
Security & Rate Limiting
Authentication & Key Storage
All requests require a Bearer key. MardiPay cryptographically hashes keys with SHA-256 upon generation and only displays the raw key once. Store your key securely in server environment variables.
Rate Limits & Payload Guards
Public API endpoints enforce a rate limit of 60 requests per minute per key/IP. Payloads are strictly capped at 64KB. Requests exceeding limits receive HTTP 429.
Start building with MardiPay.
Create a free Devnet key and accept your first Solana USDC payment today.