426 lines
12 KiB
Python
426 lines
12 KiB
Python
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
|
|
)
|
|
|
|
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
|
|
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']
|
|
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']
|
|
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:
|
|
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.save()
|
|
name = '{f} {l}'.format(
|
|
f = rower.user.first_name,
|
|
l = rower.user.last_name,
|
|
)
|
|
|
|
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']
|
|
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
|
|
})
|
|
|
|
if result.is_success:
|
|
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.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 = []
|
|
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)
|
|
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')
|
|
|
|
|
|
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
|
|
}
|
|
)
|
|
|
|
return df
|
|
|
|
|
|
def mocktest(rower):
|
|
return '5'
|