Skip to content
2E0JWR
PBNPorkbun for WHMCS

Markup rules

The per-TLD markup rule syntax in full: selectors, percentages, fixed uplifts, minimum margins, flat prices, rounding and skip — with worked examples and how a rule is chosen.

The Per-TLD markup rules field lets you override the global markup for individual extensions, or for individual operations on an extension.

One rule per line.

The shape of a rule

<selector>  <what to do>
.com            40%
.co.uk          60% +0.50
.io:renew       20% min 8.00
.dev            flat 14.99
.xyz:transfer   skip
*:transfer      15% round .95

Selectors

SelectorMatches
.comevery operation on .com
comthe same — the leading dot is optional
.co.ukevery operation on .co.uk
.io:renewrenewals of .io only
*every TLD
*:transfertransfers of every TLD

Operations are register, renew and transfer. Anything else is rejected when you save.

Instructions

TokenMeaningExample
30%Percentage added to cost.com 30%
+1.50Flat amount added after the percentage.com 30% +1.50
min 5.00Minimum margin — lift the price if the margin is under this.io 20% min 5.00
flat 14.99Fixed retail price; cost is ignored entirely.dev flat 14.99
round .99Override the global rounding for this rule.com 30% round .99
skipLeave this price alone in WHMCS.xyz:transfer skip

Rounding values are none, up, .95 and .99.

# starts a comment; anything after it on a line is ignored. Blank lines are fine.

# House rules, reviewed April
.com          30%          # volume seller, thin margin is fine
.io           45% min 12   # expensive to support

How a rule is chosen

For each TLD and operation, the first match wins:

  1. .tld:operation — e.g. .io:renew
  2. .tld — e.g. .io
  3. *:operation — e.g. *:renew
  4. *
  5. the global settings on the config page

The winning rule replaces the calculation entirely. It is not merged with the global settings. If .com 40% is your rule, .com gets 40% and nothing else — not 40% plus your global fixed uplift, and not your global minimum margin.

Rounding is the single exception. A rule that says nothing about rounding inherits the global rounding, because rounding is a house style rather than part of the margin. Add round to a rule to override it.

How the price is worked out

Given a cost and a rule:

price = cost × (1 + percent/100)
price = price + fixed
if price < cost + minimum margin:
    price = cost + minimum margin
round upwards

A flat rule short-circuits all of that and uses the stated price, rounded.

A skip rule produces no price at all, and whatever WHMCS already holds for that operation is left untouched.

Worked examples

Cost $11.08, rule 30% +1.00 round .99:

11.08 × 1.30 = 14.40
14.40 + 1.00 = 15.40
round up to next .99 = 15.99

Cost $2.04, rule 25% min 5.00 round .99:

2.04 × 1.25 = 2.55
margin is 0.51, under the 5.00 floor
2.04 + 5.00 = 7.04
round up to next .99 = 7.99

Validation

Rules are parsed when you save the configuration page. A line that cannot be understood blocks the save and names the line number and the problem:

Markup rules, line 3: "sell" is not an operation. Use register, renew or transfer.
Markup rules, line 5: "min" needs a value after it.
Markup rules, line 7: ".com" is already set on an earlier line.

The same rules are parsed again by php pricing.php, so a preview run confirms them a second time before anything is written.