├── .gitignore ├── Gruntfile.js ├── LICENSE ├── README.md ├── dist ├── abandoned_checkout_notification.html ├── abandoned_checkout_notification.txt ├── customer_account_activation.html ├── customer_account_activation.txt ├── customer_account_welcome.html ├── customer_account_welcome.txt ├── customer_password_reset.html ├── customer_password_reset.txt ├── fulfillment_request.html ├── fulfillment_request.txt ├── giftcard_notification.html ├── giftcard_notification.txt ├── new_order_notification.html ├── new_order_notification.txt ├── order_cancelled.html ├── order_cancelled.txt ├── order_confirmation.html ├── order_confirmation.txt ├── refund_notification.html ├── refund_notification.txt ├── shipping_confirmation.html ├── shipping_confirmation.txt ├── shipping_update.html └── shipping_update.txt ├── package.json └── src ├── css ├── main.css └── scss │ ├── _config.scss │ ├── _global.scss │ ├── _layout.scss │ ├── _links.scss │ ├── _other.scss │ ├── _responsive.scss │ ├── _type.scss │ └── main.scss ├── emails ├── abandoned_checkout_notification.hbs ├── customer_account_activation.hbs ├── customer_account_welcome.hbs ├── customer_password_reset.hbs ├── fulfillment_request.hbs ├── giftcard_notification.hbs ├── new_order_notification.hbs ├── order_cancelled.hbs ├── order_confirmation.hbs ├── refund_notification.hbs ├── shipping_confirmation.hbs └── shipping_update.hbs ├── img ├── email-logo.gif └── email-logo.png └── layouts ├── branded.hbs └── default.hbs /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | .sass-cache 4 | .secret 5 | .idea 6 | *.css.map -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 3 | grunt.initConfig({ 4 | pkg: grunt.file.readJSON('package.json'), 5 | 6 | // Takes your scss files and compiles them to css 7 | sass: { 8 | dist: { 9 | options: { 10 | style: 'expanded' 11 | }, 12 | files: { 13 | 'src/css/main.css': 'src/css/scss/main.scss' 14 | } 15 | } 16 | }, 17 | 18 | // Assembles your email content with html layout 19 | assemble: { 20 | options: { 21 | layoutdir: 'src/layouts', 22 | flatten: true 23 | }, 24 | pages: { 25 | src: ['src/emails/*.hbs'], 26 | dest: 'dist/' 27 | } 28 | }, 29 | 30 | // Inlines your css 31 | premailer: { 32 | html: { 33 | options: { 34 | removeComments: true 35 | }, 36 | files: [{ 37 | expand: true, 38 | src: ['dist/*.html'], 39 | dest: '' 40 | }] 41 | }, 42 | txt: { 43 | options: { 44 | mode: 'txt' 45 | }, 46 | files: [{ 47 | expand: true, 48 | src: ['dist/*.html'], 49 | dest: '', 50 | ext: '.txt' 51 | }] 52 | } 53 | }, 54 | 55 | // Watches for changes to css or email templates then runs grunt tasks 56 | watch: { 57 | files: ['src/css/scss/*','src/emails/*','src/layouts/*'], 58 | tasks: ['default'] 59 | }, 60 | 61 | // Use Mailgun option if you want to email the design to your inbox or to something like Litmus 62 | mailgun: { 63 | mailer: { 64 | options: { 65 | key: 'MAILGUN_KEY', // Enter your Mailgun API key here 66 | sender: 'me@me.com', // Change this 67 | recipient: 'you@you.com', // Change this 68 | subject: 'This is a test email' 69 | }, 70 | src: ['dist/'+grunt.option('template')] 71 | } 72 | }, 73 | 74 | // Use Rackspace Cloud Files if you're using images in your email 75 | cloudfiles: { 76 | prod: { 77 | 'user': 'Rackspace Cloud Username', // Change this 78 | 'key': 'Rackspace Cloud API Key', // Change this 79 | 'region': 'ORD', // Might need to change this 80 | 'upload': [{ 81 | 'container': 'Files Container Name', // Change this 82 | 'src': 'src/img/*', 83 | 'dest': '/', 84 | 'stripcomponents': 0 85 | }] 86 | } 87 | }, 88 | 89 | // CDN will replace local paths with your Cloud CDN path 90 | cdn: { 91 | options: { 92 | cdn: 'Rackspace Cloud CDN URI', // Change this 93 | flatten: true, 94 | supportedTypes: 'html' 95 | }, 96 | dist: { 97 | src: ['./dist/*.html'] 98 | } 99 | } 100 | 101 | }); 102 | 103 | // Where we tell Grunt we plan to use this plug-in. 104 | grunt.loadNpmTasks('grunt-contrib-sass'); 105 | grunt.loadNpmTasks('assemble'); 106 | grunt.loadNpmTasks('grunt-mailgun'); 107 | grunt.loadNpmTasks('grunt-premailer'); 108 | grunt.loadNpmTasks('grunt-contrib-watch'); 109 | grunt.loadNpmTasks('grunt-cloudfiles'); 110 | grunt.loadNpmTasks('grunt-cdn'); 111 | 112 | // Where we tell Grunt what to do when we type "grunt" into the terminal. 113 | grunt.registerTask('default', ['sass','assemble','premailer']); 114 | 115 | // Use grunt send if you want to actually send the email to your inbox 116 | grunt.registerTask('send', ['mailgun']); 117 | 118 | // Upload images to our CDN on Rackspace Cloud Files 119 | grunt.registerTask('cdnify', ['default','cloudfiles','cdn']); 120 | 121 | }; 122 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Grunt Shopify Transactional Emails 2 | Grunt workflow for generating Shopify transactional emails. 3 | 4 | This repo was forked from [leemunroe/grunt-email-design](https://github.com/leemunroe/grunt-email-design) 5 | 6 | The layouts and emails have been updated to include all the standard Shopify HTML transactional emails. 7 | 8 | ## Included Emails 9 | 10 | 1. Abandoned Checkout Notification 11 | 2. Customer Account Activation 12 | 3. Customer Account Welcome 13 | 4. Customer Password Reset 14 | 5. Fulfillment Request 15 | 6. GiftCard Notifications 16 | 7. New Order Notification 17 | 8. Order Cancelled 18 | 9. Order Confirmation 19 | 10. Refund Notification 20 | 11. Shipping Confirmation 21 | 12. Shipping Update 22 | 23 | These two templates were not included since they are always sent in plaintext. 24 | 25 | 1. Contact Buyer 26 | 2. New Order Notification (mobile) 27 | 28 | ## Included Layouts 29 | 30 | 1. default.hbs 31 | 2. branded.hbs 32 | 33 | default.hbs is the layout that comes with the original workflow. branded.hbs is slightly different. Here we've moved the header and the footer outside of the individual email templates so you only need to edit the layout once. This allowed us to focus specifically on each email's content in the individual templates. 34 | 35 | ## How it Works 36 | 37 | Familiarize yourself with [Grunt](http://gruntjs.com/) before you get started. You can read Chris Coyier's post on [getting started with Grunt](http://24ways.org/2013/grunt-is-not-weird-and-hard/). 38 | 39 | Make sure you've read the [grunt-email-design](https://github.com/leemunroe/grunt-email-design) getting started guide. This will teach you the Grunt workflow used here. 40 | 41 | Once you're familiar with the workflow, you can use these templates (`/src`) to generate all your Shopify Transactional emails easily. 42 | 43 | 44 | ## Escaping Liquid Variables 45 | 46 | Since both Assemble and Shopify's liquid variables use double brackets for variable declaration we have to escape the liquid variables before we assemble the emails. You'll see that we can do this by prefixing each variable with a backslash. ex: `\{{ shop.name }}` 47 | 48 | 49 | ## Notes 50 | 51 | If you get this when running your workflow: 52 | 53 | ``` 54 | warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit. 55 | ``` 56 | 57 | Your templates will still render, however the watch task might not work exactly as expected. This is a node limit set to warn against possible recursion and infinite loops. However since we have more than 10 templates we're working with, this error often gets thrown. [You can checkout this fix in premailer](https://github.com/dwightjack/grunt-premailer/blob/master/tasks/premailer.js#L95). 58 | 59 | 60 | ### Resources 61 | 62 | These templates were based off of Mailgun's Transactional Email Templates, and the content pulled from the default Shopify Transactional Emails 63 | 64 | 1. [Shopify Email Variable Reference](http://docs.shopify.com/manual/settings/notifications/email-variables) 65 | 2. [Mailgun's Transactional Email Templates](http://blog.mailgun.com/transactional-html-email-templates/) 66 | -------------------------------------------------------------------------------- /dist/abandoned_checkout_notification.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Complete Your Purchase 7 | 8 | 9 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 132 | 133 | 134 |
63 |
64 | 65 | 66 | 75 | 76 | 77 | 119 | 120 | 121 | 128 | 129 |
67 | 68 | 69 | 72 | 73 |
70 | {{ shop.name }} 71 |
74 |
78 | 79 | 80 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 |
81 |

Hey{% if billing_address.name %} {{ billing_address.name }}{% endif %},

82 |

Your shopping cart at {{ shop_name }} has been reserved and is waiting for your return!

In your cart, you left:
92 | 93 | 94 | 104 | 105 |
95 | 96 | {% for line in line_items %} 97 | 98 | 99 | 100 | 101 | {% endfor %} 102 |
{{ line.title }}x {{ line.quantity }}
103 |
106 |
But it's not too late! To complete your purchase, click this link:
Complete Your Purchase
Thanks for shopping!
118 |
130 |
131 |
135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /dist/abandoned_checkout_notification.txt: -------------------------------------------------------------------------------- 1 | {{ shop.name }} ( {{ 2 | shop.url }} ) 3 | 4 | ***************************************************************** 5 | Hey{% if billing_address.name %} {{ billing_address.name }}{% 6 | endif %}, 7 | ***************************************************************** 8 | 9 | ----------------------------------------------------------------- 10 | Your shopping cart at {{ shop_name }} has been reserved and is 11 | waiting for your return! 12 | ----------------------------------------------------------------- 13 | 14 | In your cart, you left: 15 | 16 | {% for line in line_items %} 17 | 18 | {{ line.title }} 19 | x {{ line.quantity }} 20 | 21 | {% endfor %} 22 | 23 | But it's not too late! To complete your purchase, click 24 | this link: 25 | 26 | Complete Your Purchase ( {{ url }} ) 27 | 28 | Thanks for shopping! 29 | 30 | © {{ 'now' | date: "%Y" 31 | }} {{ shop.name }} All Rights Reserved 32 | -------------------------------------------------------------------------------- /dist/customer_account_activation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Customer Account Activation 7 | 8 | 9 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 105 | 106 | 107 |
63 |
64 | 65 | 66 | 75 | 76 | 77 | 92 | 93 | 94 | 101 | 102 |
67 | 68 | 69 | 72 | 73 |
70 | {{ shop.name }} 71 |
74 |
78 | 79 | {% if customer.name %} 80 | 81 | 82 | 83 | {% endif %} 84 | 85 | 86 | 87 | 88 | 89 | 90 |

Dear {{ customer.name }},

This is to confirm that your account for the shop {{ shop.name }} is now active.

The next time you shop at {{ shop.name }}, you can save time at checkout by logging into your account. This will prefill your address information at the checkout.
91 |
103 |
104 |
108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /dist/customer_account_activation.txt: -------------------------------------------------------------------------------- 1 | {{ shop.name }} ( {{ 2 | shop.url }} ) 3 | 4 | {% if customer.name %} 5 | 6 | ************************* 7 | Dear {{ customer.name }}, 8 | ************************* 9 | 10 | {% endif %} 11 | 12 | ----------------------------------------------------------------- 13 | This is to confirm that your account for the shop {{ shop.name }} 14 | is now active. 15 | ----------------------------------------------------------------- 16 | 17 | The next time you shop at {{ shop.name }}, you can save 18 | time at checkout by logging into your account. This will prefill 19 | your address information at the checkout. 20 | 21 | © {{ 'now' | date: "%Y" 22 | }} {{ shop.name }} All Rights Reserved 23 | -------------------------------------------------------------------------------- /dist/customer_account_welcome.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Customer Account Welcome 7 | 8 | 9 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 111 | 112 | 113 |
63 |
64 | 65 | 66 | 75 | 76 | 77 | 98 | 99 | 100 | 107 | 108 |
67 | 68 | 69 | 72 | 73 |
70 | {{ shop.name }} 71 |
74 |
78 | 79 | {% if customer.name %} 80 | 81 | 82 | 83 | {% endif %} 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 |

Dear {{ customer.name }},

An account has been created for you at {{ shop.name }}.

Please visit this url to activate your account and set your password.
Active Your Account
If the account was created in error, you can visit the link above and select "Decline" to decline this invitation.
97 |
109 |
110 |
114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /dist/customer_account_welcome.txt: -------------------------------------------------------------------------------- 1 | {{ shop.name }} ( {{ 2 | shop.url }} ) 3 | 4 | {% if customer.name %} 5 | 6 | ************************* 7 | Dear {{ customer.name }}, 8 | ************************* 9 | 10 | {% endif %} 11 | 12 | ------------------------------------------------------- 13 | An account has been created for you at {{ shop.name }}. 14 | ------------------------------------------------------- 15 | 16 | Please visit this url to activate your account and set 17 | your password. 18 | 19 | Active Your Account ( {{ customer.account_activation_url 20 | }} ) 21 | 22 | If the account was created in error, you can visit the 23 | link above and select "Decline" to decline this invitation. 24 | 25 | © {{ 'now' | date: "%Y" 26 | }} {{ shop.name }} All Rights Reserved 27 | -------------------------------------------------------------------------------- /dist/customer_password_reset.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Customer Account Password Reset 7 | 8 | 9 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 111 | 112 | 113 |
63 |
64 | 65 | 66 | 75 | 76 | 77 | 98 | 99 | 100 | 107 | 108 |
67 | 68 | 69 | 72 | 73 |
70 | {{ shop.name }} 71 |
74 |
78 | 79 | {% if customer.name %} 80 | 81 | 82 | 83 | {% endif %} 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 |

Dear {{ customer.name }},

You have requested to have your password reset for your account at {{ shop.name }}
Please visit this url to reset your password.
Reset Your Password
If you received this email in error, you can safely ignore this email.
97 |
109 |
110 |
114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /dist/customer_password_reset.txt: -------------------------------------------------------------------------------- 1 | {{ shop.name }} ( {{ 2 | shop.url }} ) 3 | 4 | {% if customer.name %} 5 | 6 | ************************* 7 | Dear {{ customer.name }}, 8 | ************************* 9 | 10 | {% endif %} 11 | 12 | You have requested to have your password reset for your 13 | account at {{ shop.name }} 14 | 15 | Please visit this url to reset your password. 16 | 17 | Reset Your Password ( {{ customer.reset_password_url }} ) 18 | 19 | If you received this email in error, you can safely 20 | ignore this email. 21 | 22 | © {{ 'now' | date: "%Y" 23 | }} {{ shop.name }} All Rights Reserved 24 | -------------------------------------------------------------------------------- /dist/fulfillment_request.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Fulfillment Request 7 | 8 | 9 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 164 | 165 | 166 |
63 |
64 | 65 | 66 | 75 | 76 | 77 | 151 | 152 | 153 | 160 | 161 |
67 | 68 | 69 | 72 | 73 |
70 | {{ shop.name }} 71 |
74 |
78 | 79 | 80 | 81 | 82 | 83 | 88 | 89 | 90 | 114 | 115 | {% if shipping_address %} 116 | 117 | 129 | 130 | {% endif %} 131 | 132 | 136 | 137 | 138 | 142 | 143 | 144 | 148 | 149 |

{{ service_name }},

84 |

Please fulfill order {{ name }}.

85 |

Total number of items: {{ fulfillment.item_count }}

86 |

Unique items: {{ fulfillment.fulfillment_line_items.size }}

87 |
91 |

Items to fulfill:

92 | 93 | 94 | 111 | 112 |
95 | 96 | {% for line in fulfillment.fulfillment_line_items %} 97 | 98 | 104 | 107 | 108 | {% endfor %} 109 |
99 | Title: {{ line.line_item.title }}
100 | SKU: {{ line.line_item.sku }}
101 | {% if line.line_item.vendor != blank %} Vendor: {{ line.line_item.vendor }}
{% endif %} 102 | {% if line.line_item.grams != blank %}Grams: {{ line.line_item.grams }} {% endif %} 103 |
105 | x {{ line.quantity }} 106 |
110 |
113 |
118 |

Shipping Address:

119 |
120 |

{{ shipping_address.name }}

121 | {% if shipping_address.company %}

{{ shipping_address.company }}

{% endif %} 122 |

{{ shipping_address.address1 }}

123 |

{{ shipping_address.address2 }}

124 |

{{ shipping_address.city }}, {{ shipping_address.province }}

125 |

{{ shipping_address.zip }}

126 |

{{ shipping_address.country }}

127 | {% if shipping_address.phone %}

Phone: {{ shipping_address.phone }}

{% endif %} 128 |
133 |

Shipping Method:

134 | {% if shipping_method %}{{ shipping_method.title }}{% else %}None{% endif %} 135 |
139 |

Tracking Number:

140 | {% if fulfillment.tracking_number %}{{ fulfillment.tracking_number }}{% else %}None{% endif %} 141 |
145 |

Customer Email:

146 | {{ email }} 147 |
150 |
162 |
163 |
167 | 168 | 169 | 170 | -------------------------------------------------------------------------------- /dist/fulfillment_request.txt: -------------------------------------------------------------------------------- 1 | {{ shop.name }} ( {{ 2 | shop.url }} ) 3 | 4 | ******************* 5 | {{ service_name }}, 6 | ******************* 7 | 8 | Please fulfill order {{ name }}. 9 | 10 | Total number of items: {{ fulfillment.item_count }} 11 | 12 | Unique items: {{ 13 | fulfillment.fulfillment_line_items.size }} 14 | 15 | Items to fulfill: 16 | ----------------- 17 | 18 | {% for line in 19 | fulfillment.fulfillment_line_items %} 20 | 21 | Title: {{ 22 | line.line_item.title }} 23 | SKU: {{ line.line_item.sku }} 24 | {% if line.line_item.vendor 25 | != blank %} Vendor: {{ line.line_item.vendor }} {% endif %} 26 | {% if line.line_item.grams != 27 | blank %}Grams: {{ line.line_item.grams }} {% endif %} 28 | 29 | x {{ line.quantity }} 30 | 31 | {% endfor %} 32 | 33 | {% if shipping_address %} 34 | 35 | Shipping Address: 36 | ----------------- 37 | 38 | {{ shipping_address.name }} 39 | 40 | {% if shipping_address.company %}{{ 41 | shipping_address.company }} 42 | 43 | {% endif %} 44 | {{ shipping_address.address1 }} 45 | 46 | {{ shipping_address.address2 }} 47 | 48 | {{ shipping_address.city }}, {{ 49 | shipping_address.province }} 50 | 51 | {{ shipping_address.zip }} 52 | 53 | {{ shipping_address.country }} 54 | 55 | {% if shipping_address.phone %}Phone: {{ 56 | shipping_address.phone }} 57 | 58 | {% endif %} 59 | 60 | {% endif %} 61 | 62 | Shipping Method: 63 | ---------------- 64 | 65 | {% if shipping_method %}{{ shipping_method.title }}{% 66 | else %}None{% endif %} 67 | 68 | Tracking Number: 69 | ---------------- 70 | 71 | {% if fulfillment.tracking_number %}{{ 72 | fulfillment.tracking_number }}{% else %}None{% endif %} 73 | 74 | Customer Email: 75 | --------------- 76 | 77 | {{ email }} 78 | 79 | © {{ 'now' | date: "%Y" 80 | }} {{ shop.name }} All Rights Reserved 81 | -------------------------------------------------------------------------------- /dist/giftcard_notification.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Gift Card Notification 7 | 8 | 9 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 114 | 115 | 116 |
63 |
64 | 65 | 66 | 75 | 76 | 77 | 101 | 102 | 103 | 110 | 111 |
67 | 68 | 69 | 72 | 73 |
70 | {{ shop.name }} 71 |
74 |
78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | {% if gift_card.initial_value != gift_card.balance %} 86 | 87 | 88 | 89 | {% endif %} 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 |

Hi{% if gift_card.customer %} {{ gift_card.customer.first_name }}{% endif %},

Here is your {{ shop.name }} gift card for {{ gift_card.initial_value | money_without_trailing_zeros }}.

You have {{ gift_card.balance | money_without_trailing_zeros }} left on this gift card.
View or print your gift card
Purchased this gift card for someone else? Feel free to forward them this email.
Thank you for shopping at {{ shop.name }}!
100 |
112 |
113 |
117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /dist/giftcard_notification.txt: -------------------------------------------------------------------------------- 1 | {{ shop.name }} ( {{ 2 | shop.url }} ) 3 | 4 | ***************************************************************** 5 | Hi{% if gift_card.customer %} {{ gift_card.customer.first_name 6 | }}{% endif %}, 7 | ***************************************************************** 8 | 9 | ----------------------------------------------------------------- 10 | Here is your {{ shop.name }} ( {{ shop.url }} ) gift card for {{ 11 | gift_card.initial_value | money_without_trailing_zeros }}. 12 | ----------------------------------------------------------------- 13 | 14 | {% if gift_card.initial_value != gift_card.balance %} 15 | 16 | You have {{ gift_card.balance | 17 | money_without_trailing_zeros }} left on this gift card. 18 | 19 | {% endif %} 20 | 21 | View or print your gift card ( {{ gift_card.url }} ) 22 | 23 | Purchased this gift card for someone else? Feel free to 24 | forward them this email. 25 | 26 | Thank you for shopping at {{ shop.name }} ( {{ shop.url 27 | }} )! 28 | 29 | © {{ 'now' | date: "%Y" 30 | }} {{ shop.name }} All Rights Reserved 31 | -------------------------------------------------------------------------------- /dist/new_order_notification.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | New Order Notification 7 | 8 | 9 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 160 | 161 | 162 |
63 |
64 | 65 | 66 | 75 | 76 | 77 | 147 | 148 | 149 | 156 | 157 |
67 | 68 | 69 | 72 | 73 |
70 | {{ shop.name }} 71 |
74 |
78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 104 | 105 | 106 | 107 | 108 | {% if fulfillment_aborted %} 109 | 110 | 111 | 112 | {% endif %} 113 | {% if has_high_risks? %} 114 | 115 | 119 | 120 | {% endif %} 121 | 122 | 126 | 127 | {% if requires_shipping and shipping_address %} 128 | 129 | 133 | 134 | 135 | 143 | 144 | {% endif %} 145 |

Hello {{ shop_name }},

{% if customer.name %}{{ customer.name }}{% else %}Someone{% endif %} placed a new order with you today, {{ date | date: "%b %d %I:%M%p" }}:
87 | 88 | 89 | 101 | 102 |
90 | 91 | {% for line in line_items %} 92 | 93 | 94 | 95 | 96 | 97 | 98 | {% endfor %} 99 |
{{ line.title }}x {{ line.quantity }}{{ line.price | money }} each
100 |
103 |
View order {{order_name}}
The above order was not automatically fulfilled because it was flagged as suspicious.
116 |

Security check:

117 | This order has a risk of being fraudulent. Review the order in your store's admin and contact the customer to verify their information. 118 |
123 |

Payment processing method:

124 | {{ gateway }} 125 |
130 |

Delivery method:

131 | {% for shipping_method in shipping_methods %}{{ shipping_method.title }}
{% endfor %} 132 |
136 |

Shipping address:

137 |

{{ shipping_address.name }}

138 |

{{ shipping_address.street }}

139 |

{{ shipping_address.city }}, {{ shipping_address.province }} {{ shipping_address.zip }}

140 |

{{ shipping_address.country }}

141 |

{{ shipping_address.phone }}

142 |
146 |
158 |
159 |
163 | 164 | 165 | 166 | -------------------------------------------------------------------------------- /dist/new_order_notification.txt: -------------------------------------------------------------------------------- 1 | {{ shop.name }} ( {{ 2 | shop.url }} ) 3 | 4 | ********************** 5 | Hello {{ shop_name }}, 6 | ********************** 7 | 8 | {% if customer.name %}{{ customer.name }}{% else 9 | %}Someone{% endif %} placed a new order with you today, {{ date | 10 | date: "%b %d %I:%M%p" }}: 11 | 12 | {% for line in line_items %} 13 | 14 | {{ line.title }} 15 | x {{ line.quantity }} 16 | {{ line.price | money }} each 17 | 18 | {% endfor %} 19 | 20 | View order {{order_name}} ( {{ shop.url 21 | }}/admin/orders/{{ id }} ) 22 | 23 | {% if fulfillment_aborted %} 24 | 25 | The above order was not automatically fulfilled 26 | because it was flagged as suspicious. 27 | 28 | {% endif %} 29 | {% if has_high_risks? %} 30 | 31 | Security check: 32 | --------------- 33 | 34 | This order has a risk of being fraudulent. Review the 35 | order in your store's admin and contact the customer to verify 36 | their information. 37 | 38 | {% endif %} 39 | 40 | Payment processing method: 41 | -------------------------- 42 | 43 | {{ gateway }} 44 | 45 | {% if requires_shipping and shipping_address %} 46 | 47 | Delivery method: 48 | ---------------- 49 | 50 | {% for shipping_method in shipping_methods %}{{ 51 | shipping_method.title }}{% endfor %} 52 | 53 | Shipping address: 54 | ----------------- 55 | 56 | {{ shipping_address.name }} 57 | 58 | {{ shipping_address.street }} 59 | 60 | {{ shipping_address.city }}, {{ 61 | shipping_address.province }} {{ shipping_address.zip }} 62 | 63 | {{ shipping_address.country }} 64 | 65 | {{ shipping_address.phone }} 66 | 67 | {% endif %} 68 | 69 | © {{ 'now' | date: "%Y" 70 | }} {{ shop.name }} All Rights Reserved 71 | -------------------------------------------------------------------------------- /dist/order_cancelled.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Customer Account Activation 7 | 8 | 9 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 107 | 108 | 109 |
63 |
64 | 65 | 66 | 75 | 76 | 77 | 94 | 95 | 96 | 103 | 104 |
67 | 68 | 69 | 72 | 73 |
70 | {{ shop.name }} 71 |
74 |
78 | 79 | {% if billing_address.name %} 80 | 81 | 82 | 83 | {% endif %} 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 |

Dear {{ billing_address.name }},

Your order {{ name }} was cancelled {% case cancel_reason %}{% when 'customer' %}at your request.{% when 'inventory' %}because we did not have enough stock to fulfill your order.{% when 'fraud' %}because we suspect it is fraudulent.{% when 'other' %}due to unforseen circumstances.{% endcase %}
{% if financial_status == 'voided' %}Your payment has been voided.{% elsif financial_status == 'credited' %}Your payment has been refunded.{% endif %}
Please reply to this email if you have any questions or concerns.
105 |
106 |
110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /dist/order_cancelled.txt: -------------------------------------------------------------------------------- 1 | {{ shop.name }} ( {{ 2 | shop.url }} ) 3 | 4 | {% if billing_address.name %} 5 | 6 | ******************************** 7 | Dear {{ billing_address.name }}, 8 | ******************************** 9 | 10 | {% endif %} 11 | 12 | Your order {{ name }} was cancelled {% case cancel_reason 13 | %}{% when 'customer' %}at your request.{% when 'inventory' 14 | %}because we did not have enough stock to fulfill your order.{% 15 | when 'fraud' %}because we suspect it is fraudulent.{% when 16 | 'other' %}due to unforseen circumstances.{% endcase %} 17 | 18 | {% if financial_status == 'voided' %}Your payment has 19 | been voided.{% elsif financial_status == 'credited' %}Your 20 | payment has been refunded.{% endif %} 21 | 22 | Please reply to this email if you have any questions or 23 | concerns. 24 | 25 | © {{ 'now' | date: "%Y" 26 | }} {{ shop.name }} All Rights Reserved 27 | -------------------------------------------------------------------------------- /dist/order_confirmation.txt: -------------------------------------------------------------------------------- 1 | {{ shop.name }} ( {{ 2 | shop.url }} ) 3 | 4 | ****************************************************** 5 | Thank you for placing your order with {{ shop_name }}! 6 | ****************************************************** 7 | 8 | This email is to confirm your recent order on {{ date | 9 | date: "%m/%d/%Y" }} 10 | 11 | {% for line in line_items %} 12 | 13 | {{ line.title }} 14 | x {{ line.quantity }} 15 | {{ line.price | money }} each 16 | 17 | {% endfor %} 18 | 19 | {% if discounts %} 20 | 21 | Discounts 22 | {{ discounts_savings 23 | | money_with_currency }} 24 | 25 | {% endif %} 26 | 27 | Subtotal 28 | {{ subtotal_price | 29 | money_with_currency }} 30 | 31 | {% for tax_line in 32 | tax_lines %} 33 | 34 | {{ tax_line.title }} 35 | {{ tax_line.price | 36 | money_with_currency }} 37 | 38 | {% endfor %} 39 | {% if requires_shipping 40 | %} 41 | 42 | Shipping 43 | {{ shipping_price | 44 | money_with_currency }} 45 | 46 | {% endif %} 47 | 48 | Total 49 | {{ total_price | 50 | money_with_currency }} 51 | 52 | {% if requires_shipping and shipping_address %} 53 | 54 | Shipping address 55 | ---------------- 56 | 57 | {{ shipping_address.name }} 58 | {{ shipping_address.street }} 59 | {{ shipping_address.city }} 60 | {{ shipping_address.province }} 61 | {{ shipping_address.zip }} 62 | {{ shipping_address.country }} 63 | 64 | {% endif %} 65 | {% if billing_address %} 66 | 67 | Billing address 68 | --------------- 69 | 70 | {{ billing_address.name }} 71 | {{ billing_address.street }} 72 | {{ billing_address.city }} 73 | {{ billing_address.province }} 74 | {{ billing_address.zip }} 75 | {{ billing_address.country }} 76 | 77 | {% endif %} 78 | 79 | © {{ 'now' | date: "%Y" 80 | }} {{ shop.name }} All Rights Reserved 81 | -------------------------------------------------------------------------------- /dist/refund_notification.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Refund Notification 7 | 8 | 9 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 124 | 125 | 126 |
63 |
64 | 65 | 66 | 75 | 76 | 77 | 111 | 112 | 113 | 120 | 121 |
67 | 68 | 69 | 72 | 73 |
70 | {{ shop.name }} 71 |
74 |
78 | 79 | {% if customer.name %} 80 | 81 | 82 | 83 | {% endif %} 84 | 85 | 86 | 87 | 88 | 104 | 105 | 106 | 107 | 108 |

Dear {{ customer.name }},

{{ shop_name }} has refunded your order ({{ name }}){% if amount > 0 %} a total of {{ amount | money_with_currency }}{% endif %}{% if refund_line_items.size > 0 %} for:{% else %}.{% endif %}
89 | 90 | 91 | 101 | 102 |
92 | 93 | {% for line in refund_line_items %} 94 | 95 | 96 | 97 | 98 | {% endfor %} 99 |
{{ line.line_item.title }}x {{ line.quantity }}
100 |
103 |
The next time you shop at {{ shop.name }}, you can save time at checkout by logging into your account. This will prefill your address information at the checkout.
109 | 110 |
122 |
123 |
127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /dist/refund_notification.txt: -------------------------------------------------------------------------------- 1 | {{ shop.name }} ( {{ 2 | shop.url }} ) 3 | 4 | {% if customer.name %} 5 | 6 | ************************* 7 | Dear {{ customer.name }}, 8 | ************************* 9 | 10 | {% endif %} 11 | 12 | {{ shop_name }} has refunded your order ({{ name }}){% if 13 | amount > 0 %} a total of {{ amount | money_with_currency }}{% 14 | endif %}{% if refund_line_items.size > 0 %} for:{% else %}.{% 15 | endif %} 16 | 17 | {% for line in refund_line_items %} 18 | 19 | {{ line.line_item.title }} 20 | x {{ line.quantity }} 21 | 22 | {% endfor %} 23 | 24 | The next time you shop at {{ shop.name }}, you can save 25 | time at checkout by logging into your account. This will prefill 26 | your address information at the checkout. 27 | 28 | © {{ 'now' | date: "%Y" 29 | }} {{ shop.name }} All Rights Reserved 30 | -------------------------------------------------------------------------------- /dist/shipping_confirmation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Shipping Confirmation 7 | 8 | 9 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 175 | 176 | 177 |
63 |
64 | 65 | 66 | 75 | 76 | 77 | 162 | 163 | 164 | 171 | 172 |
67 | 68 | 69 | 72 | 73 |
70 | {{ shop.name }} 71 |
74 |
78 | 79 | 80 | {% if billing_address.name %} 81 | 82 | {% endif %} 83 | 84 | 85 | 88 | 89 | 90 | 106 | 107 | {% if requires_shipping %} 108 | 109 | 112 | 113 | 114 | 122 | 123 | {% if fulfillment.tracking_numbers.size > 0 %} 124 | {% if fulfillment.tracking_numbers.size == 1 %} 125 | 126 | 127 | 128 | 129 | 130 | 131 | {% else %} 132 | 133 | 137 | 138 | 139 | 143 | 144 | {% endif %} 145 | 146 | 147 | 148 | {% endif %} 149 | 150 | {% endif %} 151 | 152 | {% if fulfillment_status != 'fulfilled' %} 153 | 154 | 155 | 156 | {% endif %} 157 | 158 | 159 | 160 |

Dear {{ billing_address.name }},

86 |

{% if fulfillment.item_count == item_count %}All{% elsif fulfillment_status == 'fulfilled' %}The last{% else %}Some{% endif %} of the items from order {{ name }} have now been shipped:

87 |
91 | 92 | 93 | 103 | 104 |
94 | 95 | {% for line in fulfillment.fulfillment_line_items %} 96 | 97 | 98 | 99 | 100 | {% endfor %} 101 |
{{ line.line_item.title }}x {{ line.quantity }}
102 |
105 |
110 | They are being shipped {% if fulfillment.tracking_company %}via {{ fulfillment.tracking_company }} {% endif %}to the following address: 111 |
115 | {{ shipping_address.name }}
116 | {{ shipping_address.street }}
117 | {{ shipping_address.city }}
118 | {{ shipping_address.province }} 119 | {{ shipping_address.zip }}
120 | {{ shipping_address.country }} 121 |
The tracking number for these items is {{ fulfillment.tracking_numbers.first }}.
Check the status of your shipment
134 |

The tracking details for these items are as follows:

135 |

{% for tracking_number in fulfillment.tracking_numbers %} {{ tracking_number }}
{% endfor %}

136 |
140 |

Click the links below for shipping status on these items:

141 |

{% for tracking_url in fulfillment.tracking_urls %} {{ tracking_url }}
{% endfor %}

142 |
Please allow some time for the status of the shipment to correctly display at the above address.
You will receive a confirmation email when more items from your order have been shipped.
Thank you for ordering from {{ shop_name }}!
161 |
173 |
174 |
178 | 179 | 180 | 181 | -------------------------------------------------------------------------------- /dist/shipping_confirmation.txt: -------------------------------------------------------------------------------- 1 | {{ shop.name }} ( {{ 2 | shop.url }} ) 3 | 4 | {% if billing_address.name %} 5 | 6 | ******************************** 7 | Dear {{ billing_address.name }}, 8 | ******************************** 9 | 10 | {% endif %} 11 | 12 | ----------------------------------------------------------------- 13 | {% if fulfillment.item_count == item_count %}All{% elsif 14 | fulfillment_status == 'fulfilled' %}The last{% else %}Some{% 15 | endif %} of the items from order {{ name }} have now been 16 | shipped: 17 | ----------------------------------------------------------------- 18 | 19 | {% for line in 20 | fulfillment.fulfillment_line_items %} 21 | 22 | {{ line.line_item.title }} 23 | x {{ line.quantity }} 24 | 25 | {% endfor %} 26 | 27 | {% if requires_shipping %} 28 | 29 | They are being shipped {% if 30 | fulfillment.tracking_company %}via {{ 31 | fulfillment.tracking_company }} {% endif %}to the following 32 | address: 33 | 34 | {{ shipping_address.name }} 35 | {{ shipping_address.street }} 36 | {{ shipping_address.city }} 37 | {{ shipping_address.province }} 38 | {{ shipping_address.zip }} 39 | {{ shipping_address.country }} 40 | 41 | {% if fulfillment.tracking_numbers.size > 0 %} 42 | {% if fulfillment.tracking_numbers.size == 1 %} 43 | 44 | The tracking number for these items is {{ 45 | fulfillment.tracking_numbers.first }}. 46 | 47 | Check the status of your shipment ( {{ 48 | fulfillment.tracking_urls.first }} ) 49 | 50 | {% else %} 51 | 52 | The tracking details for these items are as 53 | follows: 54 | 55 | {% for tracking_number in 56 | fulfillment.tracking_numbers %} {{ tracking_number }}{% endfor %} 57 | 58 | Click the links below for shipping status on 59 | these items: 60 | 61 | {% for tracking_url in 62 | fulfillment.tracking_urls %} {{ tracking_url }} ( {{ tracking_url 63 | }} ){% endfor %} 64 | 65 | {% endif %} 66 | 67 | Please allow some time for the status of the 68 | shipment to correctly display at the above address. 69 | 70 | {% endif %} 71 | 72 | {% endif %} 73 | 74 | {% if fulfillment_status != 'fulfilled' %} 75 | 76 | You will receive a confirmation email when more items 77 | from your order have been shipped. 78 | 79 | {% endif %} 80 | 81 | Thank you for ordering from {{ shop_name }}! 82 | 83 | © {{ 'now' | date: "%Y" 84 | }} {{ shop.name }} All Rights Reserved 85 | -------------------------------------------------------------------------------- /dist/shipping_update.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Shipping Update 7 | 8 | 9 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 131 | 132 | 133 |
63 |
64 | 65 | 66 | 75 | 76 | 77 | 118 | 119 | 120 | 127 | 128 |
67 | 68 | 69 | 72 | 73 |
70 | {{ shop.name }} 71 |
74 |
78 | 79 | 80 | {% if billing_address.name %} 81 | 82 | {% endif %} 83 | 84 | 85 | 88 | 89 | 90 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 |

Dear {{ billing_address.name }},

86 |

The following shipped items from order {{ name }} have been updated with new shipping information:

87 |
91 | 92 | 93 | 103 | 104 |
94 | 95 | {% for line in fulfillment.fulfillment_line_items %} 96 | 97 | 98 | 99 | 100 | {% endfor %} 101 |
{{ line.line_item.title }}x {{ line.quantity }}
102 |
105 |
They are being shipped{% if fulfillment.tracking_company %} via {{ fulfillment.tracking_company }}{% endif %} with tracking number {{ fulfillment.tracking_number }}.
Check the status of this shipment
Please allow some time for the status of the shipment to correctly display at the above address.
117 |
129 |
130 |
134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /dist/shipping_update.txt: -------------------------------------------------------------------------------- 1 | {{ shop.name }} ( {{ 2 | shop.url }} ) 3 | 4 | {% if billing_address.name %} 5 | 6 | ******************************** 7 | Dear {{ billing_address.name }}, 8 | ******************************** 9 | 10 | {% endif %} 11 | 12 | ----------------------------------------------------------------- 13 | The following shipped items from order {{ name }} have been 14 | updated with new shipping information: 15 | ----------------------------------------------------------------- 16 | 17 | {% for line in 18 | fulfillment.fulfillment_line_items %} 19 | 20 | {{ line.line_item.title }} 21 | x {{ line.quantity }} 22 | 23 | {% endfor %} 24 | 25 | They are being shipped{% if fulfillment.tracking_company 26 | %} via {{ fulfillment.tracking_company }}{% endif %} with 27 | tracking number {{ fulfillment.tracking_number }}. 28 | 29 | Check the status of this shipment ( {{ 30 | fulfillment.tracking_url }} ) 31 | 32 | Please allow some time for the status of the shipment to 33 | correctly display at the above address. 34 | 35 | © {{ 'now' | date: "%Y" 36 | }} {{ shop.name }} All Rights Reserved 37 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "email-template", 3 | "version": "0.1.0", 4 | "devDependencies": { 5 | "assemble": "0.4.37", 6 | "grunt": "~0.4.4", 7 | "grunt-cdn": "^0.5.2", 8 | "grunt-cloudfiles": "^0.3.0", 9 | "grunt-contrib-sass": "^0.7.3", 10 | "grunt-contrib-watch": "^0.6.1", 11 | "grunt-mailgun": "0.0.3", 12 | "grunt-premailer": "0.2.5" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/css/main.css: -------------------------------------------------------------------------------- 1 | @import url(http://fonts.googleapis.com/css?family=Noto+Serif:700|Ubuntu); 2 | /* ------------------------------------- 3 | CONFIGURE YOUR VARIABLES 4 | ------------------------------------- */ 5 | /* ------------------------------------- 6 | GLOBAL 7 | ------------------------------------- */ 8 | * { 9 | margin: 0; 10 | padding: 0; 11 | font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif; 12 | box-sizing: border-box; 13 | font-size: 16px; 14 | } 15 | 16 | img { 17 | max-width: 100%; 18 | } 19 | 20 | body { 21 | -webkit-font-smoothing: antialiased; 22 | -webkit-text-size-adjust: none; 23 | width: 100% !important; 24 | height: 100%; 25 | line-height: 1.6; 26 | } 27 | 28 | /* Let's make sure all tables have defaults */ 29 | table { 30 | -premailer-cellspacing: 0; 31 | -premailer-cellpadding: 0; 32 | -premailer-width: 100%; 33 | } 34 | table td { 35 | vertical-align: top; 36 | } 37 | 38 | /* ------------------------------------- 39 | BODY, CONTAINER & MAIN 40 | ------------------------------------- */ 41 | body { 42 | background-color: #f6f6f6; 43 | } 44 | 45 | .body { 46 | background-color: #f6f6f6; 47 | width: 100%; 48 | } 49 | 50 | /* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink down on a phone or something */ 51 | .container { 52 | display: block !important; 53 | margin: 0 auto !important; 54 | /* makes it centered */ 55 | max-width: 600px; 56 | width: auto; 57 | clear: both !important; 58 | } 59 | 60 | /* This should also be a block element, so that it will fill 100% of the .container */ 61 | .content { 62 | max-width: 600px; 63 | margin: 0 auto; 64 | display: block; 65 | padding: 10px; 66 | } 67 | 68 | /* moved main into the layout section since we want to have the header and footer outside of the body area for styling */ 69 | .main { 70 | width: 100%; 71 | margin: 0 auto; 72 | } 73 | 74 | /* ------------------------------------- 75 | HEADER, FOOTER 76 | ------------------------------------- */ 77 | .header-wrap { 78 | padding: 0; 79 | background-color: #53545b; 80 | } 81 | 82 | .logo-link { 83 | text-align: center; 84 | } 85 | .logo-link img { 86 | display: block; 87 | margin: 0 auto; 88 | } 89 | 90 | .content-wrap { 91 | padding: 30px; 92 | background: #fff; 93 | border: 1px solid #e9e9e9; 94 | border-radius: 0; 95 | } 96 | 97 | .content-block { 98 | padding: 0 0 30px; 99 | } 100 | 101 | .social-wrap { 102 | text-align: right; 103 | padding-right: 30px; 104 | } 105 | 106 | .footer-wrap { 107 | padding: 20px 0; 108 | text-transform: uppercase; 109 | } 110 | 111 | .footer { 112 | width: 100%; 113 | clear: both; 114 | } 115 | .footer * { 116 | color: #999; 117 | font-size: 12px; 118 | } 119 | .footer td { 120 | padding: 20px 0; 121 | } 122 | 123 | /* ------------------------------------- 124 | INVOICE 125 | Styles for the billing table 126 | ------------------------------------- */ 127 | .invoice { 128 | margin: 20px auto; 129 | text-align: left; 130 | width: 80%; 131 | } 132 | 133 | .invoice td { 134 | padding: 5px 0; 135 | } 136 | 137 | .invoice .invoice-items { 138 | width: 100%; 139 | border-top: #eee 1px solid; 140 | } 141 | 142 | .invoice .invoice-items td { 143 | border-bottom: #eee 1px solid; 144 | } 145 | 146 | .invoice .invoice-items .total td { 147 | border: none; 148 | } 149 | 150 | .invoice .invoice-items .total > td { 151 | border-top: 2px solid #333; 152 | border-bottom: 2px solid #333; 153 | font-weight: 700; 154 | } 155 | 156 | /* ------------------------------------- 157 | FULLFILLMENT 158 | Styles for the fullfillment table 159 | ------------------------------------- */ 160 | .fullfillment { 161 | width: 100%; 162 | margin: 20px auto; 163 | } 164 | 165 | /* ------------------------------------- 166 | ALERTS 167 | Change the class depending on 168 | warning, good or bad email 169 | ------------------------------------- */ 170 | .alert { 171 | font-size: 16px; 172 | color: #fff; 173 | font-weight: 500; 174 | padding: 20px; 175 | text-align: center; 176 | border-radius: 3px 3px 0 0; 177 | } 178 | 179 | .alert a { 180 | color: #fff; 181 | text-decoration: none; 182 | font-weight: 500; 183 | font-size: 16px; 184 | } 185 | 186 | .alert.alert-warning { 187 | background-color: #FF9F00; 188 | } 189 | 190 | .alert.alert-bad { 191 | background-color: #D0021B; 192 | } 193 | 194 | .alert.alert-good { 195 | background-color: #68B90F; 196 | } 197 | 198 | /* ------------------------------------- 199 | TYPOGRAPHY 200 | ------------------------------------- */ 201 | h1, h2, h3 { 202 | font-family: Arial,Helvetica Neue,Helvetica,sans-serif; 203 | color: #ea662a; 204 | margin: 0; 205 | line-height: 1.4; 206 | font-weight: 700; 207 | } 208 | h1 a, h2 a, h3 a { 209 | font-size: inherit; 210 | font-family: Arial,Helvetica Neue,Helvetica,sans-serif; 211 | } 212 | 213 | h1 { 214 | font-size: 28px; 215 | font-weight: 600; 216 | } 217 | 218 | h2 { 219 | font-size: 24px; 220 | } 221 | 222 | h3 { 223 | font-size: 18px; 224 | } 225 | 226 | h4 { 227 | font-size: 14px; 228 | font-weight: 500; 229 | } 230 | 231 | p, ul, ol { 232 | margin: 0; 233 | font-weight: normal; 234 | } 235 | p li, ul li, ol li { 236 | margin-left: 5px; 237 | list-style-position: inside; 238 | } 239 | 240 | .copyright { 241 | font-size: 11px; 242 | color: #677a90; 243 | line-height: 20px; 244 | } 245 | 246 | /* ------------------------------------- 247 | LINKS & BUTTONS 248 | ------------------------------------- */ 249 | a { 250 | color: #28825f; 251 | text-decoration: underline; 252 | } 253 | a:hover { 254 | color: #103426; 255 | border-color: #103426; 256 | } 257 | 258 | .btn-primary { 259 | text-decoration: none; 260 | color: #28825f; 261 | border: 2px solid #28825f; 262 | line-height: 2; 263 | font-weight: bold; 264 | margin: 0; 265 | text-align: center; 266 | cursor: pointer; 267 | display: inline-block; 268 | padding: 14px 28px; 269 | text-transform: uppercase; 270 | } 271 | .btn-primary:hover { 272 | color: #103426; 273 | border-color: #103426; 274 | } 275 | 276 | .social-icon { 277 | margin: 0 15px; 278 | } 279 | 280 | .social-icon--last { 281 | margin-right: 0; 282 | } 283 | 284 | .social-icon img { 285 | height: 20px; 286 | width: 20px; 287 | } 288 | 289 | /* ------------------------------------- 290 | OTHER STYLES THAT MIGHT BE USEFUL 291 | ------------------------------------- */ 292 | .last { 293 | margin-bottom: 0; 294 | } 295 | 296 | .first { 297 | margin-top: 0; 298 | } 299 | 300 | .aligncenter { 301 | text-align: center; 302 | } 303 | 304 | .alignright { 305 | text-align: right; 306 | } 307 | 308 | .clear { 309 | clear: both; 310 | } 311 | 312 | .preheader { 313 | display: none !important; 314 | width: 0 !important; 315 | height: 0 !important; 316 | max-width: 0 !important; 317 | max-height: 0 !important; 318 | overflow: hidden !important; 319 | mso-hide: all; 320 | } 321 | 322 | /* ------------------------------------- 323 | RESPONSIVE AND MOBILE FRIENDLY STYLES 324 | ------------------------------------- */ 325 | @media only screen and (max-width: 640px) { 326 | h1, h2, h3, h4 { 327 | font-weight: 600 !important; 328 | } 329 | 330 | h1 { 331 | font-size: 22px !important; 332 | } 333 | 334 | h2 { 335 | font-size: 18px !important; 336 | } 337 | 338 | h3 { 339 | font-size: 16px !important; 340 | } 341 | 342 | .content { 343 | padding: 0 !important; 344 | } 345 | 346 | .content-wrap { 347 | padding: 20px 10px !important; 348 | } 349 | } 350 | -------------------------------------------------------------------------------- /src/css/scss/_config.scss: -------------------------------------------------------------------------------- 1 | /* ------------------------------------- 2 | CONFIGURE YOUR VARIABLES 3 | ------------------------------------- */ 4 | 5 | $padding: 30px; // For consistent padding 6 | $paddingSmall: 20px; 7 | $grey: #f6f6f6; // Background color 8 | $width: 600px; // Width of the content area 9 | $br: 0; // Border radius 10 | 11 | $primary-color: #EA662A; // Primary color for Headers 12 | $secondary-color: #28825f; // Secondary color for buttons and links 13 | 14 | $header-bg-color: #53545B; 15 | -------------------------------------------------------------------------------- /src/css/scss/_global.scss: -------------------------------------------------------------------------------- 1 | /* ------------------------------------- 2 | GLOBAL 3 | ------------------------------------- */ 4 | * { 5 | margin: 0; 6 | padding: 0; 7 | font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif; 8 | box-sizing: border-box; 9 | font-size: 16px; 10 | } 11 | 12 | img { 13 | max-width: 100%; 14 | } 15 | 16 | body { 17 | -webkit-font-smoothing: antialiased; 18 | -webkit-text-size-adjust: none; 19 | width: 100% !important; 20 | height: 100%; 21 | line-height: 1.6; 22 | } 23 | 24 | /* Let's make sure all tables have defaults */ 25 | table { 26 | -premailer-cellspacing: 0; // This is a specific style for the premailer gem 27 | -premailer-cellpadding: 0; // This is a specific style for the premailer gem 28 | -premailer-width: 100%; 29 | td{ 30 | vertical-align: top; 31 | } 32 | } -------------------------------------------------------------------------------- /src/css/scss/_layout.scss: -------------------------------------------------------------------------------- 1 | /* ------------------------------------- 2 | BODY, CONTAINER & MAIN 3 | ------------------------------------- */ 4 | body{ 5 | background-color: $grey; 6 | } 7 | 8 | .body { 9 | background-color: $grey; 10 | width: 100%; 11 | } 12 | 13 | /* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink down on a phone or something */ 14 | .container { 15 | display: block !important; 16 | margin: 0 auto !important; /* makes it centered */ 17 | max-width: $width; 18 | width: auto; 19 | clear: both !important; 20 | } 21 | 22 | /* This should also be a block element, so that it will fill 100% of the .container */ 23 | .content { 24 | max-width: $width; 25 | margin: 0 auto; 26 | display: block; 27 | padding: 10px; 28 | } 29 | 30 | /* moved main into the layout section since we want to have the header and footer outside of the body area for styling */ 31 | .main { 32 | width:100%; 33 | margin: 0 auto; 34 | } 35 | 36 | 37 | 38 | /* ------------------------------------- 39 | HEADER, FOOTER 40 | ------------------------------------- */ 41 | 42 | 43 | 44 | .header-wrap { 45 | padding:0; 46 | background-color:$header-bg-color; 47 | } 48 | 49 | .logo-link { 50 | text-align:center; 51 | 52 | img { 53 | display:block; 54 | margin:0 auto; 55 | } 56 | } 57 | 58 | .content-wrap { 59 | padding:$padding; 60 | background:#fff; 61 | border: 1px solid darken($grey,5); 62 | border-radius:$br; 63 | } 64 | 65 | // Adds padding to content - use this instead of paragraphs for consistent padding/margin rendering 66 | .content-block{ 67 | padding:0 0 $padding; 68 | } 69 | 70 | .social-wrap { 71 | text-align:right; 72 | padding-right:$padding; 73 | } 74 | 75 | .footer-wrap { 76 | padding:$paddingSmall 0; 77 | text-transform:uppercase; 78 | } 79 | 80 | .footer { 81 | width: 100%; 82 | clear: both; 83 | *{ 84 | color: #999; 85 | font-size:12px; 86 | } 87 | td{ 88 | padding:20px 0; 89 | } 90 | } 91 | 92 | 93 | 94 | 95 | 96 | /* ------------------------------------- 97 | INVOICE 98 | Styles for the billing table 99 | ------------------------------------- */ 100 | 101 | .invoice { 102 | margin: 20px auto; 103 | text-align: left; 104 | width: 80%; 105 | } 106 | .invoice td { 107 | padding: 5px 0; 108 | } 109 | .invoice .invoice-items { 110 | width: 100%; 111 | border-top: #eee 1px solid; 112 | } 113 | .invoice .invoice-items td { 114 | border-bottom: #eee 1px solid; 115 | } 116 | .invoice .invoice-items .total td { 117 | border:none; 118 | } 119 | .invoice .invoice-items .total > td { 120 | border-top: 2px solid #333; 121 | border-bottom: 2px solid #333; 122 | font-weight: 700; 123 | } 124 | 125 | 126 | 127 | /* ------------------------------------- 128 | FULLFILLMENT 129 | Styles for the fullfillment table 130 | ------------------------------------- */ 131 | 132 | .fullfillment { 133 | width:100%; 134 | margin:20px auto; 135 | } 136 | 137 | 138 | 139 | 140 | 141 | /* ------------------------------------- 142 | ALERTS 143 | Change the class depending on 144 | warning, good or bad email 145 | ------------------------------------- */ 146 | 147 | .alert { 148 | font-size: 16px; 149 | color: #fff; 150 | font-weight: 500; 151 | padding: 20px; 152 | text-align: center; 153 | border-radius: 3px 3px 0 0; 154 | } 155 | .alert a { 156 | color: #fff; 157 | text-decoration: none; 158 | font-weight: 500; 159 | font-size: 16px; 160 | } 161 | .alert.alert-warning { 162 | background-color: #FF9F00; 163 | } 164 | .alert.alert-bad { 165 | background-color: #D0021B; 166 | } 167 | .alert.alert-good { 168 | background-color: #68B90F; 169 | } -------------------------------------------------------------------------------- /src/css/scss/_links.scss: -------------------------------------------------------------------------------- 1 | /* ------------------------------------- 2 | LINKS & BUTTONS 3 | ------------------------------------- */ 4 | a { 5 | color: $secondary-color; 6 | text-decoration: underline; 7 | 8 | &:hover { 9 | color:darken($secondary-color,20%); 10 | border-color:darken($secondary-color,20%); 11 | } 12 | } 13 | 14 | .btn-primary { 15 | text-decoration: none; 16 | color: $secondary-color; 17 | border:2px solid $secondary-color; 18 | line-height: 2; 19 | font-weight: bold; 20 | margin: 0; 21 | text-align: center; 22 | cursor: pointer; 23 | display: inline-block; 24 | padding:14px 28px; 25 | text-transform: uppercase; 26 | 27 | &:hover { 28 | color:darken($secondary-color,20%); 29 | border-color:darken($secondary-color,20%); 30 | } 31 | } 32 | 33 | .social-icon { 34 | margin:0 15px; 35 | } 36 | 37 | .social-icon--last { 38 | margin-right:0; 39 | } 40 | 41 | .social-icon img { 42 | height:20px; 43 | width:20px; 44 | } -------------------------------------------------------------------------------- /src/css/scss/_other.scss: -------------------------------------------------------------------------------- 1 | /* ------------------------------------- 2 | OTHER STYLES THAT MIGHT BE USEFUL 3 | ------------------------------------- */ 4 | .last { 5 | margin-bottom: 0; 6 | } 7 | 8 | .first { 9 | margin-top: 0; 10 | } 11 | 12 | .aligncenter{ 13 | text-align:center; 14 | } 15 | 16 | .alignright{ 17 | text-align:right; 18 | } 19 | 20 | .clear{ 21 | clear:both; 22 | } 23 | 24 | // Preheader text is displayed in certain clients as a preview but not shown when the user opens the email 25 | .preheader{ 26 | display:none !important; 27 | width: 0 !important; 28 | height: 0 !important; 29 | max-width: 0 !important; 30 | max-height: 0 !important; 31 | overflow: hidden !important; 32 | mso-hide: all; 33 | } -------------------------------------------------------------------------------- /src/css/scss/_responsive.scss: -------------------------------------------------------------------------------- 1 | /* ------------------------------------- 2 | RESPONSIVE AND MOBILE FRIENDLY STYLES 3 | ------------------------------------- */ 4 | @media only screen and (max-width: $width+40) { 5 | 6 | // Type 7 | h1,h2,h3,h4{ 8 | font-weight:600 !important; 9 | } 10 | h1{ 11 | font-size:22px !important; 12 | } 13 | h2{ 14 | font-size:18px !important; 15 | } 16 | h3{ 17 | font-size:16px !important; 18 | } 19 | 20 | .content { 21 | padding:0 !important; 22 | } 23 | 24 | // Spacing 25 | .content-wrap{ 26 | padding:20px 10px !important; 27 | } 28 | 29 | } -------------------------------------------------------------------------------- /src/css/scss/_type.scss: -------------------------------------------------------------------------------- 1 | /* ------------------------------------- 2 | TYPOGRAPHY 3 | ------------------------------------- */ 4 | h1, h2, h3 { 5 | font-family: Arial,Helvetica Neue,Helvetica,sans-serif; 6 | color: $primary-color; 7 | margin: 0; 8 | line-height: 1.4; 9 | font-weight: 700; 10 | 11 | a { 12 | font-size:inherit; 13 | font-family: Arial,Helvetica Neue,Helvetica,sans-serif; 14 | } 15 | } 16 | 17 | h1 { 18 | font-size: 28px; 19 | font-weight: 600; 20 | } 21 | 22 | h2 { 23 | font-size: 24px; 24 | } 25 | 26 | h3 { 27 | font-size: 18px; 28 | } 29 | 30 | h4{ 31 | font-size: 14px; 32 | font-weight:500; 33 | } 34 | 35 | p, ul, ol { 36 | margin: 0; 37 | font-weight: normal; 38 | 39 | li{ 40 | margin-left: 5px; 41 | list-style-position: inside; 42 | } 43 | } 44 | 45 | .copyright { 46 | font-size:11px; 47 | color:#677a90; 48 | line-height:20px; 49 | } -------------------------------------------------------------------------------- /src/css/scss/main.scss: -------------------------------------------------------------------------------- 1 | @import url(http://fonts.googleapis.com/css?family=Noto+Serif:700|Ubuntu); 2 | 3 | // Main scss styles 4 | @import 'config'; 5 | @import 'global'; 6 | @import 'layout'; 7 | @import 'type'; 8 | @import 'links'; 9 | @import 'other'; 10 | @import 'responsive'; -------------------------------------------------------------------------------- /src/emails/abandoned_checkout_notification.hbs: -------------------------------------------------------------------------------- 1 | --- 2 | layout: branded.hbs 3 | subject: Complete Your Purchase 4 | --- 5 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
8 |

Hey{% if billing_address.name %} \{{ billing_address.name }}{% endif %},

9 |

Your shopping cart at \{{ shop_name }} has been reserved and is waiting for your return!

In your cart, you left:
19 | 20 | 21 | 31 | 32 |
22 | 23 | {% for line in line_items %} 24 | 25 | 26 | 27 | 28 | {% endfor %} 29 |
\{{ line.title }}x \{{ line.quantity }}
30 |
33 |
But it's not too late! To complete your purchase, click this link:
Complete Your Purchase
Thanks for shopping!
45 | -------------------------------------------------------------------------------- /src/emails/customer_account_activation.hbs: -------------------------------------------------------------------------------- 1 | --- 2 | layout: branded.hbs 3 | subject: Customer Account Activation 4 | --- 5 | 6 | {% if customer.name %} 7 | 8 | 9 | 10 | {% endif %} 11 | 12 | 13 | 14 | 15 | 16 | 17 |

Dear \{{ customer.name }},

This is to confirm that your account for the shop \{{ shop.name }} is now active.

The next time you shop at \{{ shop.name }}, you can save time at checkout by logging into your account. This will prefill your address information at the checkout.
18 | -------------------------------------------------------------------------------- /src/emails/customer_account_welcome.hbs: -------------------------------------------------------------------------------- 1 | --- 2 | layout: branded.hbs 3 | subject: Customer Account Welcome 4 | --- 5 | 6 | {% if customer.name %} 7 | 8 | 9 | 10 | {% endif %} 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |

Dear \{{ customer.name }},

An account has been created for you at \{{ shop.name }}.

Please visit this url to activate your account and set your password.
Active Your Account
If the account was created in error, you can visit the link above and select "Decline" to decline this invitation.
24 | -------------------------------------------------------------------------------- /src/emails/customer_password_reset.hbs: -------------------------------------------------------------------------------- 1 | --- 2 | layout: branded.hbs 3 | subject: Customer Account Password Reset 4 | --- 5 | 6 | {% if customer.name %} 7 | 8 | 9 | 10 | {% endif %} 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |

Dear \{{ customer.name }},

You have requested to have your password reset for your account at \{{ shop.name }}
Please visit this url to reset your password.
Reset Your Password
If you received this email in error, you can safely ignore this email.
24 | -------------------------------------------------------------------------------- /src/emails/fulfillment_request.hbs: -------------------------------------------------------------------------------- 1 | --- 2 | layout: branded.hbs 3 | subject: Fulfillment Request 4 | --- 5 | 6 | 7 | 8 | 9 | 10 | 15 | 16 | 17 | 41 | 42 | {% if shipping_address %} 43 | 44 | 56 | 57 | {% endif %} 58 | 59 | 63 | 64 | 65 | 69 | 70 | 71 | 75 | 76 |

\{{ service_name }},

11 |

Please fulfill order \{{ name }}.

12 |

Total number of items: \{{ fulfillment.item_count }}

13 |

Unique items: \{{ fulfillment.fulfillment_line_items.size }}

14 |
18 |

Items to fulfill:

19 | 20 | 21 | 38 | 39 |
22 | 23 | {% for line in fulfillment.fulfillment_line_items %} 24 | 25 | 31 | 34 | 35 | {% endfor %} 36 |
26 | Title: \{{ line.line_item.title }}
27 | SKU: \{{ line.line_item.sku }}
28 | {% if line.line_item.vendor != blank %} Vendor: \{{ line.line_item.vendor }}
{% endif %} 29 | {% if line.line_item.grams != blank %}Grams: \{{ line.line_item.grams }} {% endif %} 30 |
32 | x \{{ line.quantity }} 33 |
37 |
40 |
45 |

Shipping Address:

46 |
47 |

\{{ shipping_address.name }}

48 | {% if shipping_address.company %}

\{{ shipping_address.company }}

{% endif %} 49 |

\{{ shipping_address.address1 }}

50 |

\{{ shipping_address.address2 }}

51 |

\{{ shipping_address.city }}, \{{ shipping_address.province }}

52 |

\{{ shipping_address.zip }}

53 |

\{{ shipping_address.country }}

54 | {% if shipping_address.phone %}

Phone: \{{ shipping_address.phone }}

{% endif %} 55 |
60 |

Shipping Method:

61 | {% if shipping_method %}\{{ shipping_method.title }}{% else %}None{% endif %} 62 |
66 |

Tracking Number:

67 | {% if fulfillment.tracking_number %}\{{ fulfillment.tracking_number }}{% else %}None{% endif %} 68 |
72 |

Customer Email:

73 | \{{ email }} 74 |
77 | -------------------------------------------------------------------------------- /src/emails/giftcard_notification.hbs: -------------------------------------------------------------------------------- 1 | --- 2 | layout: branded.hbs 3 | subject: Gift Card Notification 4 | --- 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | {% if gift_card.initial_value != gift_card.balance %} 13 | 14 | 15 | 16 | {% endif %} 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |

Hi{% if gift_card.customer %} \{{ gift_card.customer.first_name }}{% endif %},

Here is your \{{ shop.name }} gift card for \{{ gift_card.initial_value | money_without_trailing_zeros }}.

You have \{{ gift_card.balance | money_without_trailing_zeros }} left on this gift card.
View or print your gift card
Purchased this gift card for someone else? Feel free to forward them this email.
Thank you for shopping at \{{ shop.name }}!
27 | -------------------------------------------------------------------------------- /src/emails/new_order_notification.hbs: -------------------------------------------------------------------------------- 1 | --- 2 | layout: branded.hbs 3 | subject: New Order Notification 4 | --- 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 31 | 32 | 33 | 34 | 35 | {% if fulfillment_aborted %} 36 | 37 | 38 | 39 | {% endif %} 40 | {% if has_high_risks? %} 41 | 42 | 46 | 47 | {% endif %} 48 | 49 | 53 | 54 | {% if requires_shipping and shipping_address %} 55 | 56 | 60 | 61 | 62 | 70 | 71 | {% endif %} 72 |

Hello \{{ shop_name }},

{% if customer.name %}\{{ customer.name }}{% else %}Someone{% endif %} placed a new order with you today, \{{ date | date: "%b %d %I:%M%p" }}:
14 | 15 | 16 | 28 | 29 |
17 | 18 | {% for line in line_items %} 19 | 20 | 21 | 22 | 23 | 24 | 25 | {% endfor %} 26 |
\{{ line.title }}x \{{ line.quantity }}\{{ line.price | money }} each
27 |
30 |
View order \{{order_name}}
The above order was not automatically fulfilled because it was flagged as suspicious.
43 |

Security check:

44 | This order has a risk of being fraudulent. Review the order in your store's admin and contact the customer to verify their information. 45 |
50 |

Payment processing method:

51 | \{{ gateway }} 52 |
57 |

Delivery method:

58 | {% for shipping_method in shipping_methods %}\{{ shipping_method.title }}
{% endfor %} 59 |
63 |

Shipping address:

64 |

\{{ shipping_address.name }}

65 |

\{{ shipping_address.street }}

66 |

\{{ shipping_address.city }}, \{{ shipping_address.province }} \{{ shipping_address.zip }}

67 |

\{{ shipping_address.country }}

68 |

\{{ shipping_address.phone }}

69 |
73 | -------------------------------------------------------------------------------- /src/emails/order_cancelled.hbs: -------------------------------------------------------------------------------- 1 | --- 2 | layout: branded.hbs 3 | subject: Customer Account Activation 4 | --- 5 | 6 | {% if billing_address.name %} 7 | 8 | 9 | 10 | {% endif %} 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |

Dear \{{ billing_address.name }},

Your order \{{ name }} was cancelled {% case cancel_reason %}{% when 'customer' %}at your request.{% when 'inventory' %}because we did not have enough stock to fulfill your order.{% when 'fraud' %}because we suspect it is fraudulent.{% when 'other' %}due to unforseen circumstances.{% endcase %}
{% if financial_status == 'voided' %}Your payment has been voided.{% elsif financial_status == 'credited' %}Your payment has been refunded.{% endif %}
Please reply to this email if you have any questions or concerns.
-------------------------------------------------------------------------------- /src/emails/order_confirmation.hbs: -------------------------------------------------------------------------------- 1 | --- 2 | layout: branded.hbs 3 | subject: Order Confirmation 4 | --- 5 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 70 | 71 | 72 | 100 | 101 |
8 |

Thank you for placing your order with \{{ shop_name }}!

9 |
This email is to confirm your recent order on \{{ date | date: "%m/%d/%Y" }}
16 | 17 | 18 | 29 | 30 | 31 | 67 | 68 |
19 | 20 | {% for line in line_items %} 21 | 22 | 23 | 24 | 25 | 26 | {% endfor %} 27 |
\{{ line.title }}x \{{ line.quantity }}\{{ line.price | money }} each
28 |
32 | 33 | 34 | 64 | 65 |
35 | 36 | {% if discounts %} 37 | 38 | 39 | 40 | 41 | {% endif %} 42 | 43 | 44 | 45 | 46 | {% for tax_line in tax_lines %} 47 | 48 | 49 | 50 | 51 | {% endfor %} 52 | {% if requires_shipping %} 53 | 54 | 55 | 56 | 57 | {% endif %} 58 | 59 | 60 | 61 | 62 |
Discounts\{{ discounts_savings | money_with_currency }}
Subtotal\{{ subtotal_price | money_with_currency }}
\{{ tax_line.title }}\{{ tax_line.price | money_with_currency }}
Shipping\{{ shipping_price | money_with_currency }}
Total\{{ total_price | money_with_currency }}
63 |
66 |
69 |
73 | 74 | 75 | {% if requires_shipping and shipping_address %} 76 | 85 | {% endif %} 86 | {% if billing_address %} 87 | 96 | {% endif %} 97 | 98 |
77 |

Shipping address

78 | \{{ shipping_address.name }}
79 | \{{ shipping_address.street }}
80 | \{{ shipping_address.city }}
81 | \{{ shipping_address.province }} 82 | \{{ shipping_address.zip }}
83 | \{{ shipping_address.country }} 84 |
88 |

Billing address

89 | \{{ billing_address.name }}
90 | \{{ billing_address.street }}
91 | \{{ billing_address.city }}
92 | \{{ billing_address.province }} 93 | \{{ billing_address.zip }}
94 | \{{ billing_address.country }} 95 |
99 |
102 | -------------------------------------------------------------------------------- /src/emails/refund_notification.hbs: -------------------------------------------------------------------------------- 1 | --- 2 | layout: branded.hbs 3 | subject: Refund Notification 4 | --- 5 | 6 | {% if customer.name %} 7 | 8 | 9 | 10 | {% endif %} 11 | 12 | 13 | 14 | 15 | 31 | 32 | 33 | 34 | 35 |

Dear \{{ customer.name }},

\{{ shop_name }} has refunded your order (\{{ name }}){% if amount > 0 %} a total of \{{ amount | money_with_currency }}{% endif %}{% if refund_line_items.size > 0 %} for:{% else %}.{% endif %}
16 | 17 | 18 | 28 | 29 |
19 | 20 | {% for line in refund_line_items %} 21 | 22 | 23 | 24 | 25 | {% endfor %} 26 |
\{{ line.line_item.title }}x \{{ line.quantity }}
27 |
30 |
The next time you shop at \{{ shop.name }}, you can save time at checkout by logging into your account. This will prefill your address information at the checkout.
36 | 37 | -------------------------------------------------------------------------------- /src/emails/shipping_confirmation.hbs: -------------------------------------------------------------------------------- 1 | --- 2 | layout: branded.hbs 3 | subject: Shipping Confirmation 4 | --- 5 | 6 | 7 | {% if billing_address.name %} 8 | 9 | {% endif %} 10 | 11 | 12 | 15 | 16 | 17 | 33 | 34 | {% if requires_shipping %} 35 | 36 | 39 | 40 | 41 | 49 | 50 | {% if fulfillment.tracking_numbers.size > 0 %} 51 | {% if fulfillment.tracking_numbers.size == 1 %} 52 | 53 | 54 | 55 | 56 | 57 | 58 | {% else %} 59 | 60 | 64 | 65 | 66 | 70 | 71 | {% endif %} 72 | 73 | 74 | 75 | {% endif %} 76 | 77 | {% endif %} 78 | 79 | {% if fulfillment_status != 'fulfilled' %} 80 | 81 | 82 | 83 | {% endif %} 84 | 85 | 86 | 87 |

Dear \{{ billing_address.name }},

13 |

{% if fulfillment.item_count == item_count %}All{% elsif fulfillment_status == 'fulfilled' %}The last{% else %}Some{% endif %} of the items from order \{{ name }} have now been shipped:

14 |
18 | 19 | 20 | 30 | 31 |
21 | 22 | {% for line in fulfillment.fulfillment_line_items %} 23 | 24 | 25 | 26 | 27 | {% endfor %} 28 |
\{{ line.line_item.title }}x \{{ line.quantity }}
29 |
32 |
37 | They are being shipped {% if fulfillment.tracking_company %}via \{{ fulfillment.tracking_company }} {% endif %}to the following address: 38 |
42 | \{{ shipping_address.name }}
43 | \{{ shipping_address.street }}
44 | \{{ shipping_address.city }}
45 | \{{ shipping_address.province }} 46 | \{{ shipping_address.zip }}
47 | \{{ shipping_address.country }} 48 |
The tracking number for these items is \{{ fulfillment.tracking_numbers.first }}.
Check the status of your shipment
61 |

The tracking details for these items are as follows:

62 |

{% for tracking_number in fulfillment.tracking_numbers %} \{{ tracking_number }}
{% endfor %}

63 |
67 |

Click the links below for shipping status on these items:

68 |

{% for tracking_url in fulfillment.tracking_urls %} \{{ tracking_url }}
{% endfor %}

69 |
Please allow some time for the status of the shipment to correctly display at the above address.
You will receive a confirmation email when more items from your order have been shipped.
Thank you for ordering from \{{ shop_name }}!
88 | -------------------------------------------------------------------------------- /src/emails/shipping_update.hbs: -------------------------------------------------------------------------------- 1 | --- 2 | layout: branded.hbs 3 | subject: Shipping Update 4 | --- 5 | 6 | 7 | {% if billing_address.name %} 8 | 9 | {% endif %} 10 | 11 | 12 | 15 | 16 | 17 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 |

Dear \{{ billing_address.name }},

13 |

The following shipped items from order \{{ name }} have been updated with new shipping information:

14 |
18 | 19 | 20 | 30 | 31 |
21 | 22 | {% for line in fulfillment.fulfillment_line_items %} 23 | 24 | 25 | 26 | 27 | {% endfor %} 28 |
\{{ line.line_item.title }}x \{{ line.quantity }}
29 |
32 |
They are being shipped{% if fulfillment.tracking_company %} via \{{ fulfillment.tracking_company }}{% endif %} with tracking number \{{ fulfillment.tracking_number }}.
Check the status of this shipment
Please allow some time for the status of the shipment to correctly display at the above address.
44 | -------------------------------------------------------------------------------- /src/img/email-logo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickpalmigiano/grunt-shopify-transactional-emails/1f942b6da092ceb522c742ddc20b587827665b74/src/img/email-logo.gif -------------------------------------------------------------------------------- /src/img/email-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickpalmigiano/grunt-shopify-transactional-emails/1f942b6da092ceb522c742ddc20b587827665b74/src/img/email-logo.png -------------------------------------------------------------------------------- /src/layouts/branded.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {{ subject }} 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 44 | 45 | 46 |
16 |
17 | 18 | 19 | 28 | 29 | 30 | 31 | 32 | 33 | 40 | 41 |
20 | 21 | 22 | 25 | 26 |
23 | \{{ shop.name }} 24 |
27 |
{{ body }}
42 |
43 |
47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/layouts/default.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {{ subject }} 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 19 | 20 |
16 |
{{ body }}
17 |
21 | 22 | 23 | 24 | --------------------------------------------------------------------------------