---
title: Pricing Your Products
description: The price we return is your cost. You set the retail price your customers pay.
---


Every product in the API carries a `price` block. This page explains exactly what that
number is, why it can look different from a figure in the product name, and how to turn
it into the price you charge your own customers.

The one idea to hold onto: **our number is your cost, your price is yours to set.**

## The `price` block

When you list products, each one returns a `price` object. Its shape depends on whether
the product has a set price or a variable amount.

### Fixed-price products (data plans and cable TV)

These have a set catalog price, so you receive an exact `amount`. Some fixed-price
products also include an optional `reference_price`:

```json
{
  "id": "prd_2270",
  "type": "data_plan",
  "attributes": {
    "display_name": "MTN 3.2GB / 30 Days",
    "network": "MTN",
    "price": {
      "amount": "976.00",
      "reference_price": "1000.00",
      "currency": "NGN",
      "basis": "fixed"
    }
  }
}
```

Here `price.amount` (976.00) is what RizPay bills you each time you buy this plan. It is
your **cost**, and it is your floor: never sell below it.

`price.reference_price`, when present, is a best-effort figure we could confidently read
off the product's public listing (for example the "N1,000" in a plan named "MTN N1,000
3.2GB", or the "N4,400" in a cable TV package named "DStv Padi N4,400"). This is just to
help you make a pricing decision - it is not the amount you must charge, and you have
full control over your own retail price. Many products have no reliable figure to read,
so `reference_price` is simply left out of the response for those. Never treat its
absence as an error, and never treat its presence as a rule.

### Variable-price products (airtime and electricity)

These do not have one fixed price, because the buyer chooses the amount. Instead of
`amount` you receive a range:

```json
{
  "id": "prd_120",
  "type": "airtime",
  "attributes": {
    "display_name": "MTN Airtime",
    "network": "MTN",
    "price": {
      "basis": "face_value",
      "min_amount": "50.00",
      "max_amount": "50000.00",
      "currency": "NGN"
    }
  }
}
```

For these, the amount you buy is the amount your customer requested, within
`min_amount` and `max_amount`. Any markup here is a service fee you add on top of that
amount in your own checkout. There is no `reference_price` for these products, since the
buyer picks the amount rather than RizPay setting one.

## What RizPay does and does not decide

RizPay tells you your cost, and where we can confidently work it out, an optional
reference figure. RizPay does not set, store, or return the price you charge your end
users. That price lives entirely in your system.

| Number               | What it is                                   | Who sets it |
| -------------------- | -------------------------------------------- | ----------- |
| Cost                 | `price.amount`, what RizPay bills you        | RizPay      |
| Reference (optional) | `price.reference_price`, a best-effort guide | RizPay      |
| Your markup          | What you add to make a profit                | You         |
| Your retail price    | What your customer pays you                  | You         |

So your retail price is simply:

```
your retail price = price.amount + your markup
```

You never have to display or pass through `price.amount` to your customers. It is only
what RizPay will bill you. What your customer sees in your app or store is your choice.

## Why the product name is not the price

A product's `display_name` is a human-readable label. Some names include a figure, such
as "N1,000". Many do not. That figure, when it appears, is a marketing label for the
bundle. It is not the price you pay.

Two rules follow:

- **Do not parse the name yourself.** The label is inconsistent: it may hold a figure, a
  different figure, or none at all. When we can confidently read a figure out of the
  name, we already do that for you and return it as `price.reference_price`.
- **Always price from `price.amount`.** That is the only authoritative cost figure, and
  it is the amount RizPay actually bills you.

This is the most common question we get: a plan labelled "MTN N1,000 3.2GB" returns a
`price.amount` of 976. That is not an error. 976 is your cost. What your customer pays
is up to you.

## Setting your own price

You set your price in your own system with simple arithmetic on `price.amount`. There is
nothing to configure inside RizPay for this. Pick whichever style fits your business.

### Flat markup

Add a fixed naira amount to every sale.

```
cost (price.amount)   976.00
flat markup          + 30.00
your retail price    1006.00
```

Flat markups are predictable and easy to explain. They work well when your costs are
similar across products.

### Percentage markup

Add a percentage of the cost.

```
cost (price.amount)     976.00
10% of 976.00         +  97.60
your retail price      1073.60
```

Percentage markups scale automatically: a pricier product earns you more, a cheaper one
earns less. They work well across a catalog with very different costs.

### Optional guardrails

When you use a percentage markup, you may want to bound the result in your own code:

- A **minimum markup** so a cheap product still earns you at least a set amount, for
  example "10%, but never less than ₦20".
- A **maximum markup** so an expensive product does not carry an eye-watering fee, for
  example "10%, but never more than ₦500".

These are choices you implement in your checkout. RizPay does not impose them.

## Best practice

1. **Never price below your cost.** `price.amount` is your floor. Selling under it loses
   you money on every sale.
2. **Stay competitive.** Check what other sellers charge for the same bundle and set your
   markup so your retail price is attractive. `price.reference_price`, when present, can
   be one input into that decision, but it is not a market rate guarantee.
3. **Price by category, not plan by plan.** Apply one rule across a group in your own
   system, for example a flat fee on all airtime or a percentage on all data plans,
   rather than hand-setting every product. This keeps pricing consistent as the catalog
   changes.
4. **Round to friendly numbers.** Customers prefer 1,100 to 1,073.60. Round your final
   retail price up to a clean figure, never down past your cost.

## Next Steps

- [Data Plans](/developers/docs/products/data-plans) - Fixed-price product example
- [Airtime](/developers/docs/products/airtime) - Variable-amount product example
- [Duplicate Prevention](/developers/docs/core-concepts/duplicate-prevention) - Keep purchases idempotent
