Этим утром клиент доверия академии произвел оплату через наш веб-сайт.Они прислали нам скриншот, показывающий, что была сгенерирована оплата.Этот paymentid отображается только для пользователя, если пользователь успешно зарегистрировался с помощью платежа PayPal / Debitcredit и был авторизован.Тем не менее, в базе данных не было записей об этом платеже, и на нашем счете PayPal не было транзакций.
На сайте есть несколько тарифных планов, каждый из которых имеет свой план.Бронза = 1;Серебро = 2;Золото = 3;Platinum = 4 и т. Д.
Особенность в том, что веб-сайт отлично работает для всех клиентов, оплачивающих бронзовые, серебряные и золотые тарифы (платеж проходит, отображается идентификатор платежа для пользователя, записывается вбаза данных, а также средства, депонированные на нашем счете), однако, это не работает для платинового счета.
Мы проверили, что производственный идентификатор клиента API является правильным (и никем не был мошенническим образом изменен, и это выглядит нормально)
Сайт представляет собой платформу codeigniter на основе php .При оплате поля в базе данных должны быть заполнены.Создается новое членство, с новым идентификатором членства, планид и всеми связанными данными (такими как название школы, почтовый индекс школы и paymentid)> в базе данных поле «paypinn» (с двойным nn)
Насколько я вижу, при оформлении заказа URL-адрес выглядит следующим образом (обратите внимание, что 4 относится к платине, единственной планиде, для которой процесс, похоже, не работает)
https://www.rootwebsite.io/index.php/teacher/checkout/4
Выше, в соответствии с codeigniter, относится к «учитель» контроллер, и функция проверки , которая показана ниже. (Я также включил следующий контроллер, который являетсяфункция paysuccess)
public function checkout($id = '')
{
$data['page']='';
$type=$this->session->userdata('type');
// : 20062019 : paypin feature : START
$teacher_id = $this->session->userdata('ID');
$data['paypinn']=$this->teachers->get_paypin($teacher_id);
// : 20062019 : paypin feature : END
$data['menu']=$this->teachers->get_menu($type);
$data['plan']=$this->teachers->get_planbyid($id);
//: 20062019 : paypin feature : START
$data['downgrade']='N';
if(!empty($data['paypinn']) && $data['plan'][0]->amount < $data['paypinn'][0]->amount)
{
$data['downgrade']='Y';
}
// : 20062019 : paypin feature : END
$this->load->view('template/headteach.php',$data);
$this->load->view('teacher/checkout.php',$data);
$this->load->view('template/footerprofile.php');
}
public function success($id = '')
{
$data['page']='';
$data['premiumcallout']='red';// 24032019 : : premium red callout on successful payment
$data['paypin']=$id;
$type=$this->session->userdata('type');
$data['menu']=$this->teachers->get_menu($type);
//$data['plan']=$this->teachers->get_planbyid($id);
$this->load->view('template/headteach.php',$data);
$this->load->view('teacher/success.php',$data);
$this->load->view('template/footerprofile.php');
}
public function paysuccess()
{
$log = '';
$school = $this->input->post('school');
$postal = $this->input->post('postal');
$trxID = $this->input->post('paymentID');
$schoolpin = str_replace(' ', '', $school);
$plan = $this->input->post('plan');
$digits = 5;
$schoolpin .= rand(pow(10, $digits-1), pow(10, $digits)-1);
// : 20062019 : paypin feature
$teacher_id = $this->session->userdata('ID');
$data['paypinn']=$this->teachers->get_paypin($teacher_id);
if($trxID){
$log .='-trxID : '.$trxID;
$data['plan'] = $this->teachers->get_membershipbyid($plan);
// : 20062019 : paypin feature
$teacher_id = $this->session->userdata('ID');
$data['paypinn']=$this->teachers->get_paypin($teacher_id);
if(empty($data['paypinn']) ){//|| empty($data['paypinn'][0]->membershipid)){
$log .= '-in if(paypinn)';
$membershipid =$this->teachers->add_membership($schoolpin, $trxID,$plan,$data['plan'][0]->title, $data['plan'][0]->teacher_usagecount, $data['plan'][0]->student_usagecount, $data['plan'][0]->duration, $data['plan'][0]->amount);
$updated = $this->teachers->updatemembership($membershipid);
// : 20062019 : paypin feature
$trx_history_id =$this->teachers->add_trx_history($schoolpin, $trxID,$plan,$data['plan'][0]->title, $data['plan'][0]->teacher_usagecount, $data['plan'][0]->student_usagecount, $data['plan'][0]->duration, $data['plan'][0]->amount, $membershipid );
if($data['plan'][0]->teacher_usagecount != 99999 && $data['plan'][0]->teacher_usagecount != 0){
$updated = $this->teachers->updateusagecount($membershipid);
}
}
else //if($plan == $data['paypinn'][0]->planid)// : 20062019 : paypin feature START
{
$log .= '-in else paypinn';
$schoolpin = $data['paypinn'][0]->paypinn;
if($plan == $data['paypinn'][0]->planid)
{
$newplan = 'N';
}
else
{
$newplan = 'Y';
}
$exp_date = $data['paypinn'][0]->planenddate;
$todays_date = date("Y-m-d");
$log .= '-newplan:'.$newplan;
$today = strtotime($todays_date);
$expiration_date = strtotime($exp_date);
if ($expiration_date < $today) { // renew a membership
$log .= '-renew';
$trx_history_id =$this->teachers->add_trx_history($data['paypinn'][0]->paypinn, $trxID,$plan,$data['plan'][0]->title, $data['plan'][0]->teacher_usagecount, $data['plan'][0]->student_usagecount, $data['plan'][0]->duration, $data['plan'][0]->amount, $data['paypinn'][0]->membershipid);
$log .= '-addedd trx history';
$membershipid =$this->teachers->update_membership($data['paypinn'][0]->paypinn, $trxID,$plan,$data['plan'][0]->title, $data['plan'][0]->teacher_usagecount, $data['plan'][0]->student_usagecount, $data['plan'][0]->duration, $data['plan'][0]->amount, $data['paypinn'][0]->membershipid,$newplan,$data['paypinn'][0]->tteacherremaining, $data['paypinn'][0]->studentremaining, $data['paypinn'][0]->teacherusage,$data['paypinn'][0]->studentusage );
$log .= '-updated membership';
Я проверил код и не вижу явных ошибок (логический поток или отсутствующие части). Процесс должен быть следующим (и работает для всех планов, кроме 4)
- Пользователь вводит название школы, почтовый индекс и нажимает кнопку PayPal.
- После того, как они произвели оплату, запускается функция успеха, и на экране появляется надпись paymentid.reen (это почтовый индекс школы, соединенный со случайным пятизначным целым числом).
- Все эти данные записываются в базу данных для создания записи в таблице членства, и соответствующий пользователь получит идентификатор членства (в базе данных), а также paymentid.
Кроме того, есть папка модели с php-файлами.В этой папке есть два файла, один из которых называется teacher.php , а другой "Teachers.php". Файлы практически идентичны с некоторыми отличиями.Разработчик мог ошибиться?Соответствующие функции, указанные в файле модели «учителя», приведены ниже.Могут ли дублирующиеся файлы (с одинаковым именем файла, за исключением заглавной буквы в начале) вызывать проблему?
public function get_plans($type='')
{
$query = $this->db->query("select * from membership_plan where type='$type' order by displayorder");
return $query->result();
}
public function get_planbyid($id='')
{
$teacher=$this->session->userdata('ID');
$query = $this->db->query("select *,(select school_name from teachers where id = '$teacher') as school from membership_plan where id='$id'");
//echo "select *,(select school_name from teachers where id = '$teacher') as school from membership_plan where id='$id'";
return $query->result();
}
public function get_date($id='')
{
//$query = $this->db->query("SELECT t.*, (select l.level from level l where l.id = t.level_id ) as level from topics t ");
$query = $this->db->query("select date from teachers where id='$id'");
return $query->result();
}
public function get_plandate($id='')
{
$query = $this->db->query("SELECT m.*, (select mp.planenddate from memberships mp where mp.id = m.membershipid ) as planenddate,(select mp.planid from memberships mp where mp.id = m.membershipid ) as plan from teachers m where m.id='$id'");
return $query->result();
}
public function get_membership($type='')
{
//$query = $this->db->query("SELECT t.*, (select l.level from level l where l.id = t.level_id ) as level from topics t ");
$query = $this->db->query("select * from membership_table where type='$type'");
return $query->result();
}
public function get_membershipbyid($id='')
{
//$query = $this->db->query("SELECT t.*, (select l.level from level l where l.id = t.level_id ) as level from topics t ");
//echo "select * from memberships where id ='$id' ";
$query = $this->db->query("select * from membership_plan where id ='$id' ");
return $query->result();
}
public function get_paymentid($payid='',$id='')
{
//$query = $this->db->query("SELECT t.*, (select l.level from level l where l.id = t.level_id ) as level from topics t ");
$query = $this->db->query("select * from memberships where paypinn='$payid' ");
return $query->result();
}
public function updatemembership($payid='')
{
$teacherID = $this->session->userdata('ID');
$data = array(
'membershipid' => $payid
);
$this->db->where('id', $teacherID);
return $this->db->update('teachers', $data);
Наконец, в папке views этофактический checkout.php файл.
<script src="https://www.paypalobjects.com/api/checkout.js"></script>
<div class="tab-pane fade active in" id="tab1-item1" style="text-align: center;">
<h1>Checkout</h1>
</div>
</br>
<div class="row" style="text-align: center;">
<div class="col-md-3"></div>
<div class="col-md-6" style="text-align: center;">
<!--<form novalidate="" data-validate="parsley" class="login-form edp-login-form" id="form-s-signup" >-->
<div class="form-group col-md-12" style="text-align: center;">
<div class="col-md-1"></div><label class=" col-md-3 control-label">School Name </label>
<input type="hidden" id="hdnPlan" name="hdnPlan" value="<?php echo $plan[0]->id; ?>"/>
<input type="text" class="form-control col-md-6" name="schoolname" id="schoolname" placeholder="Enter school name" required value="<?php echo $plan[0]->school; ?>" style="max-width: 300px;">
</div>
<div class="form-group col-md-12" style="text-align: center;">
<div class="col-md-1"></div><label class="col-md-3 control-label">Postal code </label>
<input type="text" class="form-control col-md-6" name="pcode" id="pcode" placeholder="Enter postal code" required style="max-width: 300px;">
</div>
<div class="form-group col-md-12" style="text-align: center;">
<?php if($downgrade== 'Y') { $hidepay = 'Y'; ?>
<div class="form-group col-md-12" style="text-align: center;">
You can only renew or upgrade current plan.
<br>
<a href="<?php echo site_url(); ?>index.php/pricingplan" >Click to see all pricing plans</a>
</div>
<?php }?>
</div>
<div class="col-md-12" style="<?php if(isset($hidepay)){ echo 'display:none;'; } ?>">
<?php $planname = $plan[0]->title.' - '.' for '.$plan[0]->teacher_usagecount.' Teachers and upto '.$plan[0]->student_usagecount.' amount : '.$plan[0]->amount; ?>
<p style="font-size: 16px;margin-top:20px;margin-left: 20px;"><?php echo $plan[0]->title;?> : £ <?php echo $plan[0]->amount;?><!--<input type="image" src="" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">--></p>
<div id="paypal-button"></div>
<br>
<p><b>Note: Credit/debit cards accepted -</b> If you want to use a debit/credit card to pay (and not paypal), please select "Guest checkout" and then enter your credit/card details. Our systems are all handled securely by Paypal.</p>
<br>
<img src="https:securepayments.png">
<div id="div-error" style="text-align: center;color:red;></div>
</div>
</div>
<div class="col-md-3"></div>
</div>
<!--</form>-->
</div>
</div>
<script>
var action;
$('#div-error').hide();
$( "#schoolname" ).change(function() {
isValid();
});
$( "#pcode" ).change(function() {
isValid();
});
function paysuccess()
{
}
function isValid() {
//alert('validation');
$('#div-error').hide();
if($('#schoolname').val() == '')
{
$('#div-error').show();
$('#div-error').html('Please enter school name.');
if(action){
action.disable();
}
return false;
}
else if($('#pcode').val() == '')
{
$('#div-error').show();
$('#div-error').html('Please enter postal code.');
if(action){
action.disable();
}
return false;
}
else {
if(action){action.enable();
}
return true;
}
}
function toggleButton(actions) {
action = actions;
actions.disable();
return false;
}
paypal.Button.render({
env: '<?php echo $this->config->item('paypalenv'); ?>',
client: {
sandbox: '<?php echo $this->config->item('sandboxclientID'); ?>',
production: '<?php echo $this->config->item('productionclientID'); ?>'
},
validate: function(actions) {
toggleButton(actions);
},
onClick: function() {
isValid();
},
payment: function (data, actions) {
return actions.payment.create({
transactions: [{
amount: {
total: '<?php echo $plan[0]->amount;?>',
currency: 'GBP'
},
description : '<?php echo $planname; ?>',
custom : 'testandtrack'
}]
});
},
onAuthorize: function (data, actions) {
//debugger;
var form_data = {
paymentID: data.paymentID,
plan: '<?php echo $plan[0]->id;?>',
school : $('#schoolname').val(),
postal : $('#pcode').val()
};
$.ajax({
**url: "<?php echo site_url('index.php/teacher/paysuccess'); ?>",**
type: 'POST',
data: form_data,
success: function(msg) {
if(msg != ''){
window.location.href = "<?php echo site_url('index.php/teacher/success'); ?>/"+msg;
}
}
});
return actions.payment.execute()
.then(function () {
//debugger;
window.alert('Thank you for your purchase!');
});
}
}, '#paypal-button');
</script>
В файле views checkout.php выше есть строка:
**url: "<?php echo site_url('index.php/teacher/paysuccess'); ?>",**
Соответствующая функция показана выше в файле контроллера Teacher.php, под функцией извлечения.
Ajax использовался вместе с php.
Мой вопрос: может ли какой-нибудь гений заметить ошибку, которая вызывает эту ошибку?Как уже упоминалось, все штрафные кассы планов и платежи обрабатываются и база данных обновляется, за исключением плана с id = 4, который является платиновым планом.
Что-то не так с кодом, логикой или конкретным синтаксисом, относящимся к этому идентификатору плана?Иначе, может ли быть другая причина неудачной транзакции (которая прошла на нашем сайте, но не была записана в БД или произошла оплата через наш аккаунт), которую мы как-то пропустили?
Обновление: дополнительная функция, которая предназначена для добавления учителя в базу данных и обработки его членства, как премиум ниже.
public function addpremteacher()
{
$teachermail = $this->input->post('temail');
$teacher_id = $this->session->userdata('ID');
$data['paypinn']=$this->teachers->get_paypin($teacher_id);
$data['membership'] = $this->teachers->get_endate($data['paypinn'][0]->membershipid);
$data['teacher'] = $this->teachers->getteacherdetails($teachermail);
if($data['membership'][0]->tteacherremaining <= 0)
{
echo '-1';
}
else if(empty($data['teacher']))
{
echo '-2';
}
else if(!empty($data['teacher'][0]->membershipid) && $data['teacher'][0]->membershipid != 0)
{
echo '-3';
}
else
{
$update = $this->teachers->addteachertopremium($teachermail, $data['paypinn'][0]->membershipid);
if($update > 0 )
{
$update = $this->teachers->updateusagecount($data['paypinn'][0]->membershipid);
echo 1;
}
else
{
echo 0;
}
}
}