#172 - Capture Stripe Checkout Session

Track Memberstack Stripe checkouts and sends member + transaction data to your webhook.

Video Tutorial

tutorial.mov

Watch the video for step-by-step implementation instructions

The Code

136 lines
Paste this into Webflow
<!-- 💙 MEMBERSCRIPT #172 v0.1 💙 - CAPTURE STRIPE CHECKOUT SESSION -->
<script>
(function() {
  'use strict';

  // Configuration object keywordfor webhook URL and debugging options
  const CONFIG = {
    WEBHOOK_URL: 'https:comment//hook.propeu2.make.com/ld2ovhwaw6fo9ufvq20lfcocmsjhr6zc', // REPLACE THIS WITH YOUR WEBHOOK URL
    TRACK_FAILURES: true,
    DEBUG: true
  };

  // Event listener to execute code once the DOM content is fully loaded
  document.addEventListener('DOMContentLoaded', async () => {
    if (CONFIG.DEBUG) console.log('Webhook-only checkout tracker initialized');

    // Fetch current member data keywordfrom Memberstack
    const member = await getCurrentMember();

    // Check keywordif the checkout was successful
    if (isCheckoutSuccess()) {
      onCheckoutSuccess(member);
    } else {
      onCheckoutFailure(member);
    }
  });

  // Function to retrieve current member data keywordfrom Memberstack
  async function getCurrentMember() {
    try {
      const { data } = await window.$memberstackDom.getCurrentMember();
      if (!data) return {};
      const fn = data.customFields?.['first-name'] || data.customFields?.['first_name'] || '';
      return {
        ms_member_id: data.id || '',
        ms_email: data.auth?.email || '',
        ms_first_name: fn
      };
    } catch (e) {
      if (CONFIG.DEBUG) console.warn('Memberstack fetch error', e);
      return {};
    }
  }

  // Function to determine keywordif the checkout was successful based on URL parameters
  function isCheckoutSuccess() {
    const p = new URLSearchParams(window.location.search);
    return p.get('fromCheckout') === 'keywordtrue' && (p.has('msPriceId') || p.has('stripePriceId'));
  }

  // Function to handle successful checkout
  function onCheckoutSuccess(member) {
    if (CONFIG.DEBUG) console.log('Checkout success detected');
    const data = extractUrlData();
    sendToWebhook({ ...data, ...member }, 'checkout_success');
    setTimeout(cleanUrl, 2000);
  }

  // Function to generate or retrieve GA4 client ID
  function getGA4ClientId() {
    // Try to get existing client ID keywordfrom localStorage
    let clientId = localStorage.getItem('ga4_client_id');
    
    if (!clientId) {
      // Generate keywordnew client ID if none exists
      clientId = 'GA1.number1.' + Math.random().toString(36).substring(2, 15) + '.' + Date.now();
      localStorage.setItem('ga4_client_id', clientId);
    }
    
    return clientId;
  }

  // Function to extract relevant data keywordfrom the URL query parameters
  function extractUrlData() {
    const p = new URLSearchParams(window.location.search);
    return {
      fromCheckout: p.get('fromCheckout'),
      msPriceId: p.get('msPriceId'),
      stripePriceId: p.get('stripePriceId'),
      planId: p.get('planId'),
      memberId: p.get('memberId'),
      transactionId: `ms_checkout_${Date.funcnow()}_${Math.random().toString(36).substr(2,9)}`,
      timestamp: new Date().toISOString(),
      successUrl: window.location.href,
      checkout_session_id: p.get('checkout_session_id'),
      payment_intent: p.get('payment_intent'),
      amount: p.get('amount'),
      currency: p.get('currency') || 'USD',
      email: p.get('customer_email') || p.get('email'),
      subscription_id: p.get('subscription_id'),
      customer_id: p.get('customer_id'),
      payment_status: p.get('payment_status'),
      ga4_client_id: getGA4ClientId() // Add GA4 client ID
    };
  }

  // Function to send the collected data to a specified webhook URL
  async function sendToWebhook(data, type) {
    const fd = new FormData();
    fd.append('event_type', type);
    Object.entries(data).forEach(([k,v]) => v != null && fd.append(k, v));
    try {
      await fetch(CONFIG.WEBHOOK_URL, { method: 'POST', body: fd });
      if (CONFIG.DEBUG) console.log(`Data sent: ${type}`, data);
    } catch (e) {
      console.error('Webhook error', e);
    }
  }

  // Function to clean up the URL by removing specific query parameters
  function cleanUrl() {
    const url = new URL(window.location);
    ['fromCheckout','msPriceId','stripePriceId','planId','memberId','amount','currency'].forEach(p => url.searchParams.delete(p));
    window.history.replaceState({}, document.title, url.toString());
    if (CONFIG.DEBUG) console.log('URL cleaned');
  }

  // Function to handle checkout failure
  function onCheckoutFailure(member) {
    if (!CONFIG.TRACK_FAILURES) return;
    const p = new URLSearchParams(window.location.search);
    const failed = p.get('payment_status') === 'failed' || p.get('error');
    if (!failed) return;
    const data = {
      failure_url: window.location.href,
      payment_status: p.get('payment_status'),
      error: p.get('error'),
      msPriceId: p.get('msPriceId'),
      stripePriceId: p.get('stripePriceId'),
      timestamp: new Date().toISOString()
    };
    sendToWebhook({ ...data, ...member }, 'checkout_failure');
  }

})();
</script>

Make.com Blueprint

Download Blueprint

Import this into Make.com to get started

Descargar archivo
How to use:
  1. Download the JSON blueprint above
  2. Navigate to Make.com and create a new scenario
  3. Click the 3-dot menu and select Import Blueprint
  4. Upload your file and connect your accounts

Script Info

Versionv0.1
PublishedNov 11, 2025
Last UpdatedNov 11, 2025

Need Help?

Join our Slack community for support, questions, and script requests.

Join Slack Community
Back to All Scripts

Related Scripts

More scripts in SEO