Overview
Dopayer lets customers pay with a licensed payment provider while you receive the funds instantly as USDC (Polygon) in your own wallet. Pick the integration that fits you:
Payment links
No code. Create a link in seconds and share it with your customers.
Direct API
Two requests: create a wallet, then send the customer to pay.
Crypto payments
Accept USDC/USDT directly from your customer's own wallet.
Partners
Bring your own merchants and earn a share of every sale.
How a payment works
- Create a temporary walletYour system asks Dopayer for a unique, encrypted receiving wallet for this order and gives a callback URL.
- Send the customer to payRedirect the customer to the payment page with the wallet, amount, email and currency.
- The customer paysPayment is completed on the page of a licensed payment provider.
- You get paidThe payout arrives in your wallet and Dopayer calls your callback URL with the payment details.
Base URLs
| Purpose | URL |
|---|---|
| API | https://api.dopayer.com |
| Payment pages | https://payment.dopayer.com |
| Payment links | https://dopayer.com |
All API endpoints use GET and return JSON. Any failed request returns HTTP 400.
Payment links (no code)
The quickest way to get paid. Open the payment link generator, enter your wallet, a description and an amount, and share the link it gives you. Optionally add your own logo so customers see your brand on the checkout page.
A link looks like this:
https://dopayer.com/pay.html?wallet=0xYOUR_WALLET&amount=29.99¤cy=USD&desc=Monthly%20plan&logo=https%3A%2F%2Fexample.com%2Flogo.png
| Parameter | Description |
|---|---|
wallet required | Your receiving wallet: a self-custodial EVM address (0x followed by 40 hex characters) that can receive USDC on Polygon. |
amount required | The amount the customer pays. Must be greater than 0. |
currency optional | Currency code. Defaults to USD. The generator offers USD, EUR, CAD and GBP. |
desc optional | What the customer is paying for. Shown at the top of the page. Defaults to "Payment". |
logo optional | Public https:// URL of your logo image. Shown to the customer on the checkout pages. |
Tip: the logo must be a direct link to an image that opens for anyone (PNG, JPG, SVG or WebP). If the image cannot be loaded, it is simply not shown.
Fees & payouts
Payouts are sent automatically and instantly by the temporary wallet created for each order. Percentages apply to the amount forwarded to you after the payment provider has taken its own fee.
| Who | Share of the final payout |
|---|---|
| Merchant (your wallet) | 98% |
| Platform and infrastructure fees | 2% |
For example, if the amount forwarded after provider fees is 100 USDC, the merchant wallet receives 98 USDC.
Payouts may arrive as USDC or USDT on Polygon (or other supported payout coins), so use a self-custodial wallet that can receive them.
Important: each payment provider has a minimum order amount and some accept only certain currencies. See List providers.
1. Create wallet
Creates a unique, encrypted receiving wallet for one order. Call this once per customer order.
https://api.dopayer.com/control/wallet.phpParameters
| Parameter | Description |
|---|---|
address required | Your payout wallet (USDC on Polygon). |
callback required | URL-encoded URL of yours that Dopayer will call when the customer has paid. It must contain at least one query value that is unique to the order (an order number or invoice ID). |
Unique callbacks: if you send the same callback again, you receive the same wallet again. Never reuse one payment link for several customers, or it can get blocked.
Response
| Field | Description |
|---|---|
address_in | The encrypted wallet. Pass it to the payment page in the next step, exactly as returned. |
polygon_address_in | The same wallet, readable. Handy for tracking, but it cannot be used in the next step. |
callback_url | Your callback URL, decoded, for confirmation. |
ipn_token | Token to check the payment status later or to give to support if a callback fails. |
curl "https://api.dopayer.com/control/wallet.php?address=0xYOUR_WALLET&callback=https%3A%2F%2Fyourstore.com%2Fcallback%3Forder%3DINV-1001"
{
"address_in": "eE5A43DAkczRwxoW3IL7sGsRh6CiMx4kkTCccr6n%2FYMTGhy9b1eeIJLTr9Lho64fJTIeOfgsnJNNc%2FarqtR1jw%3D%3D",
"polygon_address_in": "0x756C4D5EAad2165b3841a543Cf851Eed6AAF211B",
"callback_url": "https://yourstore.com/callback?order=INV-1001",
"ipn_token": "ZEE2cW8zb1N0N2otZEc3eHh3MDNUU1lTMEExYmVv..."
}
Do not encode address_in again. It is already URL-encoded (it contains %2F and %3D). Encoding it a second time makes the next request fail.
2a. Process payment (single provider)
Redirects the customer straight to one payment provider that you choose.
https://payment.dopayer.com/process-payment.php| Parameter | Description |
|---|---|
address required | The encrypted address_in from step 1. |
amount required | The amount the customer pays, for example 49.99. You can add extra to cover processing fees. |
provider required | A provider id from List providers, for example moonpay. |
email required | URL-encoded customer email. |
currency required | Currency code such as USD, EUR or CAD. Some providers accept only one currency (see below). |
https://payment.dopayer.com/process-payment.php?address={address_in}&amount=49.99&provider=moonpay&email=john%40example.com¤cy=USD
Redirect only. The payment page must open directly in the customer's browser. Embedding it in an iframe is not allowed.
2b. Hosted page (multi-provider)
Sends the customer to a hosted page that lists the payment options available for their location, amount and currency, so you do not have to pick a provider yourself.
https://payment.dopayer.com/pay.phpRequired parameters
| Parameter | Description |
|---|---|
address | The encrypted address_in from step 1. |
amount | The amount the customer pays. |
email | URL-encoded customer email. |
currency | Currency code, for example USD. |
Optional branding
| Parameter | Description |
|---|---|
logo | URL-encoded URL of your logo image. |
background | Page background color as HEX without # (for example 0F172A) or a CSS color name. |
theme | Theme color of the page, HEX or CSS color name. |
button | Color of the pay button, HEX or CSS color name. |
https://payment.dopayer.com/pay.php?address={address_in}&amount=49.99&email=john%40example.com¤cy=USD&logo=https%3A%2F%2Fexample.com%2Flogo.png&background=0F172A&theme=6366F1&button=6366F1
Tip: the hosted page uses light text, so choose a dark background color. A light background makes the amount and the pay button hard to read.
Full example
Create the wallet, then redirect the customer. Run this on your server so your wallet address and order logic stay under your control.
// Node.js 18+ (server side)
const MERCHANT_WALLET = '0xYOUR_WALLET';
async function createPayment(orderId, amount, customerEmail) {
// 1) Create a unique wallet for this order.
// The callback must contain a value that is unique per order.
const callback = 'https://yourstore.com/callback?order=' + orderId;
const walletRes = await fetch(
'https://api.dopayer.com/control/wallet.php' +
'?address=' + MERCHANT_WALLET +
'&callback=' + encodeURIComponent(callback)
);
if (!walletRes.ok) throw new Error('Could not create the wallet');
const { address_in, ipn_token } = await walletRes.json();
// Save ipn_token with your order (useful for the status endpoint).
// 2) Build the payment URL.
// address_in is ALREADY URL-encoded: do not encode it again.
const payUrl = 'https://payment.dopayer.com/pay.php' +
'?address=' + address_in +
'&amount=' + amount +
'&email=' + encodeURIComponent(customerEmail) +
'¤cy=USD';
return payUrl; // redirect the customer's browser to this URL
}
<?php
// PHP (server side)
$merchantWallet = '0xYOUR_WALLET';
$orderId = 'INV-1001';
$amount = '49.99';
$email = '[email protected]';
// 1) Create a unique wallet for this order.
$callback = 'https://yourstore.com/callback.php?order=' . $orderId;
$response = file_get_contents(
'https://api.dopayer.com/control/wallet.php' .
'?address=' . $merchantWallet .
'&callback=' . urlencode($callback)
);
$wallet = json_decode($response, true);
if (empty($wallet['address_in'])) { die('Could not create the wallet'); }
// Save $wallet['ipn_token'] with your order.
// 2) Redirect the customer.
// address_in is ALREADY URL-encoded: do not encode it again.
$payUrl = 'https://payment.dopayer.com/pay.php' .
'?address=' . $wallet['address_in'] .
'&amount=' . $amount .
'&email=' . urlencode($email) .
'¤cy=USD';
header('Location: ' . $payUrl);
exit;
List providers
Returns every payment provider, its current status and its minimum order amount. Use it to decide which provider values are safe to offer.
https://api.dopayer.com/control/provider-status| Field | Description |
|---|---|
id | The value to use as provider in Process payment. |
provider_name | A readable provider name. |
status | active, redirected or unstable. Avoid providers that are not active. |
minimum_currency | Currency of the minimum amount. The provider may still accept other currencies. |
minimum_amount | The minimum order amount. |
{
"providers": [
{
"id": "moonpay",
"provider_name": "MoonPay",
"status": "active",
"minimum_currency": "USD",
"minimum_amount": 20
},
{
"id": "interac",
"provider_name": "Interac",
"status": "active",
"minimum_currency": "CAD",
"minimum_amount": 100
}
]
}
Currency limits
| Provider id | Accepted currency |
|---|---|
stripe, transfi, robinhood, bitnovo | USD only |
wert, rampnetwork | USD only. Use Convert to USD for other currencies. |
upi | INR only |
interac | CAD only |
Callback event
When the customer has paid, Dopayer sends a GET request to your callback URL. All of your original query parameters are included, plus the payment details below.
| Parameter | Description |
|---|---|
value_coin | Amount of USDC paid by the provider. |
coin | Payout coin, usually polygon_usdc or polygon_usdt. |
txid_in | Polygon transaction ID of the payment into the order wallet. |
txid_out | Transaction ID of the payout to your wallet. |
address_in | The order wallet. Matches polygon_address_in from step 1. |
value_forwarded_coin | Total forwarded from the order wallet to you and any partners. |
address_out | URL-encoded JSON listing each wallet that was paid and its share of value_forwarded_coin, after all fees. |
https://yourstore.com/callback?order=INV-1001&value_coin=105.6&coin=polygon_usdc&txid_in=0xa22a82...&txid_out=0x94c2c3...&address_in=0x32e854...&value_forwarded_coin=104.016&address_out=%7B%220x34653D...%22%3A%220.0500%22%2C%220x042beb...%22%3A%220.9250%22%7D
Use your own order reference to find the order. To work out what one wallet received, multiply value_forwarded_coin by that wallet's share in address_out.
<?php
// callback.php
$order = $_GET['order'] ?? '';
$txid = $_GET['txid_in'] ?? '';
$paid = $_GET['value_coin'] ?? '';
// 1. Find the order by $order.
// 2. Callbacks can arrive more than once: if $txid was already
// processed, stop here (be idempotent).
// 3. Check that $paid matches what you expected.
// 4. Mark the order as paid.
// Optional: how much each wallet received
$shares = json_decode($_GET['address_out'] ?? '{}', true);
$forwarded = $_GET['value_forwarded_coin'] ?? '0';
foreach ($shares as $address => $share) {
$received = bcmul($forwarded, $share, 18);
}
// Node.js (Express)
app.get('/callback', (req, res) => {
const { order, txid_in, value_coin } = req.query;
// 1. Find the order by `order`.
// 2. Callbacks can arrive more than once: if txid_in was already
// processed, stop here (be idempotent).
// 3. Check that value_coin matches what you expected.
// 4. Mark the order as paid.
// Optional: how much each wallet received
const shares = JSON.parse(req.query.address_out || '{}');
for (const [address, share] of Object.entries(shares)) {
const received = Number(req.query.value_forwarded_coin) * Number(share);
}
res.sendStatus(200);
});
Tip: a callback can legitimately arrive more than once. Key your processing on txid_in or your own order reference so an order is never credited twice.
Check payment status
Looks up a payment using the ipn_token you received in step 1.
https://api.dopayer.com/control/payment-status.php| Parameter | Description |
|---|---|
ipn_token required | The token returned when you created the wallet (URL-encoded). |
curl "https://api.dopayer.com/control/payment-status.php?ipn_token=ZEE2cW8zb1N0N2otZEc3eHh3MDNUU1lTMEExYmVv..."
{
"status": "paid",
"value_coin": "117.59",
"txid_out": "0xe85ed56174785b0bb9fcb522655f961675ad236f2aad2f5bb4fa2f074ac09726",
"coin": "polygon_usdc"
}
status is either paid or unpaid.
Do not poll this endpoint to update orders, or you may be rate limited. Use it for occasional checks and rely on the callback event to mark orders as paid.
Convert to USD
Some providers accept only USD. This endpoint converts an amount from another currency.
https://api.dopayer.com/control/convert.php| Parameter | Description |
|---|---|
from required | The currency to convert from, for example EUR. |
value required | The amount to convert. |
curl "https://api.dopayer.com/control/convert.php?from=EUR&value=1258.31"
{
"status": "success",
"value_coin": "1351.76",
"exchange_rate": "1.07427"
}
Crypto payments
Customers can also pay in stablecoins (USDC or USDT). The coins they send are forwarded straight to your wallet in the same coin and network, with no holding period. This works with any EVM wallet, so you can use the same wallet address you already use for card payments.
Supported networks: Polygon, Base, BNB Chain, Arbitrum, Optimism, Avalanche C-Chain and Ethereum.
Option 1: Payment links (no code)
Create a link in the payment link generator. The customer picks the coin and network, sends the payment from their wallet, and the coins arrive in your wallet.
Option 2: API
Each coin has its own set of endpoints. The {ticker} is the network and the coin, for example polygon/usdc, base/usdc, bep20/usdt, arbitrum/usdc, optimism/usdt, avax-c/usdc or erc20/usdc.
1. Create a receiving address
https://api.dopayer.com/crypto/{ticker}/wallet.php?address=YOUR_WALLET&callback=YOUR_ENCODED_CALLBACK_URL| Parameter | Description |
|---|---|
address required | Your wallet to receive the payout. It must work on the network you chose. |
callback required | URL-encoded URL that is called when the payment arrives. It must include at least one value that is unique to the order (an order or invoice number). |
pending optional | Set to 1 to also be notified when a transaction is seen but not yet confirmed. |
confirmations optional | Number of blockchain confirmations required before the callback is sent. Default and minimum: 1. |
{
"address_in": "0xCc99282221bd39dD985978B12407dd12FDB66162",
"callback_url": "https://yoursite.com/paid?order=8271",
"ipn_token": "ZEE2cW8z...%3D"
}
Unlike the card payment API, address_in here is a normal, readable address.
Use a new unique callback for every order. Sending the same callback again returns the same address, and an address is tied to the payout wallet it was created with.
2. Show how much to pay
https://api.dopayer.com/crypto/{ticker}/convert.php?from=usd&value=250{
"status": "success",
"value_coin": "250.0134",
"exchange_rate": "1.0000536"
}
If status is not success, the currency can't be converted for that coin.
3. QR code (optional)
https://api.dopayer.com/crypto/{ticker}/qrcode.php?address=ADDRESS_INReturns qr_code, a base64 PNG you can show with <img src="data:image/png;base64,{qr_code}">.
4. Minimum amounts
https://api.dopayer.com/crypto/aff-info.phpLists every supported network and coin with its minimum amount (minimum). For a single coin use /crypto/{ticker}/aff-info.php.
Never let a customer send less than the minimum. An amount below the minimum can't cover the forwarding fee and stays in the receiving address.
Callback event
When the payment is confirmed, we send a GET request to your callback URL with your original parameters plus:
| Parameter | Description |
|---|---|
value_coin | The amount of crypto paid. |
coin | The coin and network, with an underscore (for example erc20_usdc). |
txid_in | Transaction ID of the customer's payment into the receiving address. |
Idempotent callbacks: if you enabled pending=1, reply to the callback with the plain-text response ok to avoid receiving repeated requests. As with card payments, make your handler idempotent.
Good to know
- The merchant receives 98% of the final payout, the same split as card payments.
- If a customer sends the wrong token or uses the wrong network, the coins are still forwarded to your wallet automatically on EVM networks. They just won't match the order automatically, so you may need to check manually.
- Minimums are slightly higher than sending directly to a wallet, because each payout is split between more than one wallet.
- The merchant wallet must be a wallet that works on the selected network. The same
0xaddress works on all the EVM networks listed above.
Partners (sub-affiliates)
If you bring merchants to Dopayer, you can earn a share of every sale they make. Create the wallet with the partner endpoint instead of the standard one, and set your share with sub_affiliate_fee. Everything else (payment page, callback, status) works exactly as described above.
https://api.dopayer.com/set-affiliate.php| Parameter | Description |
|---|---|
address required | The merchant's payout wallet. |
callback required | URL-encoded callback URL with a value that is unique per order. |
merchant_fee required | The merchant's share, for example 0.97 for 97%. |
sub_affiliate required | The partner's own wallet, which receives the partner share. |
sub_affiliate_fee required | The partner's share, for example 0.01 for 1%. |
The shares must add up exactly. merchant_fee plus sub_affiliate_fee must equal 0.98. The rest is taken by Dopayer and its infrastructure, and the request fails if the total is different. Write fees with two decimals (for example 0.97, not 0.970001).
Use three different wallets. The merchant wallet and the partner wallet must be different from each other, otherwise the request fails.
https://api.dopayer.com/set-affiliate.php?address=0xMERCHANT_WALLET&callback=https%3A%2F%2Fpartner-site.com%2Forder%3Fnumber%3D5001&merchant_fee=0.97&sub_affiliate_fee=0.01&sub_affiliate=0xPARTNER_WALLET
{
"address_in": "wBWnsV63iw08CXjZ%2BYQwKYMRz5K4mpBRZwHuGe5PUKmpVyBLgI5PXJqvs4X11%2F6zRrqtAnyI3kYvE1J0SSUaYA%3D%3D",
"polygon_address_in": "0x1a65e22d1A8e3001574446D6d92632D5E075073a",
"callback_url": "https://partner-site.com/order?number=5001",
"ipn_token": "ZEE2cW8zb1N0N2otZEc3eHh3MDNUU1lTMEExYmVv..."
}
Example split of a 100 USDC payout
| Who | Parameter | Share | Receives |
|---|---|---|---|
| Merchant | merchant_fee=0.97 | 97% | 97.00 USDC |
| Partner | sub_affiliate_fee=0.01 | 1% | 1.00 USDC |
| Dopayer & infrastructure | fixed | 2% | 2.00 USDC |
Fees are set per order, so a partner can offer different rates to different merchants, as long as the two shares always total 0.98.
Notes & limits
- Create a new wallet for every order, and always include a unique value in the
callback. - Pass
address_into the payment page exactly as returned. It is already URL-encoded (this does not apply to crypto addresses, which are plain). - The customer must be redirected to the payment page. It cannot be shown inside an iframe.
- Use a self-custodial wallet to receive payouts. Exchange deposit addresses are not recommended and can cause payout problems.
- The merchant wallet and any partner wallet must be different addresses.
- Each provider has its own minimum order amount and some accept only certain currencies. Check List providers for cards, or Crypto payments for stablecoin minimums.
- Any failed request returns HTTP
400. - Your callback URL must be reachable from the internet so Dopayer can notify you.