Automating SaaS activation after a USDT payment removes manual review and reduces user friction. bestuPay provides a non-custodial gateway where merchant payments settle directly to your configured wallet. This article explains how to create a payment order, redirect the customer to the hosted checkout, and trigger account activation only after blockchain confirmation and signature verification. We focus on backend implementation details and operational checks that keep the flow secure and auditable.
Why use blockchain confirmation to gate activation
Activating a SaaS account only after the payment is verified on-chain prevents chargebacks and subscription abuse. Because USDT transactions on TRC20 or BEP20 settle quickly on their respective networks, you can confirm the exact generated amount matches your order record before granting access. This level of verification is especially important for services that have immediate fulfillment, digital goods, or limited trial abuse budgets.
Manual checks do not scale when customers expect instant onboarding. Automation works best when your backend trusts only verified events, not user-side confirmation screens. bestuPay sends signed webhooks from the server, allowing you to update account status without polling every transaction or exposing sensitive logic to the browser.
- On-chain verification gives you a permanent, public record of the settlement.
- Exact amount matching prevents underpayment or overpayment errors.
- Server-side activation avoids reliance on client-side callbacks or redirects.
Create a payment order with a unique amount suffix
Server-side order creation is the foundation of the automation flow. Your backend should generate a payment order with the configured product price and a unique decimal suffix, such as adding 0.000001 USDT. This suffix ties the on-chain transfer to a specific database record without requiring a memo field on TRC20 or BEP20.
The bestuPay API accepts the exact amount and returns a hosted checkout URL. Store the expected amount, order ID, and customer reference in your database. Redirect the customer to that URL and do not rely on the browser returning a success state; the authoritative source is the webhook.
- Store the exact amount with the decimal suffix in your orders table.
- Use a server-generated order ID; never accept amounts from the client.
- Keep the hosted checkout URL short-lived or tied to the order lifecycle.
Verify the webhook signature and payload
Every webhook from the gateway includes an HMAC-SHA256 signature over the raw JSON body. Your endpoint must compute the signature using the Webhook Secret configured for your site and compare it in constant time. Reject any request that does not match, and log the mismatch for later analysis.
Use a library that compares byte arrays with a constant-time function to avoid timing attacks. Validate the JSON structure and required fields such as order_id, amount, transaction hash, and confirmations before proceeding. This step ensures that a forged or malformed payload cannot trigger any activation.
- Compute HMAC-SHA256 over the raw body, not the parsed JSON.
- Use a constant-time comparison for signature validation.
- Log rejected signatures with timestamp and source IP for review.
Match the payment to the stored order
After signature validation, query your database for the order using the returned order ID or the unique amount suffix. Confirm that the paid amount exactly equals the stored expected amount, including all decimal places. Because USDT transfers are irreversible, a correct one-time match is critical to prevent duplicate activations.
Also check the transaction hash against your records if you support retries or multiple payment attempts. Once the webhook indicates sufficient confirmations, mark the order as paid. Do not activate the account before all checks pass; otherwise you may grant access for an unconfirmed or incorrectly matched payment.
- Compare the decimal suffix from the webhook with the stored order.
- Require a minimum number of confirmations for high-value plans.
- Use an idempotency key or order status to prevent duplicate processing.
Trigger activation and send confirmation
Once the payment is verified and matched, update the user's account status to active or grant the specific plan feature. In your backend, perform this update in the same transaction or with proper rollback to avoid partial states. Send a confirmation email or in-app notification only after activation succeeds.
Keep an audit log that links the transaction hash, order ID, timestamp, and activation event. This log helps resolve disputes or debugging issues later. Because the dashboard records payment status and webhook history, you can cross-reference your internal log with the gateway's record for consistency.
- Update the user record and send the confirmation in one logical step.
- Log the transaction hash and activation timestamp for traceability.
- Handle webhook retries gracefully using the order status as a guard.
Monitor webhook history and handle failures
The dashboard provides payment status, confirmations, transaction hashes, and webhook history. Use it to debug failed activations or retries. If a webhook is not delivered, your endpoint should return a non-2xx status so the gateway can retry according to its delivery policy. This operational visibility is essential for support teams.
Consider implementing a reconciliation job that queries the dashboard or your own transaction records every few minutes to catch missed webhooks. While not required, it adds resilience for high-value activations. Ensure your webhook endpoint is idempotent because retries may deliver the same event more than once.
- Return 2xx only after processing the event successfully.
- Implement idempotent handling with order status checks.
- Schedule periodic reconciliation for missed or delayed webhooks.