/stripe-guides

How to find a payment using customer email in Stripe?

Learn how to find a payment in Stripe using a customer’s email address with step-by-step code examples for Node.js, Python, PHP, and via the Stripe Dashboard.

Matt Graham, CEO of Rapid Developers

Book a call with an Expert

Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.

Book a free consultation

How to find a payment using customer email in Stripe?

How to Find a Payment Using Customer Email in Stripe

 

In this tutorial, I'll walk you through the process of finding a payment in Stripe using a customer's email address. This is a common task for businesses that need to look up transaction details when handling customer inquiries or processing refunds.

 

Step 1: Set Up Your Stripe Environment

 

First, you need to have the Stripe API set up in your environment. You'll need to install the Stripe library for your programming language.

For Node.js:

npm install stripe

For Python:

pip install stripe

For PHP:

composer require stripe/stripe-php

 

Step 2: Initialize the Stripe Client

 

Initialize your Stripe client with your API key. You can find your API keys in the Stripe Dashboard under Developers > API keys.

For Node.js:

const stripe = require('stripe')('sk_test_YOUR_SECRET_KEY');

// Use async/await for cleaner code
async function findPaymentByEmail() {
  // We'll implement this function in the next steps
}

For Python:

import stripe
stripe.api_key = 'sk_test_YOUR_SECRET\_KEY'

For PHP:

 

Step 3: Find the Customer by Email

 

Before finding payments, you need to find the customer using their email address.

For Node.js:

async function findCustomerByEmail(email) {
  try {
    const customers = await stripe.customers.list({
      email: email,
      limit: 1
    });
    
    if (customers.data.length === 0) {
      console.log('No customer found with this email address');
      return null;
    }
    
    return customers.data[0];
  } catch (error) {
    console.error('Error finding customer:', error);
    return null;
  }
}

For Python:

def find_customer_by\_email(email):
    try:
        customers = stripe.Customer.list(email=email, limit=1)
        
        if not customers.data:
            print('No customer found with this email address')
            return None
            
        return customers.data[0]
    except Exception as e:
        print(f'Error finding customer: {str(e)}')
        return None

For PHP:

 $email,
            'limit' => 1
        ]);
        
        if (count($customers->data) === 0) {
            echo 'No customer found with this email address';
            return null;
        }
        
        return $customers->data[0];
    } catch (\Exception $e) {
        echo 'Error finding customer: ' . $e->getMessage();
        return null;
    }
}

 

Step 4: Retrieve Payments for the Customer

 

Once you have the customer object, you can retrieve all payments (charges) associated with that customer.

For Node.js:

async function getPaymentsForCustomer(customerId) {
  try {
    const charges = await stripe.charges.list({
      customer: customerId,
      limit: 100 // Adjust as needed
    });
    
    return charges.data;
  } catch (error) {
    console.error('Error retrieving payments:', error);
    return [];
  }
}

For Python:

def get_payments_for_customer(customer_id):
    try:
        charges = stripe.Charge.list(
            customer=customer\_id,
            limit=100  # Adjust as needed
        )
        
        return charges.data
    except Exception as e:
        print(f'Error retrieving payments: {str(e)}')
        return []

For PHP:

 $customerId,
            'limit' => 100 // Adjust as needed
        ]);
        
        return $charges->data;
    } catch (\Exception $e) {
        echo 'Error retrieving payments: ' . $e->getMessage();
        return [];
    }
}

 

Step 5: Find a Specific Payment (Optional)

 

If you want to find a specific payment with additional criteria (like amount or date), you can filter the results.

For Node.js:

function findSpecificPayment(payments, criteria = {}) {
  return payments.filter(payment => {
    let match = true;
    
    // Filter by amount (in cents)
    if (criteria.amount && payment.amount !== criteria.amount) {
      match = false;
    }
    
    // Filter by date range
    if (criteria.startDate && criteria.endDate) {
      const paymentDate = new Date(payment.created \* 1000);
      const startDate = new Date(criteria.startDate);
      const endDate = new Date(criteria.endDate);
      
      if (paymentDate < startDate || paymentDate > endDate) {
        match = false;
      }
    }
    
    // Filter by payment status
    if (criteria.status && payment.status !== criteria.status) {
      match = false;
    }
    
    return match;
  });
}

For Python:

