How to store billing address information from the s2member plugin

s2member logos2member, the membership plugin we use on Smart Insights, doesn’t store the billing address entered when people purchase memberships or products. I needed a way to be able to get access to that information, and here’s the solution I figured out.

Why doesn’t s2member store billing address information?

Storing cardholder data such as billing address and credit card number is not secure, and puts you in a tricky situation in terms of your site’s PCI Compliance. To avoid this, s2member just passes this information straight onto your payment gateway of choice (in our case this is PayPal) and does not store it locally. It goes without saying that you should NEVER store any credit card details in the WordPress database.

Why would you need to store billing address information from the s2member plugin?

For us, there are two reasons to have access to this information;

1) We want to be able to send billing address (not credit card details) to our CRM/marketing automation platform

We have a marketing automation platform called Office Auto Pilot which runs our email and other marketing activities. It also acts as our customer relationship management (CRM) platform. Not having a member’s address and country details in this is a pain – we’re unable to segment our communications on geographical area, which is lousy when we have members in 50 different countries paying different prices in different currencies.

2) We want our members to be able to see what they’ve purchased previously, and print invoices

s2member doesn’t currently provide any functionality for generating invoices from within WordPress, or allowing members to see what they’ve paid in the past. Relying on PayPal to send receipts to our members isn’t sufficient – many require tax invoices with a letterhead, and at present that means we have to manually create an invoice. As we grow and the volumes increase, this is taking too much time.

How do we store billing address information in the s2member plugin?

s2member comes complete with hundreds of hooks and filters which allow you to attach your custom code to its functionality. Unfortunately (and sorry for saying this s2 guys as the plugin is otherwise exceptional) the documentation is practically non-existent. So you’re left with visiting the API reference and trying to figure out what does what, where and when by trial and error.

After a lot of messing around, I discovered that the action ws_plugin__s2member_during_configure_user_registration_front_side_paid is fired just after someone submits the PayPal payment form, which of course contains the billing address fields.

In order to access this information, you must first create a MU (must-use) plugin in your WordPress installation. These are plugins that WordPress will load automatically. There’s good documentation on creating an s2member MU plugin on the s2member site, so I’ll assume you’ve gone and done that and are now ready to continue.

In order to grab the billing information from the payment form, use the following function and action:

// This function will grab the user street, city, state, country and zip billing address fields and save them as user meta.

add_action('ws_plugin__s2member_during_configure_user_registration_front_side_paid', 's2_grab_fields_from_form');
function s2_grab_fields_from_form($vars = array()) {

update_user_meta( $vars['user_id'], 'billing_street', $_POST['s2member_pro_paypal_checkout']['street'] );
update_user_meta( $vars['user_id'], 'billing_city', $_POST['s2member_pro_paypal_checkout']['city'] );
update_user_meta( $vars['user_id'], 'billing_state', $_POST['s2member_pro_paypal_checkout']['state'] );
update_user_meta( $vars['user_id'], 'billing_country', $_POST['s2member_pro_paypal_checkout']['country'] );
update_user_meta( $vars['user_id'], 'billing_zip', $_POST['s2member_pro_paypal_checkout']['zip'] );


Now, I put the example above to show you how the $vars parameter also contains the WordPress user_id of the person who just purchased a membership, which allows you to store this (and indeed any other information in either the $vars or $_POST arrays) as user_meta. But I stress here that just because you can, doesn’t mean you should. In my case I send the billing address information straight off to our CRM system via an API call, and do not store them locally at all. I would strongly recommend you do the same.

Hope that helps someone else save some time instead of trawling the internet for hours looking for a way of storing billing address information from s2member.