Create a Stripe Customer with Gravity Forms Stripe Product Feed

Stripe is our favourite payment processor around here. We love how easy it is to set up and the level of information it gives you without compromising the security of people paying you. One of the features we particularly enjoy is the Customers area. It makes it so easy to see how many payments someone has made, send receipts again if needed, manually charge them if their credit card information is saved, etc. And our favourite form plugin Gravity Forms has an add-on integration for it (you need the Elite level subscription to access the Gravity Forms Stripe add-on), so it’s perfectly smooth sailing.

So, imagine my surprise when I discovered that the Gravity Forms Stripe add-on doesn’t let you create a customer if the Transaction Type is Product/Services! We generally use Gravity Forms to create subscription payments, which does create a customer when payments are processed, so I just never noticed it before.

Annoying.

So I set about figuring out how I could make this happen. I like the customer data and just because someone is making a one-time payment, doesn’t mean I don’t want that information in Stripe!

Truthfully, I feel like this should be a native option within the add-on: the option to create a customer if you want. The ability is already there, it just needs to be added to the other transaction type.

In the mean time, here’s a workaround:

You hook into the gform_stripe_customer_id filter and call the create_customer function to force the customer creation. I used this snippet from Gravity Forms as my starting point.

Here I’ve limited the function to trigger only if the transaction type is product and the Stripe feed name is Create Customer and Payment. If you want to apply this to all product transactions, just remove the second condition.

add_filter( 'gform_stripe_customer_id', function ( $customer_id, $feed, $entry, $form ) {
    if ( rgars( $feed, 'meta/transactionType' ) == 'product' && rgars( $feed, 'meta/feedName' ) == 'Create Customer and Payment' ) {
        $customer_meta = array();
    }
 
    return $customer_id;
}, 10, 4 );

Although you can create a customer without the email address, it’s fairly useless to do so, since new payments won’t get connected to the customer then (no matching identifier)! So you want to grab the email address. In order to do this, add a new meta data field, call it Email, and then select the email field.

Screenshot of Stripe Feed with Gravity Forms

Then you have two options, you can hardcode which field contains the email address or you can loop through the metadata array and check for the email.

The Hard Coded Way

Here’s the hardcoded way, assuming that your Email field is the second piece of metadata (as in the example above):

$email_field = rgars( $feed, 'meta/metaData/2/value' );

You’re using the Gravity Forms provided function rgars to grab the value of the second piece of metadata, which is found inside the metaData array. This gets you the field key of the email address field, which you can use to grab the actual value.

You add the email address to the customer_meta array we initialized at the beginning, using the get_field_value function and the field key we found and stored in $email_field.

$customer_meta['email'] = gf_stripe()->get_field_value( $form, $entry, $email_field );

Then you can call the create_customer function with all the proper information, and return the customer ID.

$customer = gf_stripe()->create_customer( $customer_meta, $feed, $entry, $form );
 
return $customer->id;

The complete (hard coded) function

Below you can see the hard coded field version of the function (this was my original code, which I later modified to be more flexible aka proper, hard coding is a terrible practice, but good for learning):

add_filter( 'gform_stripe_customer_id', function ( $customer_id, $feed, $entry, $form ) {
    if ( rgars( $feed, 'meta/transactionType' ) == 'product' && rgars( $feed, 'meta/feedName' ) == 'Create Customer and Payment' ) {
        $customer_meta = array();
 		
        $email_field = rgars( $feed, 'meta/metaData/2/value' );
        if ( ! empty( $email_field ) ) {
            $customer_meta['email'] = gf_stripe()->get_field_value( $form, $entry, $email_field );
        }
		
        $customer = gf_stripe()->create_customer( $customer_meta, $feed, $entry, $form );
 
        return $customer->id;
    }
 
    return $customer_id;
}, 10, 4 );

The Flexible Way

The better way is to loop through the metaData array to find the metadata that contains the email field, and then use that. This way you don’t have to worry about the order you add the metadata in.

To loop through, you’ll replace line 5 in the function with this:

$metadata_field = rgars( $feed, 'meta/metaData' );

foreach ($metadata_field as $metadata) {
    if ($metadata['custom_key'] == 'Email') {
        $email_field = $metadata['value'];
    }
}

The complete (flexible) function

add_filter( 'gform_stripe_customer_id', function ( $customer_id, $feed, $entry, $form ) {
    if ( rgars( $feed, 'meta/transactionType' ) == 'product' && rgars( $feed, 'meta/feedName' ) == 'Create Customer and Payment' ) {
        $customer_meta = array();
 		
        $metadata_field = rgars( $feed, 'meta/metaData' );

        foreach ($metadata_field as $metadata) {
            if ($metadata['custom_key'] == 'Email') {
                $email_field = $metadata['value'];
            }
        }
        
        if ( ! empty( $email_field ) ) {
            $customer_meta['email'] = gf_stripe()->get_field_value( $form, $entry, $email_field );
        }
		
        $customer = gf_stripe()->create_customer( $customer_meta, $feed, $entry, $form );
 
        return $customer->id;
    }
 
    return $customer_id;
}, 10, 4 );

And that’s it! Just add your preferred version of the function to your functions.php file or to your functionality plugin, and you’re good to go.