使用 MemberPress 交易完成鉤子自動寄送訂閱確認信

前言

這段程式碼示範如何在 WordPress 使用 MemberPress 交易完成事件鉤子,自動寄送訂閱方案的確認電子郵件。適合使用 MemberPress 管理會員訂閱,並希望自動化寄送付款成功通知的工程師或自學者。

交易完成事件監聽

透過 add_action 監聽 mepr-event-transaction-completed 事件,當交易完成時觸發自訂函式。函式內部先檢查事件與交易物件有效性,避免錯誤執行。

add_action('mepr-event-transaction-completed', function($event) {
  if(!is_object($event)) return;

  $txn = $event->get_data();
  if(!is_object($txn)) return;
  // ...
});

交易資料擷取與條件判斷

取得交易相關資訊如使用者 ID、方案 ID、交易 ID、付款狀態與金額,並做以下條件過濾:

  • 使用者、方案、交易 ID 必須有效
  • 交易狀態必須為 complete
  • 可選擇只寄首次付款通知(此範例預設為每次付款皆寄)
  • 防止重複寄送,透過交易文章 meta 標記

這些判斷確保只有有效且未重複的交易會觸發郵件寄送。

根據方案選擇郵件模板

根據方案 ID(範例中為 626 月付方案與 639 年付方案)選擇對應的郵件主旨與 HTML 內容。郵件內容包含隱藏文字供郵件摘要使用,以及簡潔的訂閱資訊與操作連結。

if($membership_id === 626) {
  $subject = $subject_626;
  $message = $message_626;
} elseif($membership_id === 639) {
  $subject = $subject_639;
  $message = $message_639;
} else {
  return;
}

寄送郵件與防重複標記

使用 WordPress 內建的 wp_mail 函式寄送 HTML 格式郵件,並在成功寄出後,透過 update_post_meta 設定交易文章的自訂 meta,避免重複寄信。

$headers = ['Content-Type: text/html; charset=UTF-8'];
$sent = wp_mail($user->user_email, $subject, $message, $headers);

if($sent) {
  update_post_meta($txn_id, '_custom_plan_email_sent', 'yes');
}

實務應用與優化建議

  • 可依照不同方案擴充更多模板,提升客製化體驗
  • 建議搭配會員資料完整性檢查,確保郵件內容正確
  • 若有多語系需求,可整合翻譯函式動態產生郵件內容
  • 透過設定參數控制是否只寄首次付款通知,靈活調整行銷策略

常見問題與注意事項

  • 確認 MemberPress 交易狀態名稱是否與程式碼一致,避免漏寄
  • 郵件內容中圖片 URL 請替換成實際可用路徑
  • 測試時注意交易狀態與交易金額,避免誤寄測試郵件

完整程式碼

