Choose how the buyer pays
| Option | Best for | Effort |
|---|---|---|
Hosted payment page — redirect to checkout_url | Any site, fastest launch. Shows amount, network, address, QR and live status | One API call |
Your own checkout — show crypto.address and crypto.amount_coin | Custom UX, the buyer never leaves your domain | API call + your UI |
| CMS — WooCommerce, Shopify | Stores on a platform | See the sections below |
Step 1 — create an order on your server
Never create orders from the browser with a secret key. Call the API from your backend with the cart total and the coin the buyer chose:
curl -X POST https://api.utopay.app/v1/crypto/payments \
-H "Authorization: Bearer utopay_sk_live_..." \
-H "content-type: application/json" \
-d '{ "coin": "bep20/usdt", "amount": 49.90, "currency": "EUR",
"description": "Order #1042",
"success_url": "https://shop.example/thanks",
"cancel_url": "https://shop.example/cart" }'
With an account the payout wallet comes from your project settings. Without an account use POST /v1/crypto/pay and pass payout_address. The list of coins and networks — with minimum amounts — is at GET /v1/crypto/coins.
Step 2 — send the buyer to pay
- Redirect to
checkout_url: the page shows the exact amount, network, QR code and a live status, then returns the buyer to yoursuccess_url. - Or render
crypto.addressandcrypto.amount_coinyourself and pollGET /v1/payments/:idwhile the buyer is on the page.
Step 3 — confirm the payment by webhook
Do not trust the redirect alone. Mark the order paid when your endpoint receives a signed payment.succeeded event; handle payment.underpaid if less arrived than requested. Verify the x-utopay-signature header with your whsec_… secret — examples for Node.js, PHP and Python are in the webhook docs.
<?php // PHP: verify a UTOPAY webhook
$raw = file_get_contents("php://input");
parse_str(str_replace(",", "&", $_SERVER["HTTP_X_UTOPAY_SIGNATURE"]), $sig);
$expected = hash_hmac("sha256", $sig["t"] . "." . $raw, getenv("UTOPAY_WHSEC"));
if (!hash_equals($expected, $sig["v1"] ?? "") || abs(time() - (int)$sig["t"]) > 300) {
http_response_code(400); exit;
}
$event = json_decode($raw, true);
if ($event["event"] === "payment.succeeded") { /* mark $event["data"]["id"] as paid */ }
http_response_code(200);
WordPress and WooCommerce
There is a ready UTOPAY plugin for WooCommerce — see plugins. Without the plugin, a WooCommerce store integrates through the API: create the order in the woocommerce_checkout_order_processed hook, redirect to checkout_url, and complete the order from the webhook handler.
Shopify
Shopify only lets approved payment apps appear as a checkout gateway. The practical setup is a manual payment method (for example “Pay with crypto”) plus a UTOPAY payment page: when the order is placed, your app or automation creates a UTOPAY order for the total and emails the buyer the checkout_url. The webhook then marks the Shopify order as paid.
Go-live checklist
- Test the full flow with test keys (
utopay_sk_test_…) — test orders never touch the blockchain. - Check the payout wallet supports every network you offer.
- Show the network name next to the amount — wrong-network transfers are the most common support issue.
- Store the UTOPAY order
idwith your order and de-duplicate webhooks by it. - Decide your policy for
underpaidorders before launch.
Updated · UTOPAY team