Offer discounts to your customers

Offering coupons and discounts for your customers’ subscriptions is a great way to acquire new users by lowering the friction.


What are coupons and discounts

A Coupon can be seen as a template for a Discount to be applied on a subscription: the coupon can be a percentage of the subscription’s price, or a fixed amount. A customer can also have multiple coupons applied on one of its subscriptions.

A coupon is also composed of several additional attributes that can be used to further control how your coupons are used:

  • iteration_count is the number of iteration of the subscription the coupon will last. For example, a coupon with an iteration_count of 3 applied on a monthly subscription will last 3 months. If this attribute is set to 0, the applied discount will last forever.
  • max_redemptions is the maximum number of times a coupon can be redeemed (ie applied on a subscription) by your customers before expiring.
  • expires_at is the date at which the coupon will automatically expire.

It is also important to note that coupons cannot be redeemed more than once per subscription, and the amount deduced by the sum of all the discounts applied to a subscription cannot be greater than the amount of the subscription.

Create a coupon

The easiest way to apply discounts on your customers’ subscriptions it to create coupon codes that can be redeemed by your customers (or yourself in your Dashboard).

For reference, let’s create one through the API:

curl -X POST https://api.processout.com/coupons \
    -u test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x:key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8 \
    -d id="25percentoff" \
    -d percent_off=25 \
    -d iteration_count=3 \
    -d expires_at="2022-10-02T15:00:00Z"
var ProcessOut = require("processout");
var client = new ProcessOut(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
    "key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8");

client.newCoupon().create({
    id:              "25percentoff",
    percent_off:     25,
    iteration_count: 3,
    expires_at:      "2022-10-02T15:00:00Z"
}).then(function(coupon) {
    // 

}, function(err) {
    // The coupon could not be created. Maybe a coupon with this
    // ID already exists?
});
import processout
client = processout.ProcessOut(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x", 
    "key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8")

coupon = client.new_coupon().create({
    "id":              "25percentoff",
    "percent_off":     25,
    "iteration_count": 3,
    "expires_at":      "2022-10-02T15:00:00Z"
})
require "processout"
client = ProcessOut::Client.new(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x", 
    "key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8")

coupon = client.coupon.create(
    id:              "25percentoff",
    percent_off:     25,
    iteration_count: 3,
    expires_at:      "2022-10-02T15:00:00Z"
)
<?php
$client = new \ProcessOut\ProcessOut(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x", 
    "key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8");

$coupon = $client->newCoupon()->create(array(
    "id":              "25percentoff",
    "percent_off":     25,
    "iteration_count": 3,
    "expires_at":      "2022-10-02T15:00:00Z"
));
import "gopkg.in/processout.v4"
client := processout.New(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x", 
    "key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8")

coupon, err := client.NewCoupon().Create(&processout.CouponCreateParameters{
    Coupon: &processout.Coupon{
        ID:             processout.String("25percentoff"),
        PercentOff:     processout.Int64(25),
        IterationCount: processout.Int64(3),
        ExpiresAt:      processout.Time(time.Now()),
    },
})
if err != nil {
    panic(err)
}

Apply a coupon to a subscription

Now that we’ve created a coupon, let’s create and apply a subscription for a customer of ours (you’ll need to replace the ID of the customer with one of yours):

curl -X POST https://api.processout.com/subscriptions \
    -u test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x:key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8 \
    -d customer_id=cust_uYW5WVnjHe91qnsUA1sHOxEjdAySvg0P \
    -d plan_id="silver-plan" \
    -d coupon_id="25percentoff"

# or 
curl -X POST https://api.processout.com/subscriptions/sub_7kAxfNML6jIc3bltGIt0uK2nKHDyzzq3/discounts \
    -u test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x:key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8 \
    -d coupon_id=25percentoff
var ProcessOut = require("processout");
var client = new ProcessOut(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
    "key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8");

client.newSubscription().create({
    customer_id: "cust_uYW5WVnjHe91qnsUA1sHOxEjdAySvg0P",
    plan_id:     "silver-plan",
    coupon_id:   "25percentoff"
}).then(function(subscription) {
    // The discount is now applied to the subscription!

}, function(err) {
    // An error occured

});

client.newDiscount().create({
    subscription_id: "sub_7kAxfNML6jIc3bltGIt0uK2nKHDyzzq3",
    coupon_id:       "25percentoff"
});

