Developers
Built to connect with your product
Create a payment request from your backend, send the customer to the returned checkout URL, then read the payment's status — by polling or by receiving a signed webhook.
Overview
The mPay API is JSON over HTTPS. The base URL is https://multiplepay.online/api/v1. Amounts are decimal in the account's currency. A payment request returns a hostedcheckout_url; mPay renders the payment experience, so you never handle payment credentials.
Authentication
Server-to-server calls authenticate with a secret API key issued in the dashboard under Developers. Send it as X-API-Key or as a bearer token. Secret keys need payments:write to create charges. Publishable and read-only keys cannot create charges. API payouts require payouts:write, explicit key enrollment, and per-send and rolling 24-hour limits. New or rotated keys are pay-in-only until enrolled. Keep keys on your backend, never in browser or mobile code.
X-API-Key: sk_live_xxxxxxxxxxxxxxxxxxxx
# or
Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxCreate a payment
POST /api/v1/charges creates a payment and returns the hosted checkout URL to send your customer to. reference is your own identifier and is echoed back so you can match the payment to your order.
curl -X POST https://multiplepay.online/api/v1/charges \
-H "X-API-Key: sk_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"amount": 100.00,
"method": "cashapp",
"customer_name": "Jordan Fisher",
"reference": "order_10482"
}'Response
{
"id": "pay_3f1c8a...",
"status": "pending",
"amount": 100.0,
"method": "cashapp",
"checkout_url": "https://...",
"reference": "order_10482"
}Some methods accept only fixed amounts. Read the method catalogue below and send an accepted value rather than assuming an arbitrary amount will be taken.
Payment status
GET /api/v1/charges/{id} returns the current state of a payment. A verified pending_settlement charge is collected but held for merchant settlement. You may credit the customer then under your risk policy; available means withdrawable, not a second payment. Match the charge id, reference and actual settled_amount, and credit only once. A customer redirect is not proof of payment.
curl https://multiplepay.online/api/v1/charges/pay_3f1c8a... \
-H "X-API-Key: sk_live_xxxxxxxxxxxxxxxxxxxx"awaiting_customerNo captured principal yet; awaiting payment, partial completion or an eligible same-URL retry
pending_settlementCollected; held for merchant settlement until available_at
availableReleased and withdrawable
failedTerminal unpaid charge; create a fresh link to try again
Same-URL retry: keep the original checkout_url and charge id. Eligible XXPayUS failures stay awaiting_customer while the 24-hour mPay link is usable. Reopening that mPay URL can switch to one supported TinyPay attempt after fresh failure checks, with the same amount and charge id. No payment.failed event is sent during this window. An unused expired retry becomes failed only after mPay freshly confirms the original provider failure; query outages remain pending for another check. Terminal failed charges require a fresh merchant link. Credit only a verified collected amount once per charge id.
Crypto limits and authenticated callbacks
Crypto checkout limits: read GET /api/v1/methods before creating a charge. For each live custom-amount method, use its current USD min and max, exact cents, and the exact method/network; the maximum is $25,000. NOWPayments minimums are calculated for the actual pay currency converted into USDT TRC-20, buffered by 10% and rounded up to cents. They are dynamic and shared by app, API and gateway validation, cached for at most five minutes; never hardcode a historical minimum. A method with live=false or temporarily_unavailable=true must not be offered; min=null means no verified quote, not a zero minimum. A lookup outage blocks new checkout creation rather than using an unsafe fallback. The browser refreshes the catalogue each minute; the server revalidates at creation. The requested USD amount and exact payment asset/network stay unchanged; custody conversion is not a change to what the payer must send. NOWPayments callbacks require the matching IPN HMAC-SHA512 signature; an unavailable signing configuration returns retryable HTTP 503, while missing/invalid signatures return 401 without credit. Authenticated provider polling remains a recovery path. Merchant callbacks still use mPay signatures, not the provider IPN secret. Credit verified pending_settlement/available receipts using settled_amount once per charge id; redirects, Waiting invoices and webhook HTTP 200 alone do not prove payment or external wallet credit.
Partial payments and exact amounts
Exact paid amounts: requested_amount is the original invoice. paid_amount is the provider-verified gross receipt, before merchant/provider fees. settled_amount is the captured gross principal eligible for customer-wallet credit, not net merchant proceeds. Uncollected states return settled_amount=0, even if a partial receipt is observed. is_partial=true means less than requested was paid; shortfall_amount is the remaining difference. A $10 invoice with $9 captured returns requested_amount=10, amount=9, paid_amount=9, settled_amount=9, is_partial=true, shortfall_amount=1. There is no new partial status: use pending_settlement/available with these amount fields. Speed underpayments are captured after checkout expiry; a still-open underpayment remains awaiting_customer and must not be credited yet. Match the ORIGINAL requested_amount, charge id, reference and currency to your order, then credit only settled_amount once per charge id in a database transaction. Never require settled_amount to equal the requested invoice, credit amount from the redirect, or credit net. Later payment.succeeded/available does not create another wallet credit. Verify webhook signature over the raw body, deduplicate event_id, and use authenticated GET /api/v1/charges/{id} for reconciliation; a failed delivery or HTTP 200 is not proof that the customer wallet was credited. Existing collected charges receive the new fields on GET; previously emitted events are not silently rewritten.
Method catalogue
GET /api/v1/methods is public and returns each rail with whether it is live, whether it accepts a custom amount, its accepted fixed amounts, and its minimum and maximum. Read it rather than hard-coding a method list.
curl https://multiplepay.online/api/v1/methodsWebhooks
Register an endpoint in the app under You → Developers. Subscribe to payment.pending_settlement for collection and payment.succeeded for later availability; never credit a charge twice. Each delivery is signed with HMAC-SHA256 over <timestamp>.<body> using the endpoint's signing secret. Verify against the exact bytes received and compare in constant time. Failed deliveries retry six times with exponential backoff over roughly eight hours, then dead-letter — and a dead-lettered delivery can be re-queued from You → Developers.
Errors
Errors use standard HTTP status codes with a JSON detail message.401 means the API key is missing or invalid, 400 means the request was rejected (for example an amount a rail cannot accept), 403 means the key lacks scope or payout enrollment, 429 means a request or payout limit was reached, and502 means the upstream payment provider could not start a checkout. Retry 502 with backoff; do not retry 400 unchanged.
Integration support
Email Official domain-based support contact details will be published before production launch. for integration questions, or use the contact form. Include your merchant handle and the reference of any payment you are asking about — never include API keys.
A dedicated sandbox/test environment, published rate limits and a public status page are not documented in the platform today, so none are described here.
Ready to simplify how you receive payments?
Sign in to mPay or contact our team to discuss payment links, hosted checkout and website integration.
Service availability, supported payment methods, settlement timing and fees may vary.