91³Ô¹ÏÍø

Watch CBS News

Dunkin' changed its points policy and cost a loyal customer $260. Know the risks of loyalty programs.

Dunkin' has loyal customers across Massachusetts, but some aren't happy about the changes the company made to its loyalty program last fall.

Aaron Braun of Stow is one of them. He had accumulated more than 93,000 points on the app over several years. But, before he could use them, Dunkin' changed its rewards policy. Points now expire one year from the last day of the month they were earned.

62,000 Dunkin' points lost

That change cost Braun 62,000 points, which equals about 100 coffees or $260.

"A lot of money," he said. Braun had originally planned to let his children use the points to get free food and drinks.

"My kids now have a driver's license so they can order on the way to school if they want to, breakfast sandwiches, all the products are there. And it doesn't cost anything," Braun told WBZ-TV. Now, he's making his coffee at home. 

He told WBZ's I-Team it took him five years to accumulate all those points. He emailed Dunkin' but said it didn't make a difference.

"I wrote and said, 'I've been loyal to you, but you're not showing any loyalty back to me.' It's a local company, I mean Dunkin' was founded up here. They're all over the place, but they started up in Massachusetts, so it's rough," Braun said.

He isn't the only customer who felt slighted by the change in policy last fall. Dunkin' received a lot of backlash on social media for the change.

Loyalty program risks

"The rule of thumb I have is you gotta use it or lose it, because these things can change, in a moment's notice, as we've seen here," said Deidre Cummings, a legislative director for the consumer watchdog group MASSPIRG.

Cummings explained that companies have the right to change their loyalty programs at any time. She said they're typically used as marketing tools and there are strings attached.

"It's also important to remember that we are paying in terms of giving them our purchasing history and personal data. So, we should just keep that in mind. So, it's not really free. I call it like 'free not free,'" Cummings said. 

Dunkin did not respond to WBZ's requests for comment. It is not the only company changing its rewards programs. Airlines and credit card companies are also revising their loyalty perks.

View CBS News In
CBS News App Open
Chrome Safari Continue
const link = doc.createElement('link'); link.rel = 'stylesheet'; link.href = '/fly/fly/bundles/cbsnewscontent/css/cmp-banner.min.css?v=50747257b890e014813016b79ece0fb2'; doc.head.appendChild(link); doc.body.innerHTML = CONSENT_MESSAGE; } else { el.insertAdjacentHTML('afterend', CONSENT_MESSAGE); } }); } function hidePrivacyMessage() { // Remove from the main document document.querySelectorAll(`.${CONSENT_MESSAGE_CLASS}`).forEach(el => el.remove()); // Remove from inside any iframes document.querySelectorAll('iframe').forEach(iframe => { const doc = iframe.contentDocument || iframe.contentWindow.document; doc.querySelectorAll(`.${CONSENT_MESSAGE_CLASS}`).forEach(el => el.remove()); }); } function activateGatedScripts() { // Handle both new format (cmp-gated-script) and old OneTrust/Ketch format (optanon-category-4) const gatedScripts = Array.from(document.querySelectorAll('script.cmp-gated-script, script.optanon-category-4')); // Activate scripts sequentially with a small delay to avoid timing issues let delay = 0; gatedScripts.forEach(function(placeholder, index) { setTimeout(function() { // Skip if already processed if (placeholder.hasAttribute('data-cmp-processed')) { return; } placeholder.setAttribute('data-cmp-processed', 'true'); const newScript = document.createElement('script'); newScript.type = 'text/javascript'; // Try new format first (data-cmp-src), then fall back to old format (data-src) const src = placeholder.getAttribute('data-cmp-src') || placeholder.getAttribute('data-src'); if (src) { newScript.src = src; } else if (placeholder.textContent) { // Inline script - just copy the content newScript.textContent = placeholder.textContent; } // Handle new format attributes (data-cmp-attrs) - for both inline and external scripts const attrs = placeholder.getAttribute('data-cmp-attrs'); if (attrs) { const tempDiv = document.createElement('div'); tempDiv.innerHTML = '
<\/div>'; const tempAttrs = tempDiv.firstChild.attributes; for (let i = 0; i < tempAttrs.length; i++) { // For external scripts, allow defer/async. For inline scripts, skip them (not valid) if (src || (tempAttrs[i].name !== 'async' && tempAttrs[i].name !== 'defer')) { newScript.setAttribute(tempAttrs[i].name, tempAttrs[i].value); } } } // Copy other attributes from old OneTrust format for (let i = 0; i < placeholder.attributes.length; i++) { const attr = placeholder.attributes[i]; // Skip attributes we've already handled or don't want to copy if (!['class', 'data-src', 'data-type', 'data-cmp-src', 'data-cmp-attrs', 'data-cmp-processed', 'type', 'async', 'defer', 'src'].includes(attr.name)) { newScript.setAttribute(attr.name, attr.value); } } placeholder.parentNode.replaceChild(newScript, placeholder); // If external script, manually trigger window.onload handlers after it loads // This handles widgets that use window.onload for initialization if (src) { newScript.addEventListener('load', function() { // If page already loaded and script set a new onload handler, trigger it if (document.readyState === 'complete' && window.onload) { const originalOnload = window.onload; window.onload = null; // Clear temporarily to prevent loops originalOnload(); // Execute the handler } }); } }, delay); delay += 500; // 500ms delay between each script to allow full loading }); } cbsoptanon.onScriptsReady(function(cmp) { cmp.ot.targetingAllowed(function(allowed) { if (!allowed) { showPrivacyMessage(); } else { activateGatedScripts(); } }); cmp.ot.awaitInitialConsent(function(consent_model) { cmp.ot.addOnConsentChangedHandler(function() { cmp.ot.targetingAllowed(function(allowed) { if (allowed) { hidePrivacyMessage(); activateGatedScripts(); } else { showPrivacyMessage(); } }); }); }); });