Private
Public Access
1
0
Files
rowsandall/rowers/braintreestuff.py
2020-09-10 20:24:50 +02:00

476 lines
14 KiB
Python

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import braintree
from django.utils import timezone
import datetime
from django.conf import settings
import sys
import django_rq
queue = django_rq.get_queue('default')
queuelow = django_rq.get_queue('low')
queuehigh = django_rq.get_queue('low')
from rowers.utils import myqueue
from rowers.tasks import (
handle_send_email_transaction,
handle_send_email_subscription_update,
handle_send_email_subscription_create,
handle_send_email_failed_cancel,
)
import pandas as pd
from rowsandall_app.settings import (
BRAINTREE_MERCHANT_ID,BRAINTREE_PUBLIC_KEY,BRAINTREE_PRIVATE_KEY,
BRAINTREE_SANDBOX_MERCHANT_ID,BRAINTREE_SANDBOX_PUBLIC_KEY,
BRAINTREE_SANDBOX_PRIVATE_KEY, BRAINTREE_MERCHANT_ACCOUNT_ID
)
if settings.DEBUG or 'dev' in settings.SITE_URL:
gateway = braintree.BraintreeGateway(
braintree.Configuration(
braintree.Environment.Sandbox,
merchant_id=BRAINTREE_SANDBOX_MERCHANT_ID,
public_key=BRAINTREE_SANDBOX_PUBLIC_KEY,
private_key=BRAINTREE_SANDBOX_PRIVATE_KEY,
)
)
else:
gateway = braintree.BraintreeGateway(
braintree.Configuration(
braintree.Environment.Production,
merchant_id=BRAINTREE_MERCHANT_ID,
public_key=BRAINTREE_PUBLIC_KEY,
private_key=BRAINTREE_PRIVATE_KEY,
)
)
from rowers.models import Rower,PaidPlan, CoachingGroup
from rowers.utils import ProcessorCustomerError
def create_customer(rower,force=False):
if not rower.customer_id or force:
result = gateway.customer.create(
{
'first_name':rower.user.first_name,
'last_name':rower.user.last_name,
'email':rower.user.email,
})
if not result.is_success:
raise ProcessorCustomerError
else:
rower.customer_id = result.customer.id
rower.paymentprocessor = 'braintree'
rower.save()
return rower.customer_id
else:
return rower.customer_id
def get_client_token(rower):
try:
client_token = gateway.client_token.generate({
"customer_id":rower.customer_id,
})
except ValueError:
customer_id = create_customer(rower,force=True)
client_token = gateway.client_token.generate({
"customer_id": customer_id,
})
return client_token
def get_plans_costs():
plans = gateway.plan.all()
localplans = PaidPlan.object.filter(paymentprocessor='braintree')
for plan in localplans:
for btplan in btplans:
if int(btplan.id) == plan.external_id:
plan.price = float(x)
plan.save()
return plans
def make_payment(rower,data):
nonce_from_the_client = data['payment_method_nonce']
nonce = gateway.payment_method_nonce.find(nonce_from_the_client)
info = nonce.three_d_secure_info
if nonce.type.lower() == 'creditcard':
if info is None or not info.liability_shifted:
return False,0
amount = data['amount']
amount = '{amount:.f2}'.format(amount=amount)
result = gateway.transaction.sale({
"amount": amount,
"payment_method_nonce": nonce_from_the_client,
"options": {
"submit_for_settlement": True
}
})
if result.is_success:
transaction = result.transaction
amount = transaction.amount
name = '{f} {l}'.format(
f = rower.user.first_name,
l = rower.user.last_name,
)
job = myqueue(queuehigh,handle_send_email_transaction,
name, rower.user.email, amount)
return amount,''
else:
return 0,''
def update_subscription(rower,data,method='up'):
planid = data['plan']
plan = PaidPlan.objects.get(id=planid)
nonce_from_the_client = data['payment_method_nonce']
nonce = gateway.payment_method_nonce.find(nonce_from_the_client)
info = nonce.three_d_secure_info
if nonce.type.lower() == 'creditcard':
if info is None or not info.liability_shifted:
return False,0
amount = data['amount']
amount = '{amount:.2f}'.format(amount=amount)
gatewaydata = {
"price": amount,
"plan_id": plan.external_id,
"payment_method_nonce": nonce_from_the_client,
"options": {
"prorate_charges":True,
},
}
if plan.paymenttype == 'single':
gatewaydata['number_of_billing_cycles'] = 1
else:
gatewaydata['never_expires'] = True
try:
result = gateway.subscription.update(
rower.subscription_id,
gatewaydata
)
except:
return False,0
if result.is_success:
yesterday = (timezone.now()-datetime.timedelta(days=1)).date()
rower.paidplan = plan
rower.planexpires = result.subscription.billing_period_end_date
rower.teamplanexpires = result.subscription.billing_period_end_date
rower.clubsize = plan.clubsize
rower.paymenttype = plan.paymenttype
rower.rowerplan = plan.shortname
rower.subscription_id = result.subscription.id
rower.protrialexpires = yesterday
rower.plantrialexpires = yesterday
rower.save()
name = '{f} {l}'.format(
f = rower.user.first_name,
l = rower.user.last_name,
)
if rower.paidplan != 'coach':
try:
coachgroup = rower.mycoachgroup
except CoachingGroup.DoesNotExist:
coachgroup = CoachingGroup()
coachgroup.save()
rower.mycoachgroup = coachgroup
rower.save()
athletes = Rower.objects.filter(coachinggroups__in=[rower.mycoachgroup]).distinct()
for athlete in athletes:
athlete.coachinggroups.remove(rower.mycoachgroup)
if method == 'up':
transactions = result.subscription.transactions
if transactions:
amount = transactions[0].amount
else:
amount = 0
else:
amount = 0
job = myqueue(queuehigh,
handle_send_email_subscription_update,
name, rower.user.email,
plan.name,
plan.paymenttype,
plan.price,
amount,
result.subscription.billing_period_end_date.strftime('%Y-%m-%d'),
method)
return True,amount
else:
errors = result.errors.for_object("subscription")
codes = [str(e.code) for e in errors]
create_new = False
proceed_codes = ['81901','81910']
for c in codes:
if c in proceed_codes:
create_new = True
if create_new:
return create_subscription(rower,data)
return False,0
return False,0
def create_subscription(rower,data):
nonce_from_the_client = data['payment_method_nonce']
nonce = gateway.payment_method_nonce.find(nonce_from_the_client)
info = nonce.three_d_secure_info
paymenttype = nonce.type
if nonce.type != 'PayPalAccount':
if info is None or not info.liability_shifted:
return False,0
amount = data['amount']
planid = data['plan']
plan = PaidPlan.objects.get(id=planid)
# create or find payment method
result = gateway.payment_method.create({
"customer_id": rower.customer_id,
"payment_method_nonce": nonce_from_the_client
})
if result.is_success:
payment_method_token = result.payment_method.token
else:
return False,0
result = gateway.subscription.create({
"payment_method_token": payment_method_token,
"plan_id": plan.external_id,
# "merchant_account_id": BRAINTREE_MERCHANT_ACCOUNT_ID,
})
if result.is_success:
yesterday = (timezone.now()-datetime.timedelta(days=1)).date()
rower.paidplan = plan
rower.planexpires = result.subscription.billing_period_end_date
rower.teamplanexpires = result.subscription.billing_period_end_date
rower.clubsize = plan.clubsize
rower.paymenttype = plan.paymenttype
rower.rowerplan = plan.shortname
rower.subscription_id = result.subscription.id
rower.protrialexpires = yesterday
rower.plantrialexpires = yesterday
rower.save()
name = '{f} {l}'.format(
f = rower.user.first_name,
l = rower.user.last_name,
)
recurring = plan.paymenttype
job = myqueue(
queuehigh,
handle_send_email_subscription_create,
name, rower.user.email,
plan.name,
recurring,
plan.price,
plan.price,
result.subscription.billing_period_end_date.strftime('%Y-%m-%d')
)
return True,plan.price
else:
return False,0
return False,0
def cancel_subscription(rower,id):
themessages = []
errormessages = []
try:
result = gateway.subscription.cancel(id)
themessages.append("Subscription canceled")
except:
errormessages.append("We could not find the subscription record in our customer database. We have notified the site owner, who will contact you.")
name = '{f} {l}'.format(f = rower.user.first_name, l = rower.user.last_name)
job = myqueue(queuehigh,
handle_send_email_failed_cancel,
name, rower.user.email,rower.user.username,id)
return False, themessages, errormessages
basicplans = PaidPlan.objects.filter(price=0,paymentprocessor='braintree')
rower.paidplan = basicplans[0]
rower.teamplanexpires = timezone.now()
rower.planexpires = timezone.now()
rower.clubsize = 0
rower.rowerplan = 'basic'
rower.subscription_id = None
rower.save()
themessages.append("Your plan was reset to basic")
return True, themessages,errormessages
def find_subscriptions(rower):
try:
result = gateway.customer.find(rower.customer_id)
except:
raise ProcessorCustomerError("We could not find the customer in the database")
active_subscriptions = []
cards = result.credit_cards
for card in cards:
for subscription in card.subscriptions:
if subscription.status == 'Active':
active_subscriptions.append(subscription)
try:
paypal_accounts = result.paypal_accounts
for account in paypal_accounts:
for subscription in account.subscriptions:
if subscription.status == 'Active':
active_subscriptions.append(subscription)
except AttributeError:
pass
result = []
for subscription in active_subscriptions:
plan = PaidPlan.objects.filter(paymentprocessor="braintree",
external_id=subscription.plan_id)[0]
thedict = {
'end_date': subscription.billing_period_end_date,
'plan_id': subscription.plan_id,
'price': subscription.price,
'id': subscription.id,
'plan': plan.name,
'never_expires': subscription.never_expires
}
result.append(thedict)
return result
def get_transactions(start_date,end_date):
results = gateway.transaction.search(
braintree.TransactionSearch.created_at.between(
start_date,
end_date,
)
)
amounts = []
countries = []
addresses = []
card_countries = []
names = []
emails = []
dates = []
currencies = []
statuses = []
ids = []
usernames = []
customerids = []
transactionids = []
subscriptionids = []
ownids = []
countlines = [1 for transaction in results]
for transaction in results:
r = None
rs = Rower.objects.filter(
customer_id=transaction.customer['id'],
paymentprocessor='braintree')
if rs:
r = rs[0]
countries.append(r.country)
addresses.append('{street}, {city}, {postal_code}'.format(
street = r.street_address,
city = r.city,
postal_code = r.postal_code))
ownids.append(r.id)
usernames.append(r.user.username)
else:
countries.append(
transaction.credit_card_details.country_of_issuance)
ownids.append('unknown')
usernames.append('unknown')
addresses.append('')
emails.append(transaction.customer_details.email)
names.append('{f} {l}'.format(
f = transaction.customer['first_name'],
l = transaction.customer['last_name']
)
)
customerids.append(transaction.customer['id'])
transactionids.append(transaction.id)
subscriptionids.append(transaction.subscription_id)
amounts.append(transaction.amount)
dates.append(transaction.created_at)
currencies.append(transaction.currency_iso_code)
card_countries.append(
transaction.credit_card_details.country_of_issuance)
statuses.append(transaction.status)
df = pd.DataFrame({
'name':names,
'email':emails,
'date':dates,
'amount':amounts,
'currency':currencies,
'country':countries,
'card_country':card_countries,
'status':statuses,
'username':usernames,
'user_id':ownids,
'customer_id':customerids,
'transaction_id':transactionids,
'subscription_id':subscriptionids,
'address':addresses
}
)
return df
def mocktest(rower):
return '5'