<?php
add_action('mepr-event-transaction-completed', function($event) {
  if(!is_object($event)) return;

  // true = 只寄首次;false = 每次扣款都寄
  $SEND_FIRST_PAYMENT_ONLY = false;

  $txn = $event->get_data();
  if(!is_object($txn)) return;

  // 交易基本資訊
  $user_id       = intval($txn->user_id ?? 0);
  $membership_id = intval($txn->product_id ?? 0);
  $txn_id        = intval($txn->id ?? 0); // MemberPress 交易文章 ID
  $total         = floatval($txn->total ?? 0);
  $status        = strval($txn->status ?? '');

  if($user_id <= 0 || $membership_id <= 0 || $txn_id <= 0) return;

  // 僅完成交易才寄(雙保險)
  if($status !== 'complete') return;

  // 避免 $0 交易(試用 / 全額折扣)也發信
//   if($total <= 0) return;

  // 只寄首次付款?
  if($SEND_FIRST_PAYMENT_ONLY === true && method_exists($txn,'is_first_payment') && !$txn->is_first_payment()) {
    return;
  }

  // 防重複寄送:用交易 ID 做旗標
  if(get_post_meta($txn_id, '_custom_plan_email_sent', true) === 'yes') {
    return;
  }

  $user = get_user_by('id', $user_id);
  if(!$user || empty($user->user_email)) return;

  $product_name = get_the_title($membership_id);

  // ===== 月付 626 =====
  $subject_626 = '感謝您購買 '.$product_name;
  $message_626 = <<<HTML
<div style="display: none; overflow: hidden; line-height: 1px; opacity: 0; max-height: 0; max-width: 0;">你已成功訂閱 。你的訂閱方案將會自動續訂:月付 $129,可隨時取消。</div>
<table style="width: 100%; background: #f5f6f8; margin: 0; padding: 0;" role="presentation">
<tr><td align="center">
<table style="width: 600px; margin: 0 auto;" role="presentation">
<tr><td style="padding: 0px 24px; background: #ffffff;" align="left">
<img src="" width="200" />
</td></tr>
<tr><td style="padding: 32px 24px; background: #ffffff; font-family: Helvetica, Arial, 'PingFang TC', 'Microsoft JhengHei', sans-serif; color: #111827;">
<table role="presentation" width="100%">
<tr><td valign="top" width="6">
<div style="width: 3px; height: 22px; background: #39A297; border-radius: 2px; margin-top: 6px;"></div>
</td>
<td style="padding-left: 10px;">
<p style="font-size: 16px; line-height: 1.75; margin: 0;">你已成功訂閱 <strong></strong> 。</p>
</td></tr></table>

<div style="height: 16px;"></div>
<p style="font-size: 16px; line-height: 1.75; margin: 0;">你的訂閱方案將會自動續訂:<strong>月付 $129</strong><br>你可以隨時取消。</p>

<div style="height: 16px;"></div>
<a style="background: #39A297; border-radius: 8px; padding: 12px 18px; display: inline-block; color: #ffffff; text-decoration: none;" href="https://.com/account/" target="_blank">點擊這裡登入</a>

<div style="height: 28px;"></div>
<p style="font-size: 14px; color: #6b7280;">如有任何問題,請於聯絡我們留言你的需求。</p>
<p style="font-size: 16px;"> 團隊</p>
</td></tr></table>
</td></tr></table>
HTML;

  // ===== 年付 639 =====
  $subject_639 = '感謝您購買 '.$product_name;
  $message_639 = <<<HTML
<div style="display: none;overflow: hidden;line-height: 1px;opacity: 0;max-height: 0;max-width: 0">你已成功訂閱 。你的訂閱方案將會自動續訂:年付 $1,290,可隨時取消。</div>
<table style="width: 100%;background: #f5f6f8;margin: 0;padding: 0" role="presentation">
<tr><td align="center">
<table style="width: 600px;margin: 0 auto" role="presentation">
<tr><td style="padding: 0 24px;background: #ffffff" align="left">
<img src="https://.com/wp-content/uploads/2025/10/forGoogleLogo.png" width="200" />
</td></tr>
<tr><td style="padding: 32px 24px;background: #ffffff;font-family: Helvetica, Arial, 'PingFang TC', 'Microsoft JhengHei', sans-serif;color: #111827">
<table role="presentation" width="100%"><tr><td valign="top" width="6">
<div style="width: 3px;height: 22px;background: #16a34a;border-radius: 2px;margin-top: 6px"></div>
</td>
<td style="padding-left: 10px">
<p style="font-size: 16px;line-height: 1.75;margin: 0">你已成功訂閱 <strong></strong> 。</p>
</td></tr></table>

<div style="height: 16px"></div>
<p style="font-size: 16px;line-height: 1.75;margin: 0">你的訂閱方案將會自動續訂:<strong>年付 $1,290</strong>
<br />你可以隨時取消。</p>

<div style="height: 16px"></div>
<p style="font-size: 16px;line-height: 1.75;margin: 0">別忘了到會員資訊裡留下你的收件資料,<br />讓我們能夠把贈品正確地寄送到你手上。</p>

<div style="height: 16px"></div>
<a style="background: #39A297;border-radius: 8px;padding: 12px 18px;display: inline-block;color: #ffffff;text-decoration: none" href="#" target="_blank">設定你的收件資料</a>

<div style="height: 28px"></div>
<p style="font-size: 14px;color: #6b7280;">如有任何問題,請於聯絡我們留言你的需求。</p>
<p style="font-size: 16px;"> 團隊</p>
</td></tr></table>
</td></tr></table>
HTML;

  // 套用對應模板
  if($membership_id === 626) {
    $subject = $subject_626;
    $message = $message_626;
  } elseif($membership_id === 639) {
    $subject = $subject_639;
    $message = $message_639;
  } else {
    return;
  }

  // 寄送
  $headers = ['Content-Type: text/html; charset=UTF-8'];
  $sent = wp_mail($user->user_email, $subject, $message, $headers);

  // 設定防重複旗標(只有寄成功才標記)
  if($sent) {
    update_post_meta($txn_id, '_custom_plan_email_sent', 'yes');
  }
});