Topic: PayPal hack for Jobberbase v1.9
Hello everyone,
redjumpsuit made a pretty good tutorial to get Jobberbase v1.8 working with PayPal. I have adapted his tutorial for v1.9 and wish to share it. Please note that I have not actually tested it live, but it seems to work... I think.
Step 1 - Create the PayPal settings table with placeholder values. Please note that you may have to add your db prefix to the table's name.
CREATE TABLE IF NOT EXISTS `paypal_settings` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`button_type` varchar(100) CHARACTER SET utf8 NOT NULL,
`button_image` varchar(255) CHARACTER SET utf8 NOT NULL,
`currency_code` varchar(3) CHARACTER SET utf8 NOT NULL,
`return_url` varchar(255) CHARACTER SET utf8 NOT NULL,
`is_active` tinyint(4) NOT NULL,
`first_post_only` tinyint(4) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
INSERT INTO `paypal_settings` (`id`, `button_type`, `button_image`, `currency_code`, `return_url`, `is_active`, `first_post_only`) VALUES
(1, '_s-xclick', 'https://www.paypal.com/en_US/i/btn/btn_paynowCC_LG.gif', 'USD', 'http://localhost/jb18/paypal/', 1, 0);
Step 2 - Alter the types table to add amount and PayPal button ID. Please note that you may have to add your db prefix to the table's name.
ALTER TABLE `types` ADD `amount` INT( 11 ) NULL ,
ADD `paypal_button_id` VARCHAR( 255 ) NULL
Step 3 - In /_config/config.php look for the line...
require_once APP_PATH . '_includes/smarty/libs/Smarty.class.php';
After the above line, add the following code...
// paypal settings
require_once APP_PATH . '_includes/class.PayPal.php';
Step 4 - In /_config/config.settings.php look for the line...
define('CAPTCHA_PRIVATE_KEY', $settings['captcha_private_key']);
After the above line, add the following code...
// PayPal Settings
$pp = new SimplePayPal();
$pp_settings = $pp->showsettings();
define('PAYPAL_IS_ACTIVE',$pp_settings['is_active']);
define('PAYPAL_FIRST_POST_ONLY',$pp_settings['first_post_only']);
define('PAYPAL_BUTTON_TYPE',$pp_settings['button_type']);
define('PAYPAL_BUTTON_IMAGE',$pp_settings['button_image']);
define('PAYPAL_CURRENCY_CODE',$pp_settings['currency_code']);
define('PAYPAL_RETURN_URL',$pp_settings['return_url']);
Step 5 - In /index.php look for the lines...
case 'confirm':
if(!ENABLE_NEW_JOBS) { redirect_to(BASE_URL); exit; }
$flag =1;
$job = new Job($id);
$job_title = BASE_URL . URL_JOB .'/' . $job->mId . '/' . $job->mUrlTitle . '/';
$smarty->assign('auth', $job->GetAuth());
$smarty->assign('job_url', $job_title);
$smarty->assign('first_time_post', $extra);
$template = 'publish-confirmation.tpl';
break;
After the above code, add the following code...
case 'payment':
if(!ENABLE_NEW_JOBS) { redirect_to(BASE_URL); exit; }
$flag =1;
$job = new Job($id);
$job_title = BASE_URL . URL_JOB .'/' . $job->mId . '/' . $job->mUrlTitle . '/';
$smarty->assign('auth', $job->GetAuth());
$smarty->assign('job_url', $job_title);
$smarty->assign('first_time_post', $extra);
if (PAYPAL_IS_ACTIVE == 1) {
$smarty->assign('first_time_post', $job->IsApprovedPosterEmail());
$smarty->assign('paypal_item_number', $id);
$smarty->assign('paypal_item_name', $job->mTitle);
$smarty->assign('paypal_job_type', get_type_name_by_id($job->mTypeId));
$smarty->assign('paypal_amount', get_type_amount_by_id($job->mTypeId));
$smarty->assign('paypal_button_id', get_type_button_id_by_id($job->mTypeId));
}
$template = 'publish-paypal.tpl';
break;
Step 6 - In /page_publish.php look for the line...
redirect_to(BASE_URL . 'confirm/' . $job->mId . '/'.$first_time_post.'/');
Replace the above line with the following code...
if (PAYPAL_IS_ACTIVE == 1 && PAYPAL_FIRST_POST_ONLY == 0)
{
redirect_to(BASE_URL . 'payment/' . $job->mId . '/'.$first_time_post.'/');
}
else
{
redirect_to(BASE_URL . 'confirm/' . $job->mId . '/'.$first_time_post.'/');
}
Step 7 - In /_includes/functions.php look for the following code...
function get_types()
{
global $db;
$sql = 'SELECT id, name, var_name
FROM '.DB_PREFIX.'types ';
$result = $db->query($sql);
$types = array();
while($row = $result->fetch_assoc())
{
$types[] = array('id' => $row['id'], 'name' => $row['name'], 'var_name' => $row['var_name']);
}
return $types;
}
Replace the above code with the following code...
function get_types()
{
global $db;
$sql = 'SELECT id, name, var_name, amount, paypal_button_id
FROM '.DB_PREFIX.'types ';
$result = $db->query($sql);
$types = array();
while($row = $result->fetch_assoc())
{
$types[] = array('id' => $row['id'], 'name' => $row['name'], 'var_name' => $row['var_name'], 'amount' => $row['amount'], 'paypal_button_id' => $row['paypal_button_id']);
}
return $types;
}
Step 8 - In /_includes/functions.php add the following code before the closing PHP tag (above the ?> at the end of the file).
function get_type_name_by_id($id)
{
global $db;
$sql = 'SELECT name FROM '.DB_PREFIX.'types WHERE
id = '.$id;
$result = $db->query($sql);
$row = $result->fetch_assoc();
if ($row)
return $row['name'];
return false;
}
// get type amount
function get_type_amount_by_id($id)
{
global $db;
$sql = 'SELECT amount FROM '.DB_PREFIX.'types WHERE
id = '.$id;
$result = $db->query($sql);
$row = $result->fetch_assoc();
if ($row)
return $row['amount'];
return false;
}
// get type button id
function get_type_button_id_by_id($id)
{
global $db;
$sql = 'SELECT paypal_button_id FROM '.DB_PREFIX.'types WHERE
id = '.$id;
$result = $db->query($sql);
$row = $result->fetch_assoc();
if ($row)
return $row['paypal_button_id'];
return false;
}
Step 9 - In /_includes/class.Jobs.php look for the following code...
public function Publish()
{
global $db;
$sql = 'UPDATE '.DB_PREFIX.'jobs SET is_temp = 0 WHERE id = ' . $this->mId;
$db->query($sql);
}
Replace the above code with...
public function Publish()
{
global $db;
if (PAYPAL_IS_ACTIVE == 0)
{
if ($this->IsApprovedPosterEmail()) {
$sql = 'UPDATE '.DB_PREFIX.'jobs SET is_temp = 0, is_active = 1 WHERE id = ' . $this->mId;
} else {
$sql = 'UPDATE '.DB_PREFIX.'jobs SET is_temp = 0, is_active = 0 WHERE id = ' . $this->mId;
}
} else {
if ($this->IsApprovedPosterEmail() && PAYPAL_FIRST_POST_ONLY == 1) {
$sql = 'UPDATE '.DB_PREFIX.'jobs SET is_temp = 0, is_active = 1 WHERE id = ' . $this->mId;
} else {
$sql = 'UPDATE '.DB_PREFIX.'jobs SET is_temp = 0, is_active = 0 WHERE id = ' . $this->mId;
}
}
$db->query($sql);
}
Step 10 - Create the file /_includes/class.PayPal.php. Put the following code within that file...
<?php
/**
* jobber job board platform
*
* @author RedJumpsuit <myredjumpsuit@gmail.com>
* @web http://www.redjumpsuit.net
*
* Very simple PayPal integration for jobberBase - strictly no IPN :)
*/
class SimplePayPal
{
function __construct()
{ }
// update paypal settings
public function updatesettings($data)
{
global $db;
$sql = 'UPDATE '.DB_PREFIX.'paypal_settings
SET
button_type = "'. trim($data['button_type']) .'",
button_image = "'. trim($data['button_image']) .'",
currency_code = "'. trim($data['currency_code']) .'",
return_url = "'. trim($data['return_url']) .'",
is_active = '. $data['is_active'] .',
first_post_only = '. $data['first_post_only'] .'
WHERE id = 1';
if ($db->query($sql))
{
return true;
}
else
{
return false;
}
}
// update paypal amount
public function updatetypeamount($id,$amount=0)
{
global $db;
if (empty($amount))
{
$amount = 0;
}
$sql = 'UPDATE '.DB_PREFIX.'types
SET
amount = '. $amount .'
WHERE id = '. $id ;
if ($db->query($sql))
{
return true;
}
else
{
return false;
}
}
// update paypal amount
public function updatetypebutton($id,$button='')
{
global $db;
if (empty($button))
{
$button = '';
}
$sql = 'UPDATE '.DB_PREFIX.'types
SET
paypal_button_id = "'. trim($button) .'"
WHERE id = '. $id ;
if ($db->query($sql))
{
return true;
}
else
{
return false;
}
}
// show paypal settings
public function showsettings()
{
global $db;
$pp = array();
$sql = 'SELECT * FROM '.DB_PREFIX.'paypal_settings';
$result = $db->query($sql);
$row = $result->fetch_assoc();
$pp['button_type'] = $row['button_type'];
$pp['button_image'] = $row['button_image'];
$pp['currency_code'] = $row['currency_code'];
$pp['return_url'] = $row['return_url'];
$pp['is_active'] = $row['is_active'];
$pp['first_post_only'] = $row['first_post_only'];
if (isset($pp))
{
return $pp;
}
}
}
?>
Step 11 - In /_translations/translations_en.ini add the following code to the end of the file...
[paypal]
button_type = "Button Type"
button_image = "Button Image"
currency_code = "Currency Code"
return_url = "Return URL"
is_active = "PayPal Active"
first_post_only = "First Post"
settings = "PayPal Settings"
update = "Update PayPal Settings"
update_types = "Update Types"
info = "Payment is required before job is posted."
amount = "Amount"
payment_needed = "Your job post has been submitted. In order for your post to be activated, complete the payment for the ad using the payment button below. Once payment is received you will be notified by email and your ad will be posted on the website."
Step 12 - In /_templates/{theme}/publish-write.tpl look for the line...
<label for="type_id_{$types[tmp2].id}"><img src="{$BASE_URL}_templates/{$THEME}/img/icon-{$types[tmp2].var_name}.png" alt="{$types[tmp2].name}" />
Replace the above line with the following code...
<label for="type_id_{$types[tmp2].id}">
<img src="{$BASE_URL}_templates/{$THEME}/img/icon-{$types[tmp2].var_name}.png" alt="{$types[tmp2].name}" />
{if $smarty.const.PAYPAL_IS_ACTIVE == 1}{$smarty.const.PAYPAL_CURRENCY_CODE}{$types[tmp2].amount}{/if}
Step 13 - Create the file /_templates/{theme}/publish-paypal.tpl. Put the following code in that file...
{include file="header.tpl"}
<div id="content">
<div id="job-listings"></div><!-- #job-listings -->
<div class="steps">
<div id="step-1">
{$translations.publish.step1}
</div>
<div id="step-2">
{$translations.publish.step2}
</div>
<div id="step-3" class="step-active">
{$translations.publish.step3}
</div>
<div class="clear"></div>
</div>
<br />
{if $first_time_post == 1 && $smarty.const.PAYPAL_FIRST_POST_ONLY == 1}
<div class="posted-ok">
<strong>{$translations.publish.congratulations}</strong><br /><a href="{$job_url}">{$translations.publish.view}</a>.
</div>
<h4>{$translations.publish.options_title}</h4>
<p>
{$translations.publish.options_info}:
</p>
<ul>
<li><a href="{$BASE_URL}post/{$CURRENT_ID}/{$auth}/" title="{$translations.publish.edit}">» {$translations.publish.edit}</a></li>
<li><a href="{$BASE_URL}deactivate/{$CURRENT_ID}/{$auth}/" title="{$translations.publish.deactivate}">» {$translations.publish.deactivate}</a></li>
</ul>
</div>
{else}
<div class="posted-pending">
<p>{$translations.paypal.payment_needed}</p>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="{$smarty.const.PAYPAL_BUTTON_TYPE}">
<input type="hidden" name="currency_code" value="{$smarty.const.PAYPAL_CURRENCY_CODE}">
<input type="hidden" name="item_number" value="{$paypal_item_number}">
<input type="hidden" name="item_name" value="#{$paypal_item_number} - ({$paypal_job_type}) {$paypal_item_name}">
<input type="hidden" name="hosted_button_id" value="{$paypal_button_id}">
<input type="hidden" name="notify_url" value="{$smarty.const.PAYPAL_RETURN_URL}">
<div class="suggestion">
<input type="image" src="{$smarty.const.PAYPAL_BUTTON_IMAGE}" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
<strong>{$translations.paypal.amount}: {$smarty.const.PAYPAL_CURRENCY_CODE} {$paypal_amount}</strong> | {$translations.paypal.info}
<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1">
</div>
</form>
</div>
{/if}
<p>
<a href="{$BASE_URL}">« {$translations.notfound.back}</a>
</p>
</div><!-- /content -->
{include file="footer.tpl"}
Step 14 - In /admin/index.php look for the lines...
case URL_JOBS:
if(!isset($_SESSION['AdminId']))
{
redirect_to(BASE_URL);
exit;
}
require_once 'page_category.php';
$flag = 1;
break;
After the above code, add the following code...
case 'paypal':
if(!isset($_SESSION['AdminId']))
{
redirect_to(BASE_URL);
exit;
}
require_once 'page_paypal.php';
$flag = 1;
break;
Step 15 - Create the file /admin/page_paypal.php. Put the following code in that file...
<?php
$pp = new SimplePayPal();
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['update_what']) && trim($_POST['update_what']) == 'settings')
{
if (empty($_POST['button_type']))
{
$smarty->assign('error', 'Button Type is required.');
}
elseif (empty($_POST['button_image']))
{
$smarty->assign('error', 'Button Image is required.');
}
elseif (empty($_POST['currency_code']))
{
$smarty->assign('error', 'Currency Code is required.');
}
elseif (empty($_POST['return_url']))
{
$smarty->assign('error', 'Return URL is required.');
}
else
{
$data = array('button_type' => $_POST['button_type'],
'button_image' => $_POST['button_image'],
'currency_code' => $_POST['currency_code'],
'return_url' => $_POST['return_url'],
'is_active' => $_POST['is_active'],
'first_post_only' => $_POST['first_post_only']);
$pp->updatesettings($data);
unset($_POST['button_type']);
unset($_POST['button_image']);
unset($_POST['currency_code']);
unset($_POST['return_url']);
unset($_POST['is_active']);
unset($_POST['first_post_only']);
$smarty->assign('success', 'PayPal Settings has been updated!');
}
}
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['update_what']) && trim($_POST['update_what']) == 'types')
{
foreach ($_POST['amount'] as $k1 => $v1) {
$pp->updatetypeamount($k1,$v1);
}
foreach ($_POST['paypal_button_id'] as $k2 => $v2) {
$pp->updatetypebutton($k2,$v2);
}
$smarty->assign('type_success', 'PayPal Setting for Job Types has been updated!');
}
$smarty->assign('current_category', 'paypal');
$smarty->assign('paypal', $pp->showsettings());
$smarty->assign('types', get_types());
$html_title = 'PayPal Settings / ' . SITE_NAME;
$template = 'paypal.tpl';
?>
Step 16 - In /admin/_templates/header.tpl look for the following line...
<li><a {if $CURRENT_PAGE == 'settings'}class="selected"{/if} href="{$BASE_URL_ADMIN}settings/">Settings</a>
After the above line, add the following code...
<li><a {if $CURRENT_PAGE == 'paypal'}class="selected"{/if} href="{$BASE_URL_ADMIN}paypal/">PayPal</a></li>
Step 17 - Create file /admin/_templates/paypal.tpl. Put the following code in that file...
{include file="header.tpl"}
<div id="content">
<h3 class="page-heading">{$translations.paypal.settings}</h3>
<form id="publish_form" name="settings" action="{$smarty.server.REQUEST_URI}" method="post">
<fieldset>
<table cellspacing="2" cellpadding="2" border="0">
{if $success}
<tr>
<td colspan="2">
<img src="{$BASE_URL_ADMIN}img/icon_accept.gif" alt="" /> {$success}
</td>
</tr>
{elseif $error}
<tr>
<td colspan="2">
<img src="{$BASE_URL_ADMIN}img/exclamation.png" alt="" /> {$error}
</td>
</tr>
{/if}
{if $success == ''}
<tr>
<td>{$translations.paypal.button_type}:</td>
<td><input type="text" name="button_type" size="20" maxlength="100" value="{if $paypal.button_type != ''}{$paypal.button_type}{else}{$smarty.const.PAYPAL_BUTTON_TYPE}{/if}"/></td>
</tr>
<tr>
<td>{$translations.paypal.button_image }:</td>
<td><input type="text" name="button_image" size="60" maxlength="255" value="{if $paypal.button_image != ''}{$paypal.button_image}{else}{$smarty.const.PAYPAL_BUTTON_IMAGE}{/if}"/></td>
</tr>
<tr>
<td>{$translations.paypal.currency_code}:</td>
<td><input type="text" name="currency_code" size="20" maxlength="3" value="{if $paypal.currency_code != ''}{$paypal.currency_code}{else}{$smarty.const.PAYPAL_CURRENCY_CODE}{/if}"/></td>
</tr>
<tr>
<td>{$translations.paypal.return_url}:</td>
<td><input type="text" name="return_url" size="60" maxlength="255" value="{if $paypal.return_url != ''}{$paypal.return_url}{else}{$smarty.const.PAYPAL_RETURN_URL}{/if}"/></td>
</tr>
<tr>
<td>{$translations.paypal.is_active}:</td>
<td>
<select name="is_active">
<option value="1"{if $smarty.const.PAYPAL_IS_ACTIVE == 1} selected="selected"{/if}>Yes</option>
<option value="0"{if $smarty.const.PAYPAL_IS_ACTIVE == 0} selected="selected"{/if}>No</option>
</select>
<span class="suggestion">Specify if PayPal is active (Yes) or not (No)</span>
</td>
</tr>
<tr>
<td colspan="2">Option below applies only if PayPal is set to Active.</td>
<td>
</tr>
<tr>
<td>{$translations.paypal.first_post_only}:</td>
<td>
<select name="first_post_only">
<option value="1"{if $smarty.const.PAYPAL_FIRST_POST_ONLY == 1} selected="selected"{/if}>Yes</option>
<option value="0"{if $smarty.const.PAYPAL_FIRST_POST_ONLY == 0} selected="selected"{/if}>No</option>
</select>
<span class="suggestion">Specify if PayPal is active on first post only (Yes) or required whenever posting a job (No)</span>
</td>
</tr>
<tr>
<td colspan="2">
<input type="hidden" name="update_what" value="settings">
<input type="submit" name="submit" id="submit" value="{$translations.paypal.update}" />
</td>
</tr>
{/if}
</table>
</fieldset>
</form>
<h2>PayPal Setting for Job Types</h2>
{if $type_success}
<p><img src="{$BASE_URL_ADMIN}img/icon_accept.gif" alt="" /> {$type_success}</p>
{/if}
<form id="publish_form" name="types" action="{$smarty.server.REQUEST_URI}" method="post">
<table id="job-posts" class="job-posts" cellspacing="0">
<tr class="alt">
<td>ID</td>
<td>Type Name</td>
<td>Amount</td>
<td>PayPal ID</td>
</tr>
{foreach from=$types item=types}
<tr>
<td class="center">{$types.id}</td>
<td>{$types.name}</td>
<td class="center"><input type="text" name="amount[{$types.id}]" value="{$types.amount}" /></td>
<td class="center"><input type="text" name="paypal_button_id[{$types.id}]" value="{$types.paypal_button_id}" /></td>
</tr>
{/foreach}
</table>
<input type="hidden" name="update_what" value="types">
<input type="submit" name="submit" id="submit" value="{$translations.paypal.update_types}" />
</form>
<p> </p>
<p> </p>
</div><!-- #job-details -->
Step 18 - Now comes configuring a PayPal account. Per redjumpsuit's instructions, you need to do the following things...
(1) For each job type, create a hosted Buy Now button on PayPal (and change button type to Pay Now).
(2) Take note of the PayPal button ID for each of the Buy Now/Pay Now buttons you created.
(3) Go to Admin->PayPal->PayPal Setting for Job Types and enter the corresponding amount and PayPal button ID for each of the job types.
(4) You will approve the jobs paid for in the Admin to activate the job ad.
I hope this tutorial is both functional and helpful. Best of luck using it! All credit goes to redjumpsuit as much of this is his work verbatim.
Last edited by akanevsky (2010-07-02 07:48:09)