Migrate your existing Magento® store to Shopify Plus and receive up to 6 months free! Learn more +

Want To Add 70,000 Unique One-Time Use Coupons In Less Than 2 Hours?

Dec 13th, 2016

One of the most overlooked benefits of Shopify Plus is the additional API resources available such as the Discount API.

Note: After upgrading to Shopify Plus you will have to ask your dedicated account manager to enable the Plus-specific endpoints else you will get an error.

One of our clients, Guns n Roses, wanted to launch a holiday promotion. Easy enough. They went to the app store, found an app with raving reviews and installed the Bulk Discount app. It wasn't until one of their customers called in did they realize what happened.

Turns out the app wasn't able to handle creating 70,000 unique discount codes. In fact, the app deleted all active coupons... Ouch!

This is where Discount API came to the rescue. Within an hour we were able to quickly build a script using Node.js that leveraged the Shopify Plus Discount API to implement 70,000 unique coupon codes. The entire process took Shopify less than two hours to create all the coupons within the admin interface.

Why wouldn't you just use the same code and check the "one time use per customer" box?

There are a couple of situations where you might want to use a bunch of one-time use codes instead of the same code with the "one use per email address" option:

1. You don't want customers to be able to share the code. If a customer gets a "10OFF" code and posts it online, thousands of customers could use it (or one customer with thousands of auto-generated emails). Some merchants are ok with widespread discounting, but others are careful with it because of either margins or creating the appearance that their stuff is always on sale. Just depends on the brand.

2. You want customers to be able to earn a given discount more than once. The big use case here would be rewards, referrals, or any other mechanism where you'd actually want a customer getting the same discount more than once (usually with a good chunk of time in between). If they're getting a generic "10OFF" code, the one use per email address falls down there.

The Copy And Paste Solution

Being that we get asked about this a lot, especially from Shopify merchants running promotions through Groupon, WagJag or other daily deal sites we decided to share the script we wrote for all to use, free!

var fs = require('fs');
var moment = require('moment');
var csv = require('csv-parser');
var request = require('request-promise');

var shop = 'shop.myshopify.com';
var key = '';
var password = '';

var url = `https://${key}:${password}@${shop}`;
function attachEndpoint(resource) {
  return `${url}/admin/${resource}.json`;
};

request(attachEndpoint('discounts/count')).then(function(json) {
  console.log(json); // total discounts count;
});

var time;
var count = 1;
var skip = 0;
var REQUEST_INTERVAL = 1000; // delay between each request
var isLastRecord = false;

console.log('STARGING UPLOADING');
fs.createReadStream('discount.csv')
  .pipe(csv())
  .on('data', function (data) {
    count++;
    if (skip > count) { return; }
    this.pause();
    time = Date.now();
    var self = this;
    createDiscount(data)
      .then(function(json) {
        var id = json.discount.id;
        recordId(id);
      })
      .finally(function() {
        var delta = Date.now() - time;
        if (delta > REQUEST_INTERVAL) {
          self.resume();
        } else {
          setTimeout(function() {
            self.resume()
          }, REQUEST_INTERVAL - delta);
        }
        console.log('count', count);
        if (isLastRecord) {
          console.log('FINISHED UPLOADING');
        }
      });
  })
  .on('end', function () {
    isLastRecord = true;
  });

function recordId(id) {
  fs.appendFile(
    'added-discount-ids.txt',
    id + ',',
    function (err) { if(err) { console.log(err) } }
  );
}

function createDiscount(data) {
  var startDate = moment(data['Starts At'], 'MM/DD/YYYY HH:mm').utcOffset(-60 * 5).format();
  var endDate = moment(data['Ends At'], 'MM/DD/YYYY HH:mm').utcOffset(-60 * 5).format();
  var discount = {
    "discount_type": data.Type === 'PercentageDiscount' ? "percentage": data.Type,
    "code": data.Code,
    "value": data.Value,
    "status": data.Status,
    "minimum_order_amount": data['Minimum Order Amount'],
    "starts_at": startDate,
    "ends_at": endDate,
    "usage_limit": data['Usage Limit'],
    "applies_once": data['Applies Once'] === 'FALSE' ? false : data['Applies Once']
  }
  return request({
    method: 'POST',
    url: attachEndpoint('discounts'),
    body: { discount: discount },
    json: true
  });
}

function deleteDiscount(id) {
  return request({
    method: 'DELETE',
    url: attachEndpoint('discounts/' + id)
  });
}

*Requirements for this script include node v5+ and npm installed.

Steps To Implement:

  1. Create a private app within your Shopify Admin
  2. Install all npm dependencies (npm install .)
  3. Copy access credentials from private app to script
  4. Put your CSV file in same folder as script
  5. Correct property names / header names according to CSV file header in createDiscount function
  6. Set REQUEST_INTERVAL to appropriate value. By default this is 500(ms).
    Pro tip: Ask your Account Manager to increase it to 100ms (Yes, this is another benefit of Shopify Plus. Increased API Limits!)
  7. Run script (node index.js)

If this looks like gibberish to you reach out. Our talented team of experts would love to help.

Curious how else you can leverage the Discount API?

Swell Rewards is a third-party app that uses the Discount API to help convert loyalty points into coupon codes at checkout to improve user experience and maximize conversions.

Control Discount Options


Image via: Vanity Planet

In this case, Vanity Planet controls the discount options they want their customers to be able to redeem their points for. Then, when the customer wants to redeem points, Swell generates a discount code via the Discount API and applies it directly to the cart.

Customer Converts Points To Dollars


Image via: Island Surf

This method used by Island Surf converts the customer's point balance into a dollar value, and then uses the Discount API to generate a coupon dynamically for the amount of the discount if the customer chooses to do so.

Want To Know The 15 Tools We Used To Generate Over $24 Million For Our Clients?

This past year, we have tested dozens of products to figure out which ones yield the best results.
Our toolbox contains some of the most impactful tools we found to grow a brand on Shopify.