// or
subscription.applyCoupon("25percentoff");
import processout
client = processout.ProcessOut(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x", 
    "key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8")

subscription = client.new_subscription().create({
    "customer_id": "cust_uYW5WVnjHe91qnsUA1sHOxEjdAySvg0P",
    "plan_id":     "silver-plan",
    "coupon_id":   "25percentoff"
})

# or
discount = client.new_discount().create({
    "subscription_id": "sub_7kAxfNML6jIc3bltGIt0uK2nKHDyzzq3",
    "coupon_id":       "25percentoff"
})
require "processout"
client = ProcessOut::Client.new(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x", 
    "key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8")

subscription = client.subscription.create(
    customer_id: "cust_uYW5WVnjHe91qnsUA1sHOxEjdAySvg0P",
    plan_id:     "silver-plan",
    coupon_id:   "25percentoff"
)

# or
discount = client.discount.create(
    subscription_id: "sub_7kAxfNML6jIc3bltGIt0uK2nKHDyzzq3",
    coupon_id:       "25percentoff"
)
<?php
$client = new \ProcessOut\ProcessOut(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x", 
    "key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8");

$subscription = $client->newSubscription()->create(array(
    "customer_id" => "cust_uYW5WVnjHe91qnsUA1sHOxEjdAySvg0P",
    "plan_id"     => "silver-plan",
    "coupon_id"   => "25percentoff"
));

// or
$discount = $client->newDiscount()->create(array(
    "subscription_id" => "sub_7kAxfNML6jIc3bltGIt0uK2nKHDyzzq3",
    "coupon_id"       => "25percentoff"
));
import "gopkg.in/processout.v4"
client := processout.New(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x", 
    "key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8")

sub, _ := client.NewSubscription().Create(&processout.SubscriptionCreateParameters{
    Subscription: &processout.Subscription{
        CustomerID: processout.String("cust_uYW5WVnjHe91qnsUA1sHOxEjdAySvg0P"),
        PlanID:     processout.String("silver-plan"),
    },
    CouponID: "25percentoff",
})

// or
discount, err := client.NewDiscount().Create(&processout.DiscountCreateParameters{
    Discount: &processout.Discount{
        SubscriptionID: processout.String("sub_7kAxfNML6jIc3bltGIt0uK2nKHDyzzq3"),
        CouponID:       processout.String("25percentoff"),
    }})

Remove a coupon discount

Sometimes, you might also want to remove a discount from a subscription. This can be done by providing the coupon with which the discount was created:

curl -X DELETE https://api.processout.com/subscriptions/sub_7kAxfNML6jIc3bltGIt0uK2nKHDyzzq3/discounts/25percentoff \
    -u test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x:key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8
var ProcessOut = require("processout");
var client = new ProcessOut(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
    "key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8");

client.newDiscount({
    id:              "25percentoff",
    subscription_id: "sub_7kAxfNML6jIc3bltGIt0uK2nKHDyzzq3"
}).delete().then(function(subscription) {
    //

}, function(err) {
    // The subscription could not be found

});
import processout
client = processout.ProcessOut(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x", 
    "key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8")

client.new_discount().delete({
    id:              "25percentoff",
    subscription_id: "sub_7kAxfNML6jIc3bltGIt0uK2nKHDyzzq3"
})
require "processout"
client = ProcessOut::Client.new(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x", 
    "key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8")

client.discount.delete(
    id:              "25percentoff",
    subscription_id: "sub_7kAxfNML6jIc3bltGIt0uK2nKHDyzzq3"
)
<?php
$client = new \ProcessOut\ProcessOut(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x", 
    "key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8");

$subscription = $client->newSubscription()->find("sub_7kAxfNML6jIc3bltGIt0uK2nKHDyzzq3");
$subscription->removeDiscount("25percentoff");
$client->newDiscount()->delete(array(
    "id"              => "25percentoff",
    "subscription_id" => "sub_7kAxfNML6jIc3bltGIt0uK2nKHDyzzq3"
))
import "gopkg.in/processout.v4"
client := processout.New(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x", 
    "key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8")

err := client.NewDiscount().Delete(&processout.DiscountDeleteParameters{
    Discount: &processout.Discount{
        ID:             processout.String("25percentoff"),
        SubscriptionID: processout.String("sub_7kAxfNML6jIc3bltGIt0uK2nKHDyzzq3"),
    },
})