2026年8月29日
2026年8月29日
MemberPressのエラーを解決する方法
はじめに
MemberPressで会員登録フォームを送信しても「Registration failed」エラーが出てアカウントが作成されない・有料会員向けに設定したコンテンツ保護ルールが機能せず非会員でも閲覧できてしまう・Stripeで決済すると「Card declined」エラーが出るが管理画面では決済完了と表示される・無料トライアル期間終了後に自動課金されないといった問題は、決済設定・アクセスルール・メール設定が原因です。
症状・原因
- 会員登録時に「There was an error processing your payment」と表示される
- 有料会員限定ページに設定したのに非ログインユーザーがコンテンツを閲覧できる
- Stripeの決済画面でエラーなく進んでもWordPress側のトランザクションが「Pending」のまま
- 無料トライアル期間が終わっても会員のステータスが「Active」のまま
解決手順
ステップ1:MemberPressの状態を確認する
# MemberPressの設定確認
wp eval "
if (defined('MEMBERPRESS_VERSION')) {
echo 'MemberPress version: ' . MEMBERPRESS_VERSION . PHP_EOL;
}
// メンバーシップ一覧を確認
\$memberships = MeprProduct::get_all();
echo 'Total memberships: ' . count(\$memberships) . PHP_EOL;
foreach (\$memberships as \$membership) {
printf(' #%d: %s | Price: %s | Period: %s %s | Trial: %s' . PHP_EOL,
\$membership->ID,
\$membership->post_title,
\$membership->price,
\$membership->period,
\$membership->period_type,
\$membership->trial ? 'yes (' . \$membership->trial_days . ' days)' : 'no'
);
}
// アクティブなトランザクションを確認
global \$wpdb;
\$transactions = \$wpdb->get_results(
\"SELECT t.id, t.status, t.amount, t.created_at, u.user_email
FROM {\$wpdb->prefix}mepr_transactions t
JOIN {\$wpdb->users} u ON t.user_id = u.ID
WHERE t.status IN ('complete', 'pending')
ORDER BY t.created_at DESC LIMIT 10\",
ARRAY_A
);
echo 'Recent transactions: ' . count(\$transactions) . PHP_EOL;
foreach (\$transactions as \$tx) {
printf(' #%d: %s | %s | %s | %s' . PHP_EOL,
\$tx['id'], \$tx['status'], \$tx['amount'], \$tx['user_email'], \$tx['created_at']
);
}
"
ステップ2:トランザクション処理をカスタマイズする
// functions.php: MemberPressトランザクション処理
// ① 決済完了時にカスタム処理を実行
add_action('mepr_event_transaction_completed', function(MeprEvent $event): void {
$transaction = $event->get_data();
$user = $transaction->user();
$membership = $transaction->product();
// 決済完了時にユーザーメタを更新
update_user_meta($user->ID, '_mepr_joined_at', current_time('mysql'));
update_user_meta($user->ID, '_mepr_membership', $membership->post_title);
// カスタムウェルカムメールを送信
wp_mail(
$user->user_email,
sprintf('[%s] 会員登録が完了しました', get_bloginfo('name')),
sprintf("こんにちは %s さん、\n\n「%s」プランへのご登録ありがとうございます。\n\nマイページ: %s",
$user->display_name,
$membership->post_title,
mepr_account_url()
)
);
error_log(sprintf('[MeprP] Transaction #%d completed for user #%d (%s)',
$transaction->id, $user->ID, $user->user_email));
});
// ② サブスクリプション更新成功時の処理
add_action('mepr_event_subscription_resumed', function(MeprEvent $event): void {
$subscription = $event->get_data();
$user = $subscription->user();
update_user_meta($user->ID, '_mepr_last_renewal', current_time('mysql'));
});
// ③ 決済失敗時の処理
add_action('mepr_event_transaction_failed', function(MeprEvent $event): void {
$transaction = $event->get_data();
$user = $transaction->user();
error_log(sprintf('[MeprP] Transaction failed for user #%d: %s',
$user->ID, $user->user_email));
// 管理者に通知
wp_mail(
get_option('admin_email'),
'[MemberPress] 決済失敗の通知',
sprintf('ユーザー: %s (%s) の決済が失敗しました。', $user->display_name, $user->user_email)
);
});
ステップ3:コンテンツ保護ルールを確認する
// functions.php: アクセスルール管理
// ① 現在のユーザーがコンテンツにアクセスできるか確認
function check_memberpress_access(int $post_id, int $user_id = 0): bool {
if (!function_exists('mepr_post_rules_to_string')) return true;
$user_id = $user_id ?: get_current_user_id();
if (!$user_id) return false;
$mepr_user = new MeprUser($user_id);
return $mepr_user->can_access_post($post_id);
}
// ② コンテンツ保護ルールのデバッグ
add_action('mepr_unauthorized_content', function(WP_Post $post, int $user_id): void {
error_log(sprintf('[MeprP] Access denied: post #%d for user #%d', $post->ID, $user_id));
// アクセスルールを確認
$rules = MeprRule::get_rules_for_post($post->ID);
foreach ($rules as $rule) {
error_log(sprintf('[MeprP] Rule #%d: %s requires membership #%d',
$rule->ID, $rule->mepr_type, $rule->mepr_authorized_types_association ?? 0));
}
}, 10, 2);
// ③ 特定の投稿タイプをMeprアクセスチェックから除外
add_filter('mepr_pre_run_rule_content', function(bool $run, WP_Post $post): bool {
// カスタム投稿タイプ「announcement」は常に表示
if ($post->post_type === 'announcement') {
return false;
}
return $run;
}, 10, 2);
ステップ4:Webhook設定を確認する
# StripeのWebhook設定確認
wp eval "
// MeprPの決済ゲートウェイ設定を確認
\$gateways = MeprOptions::fetch()->gateways;
echo 'Payment gateways: ' . count(\$gateways) . PHP_EOL;
foreach (\$gateways as \$gateway) {
printf(' %s: %s | Test mode: %s' . PHP_EOL,
\$gateway->name,
get_class(\$gateway),
(\$gateway->test_mode ?? false) ? 'yes' : 'no'
);
}
// 保留中のトランザクションを確認
global \$wpdb;
\$pending = \$wpdb->get_results(
\"SELECT id, user_id, amount, gateway, created_at
FROM {\$wpdb->prefix}mepr_transactions
WHERE status = 'pending'
AND created_at < DATE_SUB(NOW(), INTERVAL 24 HOUR)
ORDER BY created_at DESC LIMIT 10\"
);
echo 'Stuck pending transactions (>24h): ' . count(\$pending) . PHP_EOL;
foreach (\$pending as \$tx) {
printf(' #%d: user=%d, amount=%s, gw=%s, at=%s' . PHP_EOL,
\$tx->id, \$tx->user_id, \$tx->amount, \$tx->gateway, \$tx->created_at
);
}
"
ステップ5:サブスクリプションの有効期限を管理する
// functions.php: サブスクリプション管理
// ① 期限切れ会員のアクセスを即座に取り消し
add_action('mepr_event_subscription_expired', function(MeprEvent $event): void {
$subscription = $event->get_data();
$user = $subscription->user();
// 会員ロールを削除してSubscriberに戻す
$wp_user = new WP_User($user->ID);
$wp_user->set_role('subscriber');
// アクセス期限メタを更新
update_user_meta($user->ID, '_mepr_expired_at', current_time('mysql'));
error_log(sprintf('[MeprP] Subscription expired for user #%d', $user->ID));
});
// ② 期限切れ前7日に更新リマインダーを送信
add_action('mepr_event_subscription_reminder', function(MeprEvent $event): void {
$subscription = $event->get_data();
$user = $subscription->user();
$membership = $subscription->product();
$expiry = new DateTime($subscription->expires_at);
$now = new DateTime();
$days = $now->diff($expiry)->days;
wp_mail(
$user->user_email,
sprintf('[%s] 会員期限まで%d日です', get_bloginfo('name'), $days),
sprintf("こんにちは %s さん、\n\n「%s」プランの有効期限まで残り%d日です。\n\n更新はこちら: %s",
$user->display_name,
$membership->post_title,
$days,
mepr_account_url()
)
);
});
// ③ トライアル期間終了時の処理
add_action('mepr_event_transaction_expired', function(MeprEvent $event): void {
$transaction = $event->get_data();
if (!$transaction->is_trial_txn()) return;
$user = $transaction->user();
error_log(sprintf('[MeprP] Trial expired for user #%d', $user->ID));
});
注意事項
- MemberPressのStripe連携でWebhookが機能しない場合は、StripeダッシュボードのWebhookエンドポイントURLが
https://example.com/?mepr-listener=stripeの形式で正しく設定されているか確認してください。SSL証明書のエラーがあるとWebhookが届きません - コンテンツ保護ルールが機能しない場合は「MemberPress → 設定 → 詳細」の「Force SSL」オプションを確認してください。HTTPとHTTPSが混在している場合にルールが正しく適用されないことがあります
- テストモードと本番モードでAPIキーが混在しないよう注意してください。Stripeのテストキー(sk_test_)で本番決済しようとするとエラーになります
まとめ
MemberPress修復は①mepr_transactionsテーブルでトランザクション状態・MeprProduct::get_all()でメンバーシップ設定を確認、②mepr_event_transaction_completedフックで決済完了時のメタ更新・ウェルカムメール送信・mepr_event_transaction_failedで管理者通知、③MeprRule::get_rules_for_post()でアクセスルール確認・mepr_unauthorized_contentフックでデバッグログ・mepr_pre_run_rule_contentで特定投稿タイプを除外、④ゲートウェイ設定確認・24時間以上Pendingのトランザクション特定、⑤mepr_event_subscription_expiredで期限切れ時にロール変更・mepr_event_subscription_reminderで更新リマインダーメールを送信する手順で解決します。