Discounts
PaymentKit offers a flexible discount system using Coupons and Promotion Codes. This allows you to provide various types of discounts to your customers, such as percentage-off, fixed amount-off, and limited-time offers.
- Coupons: Define the core discount rules, such as the discount percentage or amount, duration (e.g., once, forever, repeating), and maximum total redemptions.
- Promotion Codes: These are the customer-facing codes that are linked to a coupon. They can have their own set of rules, such as individual redemption limits, expiration dates, and restrictions (e.g., for first-time customers only).
You can think of a Coupon as a template for a discount, and Promotion Codes as specific instances of that discount that customers can use.
For a detailed breakdown of all available API operations, see the Coupons API Reference and Promotion Codes API Reference.
How Discounts Work#
The following diagram illustrates the relationship between Coupons, Promotion Codes, and their application during a transaction.
Creating Coupons#
A Coupon object contains information about a discount, such as whether it's a percentage or a fixed amount. You can create coupons and then attach promotion codes to them.
Create a Coupon with Promotion Codes#
You can create a coupon and one or more associated promotion codes in a single API call. This is useful for setting up a new campaign quickly.
Create Coupon with Promo Code
import payment from '@blocklet/payment-js';
async function createDiscountCampaign() {
try {
const result = await payment.coupons.create({
name: 'New User Discount',
percent_off: 20,
duration: 'once',
max_redemptions: 1000, // Max redemptions for the coupon itself
promotion_codes: [
{
code: 'WELCOME20',
description: 'Welcome discount for new users',
max_redemptions: 100, // Max redemptions for this specific code
expires_at: Math.floor(Date.now() / 1000) + (30 * 24 * 60 * 60) // 30 days from now
}
]
});
console.log('Coupon created:', result.coupon);
console.log('Promotion codes created:', result.promotion_codes);
} catch (error) {
console.error('Error creating coupon:', error.message);
}
}See all 2 lines
Parameters
Required if amount_off is set. The ID of the currency for the fixed amount discount.
Describes how long the discount will be applied. Can be once, forever, or repeating.
If duration is repeating, the number of months the coupon applies.
Creating Promotion Codes#
While you can create promotion codes along with a coupon, you can also create them separately and attach them to an existing coupon. This is useful for generating multiple unique codes for a single campaign.
Create a Standalone Promotion Code#
Create Promotion Code
import payment from '@blocklet/payment-js';
async function createPromoCode(couponId) {
try {
const promotionCode = await payment.promotionCodes.create({
coupon_id: couponId, // ID of an existing coupon
code: 'SAVE15NOW',
description: 'Save 15% on your next purchase',
max_redemptions: 500,
restrictions: {
first_time_transaction: true, // Only for new customers
}
});
console.log('Promotion code created:', promotionCode);
} catch (error) {
console.error('Error creating promotion code:', error.message);
}
}
createPromoCode('coupon_xxx'); // Replace with your actual coupon IDParameters
Applying Discounts at Checkout#
To allow customers to enter a promotion code on the checkout page, you must explicitly enable this option when creating a Checkout Session or a Payment Link.
Enable on a Checkout Session#
Set the allow_promotion_codes parameter to true when creating a Checkout Session. This will add a field to the payment page for customers to enter their code.
Enable Promotion Codes
import payment from '@blocklet/payment-js';
async function createCheckoutWithDiscounts() {
try {
const session = await payment.checkout.sessions.create({
success_url: 'https://example.com/success',
cancel_url: 'https://example.com/cancel',
mode: 'payment',
line_items: [
{ price_id: 'price_xxx', quantity: 1 }
],
allow_promotion_codes: true // This enables the promo code field
});
console.log('Checkout session created with promotion codes enabled:', session.url);
} catch (error) {
console.error('Error creating checkout session:', error.message);
}
}
createCheckoutWithDiscounts();Enable on a Payment Link#
The same logic applies to reusable Payment Links. Setting allow_promotion_codes to true ensures that anyone using the link can apply a valid promotion code.
Enable on Payment Link
import payment from '@blocklet/payment-js';
async function createPaymentLinkWithDiscounts() {
try {
const paymentLink = await payment.paymentLinks.create({
line_items: [{
price_id: 'price_xxx',
quantity: 1,
}],
allow_promotion_codes: true,
});
console.log('Payment link created with promotion codes enabled:', paymentLink.url);
} catch (error) {
console.error('Error creating payment link:', error.message);
}
}
createPaymentLinkWithDiscounts();Managing Discounts#
The SDK provides various methods to manage and track your discounts.
Retrieve a Promotion Code by its Code#
You can fetch a promotion code's details directly using the customer-facing code string.
Get Promotion Code by Code
import payment from '@blocklet/payment-js';
async function getPromoDetails(code) {
try {
const promoByCode = await payment.promotionCodes.byCode(code);
console.log('Found promotion code:', promoByCode);
// You can now access the associated coupon details
console.log('Discount:', promoByCode.coupon);
} catch (error) {
console.error(`Promotion code '${code}' not found or an error occurred:`, error.message);
}
}
getPromoDetails('WELCOME20');Check Coupon Usage#
Determine if a coupon has been redeemed at least once. This is useful for deciding whether a coupon's rules can still be edited.
Check Coupon Usage
import payment from '@blocklet/payment-js';
async function checkCouponUsage(couponId) {
try {
const { used } = await payment.coupons.used(couponId);
if (used) {
console.log(`Coupon ${couponId} has been used and its rules are now locked.`);
} else {
console.log(`Coupon ${couponId} has not been used yet.`);
}
} catch (error) {
console.error('Error checking coupon usage:', error.message);
}
}
checkCouponUsage('coupon_xxx'); // Replace with a valid coupon IDList Redemptions#
You can retrieve a paginated list of customers or subscriptions that have redeemed a specific coupon or promotion code.
List Coupon Redemptions
import payment from '@blocklet/payment-js';
async function getCouponRedemptions(couponId) {
try {
const redemptions = await payment.coupons.redemptions(couponId, {
type: 'customer', // or 'subscription'
page: 1,
pageSize: 10
});
console.log(`Found ${redemptions.count} customer redemptions for coupon ${couponId}:`);
redemptions.customers.forEach(customer => {
console.log(`- Customer ID: ${customer.id}`);
});
} catch (error) {
console.error('Error getting redemptions:', error.message);
}
}
getCouponRedemptions('coupon_xxx'); // Replace with a valid coupon ID