up
This commit is contained in:
parent
41ac293192
commit
da59cd7d39
14 changed files with 244 additions and 99 deletions
|
@ -8,12 +8,25 @@ class ControllerPayments:
|
|||
self.args = args
|
||||
|
||||
def balance_update(self, transaction_id, amount):
|
||||
"""
|
||||
Обновление баланса пользователя
|
||||
:param transaction_id:
|
||||
:param amount:
|
||||
:return:
|
||||
"""
|
||||
user = models.UsersBalanceTransactions.select().where(models.UsersBalanceTransactions.id == transaction_id)[0]
|
||||
balance = models.UsersBalance.get(models.UsersBalance.user == user.user.id)
|
||||
balance.balance += float(amount)
|
||||
balance.save()
|
||||
|
||||
def transaction_create(self, user_id, amount, status='process'):
|
||||
"""
|
||||
Создание записи о транзакции со статусом 'proccess'
|
||||
:param user_id:
|
||||
:param amount:
|
||||
:param status:
|
||||
:return:
|
||||
"""
|
||||
# create transaction data to database
|
||||
transaction = models.UsersBalanceTransactions(user=user_id, amount=amount, status=status)
|
||||
transaction.save()
|
||||
|
@ -27,6 +40,12 @@ class ControllerPayments:
|
|||
return True
|
||||
|
||||
def transaction_set_status(self, transaction_id, status):
|
||||
"""
|
||||
Обновить статус [fail, success, process]
|
||||
:param transaction_id:
|
||||
:param status:
|
||||
:return:
|
||||
"""
|
||||
# update transaction signature
|
||||
transaction = models.UsersBalanceTransactions.get(models.UsersBalanceTransactions.id == transaction_id)
|
||||
transaction.status = status
|
||||
|
|
|
@ -156,6 +156,8 @@ class ControllerUsersDetails(ControllerUsers):
|
|||
x.country = kwargs['country']
|
||||
if 'state' in kwargs:
|
||||
x.state = kwargs['state']
|
||||
if 'phone' in kwargs:
|
||||
x.phone = kwargs['phone']
|
||||
if 'zipcode' in kwargs:
|
||||
x.zipcode = kwargs['zipcode']
|
||||
x.save()
|
||||
|
|
|
@ -10,6 +10,8 @@ from flask import request
|
|||
from flask import Blueprint
|
||||
from app import models
|
||||
from app.cloud.controllers.users import ControllerUsers
|
||||
from app.cloud.controllers.users import ControllerUsersDetails
|
||||
from app.cloud.controllers.payments import ControllerPayments
|
||||
from app.cloud.controllers.payments import ControllerPaymentsRobokassa
|
||||
from app.cloud.controllers.payments import twocheckout
|
||||
|
||||
|
@ -118,34 +120,57 @@ def robokassa(action):
|
|||
|
||||
@viewPayments.route('/twocheckout/order', methods=['POST'])
|
||||
def twocheckout_order():
|
||||
# check session
|
||||
if not ControllerUsers().check_session():
|
||||
return redirect(url_for("account.logout"))
|
||||
# auth user
|
||||
if not ControllerUsers().auth(session['email'], session['password']):
|
||||
return redirect(url_for("account.logout"))
|
||||
|
||||
user_account = ControllerUsers(session['user_id']).get()
|
||||
user_details = ControllerUsersDetails(session['user_id']).details_get()
|
||||
|
||||
transaction_id = ControllerPayments().transaction_create(session['user_id'], request.form['amount'], 'process')
|
||||
|
||||
# Setup credentials and environment
|
||||
twocheckout.Api.auth_credentials({
|
||||
'private_key': 'sandbox-private-key',
|
||||
'seller_id': 'sandbox-seller_id',
|
||||
# sandbox-private-key
|
||||
'private_key': g.settings['PAY_TWOCHECKOUT_PRIVATEKEY'],
|
||||
# sandbox-seller_id
|
||||
'seller_id': g.settings['PAY_TWOCHECKOUT_SELLER_ID'],
|
||||
'mode': 'sandbox'
|
||||
})
|
||||
|
||||
# Setup arguments for authorization request
|
||||
args = {
|
||||
'merchantOrderId': '123',
|
||||
'merchantOrderId': transaction_id,
|
||||
'token': request.form["token"],
|
||||
'currency': 'USD',
|
||||
'total': '1.00',
|
||||
'total': request.form['amount'],
|
||||
'billingAddr': {
|
||||
'name': 'Testing Tester',
|
||||
'addrLine1': '123 Test St',
|
||||
'city': 'Columbus',
|
||||
'state': 'OH',
|
||||
'zipCode': '43123',
|
||||
'country': 'USA',
|
||||
'email': 'example@2co.com',
|
||||
'phoneNumber': '555-555-5555'
|
||||
'name': '%s %s' % (user_details.fname, user_details.lname),
|
||||
'addrLine1': user_details.address,
|
||||
'city': user_details.city,
|
||||
'state': user_details.state,
|
||||
'zipCode': str(user_details.zipcode),
|
||||
'country': user_details.country,
|
||||
'email': user_account.email,
|
||||
'phoneNumber': user_details.phone
|
||||
}
|
||||
}
|
||||
|
||||
print args
|
||||
|
||||
# Make authorization request
|
||||
try:
|
||||
result = twocheckout.Charge.authorize(args)
|
||||
return result.responseMsg
|
||||
ControllerPayments().transaction_set_status(transaction_id, 'success')
|
||||
ControllerPayments().balance_update(transaction_id, request.form['amount'])
|
||||
|
||||
# return result.responseMsg
|
||||
return redirect(url_for('settings.billing'))
|
||||
except twocheckout.TwocheckoutError as error:
|
||||
return error.msg
|
||||
ControllerPayments().transaction_set_status(transaction_id, 'fail')
|
||||
|
||||
# return error.msg
|
||||
return redirect(url_for('settings.billing'))
|
||||
|
|
|
@ -81,7 +81,7 @@ def profile():
|
|||
)
|
||||
|
||||
|
||||
@viewSettings.route('/profile_edit')
|
||||
@viewSettings.route('/profile_edit', methods=['GET', 'POST'])
|
||||
def profile_edit():
|
||||
# check session
|
||||
if not ControllerUsers().check_session():
|
||||
|
@ -109,9 +109,10 @@ def profile_edit():
|
|||
city=request.form['city'],
|
||||
country=request.form['country'],
|
||||
state=request.form['state'],
|
||||
phone=request.form['phone'],
|
||||
zipcode=request.form['zipcode']
|
||||
)
|
||||
return redirect(url_for('account.edit'))
|
||||
return redirect(url_for('settings.profile_edit'))
|
||||
# get user details
|
||||
user_details = cud.details_get()
|
||||
return render_template(
|
||||
|
|
|
@ -92,9 +92,25 @@ class UsersDetails(PgSQLModel):
|
|||
city = CharField(null=True)
|
||||
country = CharField(null=True)
|
||||
state = CharField(null=True)
|
||||
phone = CharField(null=True)
|
||||
zipcode = IntegerField(null=True)
|
||||
|
||||
|
||||
# class UsersBillingDetails(PgSQLModel):
|
||||
# user = ForeignKeyField(Users)
|
||||
# fname = CharField(null=True)
|
||||
# lname = CharField(null=True)
|
||||
# city = CharField(null=True)
|
||||
# address = CharField(null=True)
|
||||
# country = CharField(null=True)
|
||||
# state = CharField(null=True)
|
||||
# zipcode = IntegerField(null=True)
|
||||
# ccno = CharField(null=True)
|
||||
# ccmonth = CharField(null=True)
|
||||
# ccyear = CharField(null=True)
|
||||
# cccvc = CharField(null=True)
|
||||
#
|
||||
|
||||
class UsersBalance(PgSQLModel):
|
||||
user = ForeignKeyField(Users, related_name='usersbalance')
|
||||
balance = FloatField(default=0, null=False)
|
||||
|
|
|
@ -77,4 +77,10 @@ ul#features-list {
|
|||
ul#features-list li {
|
||||
font-family: 'Clear sans';
|
||||
margin-left: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
# tabs
|
||||
|
||||
div .tabs-content {
|
||||
border: 2px solid #cccccc;
|
||||
}
|
||||
|
|
|
@ -120,7 +120,12 @@
|
|||
<li><a href="{{ url_for('administrator.ips_index') }}"><i class="fa fa-fw fa-table"></i> IPs</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="{{ url_for('administrator.settings_index') }}"><i class="fa fa-fw fa-table"></i> Settings</a></li>
|
||||
<li><a href="{{ url_for('administrator.settings_index') }}"><i class="fa fa-fw fa-table"></i> Settings</a>
|
||||
<ul>
|
||||
<li><a href="{{ url_for('administrator.settings_index') }}"><i class="fa fa-fw fa-table"></i> SMTP</a></li>
|
||||
<li><a href="{{ url_for('administrator.settings_index') }}"><i class="fa fa-fw fa-table"></i> Payments</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- /.navbar-collapse -->
|
||||
|
|
38
app/templates/administrator/settings/payments/index.html
Normal file
38
app/templates/administrator/settings/payments/index.html
Normal file
|
@ -0,0 +1,38 @@
|
|||
{% extends 'administrator/_layout.auth.html' %}
|
||||
|
||||
{% block title %}Settings{% endblock %}
|
||||
|
||||
{% block subtitle %}Payments{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<th>Key</th>
|
||||
<th>Value</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% if settings.total == 0 %}
|
||||
<tr>
|
||||
<td colspan="4">Нет ни одного параметра.</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
{% for setting in settings['items'] %}
|
||||
<tr>
|
||||
<td>{{ setting.id }}</td>
|
||||
<td>{{ setting.key }}</td>
|
||||
<td>{{ setting.val }}</td>
|
||||
<td>
|
||||
[<a href="{{ url_for('administrator.settings_update', id=setting.id) }}">Edit</a>]
|
||||
[<a href="{{ url_for('administrator.settings_delete', id=setting.id) }}">Delete</a>]
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
<a href="{{ url_for('administrator.settings_create') }}" class="btn btn-success">Create new</a>
|
||||
{% endblock %}
|
|
@ -1,49 +1,63 @@
|
|||
<form id="myCCForm" action="/order" method="post">
|
||||
<input id="token" name="token" type="hidden" value="">
|
||||
<div class="row">
|
||||
<div class="large-12 columns">
|
||||
<label>
|
||||
<span>Card Number</span>
|
||||
</label>
|
||||
<input id="ccNo" type="text" size="20" value="" autocomplete="off" required />
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="large-12 columns">
|
||||
<form id="myCCForm" action="{{ url_for('payments.twocheckout_order') }}" method="post">
|
||||
<input id="token" name="token" type="hidden" value="">
|
||||
<div class="row">
|
||||
<div class="large-12 columns">
|
||||
<h4>{{ _("Credit Cards") }}</h4>
|
||||
<p>{# Card will be charged monthly for resources used. #}All major credit cards accepted.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="large-12 columns">
|
||||
<label for="ccNo">{{ _("Card Number") }}</label>
|
||||
<input id="ccNo" name="ccNo" type="text" size="20" value="" autocomplete="off" required />
|
||||
</div>
|
||||
<div class="large-3 columns">
|
||||
<label for="expMonth">Expiration month</label>
|
||||
<select id="expMonth" name="expMonth" required>
|
||||
<option value="01">01</option>
|
||||
<option value="02">02</option>
|
||||
<option value="03">03</option>
|
||||
<option value="04">04</option>
|
||||
<option value="05">05</option>
|
||||
<option value="06">06</option>
|
||||
<option value="07">07</option>
|
||||
<option value="08">08</option>
|
||||
<option value="09">09</option>
|
||||
<option value="10">10</option>
|
||||
<option value="11">11</option>
|
||||
<option value="12">12</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="large-3 columns">
|
||||
<label for="expYear">Expiration year</label>
|
||||
<select name="expYear" id="expYear" required >
|
||||
<option value="2016">2016</option>
|
||||
<option value="2017">2017</option>
|
||||
<option value="2018">2018</option>
|
||||
<option value="2019">2019</option>
|
||||
<option value="2020">2020</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="large-3 columns">
|
||||
<label for="cvv">CVV</label>
|
||||
<input id="cvv" name="cvv" size="4" type="text" value="" autocomplete="off" required />
|
||||
</div>
|
||||
<div class="large-3 columns">
|
||||
<label for="amount">Amount</label>
|
||||
<select id="amount" name="amount">
|
||||
<option value="5">$5</option>
|
||||
<option value="10">$10</option>
|
||||
<option value="25">$25</option>
|
||||
<option value="50">$50</option>
|
||||
<option value="100">$100</option>
|
||||
<option value="500">$500</option>
|
||||
<option value="1000">$1000</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<input type="submit" value="Submit Payment" class="button success" />
|
||||
</form>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="large-4 columns">
|
||||
<label>
|
||||
<span>Expiration month</span>
|
||||
</label>
|
||||
<select id="expMonth" required>
|
||||
<option value="01">01</option>
|
||||
<option value="02">02</option>
|
||||
<option value="03">03</option>
|
||||
<option value="04">04</option>
|
||||
<option value="05">05</option>
|
||||
<option value="06">06</option>
|
||||
<option value="07">07</option>
|
||||
<option value="08">08</option>
|
||||
<option value="09">09</option>
|
||||
<option value="10">10</option>
|
||||
<option value="11">11</option>
|
||||
<option value="12">12</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="large-4 columns">
|
||||
<label>Expiration year</label>
|
||||
<select name="expYear" id="expYear" required >
|
||||
<option value="2016">2016</option>
|
||||
<option value="2017">2017</option>
|
||||
<option value="2018">2018</option>
|
||||
<option value="2019">2019</option>
|
||||
<option value="2020">2020</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="large-4 columns">
|
||||
<label>
|
||||
<span>CVC</span>
|
||||
</label>
|
||||
<input id="cvv" size="4" type="text" value="" autocomplete="off" required />
|
||||
</div>
|
||||
</div>
|
||||
<input type="submit" value="Submit Payment">
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
<form action="{{ url_for('payments.robokassa', action='process') }}" method="post">
|
||||
<div class="large-6 columns">
|
||||
<h4>PayPal Payment</h4>
|
||||
<p>This is a one-time payment that will not recur. Payment may take up to 5 minutes to process.</p>
|
||||
</div>
|
||||
<div class="large-3 columns">
|
||||
<select name="amount">
|
||||
<option value="500">500 рублей</option>
|
||||
<option value="1000">1000 рублей</option>
|
||||
<option value="2000">2000 рублей</option>
|
||||
<option value="5000">5000 рублей</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="large-3 columns">
|
||||
<input type="submit" value="Оплатить" class="button postfix" />
|
||||
</div>
|
||||
</form>
|
||||
<div class="row">
|
||||
<form action="{{ url_for('payments.robokassa', action='process') }}" method="post">
|
||||
<div class="large-6 columns">
|
||||
<h4>PayPal Payment</h4>
|
||||
<p>This is a one-time payment that will not recur. Payment may take up to 5 minutes to process.</p>
|
||||
</div>
|
||||
<div class="large-3 columns">
|
||||
<select name="amount">
|
||||
<option value="500">500 рублей</option>
|
||||
<option value="1000">1000 рублей</option>
|
||||
<option value="2000">2000 рублей</option>
|
||||
<option value="5000">5000 рублей</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="large-3 columns">
|
||||
<input type="submit" value="Оплатить" class="button postfix" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
|
@ -18,7 +18,7 @@
|
|||
<h3>{{ _("Billing") }}</h3>
|
||||
</div>
|
||||
<div class="large-12 columns">
|
||||
<p>Баланс: {{ user_balance }} рублей</p>
|
||||
<p>{{ _("Balance") }}: ${{ user_balance }}</p>
|
||||
<hr/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -26,26 +26,31 @@
|
|||
<div class="large-12 columns">
|
||||
<h3>{{ _("Payment Methods") }}</h3>
|
||||
<ul class="tabs" data-tab role="tablist">
|
||||
{% if g.settings['PAY_TWOCHECKOUT_ENABLED'] == "1" %}
|
||||
<li class="tab-title active" role="presentation"><a href="#panel2-1" role="tab" tabindex="0" aria-selected="true" aria-controls="panel2-1">Credit card</a></li>
|
||||
<!-- li class="tab-title" role="presentation"><a href="#panel2-2" role="tab" tabindex="0" aria-selected="false" aria-controls="panel2-2">Paypal</a></--li>
|
||||
<li class="tab-title" role="presentation"><a href="#panel2-3" role="tab" tabindex="0" aria-selected="false" aria-controls="panel2-3">Robokassa</a></li -->
|
||||
{% endif %}
|
||||
<!-- li class="tab-title" role="presentation"><a href="#panel2-2" role="tab" tabindex="0" aria-selected="false" aria-controls="panel2-2">Paypal</a></--li -->
|
||||
{% if g.settings['PAY_ROBOKASSA_ENABLED'] == "1" %}
|
||||
<li class="tab-title" role="presentation"><a href="#panel2-3" role="tab" tabindex="0" aria-selected="false" aria-controls="panel2-3">Robokassa</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
<div class="tabs-content">
|
||||
{% if g.settings['PAY_TWOCHECKOUT_ENABLED'] == "1" %}
|
||||
<section role="tabpanel" aria-hidden="false" class="content active" id="panel2-1">
|
||||
{% include "default/settings/billing/_tab.creditcard.html" %}
|
||||
</section>
|
||||
<!-- section role="tabpanel" aria-hidden="true" class="content" id="panel2-2">
|
||||
{% endif %}
|
||||
<!--section role="tabpanel" aria-hidden="true" class="content" id="panel2-2">
|
||||
{% include "default/settings/billing/_tab.paypal.html" %}
|
||||
</section>
|
||||
<section role="tabpanel" aria-hidden="true" class="content" id="panel2-3">
|
||||
{% if g.settings['PAY_ROBOKASSA_ENABLED'] == "1" %}
|
||||
{% include "default/settings/billing/_tab.robokassa.html" %}
|
||||
{% endif %}
|
||||
</section -->
|
||||
{% if g.settings['PAY_ROBOKASSA_ENABLED'] == "1" %}
|
||||
<section role="tabpanel" aria-hidden="true" class="content" id="panel2-3">
|
||||
{% include "default/settings/billing/_tab.robokassa.html" %}
|
||||
</section>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="large-12 columns">
|
||||
<h4>{{ _("Billing History") }}</h4>
|
||||
|
@ -87,7 +92,6 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="https://www.2checkout.com/checkout/api/2co.min.js"></script>
|
||||
<script>
|
||||
$(document).foundation({
|
||||
tab: {
|
||||
|
@ -97,6 +101,8 @@
|
|||
}
|
||||
});
|
||||
</script>
|
||||
{% if g.settings['PAY_TWOCHECKOUT_ENABLED'] == "1" %}
|
||||
<script src="https://www.2checkout.com/checkout/api/2co.min.js"></script>
|
||||
<script>
|
||||
// Called when token created successfully.
|
||||
var successCallback = function(data) {
|
||||
|
@ -121,8 +127,8 @@
|
|||
var tokenRequest = function() {
|
||||
// Setup token request arguments
|
||||
var args = {
|
||||
sellerId: "sandbox-seller-id",
|
||||
publishableKey: "sandbox-publishable-key",
|
||||
sellerId: "{{ g.settings['PAY_TWOCHECKOUT_SELLER_ID'] }}",
|
||||
publishableKey: "{{ g.settings['PAY_TWOCHECKOUT_PUBLICKEY'] }}",
|
||||
ccNo: $("#ccNo").val(),
|
||||
cvv: $("#cvv").val(),
|
||||
expMonth: $("#expMonth").val(),
|
||||
|
@ -132,18 +138,17 @@
|
|||
// Make the token request
|
||||
TCO.requestToken(successCallback, errorCallback, args);
|
||||
};
|
||||
|
||||
$(function() {
|
||||
// Pull in the public encryption key for our environment
|
||||
TCO.loadPubKey('sandbox');
|
||||
|
||||
//
|
||||
$("#myCCForm").submit(function(e) {
|
||||
// Call our token request function
|
||||
tokenRequest();
|
||||
|
||||
// Prevent form from submitting
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
<input name="state" id="state" type="text" class="long-field" value="{{ user_details['state'] }}" />
|
||||
<label for="zipcode">{{ _("ZIP") }}</label>
|
||||
<input name="zipcode" id="zipcode" type="text" class="small-field" value="{{ user_details['zipcode'] }}" />
|
||||
<label for="phone">{{ _("Phone") }}</label>
|
||||
<input name="phone" id="phone" type="text" class="small-field" value="{{ user_details['phone'] }}" />
|
||||
<input type="submit" value="{{ _('Save changes') }}" class="button success" />
|
||||
|
||||
<a href="{{ url_for('settings.profile') }}">{{ _("Cancel") }}</a>
|
||||
|
|
|
@ -12,4 +12,6 @@
|
|||
<input type="text" class="long-field" value="{{ user_details['state'] }}" disabled />
|
||||
<label>{{ _("ZIP") }}</label>
|
||||
<input type="text" class="long-field" value="{{ user_details['zipcode'] }}" disabled />
|
||||
<label>{{ _("Phone") }}</label>
|
||||
<input type="text" class="long-field" value="{{ user_details['phone'] }}" disabled />
|
||||
<a href="{{ url_for('settings.profile_edit') }}" class="button success">{{ _("Change") }}</a>
|
||||
|
|
|
@ -19,6 +19,14 @@ create_key('PAY_ROBOKASSA_LOGIN', '')
|
|||
create_key('PAY_ROBOKASSA_PASSWORD1', '')
|
||||
create_key('PAY_ROBOKASSA_PASSWORD2', '')
|
||||
create_key('PAY_ROBOKASSA_ENABLED', '')
|
||||
|
||||
create_key('PAY_TWOCHECKOUT_ENABLED', '0')
|
||||
create_key('PAY_TWOCHECKOUT_MODE', '')
|
||||
create_key('PAY_TWOCHECKOUT_SELLER_ID', '')
|
||||
create_key('PAY_TWOCHECKOUT_PRIVATEKEY', '')
|
||||
create_key('PAY_TWOCHECKOUT_PUBLICKEY', '')
|
||||
|
||||
|
||||
create_key('SMTP_PORT', '')
|
||||
create_key('SMTP_USERNAME', '')
|
||||
create_key('SMTP_PASSWORD', '')
|
||||
|
|
Loading…
Add table
Reference in a new issue