← back to Dw Signup Fulfillment
lib/giftcard.js
50 lines
'use strict';
// WIRED retail default (Steve's decision, TK-10006). On customers/create the service
// emails the new customer a UNIQUE Shopify gift-card code for their 3 free samples.
// Chosen because the function-backed discount is app-scoped (our token belongs to a
// different app, so it can't mint per-customer function codes), and the admin
// shared-code path wasn't surfacing cleanly. The gift card is fully automated with
// the token we have, unique + single-use per signup, and bounded to $12.75 (so the
// roll-leak exposure is capped at the card balance).
//
// create a Shopify GIFT CARD worth
// FREE_SAMPLE_COUNT × SAMPLE_PRICE (default 3 × $4.25 = $12.75), then email the
// customer the code with a friendly "here are your 3 free samples" template.
//
// Why a gift card (vs a discount code): a gift card is a stored-value balance the
// customer redeems at checkout on ANY line items. The face value ($12.75) is
// sized to exactly cover 3 samples at $4.25. It does NOT hard-limit to 3 samples
// or to the Samples collection — the customer could spend it on anything up to
// the balance. See giftcode-discount.js for the alternative that scopes 100%-off
// to the Samples product set and enforces single-use (Steve chooses at go-live).
//
// DRY_RUN-safe: lib/shopify.js short-circuits the POST and returns a synthetic
// gift_card with a DRYRUN… code so the email template still has something to show.
const config = require('./config');
const shopify = require('./shopify');
const email = require('./email');
async function issueRetailGiftCode(customer) {
const value = config.SAMPLE_GIFT_VALUE; // 3 × 4.25
const note = `DW retail free samples (${config.FREE_SAMPLE_COUNT} × $${config.SAMPLE_PRICE}) — customer ${customer.email || customer.id}`;
const gc = await shopify.createGiftCard({ value, note, currency: config.CURRENCY });
const card = gc.json && gc.json.gift_card ? gc.json.gift_card : {};
const code = card.code || '(code returned by Shopify at go-live)';
const firstName = customer.first_name || (customer.email ? customer.email.split('@')[0] : '');
const tpl = email.retailGiftEmail({ firstName, code, value, count: config.FREE_SAMPLE_COUNT });
const mail = await email.sendEmail({ to: customer.email, subject: tpl.subject, html: tpl.html, source: 'retail-gift' });
return {
path: 'gift_card',
value,
count: config.FREE_SAMPLE_COUNT,
giftCard: { id: card.id || null, code, dryRun: gc.dryRun || false },
email: { to: customer.email, subject: tpl.subject, dryRun: mail.dryRun || false, ok: mail.ok !== false },
shopifyCall: gc.dryRun ? { WOULD: `${gc.method} ${gc.url}`, payload: gc.body } : { status: gc.status },
};
}
module.exports = { issueRetailGiftCode };