new templates
This commit is contained in:
parent
2ccc838b11
commit
b410078649
8 changed files with 821 additions and 6 deletions
|
|
@ -91,6 +91,15 @@ class PaymentRequest(models.Model):
|
|||
|
||||
self.save()
|
||||
|
||||
@property
|
||||
def reference_number(self):
|
||||
pna = PNA.objects.filter(payment_request=self).first()
|
||||
if pna:
|
||||
return pna.pk
|
||||
|
||||
else:
|
||||
return '00000000'
|
||||
|
||||
# TODO: complete and use this
|
||||
def change_state(self, from_state, to_state, error_message=None, **data):
|
||||
if self.state == from_state:
|
||||
|
|
@ -222,7 +231,7 @@ class PNA(BasePGModel):
|
|||
def confirm_request(self, request=None):
|
||||
if self.payment_request.state not in [StateChoices.IPG_PENDING]:
|
||||
messages.error(request, "وضعیت تراکنش در حالت مناسبی نیست.")
|
||||
return
|
||||
return False, "وضعیت تراکنش در حالت مناسبی نیست."
|
||||
|
||||
print(dict(request.POST))
|
||||
post_dict = dict(request.POST)
|
||||
|
|
@ -246,13 +255,16 @@ class PNA(BasePGModel):
|
|||
self.payment_request.charge_wallet_balance()
|
||||
|
||||
messages.success(request, 'شارژ انجام شد')
|
||||
return True, 'شارژ انجام شد'
|
||||
|
||||
except Exception as e:
|
||||
print(e)
|
||||
messages.error(request, str(e))
|
||||
return False, "خطایی رخ داده است."
|
||||
else:
|
||||
print(request.POST)
|
||||
messages.error(request, "نتیجه تراکنش از سمت درگاه دریافت نشد.")
|
||||
return False, "نتیجه تراکنش از سمت درگاه دریافت نشد."
|
||||
|
||||
def reverse_request(self):
|
||||
raise NotImplementedError()
|
||||
|
|
|
|||
|
|
@ -83,7 +83,8 @@ class PaymentRequestView(UpdateView):
|
|||
|
||||
@method_decorator(csrf_exempt, name='dispatch')
|
||||
class PaymentConfirmView(UpdateView):
|
||||
template_name = 'pg/payment-confirm.html'
|
||||
template_name = 'pg/payment_failure.html'
|
||||
# template_name = 'pg/payment_success.html'
|
||||
form_class = PaymentRequestForm
|
||||
# pk_url_kwarg = 'uuid'
|
||||
slug_field = 'uuid'
|
||||
|
|
@ -118,8 +119,11 @@ class PaymentConfirmView(UpdateView):
|
|||
return response
|
||||
|
||||
tool = self.object.get_gateway_tools()
|
||||
tool.confirm_request(request)
|
||||
state, message = tool.confirm_request(request)
|
||||
if state:
|
||||
self.template_name = 'pg/payment_success.html'
|
||||
context = self.get_context_data(object=self.object)
|
||||
context['message'] = message
|
||||
return self.render_to_response(context)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -244,6 +244,6 @@ CACHES = {
|
|||
}
|
||||
}
|
||||
|
||||
PNA_CORPORATION_PIN = config('PNA_CORPORATION_PIN')
|
||||
WALLET_BASE_PUBLIC_URL = config('WALLET_BASE_PUBLIC_URL')
|
||||
IPG_BASE_PUBLIC_URL = config('IPG_BASE_PUBLIC_URL')
|
||||
PNA_CORPORATION_PIN = config('PNA_CORPORATION_PIN')
|
||||
WALLET_BASE_PUBLIC_URL = config('WALLET_BASE_PUBLIC_URL')
|
||||
IPG_BASE_PUBLIC_URL = config('IPG_BASE_PUBLIC_URL')
|
||||
|
|
|
|||
34
static/css/datetimepicker.css
Normal file
34
static/css/datetimepicker.css
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
.cursorily{ cursor: pointer;}
|
||||
.hov:hover{ color: #000;}
|
||||
.ico-size{font-size: 16px;}
|
||||
.ico-size-month{font-size: 26px!important; line-height: 26px!important;}
|
||||
.ico-size-large{ font-size: 40px!important; line-height: 30px;}
|
||||
.dtp_main{ border: solid 1px #eee; border-radius: 3px; background-color: #fff; padding: 8px 0 8px 8px;}
|
||||
.dtp_main span, .dtp_main i{ display: inline-block; padding-right: 8px;}
|
||||
.dtp_modal-win{position: fixed;left: 0; top: 0; width: 100%; height: 100%;
|
||||
z-index: 999; background-color: #eeeeee; opacity: 0.6;}
|
||||
.dtp_modal-content{ background-color: #fff; border-radius: 10px; width: 624px;
|
||||
position: absolute; z-index: 1000; top: 100px; left: 100px; font-size: 16px;font-weight: normal;}
|
||||
.dtp_modal-content-no-time{ background-color: #fff; border-radius: 10px; width: 312px;
|
||||
position: absolute; z-index: 1000; top: 100px; left: 100px; font-size: 16px;font-weight: normal;}
|
||||
.dtp_modal-title{ border-bottom: solid 3px #54646b; padding: 16px 36px; margin-bottom: 16px; font-size: 22px; }
|
||||
.dtp_modal-cell-date{ width: 312px; float: right; margin-bottom: 22px; margin-top: 6px;}
|
||||
.dtp_modal-cell-time{width: 311px; float: left; direction: ltr; border-right: solid 1px #000;}
|
||||
.dtp_modal-months{ color: #7d7d7d; text-align: center; font-size: 20px; padding: 0 20px;}
|
||||
.dtp_modal-months span{ display: inline-block; padding: 10px 20px; width: 182px;}
|
||||
.dtp_modal-calendar{ width: 266px; margin-left: 22px; }
|
||||
.dtp_modal-calendar-cell{ width: 38px; padding: 7px 0; display: inline-block; text-align: center;}
|
||||
.dtp_modal-colored{ color: #54646b; }
|
||||
.dtp_modal-grey{ color: #7d7d7d; }
|
||||
.dtp_modal-cell-selected{ background-color: #54646b; border-radius: 48%; transition: background-color 1s ease-out;}
|
||||
.dtp_modal-time-block{ height: 212px; width: 310px; }
|
||||
.dpt_modal-button{ background-color: #54646b; color: #fff; font-size: 24px; padding: 8px 40px; float: left;
|
||||
text-align: center; display: inline-block; margin-left: 22px; cursor: pointer; border: solid 1px #fff;
|
||||
border-radius: 3px; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);}
|
||||
.dtp_modal-time-line{ text-align: center; color: #7d7d7d; font-size: 20px; padding-top: 15px; }
|
||||
.dtp_modal-time-mechanic{ padding-top: 16px;}
|
||||
.dtp_modal-append{ color: #7d7d7d; padding-left: 108px; font-weight: normal; }
|
||||
.dtp_modal-midle{ display: inline-block; width: 40px; }
|
||||
.dtp_modal-midle-dig{display: inline-block; width: 16px; text-align: center; }
|
||||
.dtp_modal-digits{ font-size: 50px; padding-left: 96px;}
|
||||
.dtp_modal-digit{ }
|
||||
396
static/js/datetimepicker.js
Normal file
396
static/js/datetimepicker.js
Normal file
|
|
@ -0,0 +1,396 @@
|
|||
(function ($) {
|
||||
'use strict';
|
||||
$.fn.dateTimePicker = function (options) {
|
||||
|
||||
var settings = $.extend({
|
||||
selectData: "now",
|
||||
dateFormat: "YYYY-MM-DD HH:mm",
|
||||
showTime: true,
|
||||
locale: 'en',
|
||||
positionShift: { top: 20, left: 0},
|
||||
title: "Select Date and Time",
|
||||
buttonTitle: "Select",
|
||||
allowBackwards: false
|
||||
}, options);
|
||||
moment.locale(settings.locale);
|
||||
var elem = this;
|
||||
var limitation = {"hour": 23, "minute": 59};
|
||||
var mousedown = false;
|
||||
var timeout = 800;
|
||||
var selectDate = settings.selectData == "now" ? moment() : moment(settings.selectData, settings.dateFormat);
|
||||
if (selectDate < moment() && (settings.allowBackwards == false)) {
|
||||
selectDate = moment();
|
||||
}
|
||||
var startDate = copyDate(moment());
|
||||
var lastSelected = copyDate(selectDate);
|
||||
return this.each(function () {
|
||||
if (lastSelected != selectDate) {
|
||||
selectDate = copyDate(lastSelected);
|
||||
}
|
||||
elem.addClass("dtp_main");
|
||||
updateMainElemGlobal();
|
||||
// elem.text(selectDate.format(settings.dateFormat));
|
||||
function updateMainElemGlobal() {
|
||||
var arrF = settings.dateFormat.split(' ');
|
||||
if (settings.showTime && arrF.length != 2) {
|
||||
arrF.length = 2;
|
||||
arrF[0] = 'DD/MM/YY';
|
||||
arrF[1] = 'HH:mm';
|
||||
}
|
||||
var $s = $('<span>');
|
||||
$s.text(lastSelected.format(arrF[0]));
|
||||
elem.empty();
|
||||
elem.append($s);
|
||||
$s = $('<i>');
|
||||
$s.addClass('fa fa-calendar ico-size');
|
||||
elem.append($s);
|
||||
if (settings.showTime) {
|
||||
$s = $('<span>');
|
||||
$s.text(lastSelected.format(arrF[1]));
|
||||
elem.append($s);
|
||||
$s = $('<i>');
|
||||
$s.addClass('fa fa-clock-o ico-size');
|
||||
elem.append($s);
|
||||
}
|
||||
}
|
||||
elem.on('click', function () {
|
||||
var $win = $('<div>');
|
||||
$win.addClass("dtp_modal-win");
|
||||
var $body = $('body');
|
||||
$body.append($win);
|
||||
var $content = createContent();
|
||||
$body.append($content);
|
||||
var offset = elem.offset();
|
||||
$content.css({top: (offset.top + settings.positionShift.top) + "px", left: (offset.left + settings.positionShift.left) + "px"});
|
||||
feelDates(selectDate);
|
||||
$win.on('click', function () {
|
||||
$content.remove();
|
||||
$win.remove();
|
||||
})
|
||||
if (settings.showTime) {
|
||||
attachChangeTime();
|
||||
var $fieldTime = $('#field-time');
|
||||
var $hour = $fieldTime.find('#d-hh');
|
||||
var $minute = $fieldTime.find('#d-mm');
|
||||
}
|
||||
|
||||
function feelDates(selectM) {
|
||||
var $fDate = $content.find('#field-data');
|
||||
$fDate.empty();
|
||||
$fDate.append(createMonthPanel(selectM));
|
||||
$fDate.append(createCalendar(selectM));
|
||||
}
|
||||
|
||||
function createCalendar(selectedMonth) {
|
||||
var $c = $('<div>');
|
||||
$c.addClass('dtp_modal-calendar');
|
||||
for (var i = 0; i < 7; i++) {
|
||||
var $e = $('<div>');
|
||||
$e.addClass('dtp_modal-calendar-cell dtp_modal-colored');
|
||||
$e.text(moment().weekday(i).format('ddd'));
|
||||
$c.append($e);
|
||||
}
|
||||
var m = copyDate(selectedMonth);
|
||||
m.date(1);
|
||||
// console.log(m.format('DD--MM--YYYY'));
|
||||
// console.log(selectData.format('DD--MM--YYYY'));
|
||||
// console.log(m.weekday());
|
||||
var flagStart = totalMonths(selectedMonth) === totalMonths(startDate);
|
||||
var flagSelect = totalMonths(lastSelected) === totalMonths(selectedMonth);
|
||||
var cerDay = parseInt(selectedMonth.format('D'));
|
||||
var dayNow = parseInt(startDate.format('D'));
|
||||
for (var i = 0; i < 6; i++) {
|
||||
for (var j = 0; j < 7; j++) {
|
||||
var $b = $('<div>');
|
||||
$b.html(' ');
|
||||
$b.addClass('dtp_modal-calendar-cell');
|
||||
if (m.month() == selectedMonth.month() && m.weekday() == j) {
|
||||
var day = parseInt(m.format('D'));
|
||||
$b.text(day);
|
||||
if (flagStart && day < dayNow) {
|
||||
|
||||
if (settings.allowBackwards == false) {
|
||||
$b.addClass('dtp_modal-grey');
|
||||
} else {
|
||||
$b.addClass('cursorily');
|
||||
$b.bind('click', changeDate);
|
||||
}
|
||||
|
||||
}
|
||||
else if (flagSelect && day == cerDay) {
|
||||
$b.addClass('dtp_modal-cell-selected');
|
||||
}
|
||||
else {
|
||||
$b.addClass('cursorily');
|
||||
$b.bind('click', changeDate);
|
||||
}
|
||||
m.add(1, 'days');
|
||||
}
|
||||
$c.append($b);
|
||||
}
|
||||
}
|
||||
return $c;
|
||||
}
|
||||
|
||||
function changeDate() {
|
||||
|
||||
var $div = $(this);
|
||||
selectDate.date($div.text());
|
||||
lastSelected = copyDate(selectDate);
|
||||
updateDate();
|
||||
var $fDate = $content.find('#field-data');
|
||||
var old = $fDate.find('.dtp_modal-cell-selected');
|
||||
old.removeClass('dtp_modal-cell-selected');
|
||||
old.addClass('cursorily');
|
||||
$div.addClass('dtp_modal-cell-selected');
|
||||
$div.removeClass('cursorily');
|
||||
old.bind('click', changeDate);
|
||||
$div.unbind('click');
|
||||
// console.log(selectDate.format('DD-MM-YYYY'));
|
||||
}
|
||||
|
||||
function createMonthPanel(selectMonth) {
|
||||
var $d = $('<div>');
|
||||
$d.addClass('dtp_modal-months');
|
||||
var $s = $('<i></i>');
|
||||
$s.addClass('fa fa-angle-left cursorily ico-size-month hov');
|
||||
//$s.attr('data-fa-mask', 'fas fa-circle');
|
||||
$s.bind('click', prevMonth);
|
||||
$d.append($s);
|
||||
$s = $('<span>');
|
||||
$s.text(selectMonth.format("MMMM YYYY"));
|
||||
$d.append($s);
|
||||
$s = $('<i></i>');
|
||||
$s.addClass('fa fa-angle-right cursorily ico-size-month hov');
|
||||
$s.bind('click', nextMonth);
|
||||
$d.append($s);
|
||||
return $d;
|
||||
}
|
||||
|
||||
function close() {
|
||||
if (settings.showTime) {
|
||||
lastSelected.hour(parseInt($hour.text()));
|
||||
lastSelected.minute(parseInt($minute.text()));
|
||||
selectDate.hour(parseInt($hour.text()));
|
||||
selectDate.minute(parseInt($minute.text()));
|
||||
}
|
||||
updateDate();
|
||||
$content.remove();
|
||||
$win.remove();
|
||||
}
|
||||
|
||||
function nextMonth() {
|
||||
selectDate.add(1, 'month');
|
||||
feelDates(selectDate);
|
||||
}
|
||||
|
||||
function prevMonth() {
|
||||
if (totalMonths(selectDate) > totalMonths(startDate) || settings.allowBackwards == true) {
|
||||
selectDate.add(-1, 'month');
|
||||
feelDates(selectDate);
|
||||
}
|
||||
}
|
||||
|
||||
function attachChangeTime() {
|
||||
var $angles = $($content).find('i[id^="angle-"]');
|
||||
// $angles.bind('click', changeTime);
|
||||
$angles.bind('mouseup', function () {
|
||||
mousedown = false;
|
||||
timeout = 800;
|
||||
});
|
||||
$angles.bind('mousedown', function () {
|
||||
mousedown = true;
|
||||
changeTime(this);
|
||||
});
|
||||
}
|
||||
|
||||
function changeTime(el) {
|
||||
var $el = this || el;
|
||||
$el = $($el);
|
||||
///angle-up-hour angle-up-minute angle-down-hour angle-down-minute
|
||||
var arr = $el.attr('id').split('-');
|
||||
var increment = 1;
|
||||
if (arr[1] == 'down') {
|
||||
increment = -1;
|
||||
}
|
||||
appendIncrement(arr[2], increment);
|
||||
setTimeout(function () {
|
||||
autoIncrement($el);
|
||||
}, timeout);
|
||||
}
|
||||
|
||||
function autoIncrement(el) {
|
||||
if (mousedown) {
|
||||
if (timeout > 200) {
|
||||
timeout -= 200;
|
||||
}
|
||||
changeTime(el);
|
||||
}
|
||||
}
|
||||
|
||||
function appendIncrement(typeDigits, increment) {
|
||||
|
||||
var $i = typeDigits == "hour" ? $hour : $minute;
|
||||
var val = parseInt($i.text()) + increment;
|
||||
if (val < 0) {
|
||||
val = limitation[typeDigits];
|
||||
}
|
||||
else if (val > limitation[typeDigits]) {
|
||||
val = 0;
|
||||
}
|
||||
$i.text(formatDigits(val));
|
||||
}
|
||||
|
||||
function formatDigits(val) {
|
||||
|
||||
if (val < 10) {
|
||||
return '0' + val;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
function createTimer() {
|
||||
var $div = $('<div>');
|
||||
$div.addClass('dtp_modal-time-mechanic');
|
||||
var $panel = $('<div>');
|
||||
$panel.addClass('dtp_modal-append');
|
||||
var $i = $('<i>');
|
||||
$i.attr('id', 'angle-up-hour');
|
||||
$i.addClass('fa fa-angle-up ico-size-large cursorily hov');
|
||||
$panel.append($i);
|
||||
var $m = $('<span>');
|
||||
$m.addClass('dtp_modal-midle');
|
||||
$panel.append($m);
|
||||
$i = $('<i>');
|
||||
$i.attr('id', 'angle-up-minute');
|
||||
$i.addClass('fa fa-angle-up ico-size-large cursorily hov');
|
||||
$panel.append($i);
|
||||
$div.append($panel);
|
||||
|
||||
$panel = $('<div>');
|
||||
$panel.addClass('dtp_modal-digits');
|
||||
var $d = $('<span>');
|
||||
$d.addClass('dtp_modal-digit');
|
||||
$d.attr('id', 'd-hh');
|
||||
$d.text(lastSelected.format('HH'));
|
||||
$panel.append($d);
|
||||
$m = $('<span>');
|
||||
$m.addClass('dtp_modal-midle-dig');
|
||||
$m.html(':');
|
||||
$panel.append($m);
|
||||
$d = $('<span>');
|
||||
$d.addClass('dtp_modal-digit');
|
||||
$d.attr('id', 'd-mm');
|
||||
$d.text(lastSelected.format('mm'));
|
||||
$panel.append($d);
|
||||
$div.append($panel);
|
||||
|
||||
$panel = $('<div>');
|
||||
$panel.addClass('dtp_modal-append');
|
||||
$i = $('<i>');
|
||||
$i.attr('id', 'angle-down-hour');
|
||||
$i.addClass('fa fa-angle-down ico-size-large cursorily hov');
|
||||
$panel.append($i);
|
||||
$m = $('<span>');
|
||||
$m.addClass('dtp_modal-midle');
|
||||
$panel.append($m);
|
||||
$i = $('<i>');
|
||||
$i.attr('id', 'angle-down-minute');
|
||||
$i.addClass('fa fa-angle-down ico-size-large cursorily hov');
|
||||
$panel.append($i);
|
||||
$div.append($panel);
|
||||
return $div;
|
||||
}
|
||||
|
||||
function createContent() {
|
||||
var $c = $('<div>');
|
||||
if (settings.showTime) {
|
||||
$c.addClass("dtp_modal-content");
|
||||
}
|
||||
else {
|
||||
$c.addClass("dtp_modal-content-no-time");
|
||||
}
|
||||
var $el = $('<div>');
|
||||
$el.addClass("dtp_modal-title");
|
||||
$el.text(settings.title);
|
||||
$c.append($el);
|
||||
$el = $('<div>');
|
||||
$el.addClass('dtp_modal-cell-date');
|
||||
$el.attr('id', 'field-data');
|
||||
$c.append($el);
|
||||
if (settings.showTime) {
|
||||
$el = $('<div>');
|
||||
$el.addClass('dtp_modal-cell-time');
|
||||
var $a = $('<div>');
|
||||
$a.addClass('dtp_modal-time-block');
|
||||
$a.attr('id', 'field-time');
|
||||
$el.append($a);
|
||||
var $line = $('<div>');
|
||||
$line.attr('id', 'time-line');
|
||||
$line.addClass('dtp_modal-time-line');
|
||||
$line.text(lastSelected.format(settings.dateFormat));
|
||||
|
||||
$a.append($line);
|
||||
$a.append(createTimer());
|
||||
var $but = $('<div>');
|
||||
$but.addClass('dpt_modal-button');
|
||||
$but.text(settings.buttonTitle);
|
||||
$but.bind('click', close);
|
||||
$el.append($but);
|
||||
$c.append($el);
|
||||
}
|
||||
return $c;
|
||||
}
|
||||
function updateDate() {
|
||||
if (settings.showTime) {
|
||||
$('#time-line').text(lastSelected.format(settings.dateFormat));
|
||||
}
|
||||
updateMainElem();
|
||||
elem.next().val(selectDate.format(settings.dateFormat));
|
||||
if (!settings.showTime) {
|
||||
$content.remove();
|
||||
$win.remove();
|
||||
}
|
||||
}
|
||||
|
||||
function updateMainElem() {
|
||||
var arrF = settings.dateFormat.split(' ');
|
||||
if (settings.showTime && arrF.length != 2) {
|
||||
arrF.length = 2;
|
||||
arrF[0] = 'DD/MM/YY';
|
||||
arrF[1] = 'HH:mm';
|
||||
}
|
||||
var $s = $('<span>');
|
||||
$s.text(lastSelected.format(arrF[0]));
|
||||
elem.empty();
|
||||
elem.append($s);
|
||||
$s = $('<i>');
|
||||
$s.addClass('fa fa-calendar ico-size');
|
||||
elem.append($s);
|
||||
if (settings.showTime) {
|
||||
$s = $('<span>');
|
||||
$s.text(lastSelected.format(arrF[1]));
|
||||
elem.append($s);
|
||||
$s = $('<i>');
|
||||
$s.addClass('fa fa-clock-o ico-size');
|
||||
elem.append($s);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
function copyDate(d) {
|
||||
return moment(d.toDate());
|
||||
}
|
||||
|
||||
function totalMonths(m) {
|
||||
var r = m.format('YYYY') * 12 + parseInt(m.format('MM'));
|
||||
return r;
|
||||
}
|
||||
|
||||
}(jQuery));
|
||||
// fa-caret-down
|
||||
15
templates/admin/input_filter.html
Normal file
15
templates/admin/input_filter.html
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<!-- templates/admin/input_filter.html -->
|
||||
|
||||
{% load i18n %}
|
||||
|
||||
<h3>{% blocktrans with filter_title=title %} By {{ filter_title }} {% endblocktrans %}</h3>
|
||||
<ul>
|
||||
<li>
|
||||
<form method="GET" action="">
|
||||
<input
|
||||
type="text"
|
||||
value="{{ spec.value|default_if_none:'' }}"
|
||||
name="{{ spec.parameter_name }}"/>
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
179
templates/pg/payment_failure.html
Normal file
179
templates/pg/payment_failure.html
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
{% load static %}
|
||||
{% load crispy_forms_tags %}
|
||||
{% load jalali_tags %}
|
||||
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="fa" dir="rtl">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Payment Unsuccessful</title>
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;700&display=swap" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: 'Vazirmatn', sans-serif;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
|
||||
.mobile-frame {
|
||||
width: 390px;
|
||||
height: 844px;
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
|
||||
padding: 30px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.screen-content {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
|
||||
.message-section {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.error-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background-color: #e53935; /* Red for error */
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: white;
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.error-text {
|
||||
color: #e53935;
|
||||
font-size: 1.1rem;
|
||||
font-weight: bold;
|
||||
margin-top: 15px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
.divider {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background-color: #eeeeee;
|
||||
border: none;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
.details-text {
|
||||
color: #757575;
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.details-text .code {
|
||||
color: #424242;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.placeholder-link {
|
||||
color: #bdbdbd;
|
||||
font-size: 0.9rem;
|
||||
text-decoration: underline;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
|
||||
.button-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 15px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
padding: 14px;
|
||||
border-radius: 20px;
|
||||
font-size: 1rem;
|
||||
font-weight: bold;
|
||||
font-family: 'Vazirmatn', sans-serif;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease-in-out;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
.btn-retry {
|
||||
background-color: #ffffff;
|
||||
border: 2px solid #6931c9;
|
||||
color: #6931c9;
|
||||
}
|
||||
|
||||
.btn-retry:hover {
|
||||
background-color: #f9f7fd;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: #6931c9;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background-color: #7745ce;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="mobile-frame">
|
||||
<div class="screen-content">
|
||||
|
||||
<div class="message-section">
|
||||
<div class="error-icon">!</div>
|
||||
{% if message %}
|
||||
<p class="error-text">{{ message }}</p>
|
||||
{% else %}
|
||||
<p class="error-text">پرداخت شما ناموفق بود</p>
|
||||
{% endif %}
|
||||
<hr class="divider">
|
||||
<div class="details-text">
|
||||
<p>کد پیگیری تراکنش شما: <span class="code">{{ object.reference_number }}</span></p>
|
||||
<p>در صورت کسر از موجودی، مبلغ پرداختی طی یک تا 72 ساعت آینده به حساب شما بازگردانده خواهد شد.</p>
|
||||
</div>
|
||||
<a href="https://addwin.ir" class="placeholder-link">addwin</a>
|
||||
</div>
|
||||
|
||||
<div class="button-container">
|
||||
<form action="{{ request.get_full_path }}" method="post" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
{{ form|crispy }}
|
||||
<button class="btn btn-primary">بازگشت به صفحه اصلی</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
175
templates/pg/payment_success.html
Normal file
175
templates/pg/payment_success.html
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
{% load static %}
|
||||
{% load crispy_forms_tags %}
|
||||
{% load jalali_tags %}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="fa" dir="rtl">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Payment Successful</title>
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;700&display=swap" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: 'Vazirmatn', sans-serif;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
|
||||
.mobile-frame {
|
||||
width: 390px;
|
||||
height: 844px;
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
|
||||
padding: 30px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.screen-content {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
|
||||
.message-section {
|
||||
width: 100%;
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.success-icon {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
background-color: #4CAF50;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: white;
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: #333;
|
||||
font-size: 1.2rem;
|
||||
font-weight: bold;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
color: #757575;
|
||||
font-size: 0.9rem;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
.divider {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background-color: #eeeeee;
|
||||
border: none;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
.amount-row {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.amount-label {
|
||||
color: #757575;
|
||||
}
|
||||
|
||||
.amount-value {
|
||||
color: #4CAF50;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.placeholder-link {
|
||||
color: #bdbdbd;
|
||||
font-size: 0.9rem;
|
||||
text-decoration: underline;
|
||||
margin-top: 100px;
|
||||
}
|
||||
|
||||
|
||||
.button-container {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 100%;
|
||||
padding: 15px;
|
||||
border: none;
|
||||
border-radius: 20px;
|
||||
font-size: 1.1rem;
|
||||
font-weight: bold;
|
||||
font-family: 'Vazirmatn', sans-serif;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: #6931c9;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background-color: #7745ce;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="mobile-frame">
|
||||
<div class="screen-content">
|
||||
|
||||
<div class="message-section">
|
||||
<div class="success-icon">✓</div>
|
||||
<p class="title">پرداخت موفق</p>
|
||||
<p class="subtitle">پرداخت با موفقیت انجام شد.</p>
|
||||
<hr class="divider">
|
||||
<div class="amount-row">
|
||||
<span class="amount-label">مقدار پرداخت شده:</span>
|
||||
<span class="amount-value">{{ object.amount }} تومان</span>
|
||||
</div>
|
||||
<a href="https://addwin.ir" class="placeholder-link">addwin</a>
|
||||
</div>
|
||||
|
||||
<div class="button-container">
|
||||
<form action="{{ request.get_full_path }}" method="post" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
{{ form|crispy }}
|
||||
<button class="btn btn-primary">بازگشت به صفحه اصلی</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Reference in a new issue