<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Michael Fall</title>
    <description>The latest articles on DEV Community by Michael Fall (@fallguy04).</description>
    <link>https://dev.to/fallguy04</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4203593%2Fc4e07cd4-d299-424d-8aba-975c4c8301df.jpg</url>
      <title>DEV Community: Michael Fall</title>
      <link>https://dev.to/fallguy04</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fallguy04"/>
    <language>en</language>
    <item>
      <title>Changelog email: turn your Vercel deploys into a product update</title>
      <dc:creator>Michael Fall</dc:creator>
      <pubDate>Sat, 31 Oct 2026 01:00:10 +0000</pubDate>
      <link>https://dev.to/kicklace/changelog-email-turn-your-vercel-deploys-into-a-product-update-4c5b</link>
      <guid>https://dev.to/kicklace/changelog-email-turn-your-vercel-deploys-into-a-product-update-4c5b</guid>
      <description>&lt;p&gt;Every production deploy you ship is a small piece of news for the people using your app, and most of them never hear it. I'd gather a week of deploys, keep the changes a customer would notice, and send one short note from my own name instead of an email on every push. The lines for that note can come from the commit and pull request titles, so it helps to write those titles for a reader. The article below walks through the Vercel side, the plain way to do it by hand, and what the email should say.&lt;/p&gt;

&lt;h2&gt;
  
  
  The short answer
&lt;/h2&gt;

&lt;p&gt;Do not email people on every deploy. Gather a week of them, pick what a customer would notice, and send one short update to the people who asked to hear from you.&lt;/p&gt;

&lt;h2&gt;
  
  
  The plain way
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Once a week, open your Vercel deployments, or run &lt;code&gt;git log&lt;/code&gt;, and look at what went to production.&lt;/li&gt;
&lt;li&gt;Keep the changes a customer would notice. Drop the refactors and the fixes nobody saw.&lt;/li&gt;
&lt;li&gt;Write three or four lines in plain words.&lt;/li&gt;
&lt;li&gt;Send them to a list of people who agreed to get product updates.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Vercel can call a webhook of yours when a deploy succeeds. Its events include &lt;code&gt;deployment.succeeded&lt;/code&gt;, and the payload says whether the target was production. As of October 2026, Vercel's account webhooks are on its Pro and Enterprise plans. A webhook is handy for collecting deploys in one place, but you still choose the words.&lt;/p&gt;

&lt;p&gt;The hard part is not the sending. It is remembering to do it, every week, while you are busy building.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the email should say
&lt;/h2&gt;

&lt;p&gt;Lead with what changed for the reader, in their words, and keep it short.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Subject: What's new in [your app]&lt;/p&gt;

&lt;p&gt;Hi {{first_name}},&lt;/p&gt;

