Skip to main content

One-time links

One-time links create a direct Checkout session for a fixed charge. Use them when you already know the final amount and want to send a payment URL to the buyer.

For donations, tips, or charges where the buyer chooses the amount, use Customer chooses what to pay.

Create a fixed amount session

The endpoint receives lineItems. Each item can use an existing priceId or create an inline product with unitAmount, currency, and description. Amounts are sent in the currency's minor unit.

curl https://api.onvopay.com/v1/checkout/sessions/one-time-link \
-X POST \
-H "Authorization: Bearer $ONVO_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"lineItems": [
{
"quantity": 1,
"unitAmount": 250000,
"currency": "CRC",
"description": "Order #1001"
}
],
"customerEmail": "buyer@example.com",
"redirectUrl": "https://example.com/success",
"cancelUrl": "https://example.com/cancel",
"discounts": [
{
"coupon": "cpn_abc123"
}
],
"metadata": {
"orderId": "1001"
}
}'

The response includes url. Redirect the buyer to that URL or send it through the channel your sales flow uses.

You can create coupons from the dashboard or from the API:

  • In the dashboard, go to Discounts and create the coupon with the visual form. This works well for campaigns operated by commercial or support teams.
  • In the API, create the coupon with POST /v1/coupons. This works well for campaigns generated by your backend, internal integrations, or bulk operations.

Both paths create the same Coupon object. To use it in a one-time link, keep the coupon id and send it in discounts when you create the Checkout session.

  1. Create the coupon in the dashboard or with the API.
  2. Configure its rules: discount type, redemption limit, expiration date, and eligible BINs.
  3. Create the one-time link with discounts: [{ "coupon": "cpn_..." }].
  4. Checkout applies the discount during payment when the buyer's card matches an active BIN rule.

Create a coupon with the API

This example creates a 10% coupon for cards whose BIN starts with 411111.

curl https://api.onvopay.com/v1/coupons \
-X POST \
-H "Authorization: Bearer $ONVO_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Sponsor Bank 10%",
"type": "percentage",
"percentOff": 10,
"scope": "checkout_session",
"appliesTo": ["one_time_links"],
"maxRedemptions": 100,
"redeemBy": "2026-06-30",
"binRules": [
{
"bin": "411111"
}
]
}'

The response includes the coupon id. Use that value in the link payload:

{
"discounts": [
{
"coupon": "cpn_abc123"
}
]
}

Main attributes

AttributeWhat it does
nameInternal name used to identify the coupon in the dashboard, reports, and Checkout responses.
typeDefines whether the discount is percentage or fixed_amount.
percentOffPercentage discount when type is percentage. It must be greater than 0 and at most 100.
amountOffFixed discount amount when type is fixed_amount. Send it in the currency's minor unit.
currencyRequired currency for fixed_amount coupons. It must match the link currency.
scopeCoupon scope. For one-time links, use checkout_session. If omitted, ONVO uses that default.
appliesToSurfaces where the coupon can be used. For these links, include one_time_links. If omitted, ONVO uses that default.
binRulesCard BINs that make the discount eligible.
maxRedemptionsTotal number of successful payments that can consume the coupon. Omit it for no limit.
redeemByLast date the coupon can be used. Send a full ISO date or YYYY-MM-DD; date-only values are normalized to Costa Rica midnight.
isActiveEnables or disables the coupon without deleting it. Defaults to true.
promotionCodesPromotion codes associated with the coupon. In one-time links, these are used by your backend, not as a visible field where the buyer enters a code.

Discount types

Use percentage when you want to discount a percentage of the final amount:

{
"type": "percentage",
"percentOff": 15
}

Use fixed_amount when you want to discount a specific amount:

{
"type": "fixed_amount",
"amountOff": 250000,
"currency": "CRC"
}

Amounts are sent in the currency's minor unit. For example, 250000 in CRC represents CRC 2,500.00.

BIN rules

One-time link discounts are applied by BIN. A BIN is the first digits of a card; ONVO accepts 6 to 8 digit rules. In the dashboard, the BIN field is a simple list: paste or type the eligible BINs and ONVO stores them as rules. In the API, that same list is sent as binRules, where each item has at least bin.

Send digits only, without spaces or hyphens. When the buyer enters or selects a card, Checkout checks whether the BIN matches an active rule on the coupon.

{
"binRules": [
{
"bin": "411111"
},
{
"bin": "41111112"
}
]
}

If multiple eligible coupons match the BIN, ONVO applies the highest discount. If the discount amount ties, it uses the more specific BIN rule, meaning the one with more digits.

Real eligibility depends on bin and whether the rule is active.

Each rule can include isActive. This lets you pause a specific BIN without disabling the whole coupon. If you update a coupon through the API and send binRules, ONVO replaces the previous list with the list you sent, so include every rule you want to keep.

Promotion codes

A coupon can have promotion codes attached:

{
"promotionCodes": [
{
"code": "SUMMER25"
}
]
}

ONVO stores the code in uppercase. In the one-time link creation payload, promotionCode expects the promotion code object id, not the text code:

{
"discounts": [
{
"promotionCode": "promo_abc123"
}
]
}

For new integrations, sending coupon directly is the simplest path. Use promotionCode when you already manage promotion codes as separate objects in your system.

If you update a coupon through the API and send promotionCodes, ONVO also replaces the previous list with the list you sent.

To create a discounted link, add discounts to the session payload. ONVO accepts one discount per session. That discount can point to a direct coupon or to a promotion code:

{
"discounts": [
{
"coupon": "cpn_abc123"
}
]
}

Send coupon or promotionCode, but not both in the same object. The value must be the id of the coupon or promotion code.

The coupon must be active, belong to the same session mode (test or live), have checkout_session scope, and apply to one_time_links. If you use a fixed-amount coupon, the coupon currency must match the link currency.

For one-time links, do not use allowPromotionCodes: Checkout receives the specific discount from discounts and applies it during payment.

Checklist

  • The coupon and session must be in the same mode: test or live.
  • The coupon must be active.
  • For one-time links, use scope: "checkout_session" and appliesTo: ["one_time_links"].
  • For fixed-amount discounts, currency must match the link currency.
  • Add at least one active BIN rule so Checkout can apply the discount to eligible cards.
  • Copy the coupon id from the dashboard or from the POST /v1/coupons response.