goodmail 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,497 @@
1
+ # Pay + Goodmail Testing Guide
2
+
3
+ Complete guide for testing all Pay gem email notifications with Goodmail.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Setup](#setup)
8
+ - [Viewing Emails in Development](#viewing-emails-in-development)
9
+ - [Testing All Email Types](#testing-all-email-types)
10
+ - [1. Receipt Email](#1-receipt-email)
11
+ - [2. Refund Email](#2-refund-email)
12
+ - [3. Subscription Renewing Email](#3-subscription-renewing-email)
13
+ - [4. Payment Action Required Email](#4-payment-action-required-email)
14
+ - [5. Subscription Trial Will End Email](#5-subscription-trial-will-end-email)
15
+ - [6. Subscription Trial Ended Email](#6-subscription-trial-ended-email)
16
+ - [7. Payment Failed Email](#7-payment-failed-email)
17
+ - [Quick Test Script](#quick-test-script)
18
+ - [Tips & Tricks](#tips--tricks)
19
+
20
+ ---
21
+
22
+ ## Setup
23
+
24
+ ### 1. Install and Configure Goodmail
25
+
26
+ ```ruby
27
+ # Gemfile
28
+ gem 'goodmail'
29
+ ```
30
+
31
+ ```bash
32
+ bundle install
33
+ ```
34
+
35
+ ```ruby
36
+ # config/initializers/goodmail.rb
37
+ Goodmail.configure do |config|
38
+ config.company_name = "Your App Name"
39
+ config.brand_color = "#E62F17"
40
+ config.logo_url = "https://your-cdn.com/logo.png"
41
+ config.company_url = "https://yourapp.com"
42
+ end
43
+ ```
44
+
45
+ ### 2. Copy the PayGoodmailer
46
+
47
+ Copy `examples/pay_goodmailer.rb` to your app:
48
+
49
+ ```bash
50
+ cp examples/pay_goodmailer.rb app/mailers/pay_goodmailer.rb
51
+ ```
52
+
53
+ ### 3. Configure Pay to Use the Mailer
54
+
55
+ ```ruby
56
+ # config/initializers/pay.rb
57
+ Pay.setup do |config|
58
+ config.parent_mailer = "ApplicationMailer"
59
+ config.mailer = "PayGoodmailer"
60
+
61
+ # Enable all email notifications
62
+ config.send_emails = true
63
+ config.emails.receipt = true
64
+ config.emails.refund = true
65
+ config.emails.subscription_renewing = true
66
+ config.emails.payment_action_required = true
67
+ config.emails.subscription_trial_will_end = true
68
+ config.emails.subscription_trial_ended = true
69
+ config.emails.payment_failed = true
70
+ end
71
+ ```
72
+
73
+ ### 4. Customize URL Helpers
74
+
75
+ Edit the URL helper methods at the bottom of `pay_goodmailer.rb`:
76
+
77
+ ```ruby
78
+ def billing_url
79
+ # Change this to match your app:
80
+ billing_path # or account_billing_url, etc.
81
+ end
82
+
83
+ def dashboard_url
84
+ dashboard_path # or root_url, etc.
85
+ end
86
+
87
+ def receipt_url(pay_charge)
88
+ receipt_path(pay_charge) # or charge_url(pay_charge), etc.
89
+ end
90
+ ```
91
+
92
+ ---
93
+
94
+ ## Viewing Emails in Development
95
+
96
+ ### Option 1: Letter Opener (Recommended)
97
+
98
+ Opens emails in your browser automatically:
99
+
100
+ ```ruby
101
+ # Gemfile
102
+ group :development do
103
+ gem 'letter_opener'
104
+ end
105
+
106
+ # config/environments/development.rb
107
+ config.action_mailer.delivery_method = :letter_opener
108
+ config.action_mailer.perform_deliveries = true
109
+ ```
110
+
111
+ ### Option 2: Mailer Previews
112
+
113
+ Visit `http://localhost:3000/rails/mailers` to see previews (requires creating preview classes).
114
+
115
+ ### Option 3: Check Logs
116
+
117
+ Emails are logged in `log/development.log` when using the default `:test` delivery method.
118
+
119
+ ---
120
+
121
+ ## Testing All Email Types
122
+
123
+ Open your Rails console:
124
+
125
+ ```bash
126
+ rails console
127
+ ```
128
+
129
+ ### Setup Test User and Fake Processor
130
+
131
+ ```ruby
132
+ # Get or create a user
133
+ user = User.first || User.create!(
134
+ email: 'test@example.com',
135
+ password: 'password123'
136
+ # ... other required fields
137
+ )
138
+
139
+ # Set up the fake processor (for testing without real payments)
140
+ user.set_payment_processor(:fake_processor, allow_fake: true)
141
+ ```
142
+
143
+ ---
144
+
145
+ ### 1. Receipt Email
146
+
147
+ **Triggered when:** A payment is successfully processed (charge.succeeded webhook)
148
+
149
+ ```ruby
150
+ # Create a test charge
151
+ charge = user.payment_processor.charge(2999) # $29.99
152
+
153
+ # Send receipt email
154
+ Pay.mailer.with(
155
+ pay_customer: user.payment_processor,
156
+ pay_charge: charge
157
+ ).receipt.deliver_now
158
+ ```
159
+
160
+ **Expected email content:**
161
+ - ✅ Payment confirmation GIF
162
+ - ✅ Amount charged
163
+ - ✅ Payment method details
164
+ - ✅ Transaction date and ID
165
+
166
+ ---
167
+
168
+ ### 2. Refund Email
169
+
170
+ **Triggered when:** A charge is refunded (charge.refunded webhook)
171
+
172
+ ```ruby
173
+ # Create a charge first
174
+ charge = user.payment_processor.charge(4999) # $49.99
175
+
176
+ # Simulate a refund (full refund)
177
+ charge.update!(amount_refunded: 4999)
178
+
179
+ # Send refund email
180
+ Pay.mailer.with(
181
+ pay_customer: user.payment_processor,
182
+ pay_charge: charge
183
+ ).refund.deliver_now
184
+ ```
185
+
186
+ **For a partial refund:**
187
+
188
+ ```ruby
189
+ charge.update!(amount_refunded: 2000) # $20.00 refund on $49.99 charge
190
+ Pay.mailer.with(
191
+ pay_customer: user.payment_processor,
192
+ pay_charge: charge
193
+ ).refund.deliver_now
194
+ ```
195
+
196
+ **Expected email content:**
197
+ - ✅ Refund confirmation GIF
198
+ - ✅ Refund amount
199
+ - ✅ Original charge amount
200
+ - ✅ Processing timeline (5-10 business days)
201
+
202
+ ---
203
+
204
+ ### 3. Subscription Renewing Email
205
+
206
+ **Triggered when:** Annual subscription will renew soon (invoice.upcoming webhook)
207
+
208
+ ```ruby
209
+ # Create a subscription
210
+ subscription = user.payment_processor.subscribe(
211
+ name: "Pro Plan",
212
+ trial_ends_at: nil
213
+ )
214
+
215
+ # Send renewal notice (with renewal date)
216
+ Pay.mailer.with(
217
+ pay_customer: user.payment_processor,
218
+ pay_subscription: subscription,
219
+ date: 30.days.from_now
220
+ ).subscription_renewing.deliver_now
221
+ ```
222
+
223
+ **Expected email content:**
224
+ - ✅ Renewal reminder
225
+ - ✅ Subscription plan name
226
+ - ✅ Next billing date
227
+ - ✅ Days until renewal
228
+
229
+ ---
230
+
231
+ ### 4. Payment Action Required Email
232
+
233
+ **Triggered when:** Payment needs additional authentication (invoice.payment_action_required webhook)
234
+
235
+ ```ruby
236
+ # Create a subscription (or use existing)
237
+ subscription = user.payment_processor.subscriptions.last ||
238
+ user.payment_processor.subscribe(name: "Pro Plan")
239
+
240
+ # Send payment action required email
241
+ Pay.mailer.with(
242
+ pay_subscription: subscription,
243
+ payment_intent_id: "pi_test_123" # Optional
244
+ ).payment_action_required.deliver_now
245
+ ```
246
+
247
+ **Expected email content:**
248
+ - ✅ Action needed alert
249
+ - ✅ Security verification explanation
250
+ - ✅ "Complete Payment" button
251
+ - ✅ Urgency message
252
+
253
+ ---
254
+
255
+ ### 5. Subscription Trial Will End Email
256
+
257
+ **Triggered when:** Trial period ending in 3 days (customer.subscription.trial_will_end webhook)
258
+
259
+ ```ruby
260
+ # Create a subscription with trial
261
+ subscription = user.payment_processor.subscribe(
262
+ name: "Pro Plan",
263
+ trial_ends_at: 7.days.from_now
264
+ )
265
+
266
+ # Send trial ending email
267
+ Pay.mailer.with(
268
+ pay_subscription: subscription
269
+ ).subscription_trial_will_end.deliver_now
270
+ ```
271
+
272
+ **Expected email content:**
273
+ - ✅ Trial ending reminder
274
+ - ✅ Days remaining
275
+ - ✅ Trial end date
276
+ - ✅ What happens after trial
277
+
278
+ ---
279
+
280
+ ### 6. Subscription Trial Ended Email
281
+
282
+ **Triggered when:** Trial period has ended
283
+
284
+ #### Active Subscription (payment successful):
285
+
286
+ ```ruby
287
+ # Create active subscription (trial just ended)
288
+ subscription = user.payment_processor.subscribe(
289
+ name: "Pro Plan",
290
+ trial_ends_at: 1.day.ago,
291
+ status: "active"
292
+ )
293
+
294
+ # Send trial ended email
295
+ Pay.mailer.with(
296
+ pay_subscription: subscription
297
+ ).subscription_trial_ended.deliver_now
298
+ ```
299
+
300
+ **Expected email content:**
301
+ - ✅ Trial completion notice
302
+ - ✅ Active subscription confirmation
303
+ - ✅ Thank you message
304
+
305
+ #### Inactive Subscription (payment failed):
306
+
307
+ ```ruby
308
+ # Create inactive subscription
309
+ subscription = user.payment_processor.subscribe(
310
+ name: "Pro Plan",
311
+ trial_ends_at: 1.day.ago
312
+ )
313
+ subscription.update!(status: "incomplete")
314
+
315
+ # Send trial ended email
316
+ Pay.mailer.with(
317
+ pay_subscription: subscription
318
+ ).subscription_trial_ended.deliver_now
319
+ ```
320
+
321
+ **Expected email content:**
322
+ - ✅ Trial ended notice
323
+ - ✅ Payment failure message
324
+ - ✅ "Update Payment Method" button
325
+
326
+ ---
327
+
328
+ ### 7. Payment Failed Email
329
+
330
+ **Triggered when:** Subscription payment fails (invoice.payment_failed webhook)
331
+
332
+ ```ruby
333
+ # Create a subscription
334
+ subscription = user.payment_processor.subscribe(name: "Pro Plan")
335
+
336
+ # Send payment failed email
337
+ Pay.mailer.with(
338
+ pay_subscription: subscription
339
+ ).payment_failed.deliver_now
340
+ ```
341
+
342
+ **Expected email content:**
343
+ - ✅ "Uh-oh!" GIF
344
+ - ✅ Payment failure notice
345
+ - ✅ Common failure reasons
346
+ - ✅ "Update Payment Info" button
347
+ - ✅ Urgency message
348
+
349
+ ---
350
+
351
+ ## Quick Test Script
352
+
353
+ Run all email tests at once:
354
+
355
+ ```ruby
356
+ # rails console
357
+
358
+ # Setup
359
+ user = User.first
360
+ user.set_payment_processor(:fake_processor, allow_fake: true)
361
+
362
+ # Test all emails
363
+ puts "Testing Receipt..."
364
+ charge = user.payment_processor.charge(2999)
365
+ Pay.mailer.with(pay_customer: user.payment_processor, pay_charge: charge).receipt.deliver_now
366
+
367
+ puts "Testing Refund..."
368
+ charge.update!(amount_refunded: 2999)
369
+ Pay.mailer.with(pay_customer: user.payment_processor, pay_charge: charge).refund.deliver_now
370
+
371
+ puts "Testing Subscription Renewing..."
372
+ subscription = user.payment_processor.subscribe(name: "Pro Plan")
373
+ Pay.mailer.with(pay_subscription: subscription, date: 30.days.from_now).subscription_renewing.deliver_now
374
+
375
+ puts "Testing Payment Action Required..."
376
+ Pay.mailer.with(pay_subscription: subscription).payment_action_required.deliver_now
377
+
378
+ puts "Testing Trial Will End..."
379
+ subscription.update!(trial_ends_at: 7.days.from_now)
380
+ Pay.mailer.with(pay_subscription: subscription).subscription_trial_will_end.deliver_now
381
+
382
+ puts "Testing Trial Ended (Active)..."
383
+ subscription.update!(trial_ends_at: 1.day.ago, status: "active")
384
+ Pay.mailer.with(pay_subscription: subscription).subscription_trial_ended.deliver_now
385
+
386
+ puts "Testing Payment Failed..."
387
+ Pay.mailer.with(pay_subscription: subscription).payment_failed.deliver_now
388
+
389
+ puts "✅ All emails sent! Check your browser (Letter Opener) or logs."
390
+ ```
391
+
392
+ ---
393
+
394
+ ## Tips & Tricks
395
+
396
+ ### Testing with Stripe CLI (Most Realistic)
397
+
398
+ For end-to-end testing with real webhook events:
399
+
400
+ ```bash
401
+ # Install Stripe CLI
402
+ brew install stripe/stripe-cli/stripe
403
+
404
+ # Login
405
+ stripe login
406
+
407
+ # Forward webhooks to local server
408
+ stripe listen --forward-to localhost:3000/pay/webhooks/stripe
409
+
410
+ # In another terminal, trigger events
411
+ stripe trigger payment_intent.succeeded
412
+ stripe trigger charge.refunded
413
+ stripe trigger customer.subscription.updated
414
+ ```
415
+
416
+ ### Customizing GIF Images
417
+
418
+ Replace the GIF URLs in `pay_goodmailer.rb`:
419
+
420
+ ```ruby
421
+ # Change from:
422
+ image("https://assets.rameerez.com/mailers/ok.gif", "Payment confirmed!", width: 250)
423
+
424
+ # To your own:
425
+ image("https://your-cdn.com/success.gif", "Payment confirmed!", width: 250)
426
+ ```
427
+
428
+ ### Adding i18n Translations
429
+
430
+ Create `config/locales/pay.en.yml`:
431
+
432
+ ```yaml
433
+ en:
434
+ pay:
435
+ mailer:
436
+ receipt:
437
+ subject: "Your payment receipt from %{application_name}"
438
+ title: "Payment Received!"
439
+ message: "Thanks for your payment!"
440
+ refund:
441
+ subject: "Refund processed"
442
+ title: "Refund Processed"
443
+ # ... etc
444
+ ```
445
+
446
+ ### Testing Email Delivery
447
+
448
+ Verify emails are actually being sent:
449
+
450
+ ```ruby
451
+ # Check ActionMailer deliveries
452
+ ActionMailer::Base.deliveries.count
453
+ ActionMailer::Base.deliveries.last.subject
454
+ ActionMailer::Base.deliveries.last.to
455
+
456
+ # Clear deliveries
457
+ ActionMailer::Base.deliveries.clear
458
+ ```
459
+
460
+ ### Debugging
461
+
462
+ If emails aren't sending:
463
+
464
+ 1. Check Pay configuration: `Pay.send_emails` should be `true`
465
+ 2. Check individual email settings: `Pay.emails.receipt` etc.
466
+ 3. Check mailer is configured: `Pay.mailer` should return `"PayGoodmailer"`
467
+ 4. Check logs for errors: `tail -f log/development.log`
468
+ 5. Verify Goodmail is configured: `Goodmail.config.company_name`
469
+
470
+ ### Production Testing Checklist
471
+
472
+ Before deploying to production:
473
+
474
+ - [ ] Customize all URL helper methods
475
+ - [ ] Replace GIF URLs with your own (or remove them)
476
+ - [ ] Add i18n translations (optional)
477
+ - [ ] Configure Goodmail with your branding
478
+ - [ ] Test with real Stripe test mode webhooks
479
+ - [ ] Verify emails look good in Gmail, Outlook, Apple Mail
480
+ - [ ] Check spam score (use mail-tester.com)
481
+ - [ ] Set up proper SMTP/email delivery service
482
+ - [ ] Configure SPF, DKIM, DMARC records
483
+
484
+ ---
485
+
486
+ ## Need Help?
487
+
488
+ - **Goodmail Issues:** https://github.com/rameerez/goodmail/issues
489
+ - **Pay Gem Issues:** https://github.com/pay-rails/pay/issues
490
+ - **Email not sending?** Check that `config.action_mailer.perform_deliveries = true` in your environment
491
+ - **Emails look wrong?** Verify Goodmail configuration in `config/initializers/goodmail.rb`
492
+
493
+ ---
494
+
495
+ **Happy testing!** 🎉
496
+
497
+ If you find this guide helpful, please star the [Goodmail repository](https://github.com/rameerez/goodmail)!