I’ll just dump the basics without the patreon stuff. One interesting thing to note is that both the stripe and paypal pro forms are loaded onto the page at the same time but only one is visible at a time. In order to not confuse the user if they switch processor after providing some of the field data, I have event handlers that listen for changes on fields in one form to update the equivalent field in the others. It feels like one form with some changes happening to it as you switch payment processor. Its fast because its just javascript and not going back to the server like changing the time period of membership renewal does.
Here is what I put into the WP page - text mode:
<div class='tsc-membership-options'>
<div class="card"><div class="card-block">
<div class="card-title"><input type='radio' id='monthly' name='time' value='basic-monthly' /><label for='monthly'>Monthly</label></div>
<div class="tsc-membership-price">
<h2>$5/mo</h2>
</div>
<div>
<ul>
<li>Billed Monthly</li>
<li>Cancel at anytime</li>
</ul>
</div>
</div></div>
<div class="card"><div class="card-block">
<div class="card-title"><input type='radio' id='yearly' name='time' value='basic-yearly' /><label for='yearly'>Yearly</label></div>
<div class="tsc-membership-price">
<h2>$50/yr</h2>
</div>
<div>
<ul>
<li>Billed Yearly</li>
<li>Best Value</li>
</ul>
</div>
</div></div>
</div>
<div class="s2member-pro-paypal-form-section-title">Payment Processor</div>
<p>Use your PayPal account, or if you prefer another option, use your credit card directly via Stripe or control your StringClub membership via your Patreon donation.</p>
<div class='tsc-payment-processors'>
<div><div class='tsc-processor-note'> </div>
<button class="btn btn-green paypal" data-proc="paypal">Paypal</button>
</div>
<div><div class='tsc-processor-note'>Credit Card via</div>
<button class="btn btn-outline-green stripe" data-proc="stripe">Stripe</button>
</div>
<div><div class='tsc-processor-note'>Control your membership via</div>
<button class="btn btn-outline-green patreon" data-proc="patreon">Patreon</button>
</div>
</div>
<div class='tsc-membership-form'>
<div class='tsc-paypal-form tsc-payment-form'>
[s2Member-Pro-PayPal-Form level="1" custom="www.stringclub.com" accept="paypal" accpt_via_paypal="paypal"]
[s2Member-Pro-PayPal-Form ccaps="" desc="$5 USD / Monthly (recurring charge, for ongoing access)" ps="paypal" lc="" cc="USD" dg="0" ns="1" ta="0" tp="0" tt="D" ra="5" rp="1" rt="M" rr="1" rrt="" rra="2" coupon="" accept_coupons="0" default_country_code="" captcha="0" success="/thank-you/?auth=1m" /]
[s2Member-Pro-PayPal-Form ccaps="" desc="$50 USD / Yearly (recurring charge, for ongoing access)" ps="paypal" lc="" cc="USD" dg="0" ns="1" ta="0" tp="0" tt="D" ra="50" rp="1" rt="Y" rr="1" rrt="" rra="2" coupon="" accept_coupons="0" default_country_code="" captcha="0" success="/thank-you/?auth=1y" /]
[/s2Member-Pro-PayPal-Form]
</div>
<div class='tsc-stripe-form tsc-payment-form' style='display:none'>
[s2Member-Pro-Stripe-Form level="1" custom="www.stringclub.com"]
[s2Member-Pro-Stripe-Form l ccaps="" desc="$5 USD / Monthly (recurring charge, for ongoing access)" cc="USD" ta="0" tp="0" tt="D" ra="5" rp="1" rt="M" rr="1" coupon="" accept_coupons="0" default_country_code="US" captcha="0" success="/thank-you/?auth=1m" /]
[s2Member-Pro-Stripe-Form l ccaps="" desc="$50 USD / Yearly (recurring charge, for ongoing access)" cc="USD" ta="0" tp="0" tt="D" ra="50" rp="1" rt="Y" rr="1" coupon="" accept_coupons="0" default_country_code="US" captcha="0" success="/thank-you/?auth=1y" /]
[/s2Member-Pro-Stripe-Form]
</div>
</div>
I use css to show hide stuff:
.tsc-membership-form {
#s2member-pro-paypal-checkout-form-options-section,
#s2member-pro-stripe-checkout-form-options-section {
display: none !important;
}
}
.tsc-payment-form {
min-height:700px;
}
.tsc-payment-processors {
display: flex;
flex-flow: row wrap;
.tsc-processor-note {
font-size: small;
margin-left: 15px;
}
>div:nth-child(2) {
margin-left:25px;
}
}
#s2member-pro-stripe-checkout-form-description-div {
display:none;
}
@media (max-width:$colapse4) {
.tsc-payment-processors {
>div:first-child {
width: 100%;
}
>div:nth-child(2) {
margin-left:0;
}
}
}
I use JS to swap visibility based on interations with stuff from WP page content:
(function($) {
var selectedCssName = "btn-green";
var notSelectedCssName = "btn-outline-green";
var active = "paypal";
if($("#s2member-pro-paypal-checkout-options").val() == 2 || $("#s2member-pro-stripe-checkout-options").val() == 2) {
$("#yearly").prop("checked", true);
}
else {
$("#monthly").prop("checked", true);
}
var fieldSync = [
["#s2member-pro-stripe-checkout-first-name","#s2member-pro-paypal-checkout-first-name"],
["#s2member-pro-stripe-checkout-last-name","#s2member-pro-paypal-checkout-last-name"],
["#s2member-pro-stripe-checkout-email", "#s2member-pro-paypal-checkout-email"],
["#s2member-pro-stripe-checkout-username", "#s2member-pro-paypal-checkout-username", "#patreon_username"]
];
fieldSync.forEach(function(flds) {
var has3rd = flds.length > 2;
if($(flds[0]).val()){
$(flds[1]).val($(flds[0]).val());
}
else if($(flds[1]).val()){
$(flds[0]).val($(flds[1]).val());
}
$(flds[0]).change(function() {
$(flds[1]).val($(this).val());
if(has3rd)
$(flds[2]).val($(this).val());
});
$(flds[1]).change(function() {
$(flds[0]).val($(this).val());
if(has3rd)
$(flds[2]).val($(this).val());
});
if(has3rd)
$(flds[2]).change(function() {
$(flds[0]).val($(this).val());
$(flds[1]).val($(this).val());
});
});
$("#monthly, #yearly").click(function() {
var term = this.id;
if(active == "paypal" || active == "stripe")
$("#s2member-pro-" + active + "-checkout-options").val(term=="monthly"?1:2).change();
});
$(".tsc-payment-processors").on("click", "button", function(evt) {
$(".tsc-payment-processors button").removeClass(selectedCssName).addClass(notSelectedCssName);
$(".tsc-payment-form").hide();
var $this = $(this).removeClass(notSelectedCssName).addClass(selectedCssName);
active = $this.data("proc");
$(".tsc-"+ active +"-form").show();
});
})(jQuery);