&lt;p&gt;This week we shipped:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[Date]: [what changed, in a customer's words]&lt;/li&gt;
&lt;li&gt;[Date]: [what changed, in a customer's words]&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Something you wish we would build next? Reply to this email.&lt;/p&gt;

&lt;p&gt;[Your name]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;More in &lt;a href="https://www.kicklace.com/product-update-emails?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=post_nqsoukvcrj4" rel="noopener noreferrer"&gt;product update emails&lt;/a&gt; and the &lt;a href="https://www.kicklace.com/product-update-email-template?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=post_nqsoukvcrj4" rel="noopener noreferrer"&gt;product update email template&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Does every deploy send an email?
&lt;/h3&gt;

&lt;p&gt;No. Only the list's scheduled email goes out, and a week with nothing deployed sends nothing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do I need GitHub?
&lt;/h3&gt;

&lt;p&gt;No. Without it the lines come from each deploy's title, the first line of its commit message. GitHub adds the pull request titles.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article was written with the help of AI.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>saas</category>
      <category>email</category>
      <category>startup</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to email a customer when their Stripe payment fails</title>
      <dc:creator>Michael Fall</dc:creator>
      <pubDate>Sat, 24 Oct 2026 01:20:37 +0000</pubDate>
      <link>https://dev.to/fallguy04/how-to-email-a-customer-when-their-stripe-payment-fails-24hc</link>
      <guid>https://dev.to/fallguy04/how-to-email-a-customer-when-their-stripe-payment-fails-24hc</guid>
      <description>&lt;p&gt;When a renewal fails, Stripe fires &lt;code&gt;invoice.payment_failed&lt;/code&gt; and starts retrying. Its recommended setting tries up to 8 times in two weeks. Unless you've turned on Stripe's own email, your customer has no idea. It's usually an expired card, not someone leaving, and I think those quiet two weeks are where you lose people who meant to stay. Below is the email I'd send the same day, and the few lines that send it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The short answer
&lt;/h2&gt;

&lt;p&gt;When a payment for an invoice fails, Stripe sends an event called &lt;code&gt;invoice.payment_failed&lt;/code&gt;. Stripe's own advice is to notify the customer. You can turn on Stripe's email, or handle the event in your own code.&lt;/p&gt;

&lt;p&gt;Whatever you pick, tell the customer quickly and plainly. A failed payment is usually an expired card, not someone leaving.&lt;/p&gt;

&lt;h2&gt;
  
  
  The plain way
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Stripe's own email.&lt;/strong&gt; In Stripe's revenue recovery settings, turn on "Send emails when card payments fail". Stripe then emails the customer after each failed payment, with a link to update their payment method, in your Stripe branding.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your own webhook.&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add a webhook endpoint in Stripe that listens for &lt;code&gt;invoice.payment_failed&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Check the signature on every request. Stripe signs each one in a &lt;code&gt;Stripe-Signature&lt;/code&gt; header and needs the raw body untouched.&lt;/li&gt;
&lt;li&gt;Return a 2xx fast and send the email after. Keep the event ids you have handled, because an event can arrive twice.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;stripe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webhooks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;constructEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rawBody&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;endpointSecret&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;invoice.payment_failed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;invoice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// invoice.customer_email, invoice.attempt_count, invoice.hosted_invoice_url&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The invoice carries the customer's email and name, the amount due, and a hosted page where they can pay. It also carries &lt;code&gt;attempt_count&lt;/code&gt;, because Stripe retries a failed payment and reports those retries through this same event. Stripe's recommended Smart Retries default is 8 tries within 2 weeks, so decide whether you email on every attempt or only the first.&lt;/p&gt;

&lt;p&gt;One catch with that hosted page, which a reader pointed out in the comments. On a subscription invoice, paying there settles this one invoice, but Stripe only saves the new card as the default if the customer does not already have one, so the expired card can stay the default and next month's payment fails again. For the link in your email, use a page that changes the default card, such as Stripe's customer portal or your own billing page, and test that exact flow in test mode before you rely on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the email should say
&lt;/h2&gt;

&lt;p&gt;Say what happened, what to do, and what happens if nothing is done. No blame, no alarm.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Subject: Your payment didn't go through&lt;/p&gt;

&lt;p&gt;Hi {{first_name}},&lt;/p&gt;

&lt;p&gt;Your latest payment for [your app] did not go through. This is usually an expired card or a block from the bank, and it is quick to fix.&lt;/p&gt;

&lt;p&gt;You can update your card here: [link to your billing page].&lt;/p&gt;

&lt;p&gt;[Say what happens next and when, in your own words.] If you would like a hand, reply to this email.&lt;/p&gt;

&lt;p&gt;[Your name]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Fill the brackets with your own details.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Should I turn off Stripe's email?
&lt;/h3&gt;

&lt;p&gt;Choose one. If Stripe's email and yours are both on, a customer gets two for the same failure. Stripe's is quick to switch on. Yours can sound like you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does Stripe retry the payment?
&lt;/h3&gt;

&lt;p&gt;Yes, if you have retries on. Stripe recommends Smart Retries, and it will not retry some hard declines until the customer adds a new payment method. That is a good reason for the email to include a way to update the card.&lt;/p&gt;

</description>
      <category>saas</category>
      <category>email</category>
      <category>startup</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
