Stripe is very popular payment processing system growing in its customers day by day, it has well written and rich enhanced api with really cool documentation which provides us great flexibility in terms of utilization and customization.
Stripe dashboard itself has pretty standard customization options for emails, you can place your logo and change a bit of text BUT it doesn’t allow you to completely change the look and feel of email.
For example a merchant want to have an email with custom header text/image and custom payment message along with some help links in the footer of the email, stripe dashboard doesn’t allow such customization but of course you can do it by using stripe webhooks.
Webhooks is really a cool feature provided by stripe which allows you to intercept events in your php scripts to do what you want. You can send emails, you can make changes in database etc.
So we are going to make fully customized emails sending out to customers using webhooks. Idea is to disable the success email sending through stripe dashboard rather send our own emails. We will create a hook to our php script and will utilize the “charge.succeeded” event. “charge.succeeded” is triggered when a successful payment has been made, so we will be sending out our own emails to customers as we receive charge.succeeded event.
Lets proceed to creating and sending fully customized emails.
Create Webhooks
First thing to do is to create webhooks in stripe dashboard which will be pointing to our scripts to send events.
Head to stripe webhooks in your dashboard or click the link below.
Stripe Webooks
Click on add endpoint button as circled in image below.
We are going to add two webhooks, one is for live mode and other is for test mode.
Create Live Webhook
Click on “Add endpoint” button and follow the steps as in image below to add live webhook
- Add the live webhook url, where your live webhook script will be placed for example www.site.com/hooks/live_stripe.php
- Select the Mode as “Live”
- Click on Select events
- Select the events you want to catch in webhook script, we are going to catch charge.succeded event.
- Create the endpoint.
Create Test Webhook
Click on “Add endpoint” button and follow the steps as in image below to add test webhook
- Add the test webhook url, where your test webhook script will be placed for example www.site.com/hooks/test_stripe.php
- Select the Mode as “Test”
- Click on Select events
- Select the events you want to catch in webhook script, we are going to catch charge.succeded event.
- Create the endpoint.
Now we have created our stripe webhooks end points, next step is to turn off default emails, click on the “Emails” link on top or click the following link
Stripe emails
Uncheck the “Successful payments” checkbox and hit Done button.
That’s it, we have done with the stripe now we are heading to create our test_stripe.php and live_stripe.php scripts.
Stripe PHP SDK
You should have stripe php sdk downloaded
For example place php-sdk as /home/usrname/mywebsite/stripe-php
stripe-php-sdk is placed in root directory of your website.
Create a new directory “hooks” in your site root for example
/home/usrname/mywebsite/hooks/
Creating test webhook
First we are going to create the test_stripe.php
Create new php file under your hooks directory and name it as test_stripe.php
like /home/usrname/mywebsite/hooks/test_stripe.php
Open the file and place following code in it
<!--?php //set stripe library-sdk path $path = realpath(dirname(__FILE__) . '/../stripe-php/lib'); //include stripe library-sdk require_once(&quot;$path/Stripe.php&quot;); //set your test private api key Stripe::setApiKey(&quot;your_test_private_api_key&quot;); //get the json request from stripe $body = @file_get_contents('php://input'); //convert the json request to php array $event_json = json_decode($body); //create log file to log the test events $logfile = fopen(&quot;./log/test_evnlg.log&quot;, 'a'); $date = date(&quot;Y-m-d H:i:s&quot;); fwrite($logfile, &quot;\n===============================================\n\tNew Test log $date \n===============================================\n&quot;); //include the webhook script to send emails include_once(&quot;webhook.php&quot;);
Save the file. Creating live webhook
Now we go to create a new webhook script for live. Create new php file under your hooks directory and name it as live_stripe.php
like /home/usrname/mywebsite/hooks/live_stripe.php
Open the file and place following code in it
<!--?php //set stripe library-sdk path $path = realpath(dirname(__FILE__) . '/../stripe-php/lib'); //include stripe library-sdk require_once(&quot;$path/Stripe.php&quot;); //set your live private api key Stripe::setApiKey(&quot;your_live_private_api_key&quot;); //get the json request from stripe $body = @file_get_contents('php://input'); //convert the json request to php array $event_json = json_decode($body); //create log file to log the live events $logfile = fopen(&quot;./log/live_evnlg.log&quot;, 'a'); $date = date(&quot;Y-m-d H:i:s&quot;); fwrite($logfile, &quot;\n===============================================\n\tNew Live log $date \n===============================================\n&quot;); //include the webhook script to send emails include_once(&quot;webhook.php&quot;);
Save the file. Now we have created basic test and live scripts, both scripts are using webhook.php to send emails. Lets create a webhook.php file to implement our email logic. Create new php file under your hooks directory and name it as webhook.php like /home/usrname/mywebsite/hooks/webhook.php. Open the file and place following code in it.
<?php //if nothing in event then stop further execution if (!$event_json) { echo &quot;nothing found&quot;; die; } try { // for extra security, retrieve from the Stripe API, this will fail in Test Webhooks $event_id = $event_json--->{'id'}; $event = Stripe_Event::retrieve($event_id); fwrite($logfile, "\n\n Stripe Event Received as: $event \n"); if ($event-&gt;type == 'charge.succeeded') { fwrite($logfile, "Sending payment receipt to customer \n"); email_payment_receipt($event-&gt;data-&gt;object); } } catch (Stripe_InvalidRequestError $e) { fwrite($logfile, "ERR " . $e-&gt;getMessage() . " \n"); } //send out payment receipt function email_payment_receipt($payment) { global $logfile; fwrite($logfile, "Sending customer payment email\n"); // retrieve customer from stripe $customer = Stripe_Customer::retrieve($payment-&gt;customer); //fwrite($logfile, "Customer: " . var_export($customer, 1) . "\n"); $email = $customer-&gt;metadata-&gt;customer_email; $name = $customer-&gt;metadata-&gt;customer_name; $subject = 'Payment has been received'; send_html_email($name, $email, $subject, payment_received_body($payment, $name, $email)); } //create email body for payment received function payment_received_body($charge, $name, $email) { global $logfile; $date = date("F d, Y", $charge-&gt;created); $transaction = $charge-&gt;receipt_number ? ("#" . $charge-&gt;receipt_number) : ("#" . $charge-&gt;created); $card = $charge-&gt;source-&gt;last4; $amount = format_stripe_amount($charge-&gt;amount); $html = file_get_contents("invoice.html"); $search = array("{customerName}", "{customerEmail}", "{total}", "{date}", "{transaction}", "{card}"); $replace = array($name, $email, $amount, $date, $transaction, $card); $html = str_replace($search, $replace, $html); return $html; } function format_stripe_amount($amount) { return sprintf('$%0.2f', $amount / 100.0); } function format_stripe_timestamp($timestamp) { return strftime("%m/%d/%Y", $timestamp); } function send_html_email($name, $to, $subject, $body) { global $logfile; $from = "admin@yourwebsite.com"; $replyTo = $from; $headers = "From: " . $from . "\r\n"; $headers .= "Reply-To: ". $replyTo . "\r\n"; //$headers .= "CC: susan@example.com\r\n"; $headers .= "MIME-Version: 1.0\r\n"; $headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n"; fwrite($logfile, "Sending EMAIL\n"); fwrite($logfile, "$name\n"); fwrite($logfile, "$to\n"); fwrite($logfile, "$subject\n"); //fwrite($logfile, "$body\n"); mail($to, $subject, $body, $headers); fclose($logfile); }
Save your file.
Email Template
Now create an html email template to send out as an email and add placeholders to it
Create new html file as invoice.html, it will look like
/home/usrname/mywebsite/hooks/invoice.html
and put your html in that file with place holders like below
<meta http-equiv="&quot;Content-Type&quot;" content="&quot;text/html;" charset="utf-8&quot;"> <title>Your website Name</title> <table border="&quot;0&quot;" cellpadding="&quot;0&quot;" cellspacing="&quot;0&quot;" width="&quot;640px&quot;" style="&quot;margin:20px" auto;&quot;=""> <tbody><tr> <td align="&quot;center&quot;"> <table border="&quot;0&quot;" cellpadding="&quot;0&quot;" cellspacing="&quot;0&quot;" style="&quot;margin-bottom:30px;&quot;"> <tbody><tr> <td align="&quot;center&quot;"><a href="&quot;link_to_your_website&quot;"><img src="&quot;your_website_logo&quot;" alt="&quot;your-website-name&quot;" style="&quot;margin-bottom:15px;&quot;"></a></td> </tr> <tr> <td> <h1 style="&quot;font-family:Verdana," geneva,="" sans-serif;="" font-weight:bold;="" font-size:24px;="" color:#000;="" text-align:center;="" margin:0="" 0="" 15px="" 0;&quot;="">Title of your payment receipt</h1> </td> </tr> <tr> <td> <h2 style="&quot;font-family:Verdana," geneva,="" sans-serif;="" font-weight:normal;="" font-size:22px;="" font-style:italic;="" color:#ff0000;="" text-align:center;="" margin:0="" 0="" 20px="" 0;&quot;="">Payment Receipt</h2> </td> </tr> <tr> <td align="&quot;center&quot;"> <table width="&quot;100%&quot;" border="&quot;0&quot;" cellpadding="&quot;0&quot;" cellspacing="&quot;0&quot;"> <tbody><tr> <td align="&quot;right&quot;"><img src="&quot;visa.png&quot;" alt="&quot;&quot;"></td> <td align="&quot;left&quot;"> <h3 style="&quot;margin:0px" 0px="" 10px;&quot;="">{card}</h3> </td> </tr> </tbody></table> </td> </tr> </tbody></table> </td> </tr> <tr> <td> <table border="&quot;0&quot;" width="&quot;100%&quot;" cellpadding="&quot;0&quot;" cellspacing="&quot;0&quot;"> <tbody><tr bgcolor="&quot;#dcddd6&quot;"> <td align="&quot;left&quot;" style="&quot;padding:15px" 20px;&quot;="">{date}</td> <td align="&quot;right&quot;" style="&quot;padding:15px" 20px;&quot;="">{transaction}</td> </tr> </tbody></table> </td> </tr> <tr> <td> <table border="&quot;0&quot;" width="&quot;100%&quot;" cellpadding="&quot;0&quot;" cellspacing="&quot;0&quot;"> <tbody><tr> <td align="&quot;left&quot;" style="&quot;border-bottom:1px" solid="" #ececec;="" padding:15px="" 20px;="" color:#8b8e8d;&quot;="">Description</td> <td align="&quot;right&quot;" style="&quot;border-bottom:1px" solid="" #ececec;="" padding:15px="" 20px;="" color:#8b8e8d;="" margin:0="" 20px;&quot;="">Price</td> </tr> <tr> <td align="&quot;left&quot;" style="&quot;border-bottom:1px" solid="" #ececec;="" padding:10px="" 0px="" 10px="" 20px;&quot;=""><span style="&quot;display:" block;="" background:#ececec;="" padding:10px="" 5px;&quot;="">Payment from {customerName} for Your Website</span></td> <td align="&quot;right&quot;" style="&quot;border-bottom:1px" solid="" #ececec;="" padding:10px="" 20px;&quot;=""> <h4 style="&quot;font-family:Arial," helvetica,="" sans-serif;="" font-size:16px;="" margin:0px;&quot;="">{total}</h4> </td> </tr> <tr> <td align="&quot;right&quot;" style="&quot;padding:20px" 0px;&quot;=""><span style="&quot;font-family:Verdana," geneva,="" sans-serif;="" font-size:18px;&quot;="">Total</span></td> <td align="&quot;right&quot;" style="&quot;padding:10px" 20px;&quot;=""> <h4 style="&quot;font-family:Arial," helvetica,="" sans-serif;="" font-size:18px;="" margin:0px;&quot;="">{total}</h4> </td> </tr> </tbody></table> </td> </tr> <tr> <td align="&quot;center&quot;" style="&quot;border-top:1px" solid="" #ececec;="" padding:20px="" 20px;&quot;=""> Have a question or need help? <a href="&quot;#&quot;" onmouseover="this.style.textDecoration=&quot;none&quot;" onmouseout="this.style.textDecoration=&quot;underline&quot;" style="&quot;color:#085296;&quot;">Send us an email</a> Or give us a call at (000) 000-0000</td> </tr> <tr> <td align="&quot;center&quot;" style="&quot;padding:0px" 20px;&quot;=""> Having trouble viewing this email? <a href="&quot;#&quot;" onmouseover="this.style.textDecoration=&quot;none&quot;" onmouseout="this.style.textDecoration=&quot;underline&quot;" style="&quot;color:#085296;&quot;">View it in your Browser</a> You are reveiving this email because you made a payment to Your website Name</td> </tr> </tbody></table>
Testing emails
Upload the code to your webserver. Go to stripe dashboard and turn it to test mode. Create a test payment or subscription, you will receive the customized email. Now turn it back to live mode so your customers can get the customized emails.
Please suggest enhancements in your comments.
Thanks 🙂
While working on that code I noticed you have to pay close attention to your code when doing a charge by NOT PROVIDING receipt_email
as suggested by stripe
receipt_email
The email address to send this charge’s receipt to. The receipt will not be sent until the charge is paid. If this charge is for a customer, the email address specified here will override the customer’s email address. Receipts will not be sent for test mode charges. If receipt_email is specified for a charge in live mode, a receipt will be sent regardless of your email settings.