def find_specific_payment(payments, criteria=None):
    if criteria is None:
        criteria = {}
        
    filtered\_payments = []
    
    for payment in payments:
        match = True
        
        # Filter by amount (in cents)
        if 'amount' in criteria and payment.amount != criteria['amount']:
            match = False
            
        # Filter by date range
        if 'start_date' in criteria and 'end_date' in criteria:
            payment\_date = datetime.fromtimestamp(payment.created)
            start_date = datetime.strptime(criteria['start_date'], '%Y-%m-%d')
            end_date = datetime.strptime(criteria['end_date'], '%Y-%m-%d')
            
            if payment_date < start_date or payment_date > end_date:
                match = False
                
        # Filter by payment status
        if 'status' in criteria and payment.status != criteria['status']:
            match = False
            
        if match:
            filtered\_payments.append(payment)
            
    return filtered\_payments

For PHP:

amount !== $criteria['amount']) {
            $match = false;
        }
        
        // Filter by date range
        if (isset($criteria['startDate']) && isset($criteria['endDate'])) {
            $paymentDate = new DateTime('@' . $payment->created);
            $startDate = new DateTime($criteria['startDate']);
            $endDate = new DateTime($criteria['endDate']);
            
            if ($paymentDate < $startDate || $paymentDate > $endDate) {
                $match = false;
            }
        }
        
        // Filter by payment status
        if (isset($criteria['status']) && $payment->status !== $criteria['status']) {
            $match = false;
        }
        
        if ($match) {
            $filteredPayments[] = $payment;
        }
    }
    
    return $filteredPayments;
}

 

Step 6: Put Everything Together

 

Now, let's combine all the functions to create a complete solution.

For Node.js:

async function findPaymentsByCustomerEmail(email, criteria = {}) {
  // Step 1: Find the customer by email
  const customer = await findCustomerByEmail(email);
  if (!customer) {
    return [];
  }
  
  // Step 2: Get all payments for the customer
  const payments = await getPaymentsForCustomer(customer.id);
  
  // Step 3 (Optional): Filter for specific payments
  if (Object.keys(criteria).length > 0) {
    return findSpecificPayment(payments, criteria);
  }
  
  return payments;
}

