Work on payment system
This commit is contained in:
parent
40b9b12779
commit
4e45251563
|
@ -7,11 +7,12 @@ ENV SITE_FOLDER /etc/sites/mysite/
|
||||||
#COPY website/config/uwsgi/maidstone-hackspace.org.uk.ini /etc/sites/uwsgi/maidstone-hackspace.org.uk.ini
|
#COPY website/config/uwsgi/maidstone-hackspace.org.uk.ini /etc/sites/uwsgi/maidstone-hackspace.org.uk.ini
|
||||||
|
|
||||||
RUN apk add --update --no-cache libssl1.0 libxml2 libxslt ca-certificates
|
RUN apk add --update --no-cache libssl1.0 libxml2 libxslt ca-certificates
|
||||||
RUN apk add --update --no-cache py-psycopg2 py-lxml py-flask py-pillow py-openssl py-cffi
|
RUN apk add --update --no-cache py-psycopg2 py-lxml py-pillow py-openssl py-cffi
|
||||||
|
|
||||||
RUN apk add --update --no-cache build-base make git bzr python3-dev libffi-dev openssl-dev libxml2-dev libxslt-dev jpeg-dev zlib-dev && \
|
RUN apk add --update --no-cache build-base make git bzr python3-dev libffi-dev openssl-dev libxml2-dev libxslt-dev jpeg-dev zlib-dev && \
|
||||||
pip3 install lxml && \
|
pip3 install lxml && \
|
||||||
pip3 install --no-cache-dir lxml dateutils requests requests-oauthlib mailer gocardless paypalrestsdk pytz pytest nose2 oauthlib flask flask-login pymysql misaka slimit cssmin pillow && \
|
pip3 install -r requirements.txt && \
|
||||||
|
pip3 install --no-cache-dir lxml dateutils requests requests-oauthlib mailer gocardless paypalrestsdk pytz pytest nose2 oauthlib pymysql misaka slimit cssmin pillow && \
|
||||||
#pip3 install --upgrade git+git://github.com/olymk2/scaffold.git@master && \
|
#pip3 install --upgrade git+git://github.com/olymk2/scaffold.git@master && \
|
||||||
pip3 install --upgrade --no-cache-dir bzr+lp:scaffold/trunk#egg=scaffold && \
|
pip3 install --upgrade --no-cache-dir bzr+lp:scaffold/trunk#egg=scaffold && \
|
||||||
apk del build-base make git bzr python3-dev libffi-dev openssl-dev libxml2-dev libxslt-dev
|
apk del build-base make git bzr python3-dev libffi-dev openssl-dev libxml2-dev libxslt-dev
|
||||||
|
|
|
@ -21,7 +21,10 @@ services:
|
||||||
container_name: mhackspace_web
|
container_name: mhackspace_web
|
||||||
image: olymk2/nginx
|
image: olymk2/nginx
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
network_mode: bridge
|
network_mode: bridge
|
||||||
|
ports:
|
||||||
|
- 80:80
|
||||||
dns:
|
dns:
|
||||||
- 8.8.8.8
|
- 8.8.8.8
|
||||||
- 8.8.4.4
|
- 8.8.4.4
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
flask
|
flask
|
||||||
|
flask-login==0.3.2
|
||||||
lxml
|
lxml
|
||||||
requests
|
requests
|
||||||
pytz
|
pytz
|
||||||
pip install -e bzr+lp:scaffold#egg=scaffold
|
bzr+lp:scaffold#egg=scaffold
|
||||||
python-requests-oauthlib
|
requests_oauthlib
|
||||||
|
#python-requests-oauthlib
|
||||||
paypalrestsdk
|
paypalrestsdk
|
||||||
dateutil
|
python-dateutil
|
||||||
|
#dateutil
|
||||||
gocardless_pro
|
gocardless_pro
|
||||||
braintree
|
braintree
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,10 @@ class TestPaymentGatewaysGocardless(unittest.TestCase):
|
||||||
self.provider = gocardless_provider()
|
self.provider = gocardless_provider()
|
||||||
return self.provider #self.provider
|
return self.provider #self.provider
|
||||||
|
|
||||||
|
def test_confirm_subscription_callback(self):
|
||||||
|
with patch('gocardless.client.confirm_resources') as mock_subscription:
|
||||||
|
self.provider = gocardless_provider()
|
||||||
|
|
||||||
def test_fetch_subscription_gocardless(self):
|
def test_fetch_subscription_gocardless(self):
|
||||||
items = [Mock(
|
items = [Mock(
|
||||||
id='01',
|
id='01',
|
||||||
|
|
|
@ -8,6 +8,8 @@ import paypalrestsdk as paypal
|
||||||
from website.config import settings
|
from website.config import settings
|
||||||
from website.config.settings import app_domain
|
from website.config.settings import app_domain
|
||||||
|
|
||||||
|
from website.config.logger import log
|
||||||
|
|
||||||
PROVIDER_ID = {'gocardless':1, 'paypal': 2}
|
PROVIDER_ID = {'gocardless':1, 'paypal': 2}
|
||||||
PROVIDER_NAME = {1: 'gocardless', 2: 'paypal'}
|
PROVIDER_NAME = {1: 'gocardless', 2: 'paypal'}
|
||||||
|
|
||||||
|
@ -15,86 +17,13 @@ PROVIDER_NAME = {1: 'gocardless', 2: 'paypal'}
|
||||||
def select_provider(type):
|
def select_provider(type):
|
||||||
if type == "gocardless": return gocardless_provider()
|
if type == "gocardless": return gocardless_provider()
|
||||||
if type == "braintree": return braintree_provider()
|
if type == "braintree": return braintree_provider()
|
||||||
if type == "paypal": return paypal_provider()
|
if type == "paypal": return paypal_provider()
|
||||||
|
|
||||||
|
log.exception('[scaffold] - "No Provider for ' + type)
|
||||||
assert 0, "No Provider for " + type
|
assert 0, "No Provider for " + type
|
||||||
|
|
||||||
class paypal_provider:
|
|
||||||
def __init__(self):
|
|
||||||
print(settings.payment_providers['paypal']['credentials'])
|
|
||||||
print(paypal.configure(**settings.payment_providers['paypal']['credentials']))
|
|
||||||
|
|
||||||
def fetch_subscriptions(self):
|
|
||||||
#~ I-S39170DK26AF
|
|
||||||
start_date, end_date = "2014-07-01", "2016-07-20"
|
|
||||||
# plans_created = paypal.BillingPlan.all({"status": "CREATED", "sort_order": "DESC"})
|
|
||||||
|
|
||||||
# billing_agreement = paypal.BillingAgreement.all()
|
|
||||||
# billing_agreement = paypal.BillingAgreement.find('0HX53832PF841861G')
|
|
||||||
# print(billing_agreement)
|
|
||||||
# print(dir(billing_agreement))
|
|
||||||
# print billing_agreement.search_transactions(start_date, end_date)
|
|
||||||
#~ transactions = billing_agreement.search_transactions(start_date, end_date)
|
|
||||||
# payment_history = paypal.Payment.all({"count":transactions 2})
|
|
||||||
|
|
||||||
# List Payments
|
|
||||||
# print("List Payment:")
|
|
||||||
# print(payment_history)
|
|
||||||
# for payment in payment_history.payments:
|
|
||||||
# print(" -> Payment[%s]" % (payment.id))
|
|
||||||
#~ print paypal.BillingAgreement.all()
|
|
||||||
history = paypal.Invoice.all({"page_size": 2})
|
|
||||||
|
|
||||||
print("List Invoice:")
|
|
||||||
for invoice in history.invoices:
|
|
||||||
print(" -> Invoice[%s]" % (invoice.id))
|
|
||||||
print(invoice.to_dict())
|
|
||||||
|
|
||||||
payment_history = paypal.Payment.all({"count": 10})
|
|
||||||
print('List payments')
|
|
||||||
print(dir(payment_history))
|
|
||||||
for payment in payment_history.payments:
|
|
||||||
print(payment['id'])
|
|
||||||
# print(payment['payer']['payer_info']['name'])
|
|
||||||
# print(payment['payer']['payer_info']['email'])
|
|
||||||
# print(pprint(payment['transactions']))
|
|
||||||
for transact in payment['transactions']:
|
|
||||||
print(transact['amount']['total'])
|
|
||||||
# print(payment_history.payments)
|
|
||||||
|
|
||||||
|
|
||||||
history = paypal.BillingPlan.all(
|
|
||||||
{"status": "CREATED", "page_size": 5, "page": 1, "total_required": "yes"})
|
|
||||||
# print(history)
|
|
||||||
|
|
||||||
print("List BillingPlan:")
|
|
||||||
for plan in history.plans:
|
|
||||||
print(plan['id'])
|
|
||||||
|
|
||||||
billing_agreement = paypal.BillingAgreement.find(plan['id'])
|
|
||||||
print('agreement')
|
|
||||||
print(billing_agreement.search_transactions(start_date, end_date))
|
|
||||||
print(billing_agreement.to_dict())
|
|
||||||
print(dir(plan))
|
|
||||||
print(plan.to_dict())
|
|
||||||
print(plan['name'])
|
|
||||||
print(" -> BillingPlan[%s]" % (plan.id))
|
|
||||||
|
|
||||||
yield {
|
|
||||||
'status': paying_member.status,
|
|
||||||
'email': user.email,
|
|
||||||
'start_date': paying_member.created_at,
|
|
||||||
'reference': paying_member.id,
|
|
||||||
'amount': paying_member.amount}
|
|
||||||
#~ merchant = gocardless.client.merchant()
|
|
||||||
#~ for paying_member in merchant.subscriptions():
|
|
||||||
#~ user=paying_member.user()
|
|
||||||
#~ yield {
|
|
||||||
#~ 'email': user.email,
|
|
||||||
#~ 'start_date': paying_member.created_at,
|
|
||||||
#~ 'reference': paying_member.id,
|
|
||||||
#~ 'amount': paying_member.amount}
|
|
||||||
|
|
||||||
class gocardless_provider:
|
class gocardless_provider:
|
||||||
|
form_remote = True
|
||||||
client = None
|
client = None
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -107,7 +36,16 @@ class gocardless_provider:
|
||||||
gocardless.environment = settings.payment_providers['gocardless']['environment']
|
gocardless.environment = settings.payment_providers['gocardless']['environment']
|
||||||
gocardless.set_details(**settings.payment_providers['gocardless']['credentials'])
|
gocardless.set_details(**settings.payment_providers['gocardless']['credentials'])
|
||||||
self.client = gocardless.client.merchant()
|
self.client = gocardless.client.merchant()
|
||||||
|
|
||||||
|
def subscribe_confirm(self, args):
|
||||||
|
response = gocardless.client.confirm_resource(args)
|
||||||
|
subscription = gocardless.client.subscription(args.get('resource_id'))
|
||||||
|
return {
|
||||||
|
'amount': subscription.amount,
|
||||||
|
'start_date': subscription.created_at,
|
||||||
|
'reference': subscription.id
|
||||||
|
}
|
||||||
|
|
||||||
def fetch_subscriptions(self):
|
def fetch_subscriptions(self):
|
||||||
for paying_member in self.client.subscriptions():
|
for paying_member in self.client.subscriptions():
|
||||||
user=paying_member.user()
|
user=paying_member.user()
|
||||||
|
@ -115,24 +53,33 @@ class gocardless_provider:
|
||||||
# print('test')
|
# print('test')
|
||||||
# print(dir(bill))
|
# print(dir(bill))
|
||||||
# print(bill.created_at)
|
# print(bill.created_at)
|
||||||
|
print(dir(paying_member))
|
||||||
|
print(paying_member.reference_fields)
|
||||||
yield {
|
yield {
|
||||||
'status': paying_member.status,
|
'status': paying_member.status,
|
||||||
'email': user.email,
|
'email': user.email,
|
||||||
'start_date': paying_member.created_at,
|
'start_date': paying_member.created_at,
|
||||||
'reference': paying_member.reference,
|
'reference': paying_member.id,
|
||||||
'amount': paying_member.amount}
|
'amount': paying_member.amount}
|
||||||
|
|
||||||
|
def get_redirect_url(self):
|
||||||
|
return settings.payment_providers['gocardless']['redirect_url']
|
||||||
|
|
||||||
|
def get_token(self):
|
||||||
|
return 'N/A'
|
||||||
|
|
||||||
def create_subscription(self, amount, name, redirect_success, redirect_failure, interval_unit='month', interval_length='1'):
|
def create_subscription(self, amount, name, redirect_success, redirect_failure, interval_unit='month', interval_length='1'):
|
||||||
if self.provider == 'gocardless':
|
return gocardless.client.new_subscription_url(
|
||||||
return gocardless.client.new_subscription_url(
|
amount=float(amount),
|
||||||
amount=float(amount),
|
interval_length=interval_length,
|
||||||
interval_length=interval_length,
|
interval_unit=interval_unit,
|
||||||
interval_unit=interval_unit,
|
name=name,
|
||||||
name=name,
|
redirect_uri=redirect_success)
|
||||||
redirect_uri=redirect_success)
|
|
||||||
|
|
||||||
|
|
||||||
class braintree_provider:
|
class braintree_provider:
|
||||||
|
form_remote = False
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
braintree.Configuration.configure(
|
braintree.Configuration.configure(
|
||||||
environment=braintree.Environment.Sandbox,
|
environment=braintree.Environment.Sandbox,
|
||||||
|
@ -140,13 +87,23 @@ class braintree_provider:
|
||||||
public_key=settings.payment_providers['braintree']['credentials']['public_key'],
|
public_key=settings.payment_providers['braintree']['credentials']['public_key'],
|
||||||
private_key=settings.payment_providers['braintree']['credentials']['private_key'])
|
private_key=settings.payment_providers['braintree']['credentials']['private_key'])
|
||||||
|
|
||||||
|
def get_token(self):
|
||||||
|
return braintree.ClientToken.generate()
|
||||||
|
|
||||||
|
|
||||||
def create_subscription(self, amount, name, redirect_success, redirect_failure, interval_unit='month', interval_length='1'):
|
def create_subscription(self, amount, name, redirect_success, redirect_failure, interval_unit='month', interval_length='1'):
|
||||||
braintree.Subscription.create({
|
result = braintree.Customer.create({
|
||||||
|
"first_name": "test",
|
||||||
|
"last_name": "user",
|
||||||
|
"payment_method_nonce": nonce_from_the_client
|
||||||
|
})
|
||||||
|
|
||||||
|
return braintree.Subscription.create({
|
||||||
"payment_method_token": "the_token",
|
"payment_method_token": "the_token",
|
||||||
"plan_id": "membership",
|
"plan_id": "membership",
|
||||||
"price": 20.00,
|
"merchant_account_id": "gbp_sandbox"
|
||||||
|
#"price": "20.00"
|
||||||
|
#'name': name
|
||||||
})
|
})
|
||||||
|
|
||||||
def fetch_subscriptions(self):
|
def fetch_subscriptions(self):
|
||||||
|
|
|
@ -14,7 +14,7 @@ from website.data import badges
|
||||||
from website.data import members
|
from website.data import members
|
||||||
from website.config.settings import app_domain
|
from website.config.settings import app_domain
|
||||||
|
|
||||||
from website.libs.payments import payment
|
from website.libs.payments import payment, select_provider
|
||||||
from website.config.settings import *
|
from website.config.settings import *
|
||||||
|
|
||||||
profile_pages = Blueprint('profile_pages', __name__, template_folder='templates')
|
profile_pages = Blueprint('profile_pages', __name__, template_folder='templates')
|
||||||
|
@ -81,8 +81,7 @@ def index():
|
||||||
).render()
|
).render()
|
||||||
).set_classes('col s6').render()
|
).set_classes('col s6').render()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
web.template.body.append(web.page.render())
|
web.template.body.append(web.page.render())
|
||||||
web.template.body.append(web.popup.create('').render())
|
web.template.body.append(web.popup.create('').render())
|
||||||
|
|
||||||
|
@ -101,7 +100,8 @@ def setup():
|
||||||
for member in fetch_users():
|
for member in fetch_users():
|
||||||
user_lookup[member.get('email')] = member.get('user_id')
|
user_lookup[member.get('email')] = member.get('user_id')
|
||||||
|
|
||||||
provider = payment(provider='paypal', style='payment')
|
provider = select_provider('braintree')
|
||||||
|
# provider = payment(provider='paypal', style='payment')
|
||||||
for item in provider.fetch_subscriptions():
|
for item in provider.fetch_subscriptions():
|
||||||
print(item)
|
print(item)
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ def setup():
|
||||||
print(paying_member.user())
|
print(paying_member.user())
|
||||||
print(paying_member.amount)
|
print(paying_member.amount)
|
||||||
user=paying_member.user()
|
user=paying_member.user()
|
||||||
|
|
||||||
print(user.email)
|
print(user.email)
|
||||||
user_id = user_lookup.get(user.email)
|
user_id = user_lookup.get(user.email)
|
||||||
print(user_id)
|
print(user_id)
|
||||||
|
@ -122,17 +122,37 @@ def setup():
|
||||||
|
|
||||||
return footer()
|
return footer()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@profile_pages.route("/profile/membership/form", methods=['get'])
|
||||||
|
@login_required
|
||||||
|
def pay_membership_form():
|
||||||
|
selected_provider = request.form.get('provider', 'braintree')
|
||||||
|
provider = select_provider(type=selected_provider)
|
||||||
|
|
||||||
|
web.template.create('Maidstone Hackspace')
|
||||||
|
header('Maidstone Hackspace Member registration')
|
||||||
|
|
||||||
|
web.form_braintree.create(client_token=provider.get_token())
|
||||||
|
web.page.section(web.form_braintree.render())
|
||||||
|
web.template.body.append(web.page.render())
|
||||||
|
return footer()
|
||||||
|
|
||||||
|
|
||||||
@profile_pages.route("/profile/membership", methods=['POST'])
|
@profile_pages.route("/profile/membership", methods=['POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def pay_membership():
|
def pay_membership():
|
||||||
|
selected_provider = request.form.get('provider', 'gocardless')
|
||||||
|
provider = select_provider(type=selected_provider)
|
||||||
|
if provider.form_remote is False:
|
||||||
|
return redirect('/profile/membership/form')
|
||||||
user = get_user_details({'id': current_user.get_id()}).get()
|
user = get_user_details({'id': current_user.get_id()}).get()
|
||||||
user_code = str(user.get('user_id')).zfill(5)
|
user_code = str(user.get('user_id')).zfill(5)
|
||||||
|
|
||||||
selected_provider = request.form.get('provider', 'gocardless')
|
# provider = payment(provider=selected_provider, style='payment')
|
||||||
provider = payment(provider=selected_provider, style='payment')
|
success_url = '%s/profile/membership/%s/success' % (provider.get_redirect_url(), selected_provider)
|
||||||
success_url = '%s/profile/membership/%s/success' % (app_domain, selected_provider)
|
failure_url = '%s/profile/membership/%s/failure' % (provider.get_redirect_url(), selected_provider)
|
||||||
failure_url = '%s/profile/membership/%s/failure' % (app_domain, selected_provider)
|
url = provider.create_subscription(
|
||||||
url = provider.subscribe(
|
|
||||||
amount=request.form.get('amount'),
|
amount=request.form.get('amount'),
|
||||||
name="Membership your membership id is MH%s" % user_code,
|
name="Membership your membership id is MH%s" % user_code,
|
||||||
redirect_success=success_url,
|
redirect_success=success_url,
|
||||||
|
@ -155,7 +175,8 @@ def cancel_membership():
|
||||||
print(subscription.get('subscription_reference'))
|
print(subscription.get('subscription_reference'))
|
||||||
|
|
||||||
|
|
||||||
provider = payment(provider='paypal', style='payment')
|
provider = select_provider(type='braintree')
|
||||||
|
# provider = payment(provider='paypal', style='payment')
|
||||||
provider.lookup_provider_by_id(1)
|
provider.lookup_provider_by_id(1)
|
||||||
url = provider.unsubscribe(reference=subscription.get('subscription_reference'))
|
url = provider.unsubscribe(reference=subscription.get('subscription_reference'))
|
||||||
|
|
||||||
|
@ -170,7 +191,8 @@ def membership_signup(provider):
|
||||||
web.template.create('Maidstone Hackspace')
|
web.template.create('Maidstone Hackspace')
|
||||||
header('Maidstone Hackspace Member registration')
|
header('Maidstone Hackspace Member registration')
|
||||||
|
|
||||||
provider = payment(provider=provider, style='payment')
|
provider = select_provider(type=provider)
|
||||||
|
# provider = payment(provider=provider, style='payment')
|
||||||
|
|
||||||
payment_details = provider.subscribe_confirm(request.args)
|
payment_details = provider.subscribe_confirm(request.args)
|
||||||
try:
|
try:
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,15 +1,42 @@
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
sys.path.insert(0, os.path.abspath('../../'))
|
||||||
sys.path.append(os.path.abspath('../../'))
|
sys.path.append(os.path.abspath('../../'))
|
||||||
|
|
||||||
from website.config.settings import *
|
from website.config.settings import *
|
||||||
from website.libs.payments import payment, gocardless_provider, paypal_provider
|
from website.libs.payments import payment, gocardless_provider, paypal_provider, braintree_provider
|
||||||
|
|
||||||
|
|
||||||
|
#list go cardless subscriptions
|
||||||
|
print('gocardless subscriptions')
|
||||||
gocardless = gocardless_provider()
|
gocardless = gocardless_provider()
|
||||||
|
gocardless.create_subscription(
|
||||||
|
amount=20.00,
|
||||||
|
name='test name',
|
||||||
|
redirect_success='http://localhost/',
|
||||||
|
redirect_failure='http://localhost/',
|
||||||
|
interval_unit='month',
|
||||||
|
interval_length='1')
|
||||||
for user in gocardless.fetch_subscriptions():
|
for user in gocardless.fetch_subscriptions():
|
||||||
print(user)
|
print(user)
|
||||||
|
|
||||||
|
print('braintree subscriptions')
|
||||||
|
|
||||||
|
braintree = braintree_provider()
|
||||||
|
print (braintree.create_subscription(
|
||||||
|
amount=20.00,
|
||||||
|
name='test name',
|
||||||
|
redirect_success='http://localhost/',
|
||||||
|
redirect_failure='http://localhost/',
|
||||||
|
interval_unit='month',
|
||||||
|
interval_length='1'))
|
||||||
|
|
||||||
|
for user in braintree.fetch_subscriptions():
|
||||||
|
print(user)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# paypal = paypal_provider()
|
# paypal = paypal_provider()
|
||||||
# for user in paypal.fetch_subscriptions():
|
# for user in paypal.fetch_subscriptions():
|
||||||
|
|
|
@ -31,7 +31,7 @@ class control(base_widget_extended):
|
||||||
<div class="input-field col s8">
|
<div class="input-field col s8">
|
||||||
<select name="provider">
|
<select name="provider">
|
||||||
<option value="gocardless">GoCardless</option>
|
<option value="gocardless">GoCardless</option>
|
||||||
<option value="paypal">PayPal</option>
|
<option value="braintree">Braintree</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue