
The first payment of a VPN customer is the easy part. The hard part is the second, third and tenth: the customer pays again before or after the subscription runs out, and you need the new days added correctly, the existing config kept working and no user created twice. Here is how the SnapEX Pay modules handle a renewal.
How a returning customer is recognised
A renewal is a payment for a user who already exists in the panel.
- Marzban, 3x-ui, Remnawave services: your shop or bot sends the same username again with the new checkout. An existing username is extended; a new one is created.
- Telegram VPN bot: the panel username is
tg<telegram_id>, so each Telegram account maps to exactly one VPN user, and a repeat payment from the same Telegram account extends it.
Which date the new days count from
Paying early must not burn the days the customer already has, and paying late must not give away the days in between.
- Marzban: the subscription is extended from the current expiry, or from now if it has already expired.
- 3x-ui: the expiry is pushed forward, or counted from now if it already ran out.
- Remnawave: the plan's days are added to whichever is later: now or the user's current expiry.
- Telegram VPN bot: a returning customer is extended from the current expiry.
Traffic quota on renewal
- Marzban: traffic plans add a fresh quota on top of the usage.
- 3x-ui: traffic is reset for plans with a quota, and the client is re-enabled.
- Remnawave: the traffic limit is set to the new plan's value.
- Telegram VPN bot: a plan with a traffic limit starts a fresh quota.
The customer's config keeps working
In 3x-ui the renewed client keeps its UUID and subId, so the config already imported on the customer's devices keeps working — nothing to re-send. In Marzban, Remnawave and the bot the existing user is extended rather than replaced, and the module returns the subscription link after payment.
No duplicates when a webhook arrives twice
Webhooks can be delivered more than once, sometimes at the same moment. All four modules are idempotent: each invoice provisions the user only once, even for repeated or concurrent deliveries. Before doing anything, the module checks the HMAC-SHA256 signature (5-minute window) and re-reads the invoice from the SnapEX Pay API; only a paid invoice provisions the user. The bot also checks that the invoice belongs to the bot's own order.
If the panel is down when the payment arrives
With the Marzban service the webhook handler returns 502 when the panel cannot be reached, and SnapEX Pay retries the delivery later, so the renewal is applied once the panel is back. Webhook deliveries are retried in general: SnapEX Pay makes up to 5 attempts.
Changing prices without touching paid orders
The Telegram VPN bot keeps a copy of the plan in each order, so editing PLANS later does not change orders that are already paid.
Try a renewal without real money
Every module has a test mode: test invoices confirm by themselves and move no real funds. Create a user with one test payment, pay again for the same username or Telegram account, and check the new expiry in the panel. See How to test crypto payments without real money.
Modules: Marzban, 3x-ui, Remnawave, Telegram VPN bot. Overview for VPN services: Crypto payments for VPN services. Sign-up: pay.snapex.pro.