// Example usage
async function main() {
  const email = '[email protected]';
  
  // Find all payments for a customer
  const allPayments = await findPaymentsByCustomerEmail(email);
  console.log(`Found ${allPayments.length} payments for ${email}`);
  
  // Find payments with specific criteria
  const specificPayments = await findPaymentsByCustomerEmail(email, {
    amount: 2000, // $20.00
    status: 'succeeded',
    startDate: '2023-01-01',
    endDate: '2023-12-31'
  });
  
  console.log(`Found ${specificPayments.length} payments matching criteria`);
  
  // Display payment details
  specificPayments.forEach(payment => {
    console.log(\`
      Payment ID: ${payment.id}
      Amount: $${payment.amount / 100}
      Date: ${new Date(payment.created \* 1000).toLocaleString()}
      Status: ${payment.status}
      Description: ${payment.description || 'N/A'}
    \`);
  });
}

main().catch(console.error);

For Python:

from datetime import datetime

def find_payments_by_customer_email(email, criteria=None):
    # Step 1: Find the customer by email
    customer = find_customer_by\_email(email)
    if not customer:
        return []
    
    # Step 2: Get all payments for the customer
    payments = get_payments_for\_customer(customer.id)
    
    # Step 3 (Optional): Filter for specific payments
    if criteria:
        return find_specific_payment(payments, criteria)
    
    return payments

# Example usage
if **name** == "**main**":
    email = '[email protected]'
    
    # Find all payments for a customer
    all_payments = find_payments_by_customer\_email(email)
    print(f"Found {len(all\_payments)} payments for {email}")
    
    # Find payments with specific criteria
    specific_payments = find_payments_by_customer\_email(email, {
        'amount': 2000,  # $20.00
        'status': 'succeeded',
        'start\_date': '2023-01-01',
        'end\_date': '2023-12-31'
    })
    
    print(f"Found {len(specific\_payments)} payments matching criteria")
    
    # Display payment details
    for payment in specific\_payments:
        print(f"""
        Payment ID: {payment.id}
        Amount: ${payment.amount / 100}
        Date: {datetime.fromtimestamp(payment.created).strftime('%Y-%m-%d %H:%M:%S')}
        Status: {payment.status}
        Description: {payment.description or 'N/A'}
        """)

For PHP:

id);
    
    // Step 3 (Optional): Filter for specific payments
    if (!empty($criteria)) {
        return findSpecificPayment($payments, $criteria);
    }
    
    return $payments;
}

// Example usage
$email = '[email protected]';

// Find all payments for a customer
$allPayments = findPaymentsByCustomerEmail($email);
echo "Found " . count($allPayments) . " payments for $email\n";

// Find payments with specific criteria
$specificPayments = findPaymentsByCustomerEmail($email, [
    'amount' => 2000, // $20.00
    'status' => 'succeeded',
    'startDate' => '2023-01-01',
    'endDate' => '2023-12-31'
]);

echo "Found " . count($specificPayments) . " payments matching criteria\n";

// Display payment details
foreach ($specificPayments as $payment) {
    echo "
    Payment ID: {$payment->id}
    Amount: ${$payment->amount / 100}
    Date: " . date('Y-m-d H:i:s', $payment->created) . "
    Status: {$payment->status}
    Description: " . ($payment->description ?: 'N/A') . "
    ";
}

 

Step 7: Using the Stripe Dashboard (Alternative Method)

 

If you prefer a non-code solution, you can also use the Stripe Dashboard:

  1. Log in to your Stripe Dashboard at https://dashboard.stripe.com/
  2. Navigate to "Customers" in the left sidebar
  3. Use the search bar at the top to search for the customer's email
  4. Click on the customer to view their details
  5. Go to the "Payments" tab to see all charges associated with this customer

 

Step 8: Handling Pagination (For Large Customer Bases)

 

If you have many payments, you'll need to handle pagination to retrieve all results.

For Node.js:

async function getAllPaymentsForCustomer(customerId) {
  let allPayments = [];
  let hasMore = true;
  let startingAfter = null;
  
  while (hasMore) {
    const params = {
      customer: customerId,
      limit: 100
    };
    
    if (startingAfter) {
      params.starting\_after = startingAfter;
    }
    
    const charges = await stripe.charges.list(params);
    
    allPayments = [...allPayments, ...charges.data];
    hasMore = charges.has\_more;
    
    if (hasMore && charges.data.length > 0) {
      startingAfter = charges.data[charges.data.length - 1].id;
    }
  }
  
  return allPayments;
}

For Python:

def get_all_payments_for_customer(customer\_id):
    all\_payments = []
    has\_more = True
    starting\_after = None
    
    while has\_more:
        params = {
            'customer': customer\_id,
            'limit': 100
        }
        
        if starting\_after:
            params['starting_after'] = starting_after
            
        charges = stripe.Charge.list(\*\*params)
        
        all\_payments.extend(charges.data)
        has_more = charges.has_more
        
        if has\_more and charges.data:
            starting\_after = charges.data[-1].id
            
    return all\_payments

For PHP:

 $customerId,
            'limit' => 100
        ];
        
        if ($startingAfter) {
            $params['starting\_after'] = $startingAfter;
        }
        
        $charges = \Stripe\Charge::all($params);
        
        $allPayments = array\_merge($allPayments, $charges->data);
        $hasMore = $charges->has\_more;
        
        if ($hasMore && count($charges->data) > 0) {
            $startingAfter = end($charges->data)->id;
        }
    }
    
    return $allPayments;
}

 

Conclusion

 

You now know how to find payments in Stripe using a customer's email address. This approach works by first finding the customer associated with the email, then retrieving all payments for that customer, and optionally filtering to find specific payments.

Remember to use your test API keys during development and only switch to live keys in production. Also, consider implementing error handling and rate limiting to avoid hitting Stripe's API limits.

Want to explore opportunities to work with us?

Connect with our team to unlock the full potential of no-code solutions with a no-commitment consultation!

Book a Free Consultation

Client trust and success are our top priorities

When it comes to serving you, we sweat the little things. That’s why our work makes a big impact.

Rapid Dev was an exceptional project management organization and the best development collaborators I've had the pleasure of working with. They do complex work on extremely fast timelines and effectively manage the testing and pre-launch process to deliver the best possible product. I'm extremely impressed with their execution ability.

CPO, Praction - Arkady Sokolov

May 2, 2023

Working with Matt was comparable to having another co-founder on the team, but without the commitment or cost. He has a strategic mindset and willing to change the scope of the project in real time based on the needs of the client. A true strategic thought partner!

Co-Founder, Arc - Donald Muir

Dec 27, 2022

Rapid Dev are 10/10, excellent communicators - the best I've ever encountered in the tech dev space. They always go the extra mile, they genuinely care, they respond quickly, they're flexible, adaptable and their enthusiasm is amazing.

Co-CEO, Grantify - Mat Westergreen-Thorne

Oct 15, 2022

Rapid Dev is an excellent developer for no-code and low-code solutions.
We’ve had great success since launching the platform in November 2023. In a few months, we’ve gained over 1,000 new active users. We’ve also secured several dozen bookings on the platform and seen about 70% new user month-over-month growth since the launch.

Co-Founder, Church Real Estate Marketplace - Emmanuel Brown

May 1, 2024 

Matt’s dedication to executing our vision and his commitment to the project deadline were impressive. 
This was such a specific project, and Matt really delivered. We worked with a really fast turnaround, and he always delivered. The site was a perfect prop for us!

Production Manager, Media Production Company - Samantha Fekete

Sep 23, 2022