Tips and Tricks HQ Support Portal › Forums › WP Affiliate Platform › Integrating WP Affiliate with Recurring Paypal Subscription/Membership
Tagged: membership, PayPal, recurring, subscription, WP Affiliate
- This topic has 3 replies, 2 voices, and was last updated 13 years, 5 months ago by amin007.
-
AuthorPosts
-
June 4, 2011 at 3:14 pm #3529rlthormanMember
I bought the affiliate plugin and was told I would need to do Option 2 of this integration (http://www.tipsandtricks-hq.com/wordpress-affiliate/plain-paypal-button-and-affiliate-plugin-integration-168), but got confused because on both the first and second step (notify_url and custom) of Option 2 there was already information for the membership section of my site where I would replace the code. I am placing the gateway code below – could you possibly let me know how to edit the code so I can integrate the affiliate plugin? Thank you!
<?php
class paypalexpress extends M_Gateway {
var $gateway = 'paypalexpress';
var $title = 'PayPal Express';
function paypalexpress() {
parent::M_Gateway();
add_action('M_gateways_settings_' . $this->gateway, array(&$this, 'mysettings'));
// If I want to override the transactions output - then I can use this action
//add_action('M_gateways_transactions_' . $this->gateway, array(&$this, 'mytransactions'));
if($this->is_active()) {
// Subscription form gateway
add_action('membership_purchase_button', array(&$this, 'display_subscribe_button'), 1, 3);
// Payment return
add_action('membership_handle_payment_return_' . $this->gateway, array(&$this, 'handle_paypal_return'));
}
}
function mysettings() {
global $M_options;
?>
<table class="form-table">
<tbody>
<tr valign="top">
<th scope="row"><?php _e('PayPal Email', 'membership') ?></th>
<td><input type="text" name="paypal_email" value="<?php esc_attr_e(get_option( $this->gateway . "_paypal_email" )); ?>" />
<br />
</td>
</tr>
<tr valign="top">
<th scope="row"><?php _e('PayPal Site', 'membership') ?></th>
<td><select name="paypal_site">
<?php
$paypal_site = get_option( $this->gateway . "_paypal_site" );
$sel_locale = empty($paypal_site) ? 'US' : $paypal_site;
$locales = array(
'AU' => 'Australia',
'AT' => 'Austria',
'BE' => 'Belgium',
'CA' => 'Canada',
'CN' => 'China',
'FR' => 'France',
'DE' => 'Germany',
'HK' => 'Hong Kong',
'IT' => 'Italy',
'MX' => 'Mexico',
'NL' => 'Netherlands',
'NZ' => 'New Zealand',
'PL' => 'Poland',
'SG' => 'Singapore',
'ES' => 'Spain',
'SE' => 'Sweden',
'CH' => 'Switzerland',
'GB' => 'United Kingdom',
'US' => 'United States'
);
foreach ($locales as $key => $value) {
echo '<option value="' . esc_attr($key) . '"';
if($key == $sel_locale) echo 'selected="selected"';
echo '>' . esc_html($value) . '</option>' . "n";
}
?>
</select>
<br />
<?php //_e('Format: 00.00 - Ex: 1.25', 'supporter') ?></td>
</tr>
<tr valign="top">
<th scope="row"><?php _e('Paypal Currency', 'membership') ?></th>
<td><?php
if(empty($M_options['paymentcurrency'])) {
$M_options['paymentcurrency'] = 'USD';
}
echo esc_html($M_options['paymentcurrency']); ?></td>
</tr>
<tr valign="top">
<th scope="row"><?php _e('PayPal Mode', 'membership') ?></th>
<td><select name="paypal_status">
<option value="live" <?php if (get_option( $this->gateway . "_paypal_status" ) == 'live') echo 'selected="selected"'; ?>><?php _e('Live Site', 'membership') ?></option>
<option value="test" <?php if (get_option( $this->gateway . "_paypal_status" ) == 'test') echo 'selected="selected"'; ?>><?php _e('Test Mode (Sandbox)', 'membership') ?></option>
</select>
<br />
</td>
</tr>
<tr valign="top">
<th scope="row"><?php _e('Subscription button', 'membership') ?></th>
<?php
$button = get_option( $this->gateway . "_paypal_button", 'https://www.paypal.com/en_US/i/btn/btn_subscribe_LG.gif' );
?>
<td><input type="text" name="paypal_button" value="<?php esc_attr_e($button); ?>" style='width: 40em;' />
<br />
</td>
</tr>
</tbody>
</table>
<?php
}
function build_custom($user_id, $sub_id, $amount) {
$custom = '';
//fake:user:sub:key
$custom = time() . ':' . $user_id . ':' . $sub_id . ':';
$key = md5('MEMBERSHIP' . $amount);
$custom .= $key;
return $custom;
}
function single_button($pricing, $subscription, $user_id) {
global $M_options;
if(empty($M_options['paymentcurrency'])) {
$M_options['paymentcurrency'] = 'USD';
}
$form = '';
if (get_option( $this->gateway . "_paypal_status" ) == 'live') {
$form .= '<form action="https://www.paypal.com/cgi-bin/webscr" method="post">';
} else {
$form .= '<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post">';
}
$form .= '<input type="hidden" name="business" value="' . esc_attr(get_option( $this->gateway . "_paypal_email" )) . '">';
$form .= '<input type="hidden" name="cmd" value="_xclick">';
$form .= '<input type="hidden" name="item_number" value="' . $subscription->sub_id() . '">';
$form .= '<input type="hidden" name="item_name" value="' . $subscription->sub_name() . '">';
$form .= '<input type="hidden" name="amount" value="' . $pricing[0]['amount'] . '.00">';
$form .= '<input type="hidden" name="currency_code" value="' . $M_options['paymentcurrency'] .'">';
$form .= '<input type="hidden" name="custom" value="' . $this->build_custom($user_id, $subscription->id, $pricing[0]['amount'] . '.00') .'">';
$form .= '<input type="hidden" name="lc" value="' . esc_attr(get_option( $this->gateway . "_paypal_site" )) . '">';
$form .= '<input type="hidden" name="notify_url" value="' . trailingslashit(get_option('home')) . 'paymentreturn/' . esc_attr($this->gateway) . '">';
$button = get_option( $this->gateway . "_paypal_button", 'https://www.paypal.com/en_US/i/btn/btn_subscribe_LG.gif' );
$form .= '<input type="image" name="submit" border="0" src="' . $button . '" alt="PayPal - The safer, easier way to pay online">';
$form .= '<img alt="" border="0" width="1" height="1" src="https://www.paypal.com/en_US/i/scr/pixel.gif" >';
$form .= '</form>';
return $form;
}
function single_sub_button($pricing, $subscription, $user_id, $norepeat = false) {
global $M_options;
if(empty($M_options['paymentcurrency'])) {
$M_options['paymentcurrency'] = 'USD';
}
$form = '';
//if($pricing[0]['type'] == 'indefinite') $pricing[0]['days'] = 365;
if (get_option( $this->gateway . "_paypal_status" ) == 'live') {
$form .= '<form action="https://www.paypal.com/cgi-bin/webscr" method="post">';
} else {
$form .= '<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post">';
}
$form .= '<input type="hidden" name="business" value="' . esc_attr(get_option( $this->gateway . "_paypal_email" )) . '">';
$form .= '<input type="hidden" name="cmd" value="_xclick-subscriptions">';
$form .= '<input type="hidden" name="item_name" value="' . $subscription->sub_name() . '">';
$form .= '<input type="hidden" name="item_number" value="' . $subscription->sub_id() . '">';
$form .= '<input type="hidden" name="currency_code" value="' . $M_options['paymentcurrency'] .'">';
$form .= '<input type="hidden" name="a3" value="' . $pricing[0]['amount'] . '.00">';
$form .= '<input type="hidden" name="p3" value="' . $pricing[0]['period'] . '">';
$form .= '<input type="hidden" name="t3" value="' . strtoupper($pricing[0]['unit']) . '"> <!-- Set recurring payments until canceled. -->';
$form .= '<input type="hidden" name="custom" value="' . $this->build_custom($user_id, $subscription->id, $pricing[0]['amount'] . '.00') .'">';
$form .= '<input type="hidden" name="return" value="' . get_option('home') . '">';
$form .= '<input type="hidden" name="cancel_return" value="' . get_option('home') . '">';
$form .= '<input type="hidden" name="lc" value="' . esc_attr(get_option( $this->gateway . "_paypal_site" )) . '">';
$form .= '<input type="hidden" name="notify_url" value="' . trailingslashit(get_option('home')) . 'paymentreturn/' . esc_attr($this->gateway) . '">';
if($norepeat) {
$form .= '<input type="hidden" name="src" value="0">';
} else {
$form .= '<input type="hidden" name="src" value="1">';
}
$button = get_option( $this->gateway . "_paypal_button", 'https://www.paypal.com/en_US/i/btn/btn_subscribe_LG.gif' );
$form .= '<!-- Display the payment button. --> <input type="image" name="submit" border="0" src="' . $button . '" alt="PayPal - The safer, easier way to pay online">';
$form .= '<img alt="" border="0" width="1" height="1" src="https://www.paypal.com/en_US/i/scr/pixel.gif" >';
$form .= '</form>';
return $form;
}
function complex_sub_button($pricing, $subscription, $user_id) {
global $M_options;
if(empty($M_options['paymentcurrency'])) {
$M_options['paymentcurrency'] = 'USD';
}
$form = '';
if (get_option( $this->gateway . "_paypal_status" ) == 'live') {
$form .= '<form action="https://www.paypal.com/cgi-bin/webscr" method="post">';
} else {
$form .= '<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post">';
}
$form .= '<input type="hidden" name="business" value="' . esc_attr(get_option( $this->gateway . "_paypal_email" )) . '">';
$form .= '<input type="hidden" name="cmd" value="_xclick-subscriptions">';
$form .= '<input type="hidden" name="item_name" value="' . $subscription->sub_name() . '">';
$form .= '<input type="hidden" name="item_number" value="' . $subscription->sub_id() . '">';
$form .= '<input type="hidden" name="currency_code" value="' . $M_options['paymentcurrency'] .'">';
// complex bits here
$count = 1;
$ff = array();
foreach((array) $pricing as $key => $price) {
switch($price['type']) {
case 'finite': if(empty($price['amount'])) $price['amount'] = '0';
if($count < 3) {
$ff['a' . $count] = $price['amount'] . '.00';
$ff['p' . $count] = $price['period'];
$ff['t' . $count] = strtoupper($price['unit']);
} else {
// Or last finite is going to be the end of the subscription payments
$ff['a3'] = $price['amount'] . '.00';
$ff['p3'] = $price['period'];
$ff['t3'] = strtoupper($price['unit']);
$ff['src'] = '0';
}
$count++;
break;
case 'indefinite':
if(empty($price['amount'])) $price['amount'] = '0';
if($price['amount'] == '0') {
// The indefinite rule is free, we need to move any previous
// steps up to this one as we can't have a free a3
if( isset($ff['a2']) && $ff['a2'] != '0.00' ) {
// we have some other earlier rule so move it up
$ff['a3'] = $ff['a2'];
$ff['p3'] = $ff['p2'];
$ff['t3'] = $ff['t2'];
unset($ff['a2']);
unset($ff['p2']);
unset($ff['t2']);
$ff['src'] = '0';
} elseif( isset($ff['a1']) && $ff['a1'] != '0.00' ) {
$ff['a3'] = $ff['a1'];
$ff['p3'] = $ff['p1'];
$ff['t3'] = $ff['t1'];
unset($ff['a1']);
unset($ff['p1']);
unset($ff['t1']);
$ff['src'] = '0';
}
} else {
$ff['a3'] = $price['amount'] . '.00';
$ff['p3'] = 1;
$ff['t3'] = 'Y';
$ff['src'] = '0';
}
break;
case 'serial':
if(empty($price['amount'])) $price['amount'] = '0';
if($price['amount'] == '0') {
// The serial rule is free, we need to move any previous
// steps up to this one as we can't have a free a3
if( isset($ff['a2']) && $ff['a2'] != '0.00' ) {
// we have some other earlier rule so move it up
$ff['a3'] = $ff['a2'];
$ff['p3'] = $ff['p2'];
$ff['t3'] = $ff['t2'];
unset($ff['a2']);
unset($ff['p2']);
unset($ff['t2']);
$ff['src'] = '1';
} elseif( isset($ff['a1']) && $ff['a1'] != '0.00' ) {
$ff['a3'] = $ff['a1'];
$ff['p3'] = $ff['p1'];
$ff['t3'] = $ff['t1'];
unset($ff['a1']);
unset($ff['p1']);
unset($ff['t1']);
$ff['src'] = '1';
}
} else {
$ff['a3'] = $price['amount'] . '.00';
$ff['p3'] = $price['period'];
$ff['t3'] = strtoupper($price['unit']);
$ff['src'] = '1';
}
break;
}
}
if(!empty($ff)) {
foreach($ff as $key => $value) {
$form .= '<input type="hidden" name="' . $key . '" value="' . $value . '">';
}
}
$form .= '<input type="hidden" name="custom" value="' . $this->build_custom($user_id, $subscription->id, $ff['a3']) .'">';
// Remainder of the easy bits
$form .= '<input type="hidden" name="return" value="' . get_option('home') . '">';
$form .= '<input type="hidden" name="cancel_return" value="' . get_option('home') . '">';
$form .= '<input type="hidden" name="lc" value="' . esc_attr(get_option( $this->gateway . "_paypal_site" )) . '">';
$form .= '<input type="hidden" name="notify_url" value="' . trailingslashit(get_option('home')) . 'paymentreturn/' . esc_attr($this->gateway) . '">';
$button = get_option( $this->gateway . "_paypal_button", 'https://www.paypal.com/en_US/i/btn/btn_subscribe_LG.gif' );
$form .= '<!-- Display the payment button. --> <input type="image" name="submit" border="0" src="' . $button . '" alt="PayPal - The safer, easier way to pay online">';
$form .= '<img alt="" border="0" width="1" height="1" src="https://www.paypal.com/en_US/i/scr/pixel.gif" >';
$form .= '</form>';
return $form;
}
function build_subscribe_button($subscription, $pricing, $user_id) {
if(!empty($pricing)) {
// check to make sure there is a price in the subscription
// we don't want to display free ones for a payment system
$free = true;
foreach($pricing as $key => $price) {
if(!empty($price['amount']) && $price['amount'] > 0 ) {
$free = false;
}
}
if(!$free) {
if(count($pricing) == 1) {
// A basic price or a single subscription
if(in_array($pricing[0]['type'], array('indefinite','finite'))) {
// one-off payment
return $this->single_sub_button($pricing, $subscription, $user_id, true);
} else {
// simple subscription
return $this->single_sub_button($pricing, $subscription, $user_id);
}
} else {
// something much more complex
return $this->complex_sub_button($pricing, $subscription, $user_id);
}
}
}
}
function display_subscribe_button($subscription, $pricing, $user_id) {
echo $this->build_subscribe_button($subscription, $pricing, $user_id);
}
function update() {
if(isset($_POST['paypal_email'])) {
update_option( $this->gateway . "_paypal_email", $_POST[ 'paypal_email' ] );
update_option( $this->gateway . "_paypal_site", $_POST[ 'paypal_site' ] );
update_option( $this->gateway . "_currency", $_POST[ 'currency' ] );
update_option( $this->gateway . "_paypal_status", $_POST[ 'paypal_status' ] );
update_option( $this->gateway . "_paypal_button", $_POST[ 'paypal_button' ] );
}
// default action is to return true
return true;
}
// IPN stuff
function handle_paypal_return() {
// PayPal IPN handling code
if ((isset($_POST['payment_status']) || isset($_POST['txn_type'])) && isset($_POST['custom'])) {
if (get_option( $this->gateway . "_paypal_status" ) == 'live') {
$domain = 'https://www.paypal.com';
} else {
$domain = 'https://www.sandbox.paypal.com';
}
$req = 'cmd=_notify-validate';
if (!isset($_POST)) $_POST = $HTTP_POST_VARS;
foreach ($_POST as $k => $v) {
if (get_magic_quotes_gpc()) $v = stripslashes($v);
$req .= '&' . $k . '=' . $v;
}
$header = 'POST /cgi-bin/webscr HTTP/1.0' . "rn"
. 'Content-Type: application/x-www-form-urlencoded' . "rn"
. 'Content-Length: ' . strlen($req) . "rn"
. "rn";
@set_time_limit(60);
if ($conn = @fsockopen($domain, 80, $errno, $errstr, 30)) {
fputs($conn, $header . $req);
socket_set_timeout($conn, 30);
$response = '';
$close_connection = false;
while (true) {
if (feof($conn) || $close_connection) {
fclose($conn);
break;
}
$st = @fgets($conn, 4096);
if ($st === false) {
$close_connection = true;
continue;
}
$response .= $st;
}
$error = '';
$lines = explode("n", str_replace("rn", "n", $response));
// looking for: HTTP/1.1 200 OK
if (count($lines) == 0) $error = 'Response Error: Header not found';
else if (substr($lines[0], -7) != ' 200 OK') $error = 'Response Error: Unexpected HTTP response';
else {
// remove HTTP header
while (count($lines) > 0 && trim($lines[0]) != '') array_shift($lines);
// first line will be empty, second line will have the result
if (count($lines) < 2) $error = 'Response Error: No content found in transaction response';
else if (strtoupper(trim($lines[1])) != 'VERIFIED') $error = 'Response Error: Unexpected transaction response';
}
if ($error != '') {
echo $error;
exit;
}
}
// handle cases that the system must ignore
//if ($_POST['payment_status'] == 'In-Progress' || $_POST['payment_status'] == 'Partially-Refunded') exit;
$new_status = false;
// process PayPal response
switch ($_POST['payment_status']) {
case 'Partially-Refunded':
break;
case 'In-Progress':
break;
case 'Completed':
case 'Processed':
// case: successful payment
$amount = $_POST['mc_gross'];
$currency = $_POST['mc_currency'];
list($timestamp, $user_id, $sub_id, $key) = explode(':', $_POST['custom']);
$this->record_transaction($user_id, $sub_id, $amount, $currency, $timestamp, $_POST['txn_id'], $_POST['payment_status'], '');
// Added for affiliate system link
do_action('membership_payment_processed', $user_id, $sub_id, $amount, $currency, $_POST['txn_id']);
break;
case 'Reversed':
// case: charge back
$note = 'Last transaction has been reversed. Reason: Payment has been reversed (charge back)';
$amount = $_POST['mc_gross'];
$currency = $_POST['mc_currency'];
list($timestamp, $user_id, $sub_id, $key) = explode(':', $_POST['custom']);
$this->record_transaction($user_id, $sub_id, $amount, $currency, $timestamp, $_POST['txn_id'], $_POST['payment_status'], $note);
$member = new M_Membership($user_id);
if($member) {
$member->expire_subscription($sub_id);
$member->deactivate();
}
do_action('membership_payment_reversed', $user_id, $sub_id, $amount, $currency, $_POST['txn_id']);
break;
case 'Refunded':
// case: refund
$note = 'Last transaction has been reversed. Reason: Payment has been refunded';
$amount = $_POST['mc_gross'];
$currency = $_POST['mc_currency'];
list($timestamp, $user_id, $sub_id, $key) = explode(':', $_POST['custom']);
$this->record_transaction($user_id, $sub_id, $amount, $currency, $timestamp, $_POST['txn_id'], $_POST['payment_status'], $note);
$member = new M_Membership($user_id);
if($member) {
$member->expire_subscription($sub_id);
}
do_action('membership_payment_refunded', $user_id, $sub_id, $amount, $currency, $_POST['txn_id']);
break;
case 'Denied':
// case: denied
$note = 'Last transaction has been reversed. Reason: Payment Denied';
$amount = $_POST['mc_gross'];
$currency = $_POST['mc_currency'];
list($timestamp, $user_id, $sub_id, $key) = explode(':', $_POST['custom']);
$this->record_transaction($user_id, $sub_id, $amount, $currency, $timestamp, $_POST['txn_id'], $_POST['payment_status'], $note);
$member = new M_Membership($user_id);
if($member) {
$member->expire_subscription($sub_id);
$member->deactivate();
}
do_action('membership_payment_denied', $user_id, $sub_id, $amount, $currency, $_POST['txn_id']);
break;
case 'Pending':
// case: payment is pending
$pending_str = array(
'address' => 'Customer did not include a confirmed shipping address',
'authorization' => 'Funds not captured yet',
'echeck' => 'eCheck that has not cleared yet',
'intl' => 'Payment waiting for aproval by service provider',
'multi-currency' => 'Payment waiting for service provider to handle multi-currency process',
'unilateral' => 'Customer did not register or confirm his/her email yet',
'upgrade' => 'Waiting for service provider to upgrade the PayPal account',
'verify' => 'Waiting for service provider to verify his/her PayPal account',
'*' => ''
);
$reason = @$_POST['pending_reason'];
$note = 'Last transaction is pending. Reason: ' . (isset($pending_str[$reason]) ? $pending_str[$reason] : $pending_str['*']);
$amount = $_POST['mc_gross'];
$currency = $_POST['mc_currency'];
list($timestamp, $user_id, $sub_id, $key) = explode(':', $_POST['custom']);
$this->record_transaction($user_id, $sub_id, $amount, $currency, $timestamp, $_POST['txn_id'], $_POST['payment_status'], $note);
do_action('membership_payment_pending', $user_id, $sub_id, $amount, $currency, $_POST['txn_id']);
break;
default:
// case: various error cases
}
//check for subscription details
switch ($_POST['txn_type']) {
case 'subscr_signup':
// start the subscription
list($timestamp, $user_id, $sub_id, $key) = explode(':', $_POST['custom']);
// create_subscription
$member = new M_Membership($user_id);
if($member) {
$member->create_subscription($sub_id);
}
do_action('membership_payment_subscr_signup', $user_id, $sub_id);
break;
case 'subscr_cancel':
// mark for removal
list($timestamp, $user_id, $sub_id, $key) = explode(':', $_POST['custom']);
$member = new M_Membership($user_id);
if($member) {
$member->mark_for_expire($sub_id);
}
do_action('membership_payment_subscr_cancel', $user_id, $sub_id);
break;
case 'new_case':
// a dispute
if($_POST['case_type'] == 'dispute') {
// immediately suspend the account
$member = new M_Membership($user_id);
if($member) {
$member->deactivate();
}
}
do_action('membership_payment_new_case', $user_id, $sub_id, $_POST['case_type']);
break;
}
} else {
// Did not find expected POST variables. Possible access attempt from a non PayPal site.
header('Status: 404 Not Found');
echo 'Error: Missing POST variables. Identification is not possible.';
exit;
}
}
}
M_register_gateway('paypalexpress', 'paypalexpress');
?>June 5, 2011 at 12:34 am #33069amin007ParticipantThe following line of code indicates that the developer left a hook for affiliate plugin (which is great):
// Added for affiliate system link
do_action('membership_payment_processed', $user_id, $sub_id, $amount, $currency, $_POST['txn_id']);We could potentially use this hook to do an integration with this plugin without modifying the core code of the membership plugin. Can you please tell me which membership plugin you are using so I can read some documentation and verify the intended use of this hook?
June 6, 2011 at 12:06 pm #33070rlthormanMemberOh that’s great! I am using this one – http://wordpress.org/extend/plugins/membership/, more info – http://premium.wpmudev.org/project/membership.
Thank you!
June 7, 2011 at 1:55 am #33071amin007ParticipantOkay looks promising. I have sent you an email to take care of this.
-
AuthorPosts
- You must be logged in to reply to this topic.