WIP - Added Service Process, confirm and success for Paypal and Bank Transfer - Refs BT#12077

pull/2487/head
José Loguercio 9 years ago
parent 913af1d6d6
commit 9bd8041c2c
  1. 52
      plugin/buycourses/src/buy_course_plugin.class.php
  2. 100
      plugin/buycourses/src/service_process.php
  3. 180
      plugin/buycourses/src/service_process_confirm.php
  4. 179
      plugin/buycourses/src/service_success.php
  5. 51
      plugin/buycourses/view/process.tpl
  6. 24
      plugin/buycourses/view/process_confirm.tpl

@ -29,6 +29,7 @@ class BuyCoursesPlugin extends Plugin
const PRODUCT_TYPE_SESSION = 2;
const PAYMENT_TYPE_PAYPAL = 1;
const PAYMENT_TYPE_TRANSFER = 2;
const PAYMENT_TYPE_CULQI = 3;
const PAYOUT_STATUS_CANCELED = 2;
const PAYOUT_STATUS_PENDING = 0;
const PAYOUT_STATUS_COMPLETED = 1;
@ -960,7 +961,8 @@ class BuyCoursesPlugin extends Plugin
{
return [
self::PAYMENT_TYPE_PAYPAL => 'PayPal',
self::PAYMENT_TYPE_TRANSFER => $this->get_lang('BankTransfer')
self::PAYMENT_TYPE_TRANSFER => $this->get_lang('BankTransfer'),
self::PAYMENT_TYPE_CULQI => 'Culqi'
];
}
@ -2086,4 +2088,52 @@ class BuyCoursesPlugin extends Plugin
);
}
/**
* Register a Service sale
* @param int $serviceId The service ID
* @param int $paymentType The payment type
* @param int $infoSelect The ID for Service Type
* @param int $trial trial mode
* @return boolean
*/
public function registerServiceSale($serviceId, $paymentType, $infoSelect, $trial = null)
{
if (!in_array($paymentType, [self::PAYMENT_TYPE_PAYPAL, self::PAYMENT_TYPE_TRANSFER, self::PAYMENT_TYPE_CULQI])) {
return false;
}
$userId = api_get_user_id();
$service = $this->getServices($serviceId);
if (empty($service)) {
return false;
}
$currency = $this->getSelectedCurrency();
$values = [
'service_id' => $serviceId,
'reference' => $this->generateReference(
$userId,
$service['applies_to'],
$infoSelect
),
'currency_id' => $currency['id'],
'price' => $service['price'],
'node_type' => $service['applies_to'],
'node_id' => intval($infoSelect),
'buyer_id' => $userId,
'buy_date' => api_get_utc_datetime(),
'date_start' => api_get_utc_datetime(),
'date_end' => date_format(date_add(date_create(api_get_utc_datetime()), date_interval_create_from_date_string($service['duration_days'].' days')), 'Y-m-d H:i:s'),
'status' => self::SERVICE_STATUS_PENDING,
'payment_type' => intval($paymentType)
];
$returnedServiceSaleId = Database::insert(self::TABLE_SERVICES_SALE, $values);
return $returnedServiceSaleId;
}
}

