---
title: Promotions
description: Issue top-up codes: wallet bonuses, service-only credit and percentage discounts with a cap and a minimum order — create, distribute and track them.
url: https://nexcmp.com/docs/billing/promotions/
applies_to: NexCMP 1.6.1
updated: 2026-11-02
---

# Promotions

> **Where in the admin:** Finance › Billing › Vouchers (`/billing/vouchers`). **Where in the portal:** Billing › Redeem code (also inside the Deposit drawer).

## What it does

A **top-up code** (voucher) is a one-time-use secret you give to customers. Depending on how you create it, it can:

| Type | What the customer gets | Where the value goes |
|---|---|---|
| **Bonus credit** for all services | Money added to the wallet | Wallet balance. Usable for anything. |
| **Bonus credit** for chosen services | A service credit | A separate pocket that can only pay for those services. |
| **Discount %** | A percentage off the first order of chosen services | Nothing is credited; the discount is applied at checkout. |

Use them for campaigns, apology credits, partner deals or a first-order discount.

## Requirements

| Item | Requirement |
|---|---|
| Role | An administrator. |
| Customers | Customers redeem codes while signed in to the portal (not as a guest). By default the customer must have a verified e-mail. |
| VND codes | A code created in VND converts to USD at redemption using the stored exchange rate (see [Currency and exchange rates](https://nexcmp.com/docs/catalog/currency-and-exchange-rates/)). |

## Create a batch

1. Open **Finance › Billing › Vouchers** and click **Create vouchers**.
2. Fill in the form. Example values are in brackets.

   | Field | Notes |
   |---|---|
   | Batch name | 1–80 characters (`Spring welcome`). |
   | Target | **Main site clients**, **Single reseller's customers** (needs a list of customers) or **Reseller wallet**. |
   | Eligible users | **All in target audience** or **Specified** — one e-mail or customer ID per line, up to 1,000. For a reseller's customers it must be *Specified*. |
   | 1 code per target | With *Specified*, creates one code per listed customer. |
   | Code type | **Bonus credit** or **Discount %**. |
   | Applies to | Pick one or more services; empty = **All services**. |
   | Currency, Face value | USD from $1.00, or VND from 10,000 in multiples of 1,000 (bonus credit only). |
   | Discount (%) | 1 to 100 (Discount % only). |
   | Maximum discount cap (USD) | Required for Discount %, from $1.00. It is also the most you can lose per redemption. |
   | Minimum order (USD) | `0` = none. The first order must be at least this amount. |
   | Code count | 1 to 1,000 random codes. |
   | Uses per code | 1 to 100,000. `1` means one person per code; raise it for a shared code. |
   | Max uses per account | At least 1. For Discount % it must be `1`. |
   | Start time (optional), Expires | The expiry must be after today and after the start, at most 2 years ahead. |
   | Code prefix (0–6 chars) | Letters only; empty uses the site's prefix. |
   | Custom code (only when count = 1) | 6 to 32 characters A–Z and 0–9. Easy to share but easy to guess: keep the uses low. |
   | Require verified email | On by default. |
   | Internal note, Reason | The reason is mandatory and goes to the audit log. |

3. The form shows **Maximum exposure** (face value x codes x uses) so you know the worst case. Click **Generate codes**.
4. **Copy the codes now.** They are shown only once: NexCMP stores only a hash and the last 4 characters. Use **Copy all** or **Download CSV**, tick the confirmation and close the box.



## How each type behaves

### Wallet bonus (no service selected)

The wallet is credited with an **adjustment** entry (reference `vch:...`). It is not refundable to a card, does not earn affiliate commission, does not create an invoice and counts as wallet balance for quotas. VND codes use the exchange rate at the moment of redemption.

### Service credit (services selected)

- The credit sits in a **separate pocket**, can only pay charges of the chosen services (new orders, renewals, hourly or daily fees, upgrades) and is spent **before** the wallet.
- It cannot be withdrawn, transferred or converted to money, and it expires with the code.
- The ledger shows the full charge plus a matching credit line, so revenue per service stays correct while the wallet only drops by what the customer really paid.
- It does **not** raise a [quota](https://nexcmp.com/docs/billing/quotas/) tier and is ignored by [auto top-up](https://nexcmp.com/docs/billing/auto-top-up/).
- If a charge paid with credit or a discount is refunded, the part that the code paid is taken back from the wallet refund and returned to the credit pocket.

### Discount %

1. The customer enters the code: it becomes **activated**. A percentage code can be used only once per account.
2. The **first charge** of a selected service that is not an hourly fee, and at least the **Minimum order**, is discounted by the percentage, never more than the **Maximum discount cap**.
3. The discount is recalculated by the server at charge time; the amount in the browser is ignored. The redemption row is written when the code is actually used, with the real discount.
4. Hourly usage charges never use the code.

## What the customer does

1. Open **Billing** in the portal and click **Redeem code**, or use **Have a top-up code?** in the Deposit drawer.
2. Type the code (not case-sensitive; dashes optional) and click **Check**. The portal says what it gives, for example *Valid code: +$5.00*, *$5.00 credit for VPN* or *20% off voucher for Virtual Machines (up to $5.00)*, and *Valid for orders from $10.00*.
3. Click **Redeem** and confirm. Each code can be used once per account.

Codes are tied to the site: a code from one site is "not valid" on another, with no hint that it exists elsewhere. Wrong guesses are throttled and, after several, the account is locked out for a few minutes ("N attempts left before a temporary lock").

## Track and stop

- **Batches** lists each batch with its status (*active*, *disabled*, *expired*, *used up*), redeemed count and exposure. Open a batch for the **Codes** (masked) and **Redemptions** tabs, and **Export CSV**.
- **Redemptions** lists every redemption across batches; **Reseller quotas** shows how much of each reseller's monthly issuing limit is used; **Settings** switches reseller codes on or off and sets the default monthly limit.
- **Disable batch** stops all unused codes; redemptions already made stay. A single code can also be disabled.

## Verify

1. Create a batch of 1 code: Discount % 20, cap $5, minimum order $10, service Virtual Machines.
2. As a test customer redeem it. The portal says it is activated.
3. Order a VM that costs at least $10 (monthly cycle): the invoice shows the discount (at most $5).
4. In the batch, the code shows 1 redemption with the real discount.

## Limits & notes

- Codes are tied to the **audience** and the **site** at creation; they cannot be moved later.
- Resellers can issue codes to their own customers within a monthly exposure limit; see [Resellers](https://nexcmp.com/docs/customers/resellers/).
- The sidebar promo slides for customers (**Marketing › Promo slides**) are a separate feature and do not give any discount.
- Because the code in plain text is never stored, a lost batch cannot be recovered: disable it and create a new one.

## Troubleshooting

| Symptom | Cause | Fix |
|---|---|---|
| "Percent codes: one use per account" (`percent_one_per_account`) | Max uses per account above 1 for Discount % | Set it to `1`. |
| Form says the cap is required | Discount % without Maximum discount cap | Enter at least $1.00. |
| Customers not found | An e-mail or ID in the list does not exist | Fix the list (the error names the unknown entries). |
| Customer says "invalid code" | Wrong site, expired, disabled, used up, not the targeted customer, or e-mail not verified | Check the batch and the customer. |
| Credit was not used | The charge belongs to another service | Credit only pays the services chosen on the batch. |
| Discount not applied | Order below the minimum, hourly charge, or the code was activated for another service | Place a qualifying first order. |
| Customer locked out of redeeming | Too many wrong attempts | Wait for the lock to expire. |


