Blog

Building WordPress Membership Feature, Part 3: Creating the Paywall

Tags:

If you’ve been following along in this series, then you’ll recall the original purpose behind these tutorials. Membership plugins for WordPress like S2Member and aMember are powerful, yet somewhat bloated and confusing. If you know your way around those plugins and they work for your theme, there’s no need to reinvent the wheel. But if you need a more custom and lightweight approach to integrate membership functionality with your site, this series aims to be a great guide.

In Part 1, we created a framework to enable membership by restricting content based on a user’s capability. In Part 2, we created a form for handling user registration. And in Part 3, we will create a paywall for users.

Suppose you have your members already, but now you want to process new members—accepting payment for subscribers or one-time enrollment. Either way you do it, you’ll want to collect.

Prerequisites

As before, prerequisites for this tutorial include an intimate working knowledge of PHP and WordPress development, WordPress action and filter hooks, and a payment gateway with a supporting API. You must have all the components specified from Part 1, which includes having defined your member roles, capabilities, and access.

Advanced Tutorial

From here, you can get as complicated or be as simple as you would like. The gist is to collect all relevant user profile, registration, password, contact information, and supplemental fields as you need before processing payment. This will consist of a series of forms, and will conclude with processing all relevant fields.

To better follow this tutorial, please download the included WP_Membership package. Once you have the attached files, let’s open them up and take some inventory. You can extract the package to your theme directory. Twentyfourteen is the parent theme and is therefore required for this tutorial to work. You will find functions.php with all the helpers, the two classes that handle the form field generation for the profile/registration form, two page templates, and two form templates.

First you’ll need to create two pages in WP admin—we use ‘register’ and ‘thank-you’ as page slugs for the ‘Register’ and ‘Thank You’ pages respectively. Attach the appropriate templates to those two pages. If you modify the routes of those pages, be sure to adjust the constants at the top of the functions.php file. These two pages serve as the general logic and endpoints to the form handling.

Review

In our previous two tutorials, we detailed how to add roles and capabilities for your members, filtered the majority of the links used within WordPress, added template tags to dictate which sections are members only, and created the registration form and processor to create new users. Now we need to be able to collect payment.

Barrel_Blog-Post_Members-Only_Part3

Accepting Payment

If you remember from our last tutorial, we used a static method, WP_Membership::add_pending_user(), to process the user data and create a new user. Our function should have returned a numeric user ID. If we instead modify the method to return the result of another function, which accepts payment, we can then handle the payment once a successful user is created. Let’s call this method handle_payment() and let’s make it private.

        private function handle_payment( $user_id ) {
            // check to see if member is paying by credit card
            $payment = get_user_meta($user_id, "payment_type", true);
            if ( "by_card" == $payment ) {
                /* handle payment api here
             * Braintree, Stripe, Paypal, etc
             *
             */
                $success = true;
                if ( $success ) {
                    return self::change_member_type( $user_id );
                }
            } else {
                // no payments, register the user
                return true;
            }
        }

As you can see, the input for this function is the user ID that we were returning from the add_pending_user() method. In this example, we gave the user the choice of paying by mail or electronically, so we check the saved preference of how the user chose to pay.

At this point, you’ll need to check the documentation of your payment gateway’s API. Most allow a transaction or subscription object to be created based on the user’s information. In some cases, you might try to perform a lookup of the user to see if payment information has been saved.

        private function handle_payment( $user_id ) {
            // check to see if member is paying by credit card
            $payment = get_user_meta($user_id, "payment_type", true);
            if ( "by_card" == $payment ) {
                // handle payment api here
                $fees = array(
                    "premium" => 900,
                    "standard" => 300,
                );
                $user = new WP_User($user_id);
                $user_login = $user->user_login;
                $hashed_login = hash('adler32', $user_login);
                $args = array(
                    'planId' => 'annual_membership',
                    'price' => $fees[$member_type],
                );

                if ( $customer = Braintree_Customer::find($hashed_login) ) {
                    $args['paymentMethodToken'] = $customer->creditCards[0]->token,
                } else {
                    $result = Braintree_Customer::create(array(
                        'firstName' => @$customer['first_name'],
                        'lastName' => @$customer['last_name'],
                        'company' => @$customer['company_name'],
                        'id' => $hashed_login,
                        'email' => @$customer['email'],
                        'phone' => @$customer['phone_home'],
                        'creditCard' => array(
                            'cardholderName' => @$customer['first_name']." ".@$customer['last_name'],
                            'billingAddress' => array(
                                'firstName' => @$customer['first_name'],
                                'lastName' => @$customer['last_name'],
                                'company' => @$customer['company_name'],
                                'streetAddress' => @$customer['address_1'],
                                'extendedAddress' => @$customer['address_2'],
                                'locality' => @$customer['city'],
                                'region' => @$customer['state'],
                                'postalCode' => @$customer['zip'],
                                'countryCodeAlpha2' => @$customer['country']
                            ),
                            'number' => @$transaction['credit_card']['number'],
                            'cvv' => @$transaction['credit_card']['ccv'],
                            'expirationDate' => @$transaction['credit_card']['expiration_date'],
                            'options' => array(
                                'verifyCard' => true
                            ),
                        ),
                    ));
                    if ( $result->success == true ) {
                        $args['paymentMethodToken'] = $result->customer->creditCards[0]->token,
                    }
                }

               if ( isset($args['paymentMethodToken']) ) {
                   $response = Braintree_Subscription::create($args);
                   if ($response->success == true) {
                       return self::change_member_type( $user_id );
                   }
                }
            } else {
                // no payments, register the user
                return true;
            }
            return false;
        }

In the above example, we find a user based on their handle in Braintree, which is an adler32 hash of their login. We proceed with enrolling the user in the subscription.

There are a number of things you can do at this point, but you have to remember to include a form to collect payment fields. You can see what fields we included by looking at the array instantiated with our WP_MembershipProfiles class. If you review the thank-you.php template, you’ll notice that we do not add the user until after we’ve collected payment details (unless they chose to pay by check, in which case we process the user straight off).

In the end, we should have a new user, with a specific membership type, paid according to your subscription or one-time payment.

Illustrations by Cindy Leong

Popular This Week
25 Must-Have Pages for Your E-commerce Website
January 30, 2015

25 Must-Have Pages for Your E-commerce Website

By Yvonne Weng
New Shopify Theme: Mosaic
January 16, 2016

New Shopify Theme: Mosaic

By Peter Kang
Taking Control of Image Loading
July 29, 2013

Taking Control of Image Loading

By Patrick Kunka
Text-align: Justify and RWD
March 12, 2013

Text-align: Justify and RWD

By Patrick Kunka

Like what you’re reading? Sign up for the Barrel newsletter and receive updates.