@ -62,69 +62,18 @@ if ($form->validate()) {
header('Location:' . api_get_self() . '?' . $queryString);
exit;
}
$userGroup = $em->getRepository('ChamiloCoreBundle:Usergroup')->findBy(['name' => $formValues['info_select']]);
if ($userGroup) {
Display::addFlash(
Display::return_message($plugin->get_lang('StoreNameAlreadyExist'), 'error', false)
);
header('Location:' . api_get_self() . '?' . $queryString);
exit;
}
$serviceSaleId = $plugin->registerServiceSale($serviceId, $formValues['payment_type'], $formValues['info_select'], $formValues['enable_trial']);
if (!empty($formValues['store_code'])) {
$data = [
'store_code' => Security::remove_XSS($formValues['store_code']),
'store_name' => Security::remove_XSS($formValues['info_select']),
'parent_id' => 0,
'description' => 'Registered by User in buying process',
'type' => 1,
'discount' => 0
];
$verification = $plugin->getDiscountByCode($data['store_code']);
if (!$verification) {
$plugin->addDiscountCode($data);
}
}
if ($serviceSaleId !== false) {
$_SESSION['bc_service_sale_id'] = $serviceSaleId;
if ($verification['discount'] == 100) {
$serviceSale = $plugin->getServiceSale($serviceSaleId);
$serviceSaleIsCompleted = $plugin->completeServiceSale($serviceSale['id']);
if ($serviceSaleIsCompleted) {
Display::addFlash(Display::return_message(sprintf($plugin->get_lang('SubscriptionToServiceXSuccessful'), $serviceSale['service']['name']), 'success'));
$plugin->SendSubscriptionMail(intval($serviceSale['id']));
unset($_SESSION['bc_service_sale_id']);
header('Location: ' . api_get_path(WEB_PLUGIN_PATH) . 'buycourses/src/package_panel.php?id='.$serviceSale['id']);
exit;
}
}
if ($wizard) {
header('Location: ' . api_get_path(WEB_PLUGIN_PATH) . 'buycourses/src/service_process_confirm.php?from=register');
} else {
header('Location: ' . api_get_path(WEB_PLUGIN_PATH) . 'buycourses/src/service_process_confirm.php');
}
header('Location: ' . api_get_path(WEB_PLUGIN_PATH) . 'buycourses/src/service_process_confirm.php');
}
exit;
}
// Reset discount code
unset($_SESSION['s_discount']);
$paymentTypesOptions = $plugin->getPaymentTypes(true);
$form->addHeader('');
@ -163,47 +112,6 @@ if ($typeUser) {
}
}
$form->addSelect('info_select', get_lang('Session'), $selectOptions);
} elseif ($typeSubscriptionPackage) {
$trial = intval($serviceInfo['allow_trial']);
if ($trial) {
$trialTime = $serviceInfo['trial_period'] == 'Month' ? get_lang($serviceInfo['trial_period']) . '(es)' : get_lang($serviceInfo['trial_period']) . '(s)';
$form->addHtml('
<div class="form-group ">
<label for="qf_373cc5" class="col-sm-6">
' . sprintf($plugin->get_lang('EnableTrialSubscription'), $serviceInfo['trial_frequency'] . ' ' . $trialTime) . '
</label>
<div class="col-sm-6">
<input cols-size="" name="enable_trial" value="1" id="qf_373cc5" type="checkbox"></div>
<div class="col-sm-0"></div>
</div>
<div class="form-group ">
<div class="col-sm-12">
<p class="help-block">' . sprintf($plugin->get_lang('EnableTrialSubscriptionHelpText'), $serviceInfo['trial_frequency'] . ' ' . $trialTime) . '</p>
</div>
</div>
');
}
$form->addText('store_code', $plugin->get_lang('DiscountCodeProcess'), true, ['cols-size' => [6, 6, 0], 'id' => 'store_code']);
$form->addText('info_select_trick', $plugin->get_lang('StoreName'), true, ['cols-size' => [6, 6, 0], 'id' => 'info_select_trick']);
$form->addHidden('info_select', '');
$form->addHtml('
<div class="form-group">
<div class="col-sm-2 pull-right">
<a id="code-checker" class="btn btn-xs btn-warning">' . $plugin->get_lang('Check') . '</a>
</div>
<div id="code-verificator-text" class="col-sm-4 pull-right">
</div>
</div>
<div id="code-verificator-info">
</div>
<div class="form-group">
<div class="col-sm-12">
<p class="help-block">' . $plugin->get_lang('DiscountCodeInfoText') . '</p>
</div>
</div>
');
}
@ -217,11 +125,7 @@ $templateName = $plugin->get_lang('PaymentMethods');
$interbreadcrumb[] = array("url" => "service_catalog.php", "name" => $plugin->get_lang('ListOfServicesOnSale'));
$tpl = new Template($templateName);
if (isset($_GET['from'])) {
if($_GET['from'] == 'register') {
$tpl->assign('wizard', true);
}
}
$tpl->assign('buying_service', true);
$tpl->assign('service', $serviceInfo);
$tpl->assign('user', api_get_user_info());

@ -0,0 +1,180 @@
<?php
/* For license terms, see /license.txt */
/**
* Process purchase confirmation script for the Buy Courses plugin
* @package chamilo.plugin.buycourses
*/
/**
* Init
*/
require_once '../config.php';
$plugin = BuyCoursesPlugin::create();
$serviceSaleId = $_SESSION['bc_service_sale_id'];
if (empty($serviceSaleId)) {
api_not_allowed(true);
}
$serviceSale = $plugin->getServiceSale($serviceSaleId);
if (empty($serviceSale)) {
api_not_allowed(true);
}
$currency = $plugin->getCurrency($serviceSale['currency_id']);
switch ($serviceSale['payment_type']) {
case BuyCoursesPlugin::PAYMENT_TYPE_PAYPAL:
$paypalParams = $plugin->getPaypalParams();
$pruebas = $paypalParams['sandbox'] == 1;
$paypalUsername = $paypalParams['username'];
$paypalPassword = $paypalParams['password'];
$paypalSignature = $paypalParams['signature'];
// This var $itemPrice may be "0" if the transaction does not include a one-time purchase such as when you set up
// a billing agreement for a recurring payment that is not immediately charged. When the field is set to 0,
// purchase-specific fields are ignored. This little condition handle this fact.
$itemPrice = $serviceSale['price'];
$returnUrl = api_get_path(WEB_PLUGIN_PATH) . 'buycourses/src/service_success.php';
$cancelUrl = api_get_path(WEB_PLUGIN_PATH) . 'buycourses/src/service_error.php';
// The extra params for handle the hard job, this var is VERY IMPORTANT !!
$extra = '';
require_once("paypalfunctions.php");
$extra .= "&L_PAYMENTREQUEST_0_NAME0={$serviceSale['service']['name']}";
$extra .= "&L_PAYMENTREQUEST_0_QTY0=1";
$extra .= "&L_PAYMENTREQUEST_0_AMT0=$itemPrice";
// Full Checkout express
$expressCheckout = CallShortcutExpressCheckout(
$itemPrice,
$currency['iso_code'],
'paypal',
$returnUrl,
$cancelUrl,
$extra
);
if ($expressCheckout["ACK"] !== 'Success') {
$erroMessage = vsprintf(
$plugin->get_lang('ErrorOccurred'),
[$expressCheckout['L_ERRORCODE0'], $expressCheckout['L_LONGMESSAGE0']]
);
Display::addFlash(
Display::return_message($erroMessage, 'error', false)
);
$plugin->cancelServiceSale(intval($serviceSale['id']));
header('Location: '. api_get_path(WEB_PLUGIN_PATH) . 'buycourses/src/service_catalog.php');
exit;
}
RedirectToPayPal($expressCheckout['TOKEN']);
break;
case BuyCoursesPlugin::PAYMENT_TYPE_TRANSFER:
switch ($serviceSale['node_type']) {
case BuyCoursesPlugin::SERVICE_TYPE_USER:
$buyingCourse = true;
$user = api_get_user_info(intval($serviceSale['node_id']));
break;
case BuyCoursesPlugin::SERVICE_TYPE_COURSE:
$buyingCourse = true;
$course = $plugin->getCourseInfo($serviceSale['node_id']);
break;
case BuyCoursesPlugin::SERVICE_TYPE_SESSION:
$buyingSession = true;
$session = $plugin->getSessionInfo($serviceSale['node_id']);
break;
}
$transferAccounts = $plugin->getTransferAccounts();
$userInfo = api_get_user_info($serviceSale['buyer']['id']);
$form = new FormValidator('success', 'POST', api_get_self(), null, null, FormValidator::LAYOUT_INLINE);
if ($form->validate()) {
$formValues = $form->getSubmitValues();
if (isset($formValues['cancel'])) {
$plugin->cancelServiceSale(intval($serviceSale['id']));
unset($_SESSION['bc_service_sale_id']);
Display::addFlash(
Display::return_message($plugin->get_lang('OrderCancelled'), 'error', false)
);
header('Location: '. api_get_path(WEB_PLUGIN_PATH) . 'buycourses/src/service_catalog.php');
exit;
}
$messageTemplate = new Template();
$messageTemplate->assign(
'service_sale',
[
'name' => $serviceSale['service']['name'],
'buyer' => $serviceSale['buyer']['name'],
'buy_date' => api_format_date($serviceSale['buy_date'], DATE_TIME_FORMAT_LONG_24H),
'start_date' => api_format_date($serviceSale['start_date'], DATE_TIME_FORMAT_LONG_24H),
'end_date' => api_format_date($serviceSale['end_date'], DATE_TIME_FORMAT_LONG_24H),
'currency' => $currency['currency'],
'price' => $serviceSale['price'],
'reference' => $serviceSale['reference']
]
);
$messageTemplate->assign('transfer_accounts', $transferAccounts);
$buyer = api_get_user_info($serviceSale['buyer']['id']);
api_mail_html(
$buyer['complete_name'],
$buyer['email'],
$plugin->get_lang('bc_subject'),
$messageTemplate->fetch('buycourses/view/message_transfer.tpl')
);
Display::addFlash(
Display::return_message(
sprintf(
$plugin->get_lang('PurchaseStatusX'),
$plugin->get_lang('PendingReasonByTransfer')
),
'success',
false
)
);
unset($_SESSION['bc_service_sale_id']);
header('Location: ' . api_get_path(WEB_PLUGIN_PATH) . 'buycourses/src/service_catalog.php');
exit;
}
$form->addButton('confirm', $plugin->get_lang('ConfirmOrder'), 'check', 'success');
$form->addButtonCancel($plugin->get_lang('CancelOrder'), 'cancel');
$template = new Template();
$template->assign('title', $serviceSale['service']['name']);
$template->assign('price', $serviceSale['price']);
$template->assign('currency', $serviceSale['currency_id']);
$template->assign('buying_service', $serviceSale);
$template->assign('user', $userInfo);
$template->assign('service', $serviceSale);
$template->assign('transfer_accounts', $transferAccounts);
$template->assign('form', $form->returnForm());
$content = $template->fetch('buycourses/view/process_confirm.tpl');
$template->assign('content', $content);
$template->display_one_col_template();
break;
case BuyCoursesPlugin::PAYMENT_TYPE_CULQI:
break;
}

@ -0,0 +1,179 @@
<?php
/* For license terms, see /license.txt */
/**
* Success page for the purchase of a service in the Buy Courses plugin
* @package chamilo.plugin.buycourses
*/
/**
* Init
*/
require_once '../config.php';
$plugin = BuyCoursesPlugin::create();
$paypalEnabled = $plugin->get('paypal_enable') === 'true';
if (!$paypalEnabled) {
api_not_allowed(true);
}
$serviceSaleId = $_SESSION['bc_service_sale_id'];
$serviceSale = $plugin->getServiceSale($serviceSaleId);
$itemPrice = $serviceSale['price'];
if (empty($serviceSale)) {
api_not_allowed(true);
}
$paypalParams = $plugin->getPaypalParams();
$pruebas = $paypalParams['sandbox'] == 1;
$paypalUsername = $paypalParams['username'];
$paypalPassword = $paypalParams['password'];
$paypalSignature = $paypalParams['signature'];
require_once("paypalfunctions.php");
$buyerInformation = GetShippingDetails(urlencode($_SESSION['TOKEN']));
$form = new FormValidator('success', 'POST', api_get_self(), null, null, FormValidator::LAYOUT_INLINE);
$form->addButton('confirm', $plugin->get_lang('ConfirmOrder'), 'check', 'success');
$form->addButtonCancel($plugin->get_lang('CancelOrder'), 'cancel');
if ($form->validate()) {
$formValues = $form->getSubmitValues();
if (isset($formValues['cancel'])) {
$plugin->cancelServiceSale($serviceSale['id']);
unset($_SESSION['bc_service_sale_id']);
Display::addFlash(
Display::return_message($plugin->get_lang('OrderCancelled'), 'error', false)
);
header('Location: ' . api_get_path(WEB_PLUGIN_PATH) . 'buycourses/src/service_catalog.php');
exit;
}
$confirmPayments = ConfirmPayment($itemPrice);
if ($confirmPayments['ACK'] !== 'Success') {
$erroMessage = vsprintf(
$plugin->get_lang('ErrorOccurred'),
[$expressCheckout['L_ERRORCODE0'], $confirmPayments['L_LONGMESSAGE0']]
);
Display::addFlash(
Display::return_message($erroMessage, 'error', false)
);
unset($_SESSION['wizard']);
header('Location: ' . api_get_path(WEB_PLUGIN_PATH) . 'buycourses/src/service_catalog.php');
exit;
}
switch ($confirmPayments["PAYMENTINFO_0_PAYMENTSTATUS"]) {
case 'Completed':
$serviceSaleIsCompleted = $plugin->completeServiceSale($serviceSale['id']);
if ($serviceSaleIsCompleted) {
Display::addFlash(
Display::return_message(
sprintf($plugin->get_lang('SubscriptionToServiceXSuccessful'), $serviceSale['service']['name']),
'success'
)
);
break;
}
Display::addFlash(
Display::return_message($plugin->get_lang('ErrorContactPlatformAdmin'), 'error')
);
break;
case 'Pending':
switch ($confirmPayments["PAYMENTINFO_0_PENDINGREASON"]) {
case 'address':
$purchaseStatus = $plugin->get_lang('PendingReasonByAddress');
break;
case 'authorization':
$purchaseStatus = $plugin->get_lang('PendingReasonByAuthorization');
break;
case 'echeck':
$purchaseStatus = $plugin->get_lang('PendingReasonByEcheck');
break;
case 'intl':
$purchaseStatus = $plugin->get_lang('PendingReasonByIntl');
break;
case 'multicurrency':
$purchaseStatus = $plugin->get_lang('PendingReasonByMulticurrency');
break;
case 'order':
$purchaseStatus = $plugin->get_lang('PendingReasonByOrder');
break;
case 'paymentreview':
$purchaseStatus = $plugin->get_lang('PendingReasonByPaymentReview');
break;
case 'regulatoryreview':
$purchaseStatus = $plugin->get_lang('PendingReasonByRegulatoryReview');
break;
case 'unilateral':
$purchaseStatus = $plugin->get_lang('PendingReasonByUnilateral');
break;
case 'upgrade':
$purchaseStatus = $plugin->get_lang('PendingReasonByUpgrade');
break;
case 'verify':
$purchaseStatus = $plugin->get_lang('PendingReasonByVerify');
break;
case 'other':
//no break
default:
$purchaseStatus = $plugin->get_lang('PendingReasonByOther');
break;
}
Display::addFlash(
Display::return_message(
sprintf($plugin->get_lang('PurchaseStatusX'), $purchaseStatus),
'warning',
false
)
);
break;
default:
$plugin->cancelServiceSale(intval($serviceSale['id']));
Display::addFlash(
Display::return_message($plugin->get_lang('ErrorContactPlatformAdmin'), 'error')
);
break;
}
unset($_SESSION['bc_service_sale_id']);
header('Location: ' . api_get_path(WEB_PLUGIN_PATH) . 'buycourses/src/service_catalog.php');
exit;
}
$token = isset($_GET['token']) ? Security::remove_XSS($_GET['token']) : null;
if (empty($token)) {
api_not_allowed(true);
}
$interbreadcrumb[] = array("url" => "service_catalog.php", "name" => $plugin->get_lang('ListOfServicesOnSale'));
$templateName = $plugin->get_lang('PaymentMethods');
$tpl = new Template($templateName);
$tpl->assign('title', $serviceSale['service']['name']);
$tpl->assign('price', $serviceSale['price']);
$tpl->assign('currency', $serviceSale['currency_id']);
$tpl->assign('service', $serviceSale);
$tpl->assign('buying_service', true);
$tpl->assign('user', api_get_user_info($serviceSale['buyer']['id']));
$tpl->assign('form', $form->returnForm());
$content = $tpl->fetch('buycourses/view/success.tpl');
$tpl->assign('content', $content);
$tpl->display_one_col_template();

@ -1,5 +1,3 @@
<script type='text/javascript' src="../js/buycourses.js"></script>
<div class="row">
<div class="col-md-5 panel panel-default buycourse-panel-default">
<h3 class="panel-heading">{{ 'PurchaseData'|get_plugin_lang('BuyCoursesPlugin') }}</h3>
@ -73,59 +71,12 @@
</div>
<script>
$(document).ready(function() {
$("input[name=info_select_trick]").prop('disabled', true);
$("input[name=payment_type]").attr('hidden', true);
$("input[name=payment_type]").attr('checked', true);
$("#paypal-icon").html(' <em class="fa fa-check text-success fa-2x" aria-hidden="true"></em>');
$("input[name=payment_type]").click(function () {
$("#paypal-icon").html(' <em class="fa fa-check text-success fa-2x" aria-hidden="true"></em>');
})
$("label").removeClass('control-label');
$('.form_required').remove();
$("small").remove();
$("label[for=submit]").remove();
$("input[name=enable_trial]").attr('checked', true);
$("#code-checker").click(function () {
var code = $("#store_code").val();
$.ajax({
beforeSend: function() {
$("#code-checker").html('<em class="fa fa-refresh fa-spin"></em> {{ 'Loading' | get_lang }}');
},
type: "POST",
url: "{{ _p.web_plugin ~ 'buycourses/src/buycourses.ajax.php?a=verify_discount_code' }}",
data : { store_code: code},
success: function(response) {
$("#code-checker").html('{{ 'Check' | get_plugin_lang('BuyCoursesPlugin') }}');
if (response.msg == 'true') {
var store_name = response.store_name;
var description = response.description;
var type = response.type;
var parent = '';
if (response.parent) {
parent = '<div class="form-group"><label for="code_parent" class="col-sm-6">{{ 'Parent' | get_plugin_lang('BuyCoursesPlugin') }}</label><div class="col-sm-6">' + response.parent + '</div></div>'
}
$("input[name=info_select]").val(store_name);
$("#info_select_trick").val(store_name);
$("#code-verificator-text").html('<p style="color: green">{{ 'ValidCode' | get_plugin_lang('BuyCoursesPlugin') }}</p>');
$("#code-verificator-info").html('' +
'<div class="form-group"><label for="code_description" class="col-sm-6">{{ 'Description' | get_plugin_lang('BuyCoursesPlugin') }}</label><div class="col-sm-6">' + description + '</div></div>' +
'<div class="form-group"><label for="code_type" class="col-sm-6">{{ 'Type' | get_plugin_lang('BuyCoursesPlugin') }}</label><div class="col-sm-6">' + type + '</div></div>' + parent +
'');
var price = {{ service.price }};
var show = response.discount;
var discount = price * (response.discount / 100);
var total = price - discount;
$("#n-price").css('text-decoration', 'line-through');
$("#s-price").html('<b>Desconto especial de ' + show + '%</b> <span class="label label-success">{{ service.currency == 'BRL' ? 'R$' : service.currency }} ' + total.toFixed(2) + '</span>');
} else if (response.msg == 'false') {
$("#code-verificator-text").html('<p style="color: red">{{ 'CodeDoesntExist' | get_plugin_lang('BuyCoursesPlugin') }}</p>');
$("input[name=info_select]").val($("#store_code").val());
$("#info_select_trick").val($("#store_code").val());
}
}
});
});
});
</script>
{% endif %}

@ -54,6 +54,30 @@
</dl>
</div>
</div>
{% elseif buying_service %}
<h3 class="page-header">{{ service.service.name }}</h3>
<div class="row">
<div class="col-sm-12 col-md-5">
<p>
{% if service.node_type == 0 %}
<img alt="{{ service.service.name }}" class="img-responsive" src="{{ 'session_default.png'|icon() }}">
{% elseif service.node_type == 1 %}
<img alt="{{ service.service.name }}" class="img-responsive" style="margin: auto;" src="{{ _p.web }}plugin/buycourses/resources/img/bc-user.png">
{% elseif service.node_type == 2 %}
<img alt="{{ service.service.name }}" class="img-responsive" style="margin: auto;" src="{{ _p.web }}plugin/buycourses/resources/img/bc-course.png">
{% elseif service.node_type == 3 %}
<img alt="{{ service.service.name }}" class="img-responsive" style="margin: auto;" src="{{ _p.web }}plugin/buycourses/resources/img/bc-session.png">
{% endif %}
</p>
<p class="lead text-right">{{ service.currency == 'BRL' ? 'R$' : service.currency }} {{ service.price }}</p>
</div>
<div class="col-sm-12 col-md-7">
<p><b>{{ 'StartDate'|get_plugin_lang('BuyCoursesPlugin') }}</b></p>
<li>{{ service.date_start | format_date() }}</li>
<p><b>{{ 'EndDate'|get_plugin_lang('BuyCoursesPlugin') }}</b></p>
<li>{{ service.date_end | format_date() }}</li>
</div>
</div>
{% endif %}
</div>
</div>

Loading…
Cancel
Save