def directory_set_inv_payment(user, directory, pricing): if get_setting('module', 'directories', 'directoriesrequirespayment'): if not directory.invoice: inv = Invoice() inv.object_type = ContentType.objects.get(app_label=directory._meta.app_label, model=directory._meta.model_name) inv.object_id = directory.id inv.title = "Directory Add Invoice" inv.bill_to_user(user) inv.ship_to_user(user) inv.terms = "Due on Receipt" inv.due_date = datetime.now() inv.ship_date = datetime.now() inv.message = 'Thank You.' inv.status = True inv.total = get_directory_price(user, directory, pricing) inv.subtotal = inv.total inv.balance = inv.total inv.estimate = True inv.status_detail = 'estimate' if user and not user.is_anonymous: inv.set_creator(user) inv.set_owner(user) inv.save(user) # tender the invoice inv.tender(user) # update job directory.invoice = inv directory.save() if user.profile.is_superuser: if directory.payment_method in ['paid - cc', 'paid - check', 'paid - wire transfer']: inv.tender(user) # payment payment = Payment() payment.payments_pop_by_invoice_user(user, inv, inv.guid) payment.mark_as_paid() payment.method = directory.payment_method payment.save(user) # this will make accounting entry inv.make_payment(user, payment.amount)
def pay_online(request, invoice_id, guid="", merchant_account=None, template_name="payments/pay_online.html"): # check if they have the right to view the invoice invoice = get_object_or_404(Invoice, pk=invoice_id) if not invoice.allow_view_by(request.user, guid): raise Http403 # tender the invoice if not invoice.is_tendered: invoice.tender(request.user) # log an event for invoice edit EventLog.objects.log(instance=invoice) # generate the payment payment = Payment() boo = payment.payments_pop_by_invoice_user(request.user, invoice, guid) # log an event for payment add EventLog.objects.log(instance=payment) # post payment form to gateway and redirect to the vendor so customer can pay from there if boo: merchant_account = merchant_account or (get_setting("site", "global", "merchantaccount")).lower() if merchant_account == 'stripe': return HttpResponseRedirect(reverse('stripe.payonline', args=[payment.id, payment.guid])) else: if merchant_account == "authorizenet": form = prepare_authorizenet_sim_form(request, payment) post_url = settings.AUTHNET_POST_URL elif merchant_account == 'firstdata': from tendenci.apps.payments.firstdata.utils import prepare_firstdata_form form = prepare_firstdata_form(request, payment) post_url = settings.FIRSTDATA_POST_URL elif merchant_account == 'firstdatae4': from tendenci.apps.payments.firstdatae4.utils import prepare_firstdatae4_form form = prepare_firstdatae4_form(request, payment) post_url = settings.FIRSTDATAE4_POST_URL elif merchant_account == 'paypalpayflowlink': from tendenci.apps.payments.payflowlink.utils import prepare_payflowlink_form form = prepare_payflowlink_form(request, payment) post_url = settings.PAYFLOWLINK_POST_URL elif merchant_account == 'paypal': from tendenci.apps.payments.paypal.utils import prepare_paypal_form form = prepare_paypal_form(request, payment) post_url = settings.PAYPAL_POST_URL else: # more vendors logger.error( '"{}" did not match a known online payment method. Check the PaymentMethod.machine_name.'.format( merchant_account)) form = None post_url = "" else: form = None post_url = "" return render_to_resp(request=request, template_name=template_name, context={'form': form, 'post_url': post_url })
def pay_online(request, invoice_id, guid="", template_name="payments/pay_online.html"): # check if they have the right to view the invoice invoice = get_object_or_404(Invoice, pk=invoice_id) if not invoice.allow_view_by(request.user, guid): raise Http403 # tender the invoice if not invoice.is_tendered: invoice.tender(request.user) # log an event for invoice edit EventLog.objects.log(instance=invoice) # generate the payment payment = Payment() boo = payment.payments_pop_by_invoice_user(request.user, invoice, guid) # log an event for payment add EventLog.objects.log(instance=payment) # post payment form to gateway and redirect to the vendor so customer can pay from there if boo: merchant_account = (get_setting("site", "global", "merchantaccount")).lower() if merchant_account == 'stripe': return HttpResponseRedirect(reverse('stripe.payonline', args=[payment.id])) else: if merchant_account == "authorizenet": form = prepare_authorizenet_sim_form(request, payment) post_url = settings.AUTHNET_POST_URL elif merchant_account == 'firstdata': from tendenci.apps.payments.firstdata.utils import prepare_firstdata_form form = prepare_firstdata_form(request, payment) post_url = settings.FIRSTDATA_POST_URL elif merchant_account == 'firstdatae4': from tendenci.apps.payments.firstdatae4.utils import prepare_firstdatae4_form form = prepare_firstdatae4_form(request, payment) post_url = settings.FIRSTDATAE4_POST_URL elif merchant_account == 'paypalpayflowlink': from tendenci.apps.payments.payflowlink.utils import prepare_payflowlink_form form = prepare_payflowlink_form(request, payment) post_url = settings.PAYFLOWLINK_POST_URL elif merchant_account == 'paypal': from tendenci.apps.payments.paypal.utils import prepare_paypal_form form = prepare_paypal_form(request, payment) post_url = settings.PAYPAL_POST_URL else: # more vendors form = None post_url = "" else: form = None post_url = "" return render_to_response(template_name, {'form': form, 'post_url': post_url }, context_instance=RequestContext(request))
def directory_set_inv_payment(user, directory, pricing): if get_setting('module', 'directories', 'directoriesrequirespayment'): if not directory.invoice: inv = Invoice() inv.object_type = ContentType.objects.get( app_label=directory._meta.app_label, model=directory._meta.model_name) inv.object_id = directory.id inv.title = "Directory Add Invoice" inv.bill_to_user(user) inv.ship_to_user(user) inv.terms = "Due on Receipt" inv.due_date = datetime.now() inv.ship_date = datetime.now() inv.message = 'Thank You.' inv.status = True inv.total = get_directory_price(user, directory, pricing) inv.subtotal = inv.total inv.balance = inv.total inv.estimate = True inv.status_detail = 'estimate' if user and not user.is_anonymous: inv.set_creator(user) inv.set_owner(user) inv.save(user) # tender the invoice inv.tender(user) # update job directory.invoice = inv directory.save() if user.profile.is_superuser: if directory.payment_method in [ 'paid - cc', 'paid - check', 'paid - wire transfer' ]: inv.tender(user) # payment payment = Payment() payment.payments_pop_by_invoice_user(user, inv, inv.guid) payment.mark_as_paid() payment.method = directory.payment_method payment.save(user) # this will make accounting entry inv.make_payment(user, payment.amount)
def corp_memb_inv_add(user, corp_memb, app=None, **kwargs): """ Add an invoice for this corporate membership """ corp_profile = corp_memb.corp_profile renewal = kwargs.get('renewal', False) renewal_total = kwargs.get('renewal_total', 0) if not corp_memb.invoice or renewal: inv = Invoice() inv.entity = corp_profile.entity inv.object_type = ContentType.objects.get( app_label=corp_memb._meta.app_label, model=corp_memb._meta.model_name) inv.object_id = corp_memb.id inv.title = corp_memb.corp_profile.name if not user.is_anonymous: inv.bill_to = '%s %s' % (user.first_name, user.last_name) inv.bill_to_first_name = user.first_name inv.bill_to_last_name = user.last_name inv.bill_to_email = user.email inv.set_creator(user) inv.set_owner(user) else: if corp_memb.anonymous_creator: cmc = corp_memb.anonymous_creator inv.bill_to = '%s %s' % (cmc.first_name, cmc.last_name) inv.bill_to_first_name = cmc.first_name inv.bill_to_last_name = cmc.last_name inv.bill_to_email = cmc.email else: inv.bill_to = corp_memb.name inv.bill_to_company = corp_profile.name inv.bill_to_address = corp_profile.address inv.bill_to_city = corp_profile.city inv.bill_to_state = corp_profile.state inv.bill_to_zip_code = corp_profile.zip inv.bill_to_country = corp_profile.country inv.bill_to_phone = corp_profile.phone inv.ship_to = corp_profile.name inv.ship_to_company = corp_profile.name inv.ship_to_address = corp_profile.address inv.ship_to_city = corp_profile.city inv.ship_to_state = corp_profile.state inv.ship_to_zip_code = corp_profile.zip inv.ship_to_country = corp_profile.country inv.ship_to_phone = corp_profile.phone inv.ship_to_email = corp_profile.email inv.terms = "Due on Receipt" inv.due_date = datetime.now() inv.ship_date = datetime.now() inv.message = 'Thank You.' inv.status = True if not renewal: inv.total = corp_memb.corporate_membership_type.price else: inv.total = renewal_total inv.subtotal = inv.total inv.balance = inv.total tax = 0 if app and app.include_tax: tax = inv.total * app.tax_rate inv.tax = tax total = inv.total + tax inv.subtotal = total inv.total = total inv.balance = total inv.estimate = True inv.status_detail = 'estimate' inv.save(user) if not corp_memb.payment_method: is_online = True if inv.balance <= 0: is_online = False corp_memb.payment_method = corp_memb.get_payment_method( is_online=is_online) if user.profile.is_superuser: # if offline payment method if not corp_memb.payment_method.is_online: inv.tender(user) # tendered the invoice for admin if offline # mark payment as made payment = Payment() payment.payments_pop_by_invoice_user(user, inv, inv.guid) payment.mark_as_paid() payment.method = corp_memb.payment_method.machine_name payment.save(user) # this will make accounting entry inv.make_payment(user, payment.amount) return inv return None
def api_rp_setup(data): """Create a recurrring payment account. Accepted format: json Input fields: email - required description - required amount - required cp_id - customer profile id, required pp_id - customer payment profile id, required billing_cycle_start_dt - required billing_cycle_end_dt - required response_str - required login_name login_password url first_name last_name billing_period - optional, default to 'month' billing_frequency - optional, default to 1 billing_start_dt - optional, default to today num_days - optional, default to 0 has_trial_period - optional, default to False trial_period_start_dt - optional, default to today trial_period_end_dt - optional, default to today trial_amount - optional, default to 0 Output: rp_id - a recurring payment id rp_url - url to rp username result_code """ from tendenci.apps.base.utils import validate_email import dateutil.parser as dparser from tendenci.apps.imports.utils import get_unique_username email = data.get('email', '') description = data.get('description', '') url = data.get('url') payment_amount = data.get('amount', '') taxable = data.get('taxable', 0) if taxable in ('True', 'true', '1', 1): taxable = 1 else: taxable = 0 try: tax_rate = Decimal(data.get('tax_rate', 0)) if tax_rate > 1: tax_rate = 0 except: tax_rate = 0 tax_exempt = data.get('tax_exempt', 0) if tax_exempt in ('True', 'true', '1', 1): tax_exempt = 1 else: tax_exempt = 0 try: payment_amount = Decimal(payment_amount) except: payment_amount = 0 cp_id = data.get('cp_id') pp_id = data.get('pp_id') billing_cycle_start_dt = data.get('billing_cycle_start_dt') if billing_cycle_start_dt: billing_cycle_start_dt = dparser.parse(billing_cycle_start_dt) billing_cycle_end_dt = data.get('billing_cycle_end_dt') if billing_cycle_end_dt: billing_cycle_end_dt = dparser.parse(billing_cycle_end_dt) direct_response_str = data.get('response_str') if not all([validate_email(email), description, payment_amount>0, cp_id, pp_id, billing_cycle_start_dt, billing_cycle_end_dt, direct_response_str] ): return False, {} # 1) get or create user username = data.get('login_name') # check if user already exists based on email and username users = User.objects.filter(email=email, username=username) if users: u = users[0] else: # create user account u = User() u.email=email u.username = username if not u.username: u.username = email.split('@')[0] u.username = get_unique_username(u) raw_password = data.get('login_password') if not raw_password: raw_password = User.objects.make_random_password(length=8) u.set_password(raw_password) u.first_name = data.get('first_name', '') u.last_name = data.get('last_name', '') u.is_staff = False u.is_superuser = False u.save() profile = Profile.objects.create( user=u, creator=u, creator_username=u.username, owner=u, owner_username=u.username, email=u.email ) # 2) create a recurring payment account rp = RecurringPayment() rp.user = u rp.description = description rp.url = url rp.payment_amount = payment_amount rp.taxable = taxable rp.tax_rate = tax_rate rp.tax_exempt = tax_exempt rp.customer_profile_id = cp_id rp.billing_start_dt = billing_cycle_start_dt has_trial_period = data.get('has_trial_period') trial_period_start_dt = data.get('trial_period_start_dt') trial_period_end_dt = data.get('trial_period_end_dt') if has_trial_period in ['True', '1', True, 1] and all([trial_period_start_dt, trial_period_end_dt]): rp.has_trial_period = True rp.trial_period_start_dt = dparser.parse(trial_period_start_dt) rp.trial_period_end_dt = dparser.parse(trial_period_end_dt) else: rp.has_trial_period = False rp.status_detail = 'active' rp.save() # 3) create a payment profile account payment_profile_exists = PaymentProfile.objects.filter( customer_profile_id=cp_id, payment_profile_id=pp_id ).exists() if not payment_profile_exists: PaymentProfile.objects.create( customer_profile_id=cp_id, payment_profile_id=pp_id, owner=u, owner_username=u.username ) # 4) create rp invoice billing_cycle = {'start': billing_cycle_start_dt, 'end': billing_cycle_end_dt} rp_invoice = rp.create_invoice(billing_cycle, billing_cycle_start_dt) rp_invoice.invoice.tender(rp.user) # 5) create rp transaction now = datetime.now() payment = Payment() payment.payments_pop_by_invoice_user(rp.user, rp_invoice.invoice, rp_invoice.invoice.guid) payment_transaction = PaymentTransaction( recurring_payment=rp, recurring_payment_invoice=rp_invoice, payment_profile_id=pp_id, trans_type='auth_capture', amount=rp_invoice.invoice.total, status=True) payment = payment_update_from_response(payment, direct_response_str) payment.mark_as_paid() payment.save() rp_invoice.invoice.make_payment(rp.user, Decimal(payment.amount)) rp_invoice.invoice.save() rp_invoice.payment_received_dt = now rp_invoice.save() rp.last_payment_received_dt = now rp.num_billing_cycle_completed += 1 rp.save() payment_transaction.payment = payment payment_transaction.result_code = data.get('result_code') payment_transaction.message_code = data.get('message_code') payment_transaction.message_text = data.get('message_text') payment_transaction.save() site_url = get_setting('site', 'global', 'siteurl') return True, {'rp_id': rp.id, 'rp_url': '%s%s' % (site_url, reverse('recurring_payment.view_account', args=[rp.id])), 'username': rp.user.username}
def job_set_inv_payment(user, job, pricing): if get_setting('module', 'jobs', 'jobsrequirespayment'): if not job.invoice: inv = Invoice() inv.object_type = ContentType.objects.get( app_label=job._meta.app_label, model=job._meta.model_name) inv.object_id = job.id inv.title = _("Job Add Invoice") inv.bill_to = job.contact_name first_name = '' last_name = '' if job.contact_name: name_list = job.contact_name.split(' ') if len(name_list) >= 2: first_name = name_list[0] last_name = ' '.join(name_list[1:]) inv.bill_to_first_name = first_name inv.bill_to_last_name = last_name inv.bill_to_company = job.contact_company inv.bill_to_address = job.contact_address inv.bill_to_city = job.contact_city inv.bill_to_state = job.contact_state inv.bill_to_zip_code = job.contact_zip_code inv.bill_to_country = job.contact_country inv.bill_to_phone = job.contact_phone inv.bill_to_fax = job.contact_fax inv.bill_to_email = job.contact_email inv.ship_to = job.contact_name inv.ship_to_first_name = first_name inv.ship_to_last_name = last_name inv.ship_to_company = job.contact_company inv.ship_to_address = job.contact_address inv.ship_to_city = job.contact_city inv.ship_to_state = job.contact_state inv.ship_to_zip_code = job.contact_zip_code inv.ship_to_country = job.contact_country inv.ship_to_phone = job.contact_phone inv.ship_to_fax = job.contact_fax inv.ship_to_email = job.contact_email inv.terms = _("Due on Receipt") inv.due_date = datetime.now() inv.ship_date = datetime.now() inv.message = _('Thank You.') inv.status = True inv.total = get_job_price(user, job, pricing) inv.subtotal = inv.total inv.balance = inv.total inv.estimate = True inv.status_detail = 'estimate' tax = 0 if pricing.include_tax: tax = inv.total * pricing.tax_rate total = tax + inv.total inv.tax = tax inv.total = total inv.subtotal = total inv.balance = total if user and not user.is_anonymous: inv.set_creator(user) inv.set_owner(user) inv.save(user) # tender the invoice inv.tender(user) # update job job.invoice = inv job.save() if user.profile.is_superuser: if job.payment_method in [ 'paid - cc', 'paid - check', 'paid - wire transfer' ]: inv.tender(user) # payment payment = Payment() payment.payments_pop_by_invoice_user(user, inv, inv.guid) payment.mark_as_paid() payment.method = job.payment_method payment.save(user) # this will make accounting entry inv.make_payment(user, payment.amount)
def make_payment_transaction(self, payment_profile_id, membership=None): """ Make a payment transaction. This includes: 1) Make an API call createCustomerProfileTransactionRequest 2) Create a payment transaction entry 3) Create a payment entry 4) If the transaction is successful, populate payment entry with the direct response and mark payment as paid """ amount = self.invoice.balance # tender the invoice self.invoice.tender(self.recurring_payment.user) # create a payment record payment = Payment() payment.payments_pop_by_invoice_user(self.recurring_payment.user, self.invoice, self.invoice.guid) if self.billing_cycle_start_dt and self.billing_cycle_end_dt: description = self.recurring_payment.description description += '(billing cycle from {0} to {1})'.format( self.billing_cycle_start_dt.strftime('%m/%d/%Y'), self.billing_cycle_end_dt.strftime('%m/%d/%Y')) else: description = payment.description # charge user if self.recurring_payment.platform == "stripe": stripe.api_key = getattr(settings, 'STRIPE_SECRET_KEY', '') params = { 'amount': math.trunc(amount * 100), # amount in cents, again 'currency': get_setting('site', 'global', 'currency'), 'description': description, 'customer': self.recurring_payment.customer_profile_id } success = False response_d = { 'status_detail': 'not approved', 'response_code': '0', 'response_reason_code': '0', 'result_code': 'Error', # Error, Ok 'message_code': '', # I00001, E00027 } try: charge_response = stripe.Charge.create(**params) success = True response_d['status_detail'] = 'approved' response_d['response_code'] = '1' response_d['response_subcode'] = '1' response_d['response_reason_code'] = '1' response_d[ 'response_reason_text'] = 'This transaction has been approved. (Created# %s)' % charge_response.created response_d['trans_id'] = charge_response.id response_d['result_code'] = 'Ok' response_d['message_text'] = 'Successful.' except stripe.error.CardError as e: # it's a decline json_body = e.json_body err = json_body and json_body['error'] code = err and err['code'] message = err and err['message'] charge_response = '{message} status={status}, code={code}'.format( message=message, status=e.http_status, code=code) response_d['response_reason_text'] = charge_response response_d['message_code'] = code response_d['message_text'] = charge_response except Exception as e: charge_response = e.message response_d['response_reason_text'] = charge_response response_d['message_text'] = charge_response[:200] # update payment for key in response_d: if hasattr(payment, key): setattr(payment, key, response_d[key]) else: # make a transaction using CIM d = { 'amount': amount, 'order': { 'invoice_number': str(payment.invoice_num), 'description': description, 'recurring_billing': 'true' } } cpt = CIMCustomerProfileTransaction( self.recurring_payment.customer_profile_id, payment_profile_id) success, response_d = cpt.create(**d) # update the payment entry with the direct response returned from payment gateway payment = payment_update_from_response( payment, response_d['direct_response']) if success: payment.mark_as_paid() payment.save() payment.invoice.make_payment(self.recurring_payment.user, Decimal(payment.amount)) # approve membership if membership: membership.approve() # send notification to user self.payment_received_dt = datetime.now() else: if payment.status_detail == '': payment.status_detail = 'not approved' payment.save() self.last_payment_failed_dt = datetime.now() self.save() # create a payment transaction record payment_transaction = PaymentTransaction( recurring_payment=self.recurring_payment, recurring_payment_invoice=self, payment_profile_id=payment_profile_id, trans_type='auth_capture', amount=amount, status=success) payment_transaction.payment = payment payment_transaction.result_code = response_d['result_code'] payment_transaction.message_code = response_d['message_code'] payment_transaction.message_text = response_d['message_text'] payment_transaction.save() return payment_transaction
def corp_memb_inv_add(user, corp_memb, app=None, **kwargs): """ Add an invoice for this corporate membership """ corp_profile = corp_memb.corp_profile renewal = kwargs.get('renewal', False) renewal_total = kwargs.get('renewal_total', 0) if not corp_memb.invoice or renewal: inv = Invoice() inv.object_type = ContentType.objects.get( app_label=corp_memb._meta.app_label, model=corp_memb._meta.model_name) inv.object_id = corp_memb.id inv.title = corp_memb.corp_profile.name if not user.is_anonymous(): inv.bill_to = '%s %s' % (user.first_name, user.last_name) inv.bill_to_first_name = user.first_name inv.bill_to_last_name = user.last_name inv.bill_to_email = user.email inv.set_creator(user) inv.set_owner(user) else: if corp_memb.anonymous_creator: cmc = corp_memb.anonymous_creator inv.bill_to = '%s %s' % (cmc.first_name, cmc.last_name) inv.bill_to_first_name = cmc.first_name inv.bill_to_last_name = cmc.last_name inv.bill_to_email = cmc.email else: inv.bill_to = corp_memb.name inv.bill_to_company = corp_profile.name inv.bill_to_address = corp_profile.address inv.bill_to_city = corp_profile.city inv.bill_to_state = corp_profile.state inv.bill_to_zip_code = corp_profile.zip inv.bill_to_country = corp_profile.country inv.bill_to_phone = corp_profile.phone inv.ship_to = corp_profile.name inv.ship_to_company = corp_profile.name inv.ship_to_address = corp_profile.address inv.ship_to_city = corp_profile.city inv.ship_to_state = corp_profile.state inv.ship_to_zip_code = corp_profile.zip inv.ship_to_country = corp_profile.country inv.ship_to_phone = corp_profile.phone inv.ship_to_email = corp_profile.email inv.terms = "Due on Receipt" inv.due_date = datetime.now() inv.ship_date = datetime.now() inv.message = 'Thank You.' inv.status = True if not renewal: inv.total = corp_memb.corporate_membership_type.price else: inv.total = renewal_total inv.subtotal = inv.total inv.balance = inv.total tax = 0 if app and app.include_tax: tax = inv.total * app.tax_rate inv.tax = tax total = inv.total + tax inv.subtotal =total inv.total = total inv.balance = total inv.estimate = True inv.status_detail = 'estimate' inv.save(user) if not corp_memb.payment_method: is_online = True if inv.balance <= 0: is_online = False corp_memb.payment_method = corp_memb.get_payment_method( is_online=is_online) if user.profile.is_superuser: # if offline payment method if not corp_memb.payment_method.is_online: inv.tender(user) # tendered the invoice for admin if offline # mark payment as made payment = Payment() payment.payments_pop_by_invoice_user(user, inv, inv.guid) payment.mark_as_paid() payment.method = corp_memb.payment_method.machine_name payment.save(user) # this will make accounting entry inv.make_payment(user, payment.amount) return inv return None
def api_rp_setup(data): """Create a recurrring payment account. Accepted format: json Input fields: email - required description - required amount - required cp_id - customer profile id, required pp_id - customer payment profile id, required billing_cycle_start_dt - required billing_cycle_end_dt - required response_str - required login_name login_password url first_name last_name billing_period - optional, default to 'month' billing_frequency - optional, default to 1 billing_start_dt - optional, default to today num_days - optional, default to 0 has_trial_period - optional, default to False trial_period_start_dt - optional, default to today trial_period_end_dt - optional, default to today trial_amount - optional, default to 0 Output: rp_id - a recurring payment id rp_url - url to rp username result_code """ from decimal import Decimal from tendenci.apps.base.utils import validate_email import dateutil.parser as dparser from tendenci.apps.imports.utils import get_unique_username email = data.get("email", "") description = data.get("description", "") url = data.get("url") payment_amount = data.get("amount", "") taxable = data.get("taxable", 0) if taxable in ("True", "true", "1", 1): taxable = 1 else: taxable = 0 try: tax_rate = Decimal(data.get("tax_rate", 0)) if tax_rate > 1: tax_rate = 0 except: tax_rate = 0 tax_exempt = data.get("tax_exempt", 0) if tax_exempt in ("True", "true", "1", 1): tax_exempt = 1 else: tax_exempt = 0 try: payment_amount = Decimal(payment_amount) except: payment_amount = 0 cp_id = data.get("cp_id") pp_id = data.get("pp_id") billing_cycle_start_dt = data.get("billing_cycle_start_dt") if billing_cycle_start_dt: billing_cycle_start_dt = dparser.parse(billing_cycle_start_dt) billing_cycle_end_dt = data.get("billing_cycle_end_dt") if billing_cycle_end_dt: billing_cycle_end_dt = dparser.parse(billing_cycle_end_dt) direct_response_str = data.get("response_str") if not all( [ validate_email(email), description, payment_amount > 0, cp_id, pp_id, billing_cycle_start_dt, billing_cycle_end_dt, direct_response_str, ] ): return False, {} # 1) get or create user username = data.get("login_name") # check if user already exists based on email and username users = User.objects.filter(email=email, username=username) if users: u = users[0] else: # create user account u = User() u.email = email u.username = username if not u.username: u.username = email.split("@")[0] u.username = get_unique_username(u) raw_password = data.get("login_password") if not raw_password: raw_password = User.objects.make_random_password(length=8) u.set_password(raw_password) u.first_name = data.get("first_name", "") u.last_name = data.get("last_name", "") u.is_staff = False u.is_superuser = False u.save() profile = Profile.objects.create( user=u, creator=u, creator_username=u.username, owner=u, owner_username=u.username, email=u.email ) # 2) create a recurring payment account rp = RecurringPayment() rp.user = u rp.description = description rp.url = url rp.payment_amount = payment_amount rp.taxable = taxable rp.tax_rate = tax_rate rp.tax_exempt = tax_exempt rp.customer_profile_id = cp_id rp.billing_start_dt = billing_cycle_start_dt has_trial_period = data.get("has_trial_period") trial_period_start_dt = data.get("trial_period_start_dt") trial_period_end_dt = data.get("trial_period_end_dt") if has_trial_period in ["True", "1", True, 1] and all([trial_period_start_dt, trial_period_end_dt]): rp.has_trial_period = True rp.trial_period_start_dt = dparser.parse(trial_period_start_dt) rp.trial_period_end_dt = dparser.parse(trial_period_end_dt) else: rp.has_trial_period = False rp.status_detail = "active" rp.save() # 3) create a payment profile account payment_profile_exists = PaymentProfile.objects.filter(customer_profile_id=cp_id, payment_profile_id=pp_id).exists() if not payment_profile_exists: PaymentProfile.objects.create( customer_profile_id=cp_id, payment_profile_id=pp_id, owner=u, owner_username=u.username ) # 4) create rp invoice billing_cycle = {"start": billing_cycle_start_dt, "end": billing_cycle_end_dt} rp_invoice = rp.create_invoice(billing_cycle, billing_cycle_start_dt) rp_invoice.invoice.tender(rp.user) # 5) create rp transaction now = datetime.now() payment = Payment() payment.payments_pop_by_invoice_user(rp.user, rp_invoice.invoice, rp_invoice.invoice.guid) payment_transaction = PaymentTransaction( recurring_payment=rp, recurring_payment_invoice=rp_invoice, payment_profile_id=pp_id, trans_type="auth_capture", amount=rp_invoice.invoice.total, status=True, ) payment = payment_update_from_response(payment, direct_response_str) payment.mark_as_paid() payment.save() rp_invoice.invoice.make_payment(rp.user, Decimal(payment.amount)) rp_invoice.invoice.save() rp_invoice.payment_received_dt = now rp_invoice.save() rp.last_payment_received_dt = now rp.num_billing_cycle_completed += 1 rp.save() payment_transaction.payment = payment payment_transaction.result_code = data.get("result_code") payment_transaction.message_code = data.get("message_code") payment_transaction.message_text = data.get("message_text") payment_transaction.save() site_url = get_setting("site", "global", "siteurl") return ( True, { "rp_id": rp.id, "rp_url": "%s%s" % (site_url, reverse("recurring_payment.view_account", args=[rp.id])), "username": rp.user.username, }, )
def pay_online(request, invoice_id, guid="", merchant_account=None, template_name="payments/pay_online.html"): # check if they have the right to view the invoice invoice = get_object_or_404(Invoice, pk=invoice_id) if not invoice.allow_view_by(request.user, guid): raise Http403 # tender the invoice if not invoice.is_tendered: invoice.tender(request.user) # log an event for invoice edit EventLog.objects.log(instance=invoice) # For event registration, check if we have enough seats available obj = invoice.get_object() if obj.__class__.__name__ == 'Registration': block_message = '' event = obj.event spots_available = event.get_spots_status()[1] if not spots_available: block_message = ugettext('No seats available for this event. Please cancel your registration or contact event organizer.') else: pricings = {} for registrant in obj.registrant_set.filter(cancel_dt__isnull=True): pricing = registrant.pricing if pricing.registration_cap: if pricing not in pricings: pricings[pricing] = 1 else: pricings[pricing] += 1 for p in pricings: price_spots_available = p.spots_available() if price_spots_available < pricings[p]: if not price_spots_available: block_message += ugettext('No seats available for price option "{}". '.format(p.title)) else: block_message += ugettext('The available seats for price option "{}" is not enough for this registration. '.format(p.title)) if block_message: block_message += ugettext('Please cancel your registration and re-register at a different price.') if block_message: messages.add_message(request, messages.ERROR, block_message) return HttpResponseRedirect(reverse( 'event.registration_confirmation', args=(event.id, obj.registrant.hash))) # generate the payment payment = Payment() boo = payment.payments_pop_by_invoice_user(request.user, invoice, guid) # log an event for payment add EventLog.objects.log(instance=payment) # post payment form to gateway and redirect to the vendor so customer can pay from there if boo: merchant_account = merchant_account or (get_setting("site", "global", "merchantaccount")).lower() if merchant_account == 'stripe': return HttpResponseRedirect(reverse('stripe.payonline', args=[payment.id, payment.guid])) else: if merchant_account == "authorizenet": form = prepare_authorizenet_sim_form(request, payment) post_url = settings.AUTHNET_POST_URL elif merchant_account == 'firstdata': from tendenci.apps.payments.firstdata.utils import prepare_firstdata_form form = prepare_firstdata_form(request, payment) post_url = settings.FIRSTDATA_POST_URL elif merchant_account == 'firstdatae4': from tendenci.apps.payments.firstdatae4.utils import prepare_firstdatae4_form form = prepare_firstdatae4_form(request, payment) post_url = settings.FIRSTDATAE4_POST_URL elif merchant_account == 'paypalpayflowlink': from tendenci.apps.payments.payflowlink.utils import prepare_payflowlink_form form = prepare_payflowlink_form(request, payment) post_url = settings.PAYFLOWLINK_POST_URL elif merchant_account == 'paypal': from tendenci.apps.payments.paypal.utils import prepare_paypal_form form = prepare_paypal_form(request, payment) post_url = settings.PAYPAL_POST_URL else: # more vendors logger.error( '"{}" did not match a known online payment method. Check the PaymentMethod.machine_name.'.format( merchant_account)) form = None post_url = "" else: form = None post_url = "" return render_to_resp(request=request, template_name=template_name, context={'form': form, 'post_url': post_url })
def make_payment_transaction(self, payment_profile_id): """ Make a payment transaction. This includes: 1) Make an API call createCustomerProfileTransactionRequest 2) Create a payment transaction entry 3) Create a payment entry 4) If the transaction is successful, populate payment entry with the direct response and mark payment as paid """ amount = self.invoice.balance # tender the invoice self.invoice.tender(self.recurring_payment.user) # create a payment record payment = Payment() payment.payments_pop_by_invoice_user(self.recurring_payment.user, self.invoice, self.invoice.guid) # make a transaction using CIM d = {'amount': amount, 'order': { 'invoice_number': str(payment.invoice_num), 'description': '%s (billing cycle from %s to %s)' % ( self.recurring_payment.description, self.billing_cycle_start_dt.strftime('%m/%d/%Y'), self.billing_cycle_end_dt.strftime('%m/%d/%Y')), 'recurring_billing': 'true' } } cpt = CIMCustomerProfileTransaction(self.recurring_payment.customer_profile_id, payment_profile_id) success, response_d = cpt.create(**d) # create a payment transaction record payment_transaction = PaymentTransaction( recurring_payment = self.recurring_payment, recurring_payment_invoice = self, payment_profile_id = payment_profile_id, trans_type='auth_capture', amount=amount, status=success) # update the payment entry with the direct response returned from payment gateway #print success, response_d payment = payment_update_from_response(payment, response_d['direct_response']) if success: payment.mark_as_paid() payment.save() self.invoice.make_payment(self.recurring_payment.user, Decimal(payment.amount)) self.invoice.save() self.payment_received_dt = datetime.now() else: if payment.status_detail == '': payment.status_detail = 'not approved' payment.save() self.last_payment_failed_dt = datetime.now() self.save() payment_transaction.payment = payment payment_transaction.result_code = response_d['result_code'] payment_transaction.message_code = response_d['message_code'] payment_transaction.message_text = response_d['message_text'] payment_transaction.save() return payment_transaction
def job_set_inv_payment(user, job, pricing): if get_setting('module', 'jobs', 'jobsrequirespayment'): if not job.invoice: inv = Invoice() inv.object_type = ContentType.objects.get(app_label=job._meta.app_label, model=job._meta.model_name) inv.object_id = job.id inv.title = _("Job Add Invoice") inv.bill_to = job.contact_name first_name = '' last_name = '' if job.contact_name: name_list = job.contact_name.split(' ') if len(name_list) >= 2: first_name = name_list[0] last_name = ' '.join(name_list[1:]) inv.bill_to_first_name = first_name inv.bill_to_last_name = last_name inv.bill_to_company = job.contact_company inv.bill_to_address = job.contact_address inv.bill_to_city = job.contact_city inv.bill_to_state = job.contact_state inv.bill_to_zip_code = job.contact_zip_code inv.bill_to_country = job.contact_country inv.bill_to_phone = job.contact_phone inv.bill_to_fax = job.contact_fax inv.bill_to_email = job.contact_email inv.ship_to = job.contact_name inv.ship_to_first_name = first_name inv.ship_to_last_name = last_name inv.ship_to_company = job.contact_company inv.ship_to_address = job.contact_address inv.ship_to_city = job.contact_city inv.ship_to_state = job.contact_state inv.ship_to_zip_code = job.contact_zip_code inv.ship_to_country = job.contact_country inv.ship_to_phone = job.contact_phone inv.ship_to_fax = job.contact_fax inv.ship_to_email =job.contact_email inv.terms = _("Due on Receipt") inv.due_date = datetime.now() inv.ship_date = datetime.now() inv.message = _('Thank You.') inv.status = True inv.total = get_job_price(user, job, pricing) inv.subtotal = inv.total inv.balance = inv.total inv.estimate = True inv.status_detail = 'estimate' tax = 0 if pricing.include_tax: tax = inv.total * pricing.tax_rate total = tax + inv.total inv.tax = tax inv.total = total inv.subtotal = total inv.balance = total if user and not user.is_anonymous: inv.set_creator(user) inv.set_owner(user) inv.save(user) # tender the invoice inv.tender(user) # update job job.invoice = inv job.save() if user.profile.is_superuser: if job.payment_method in ['paid - cc', 'paid - check', 'paid - wire transfer']: inv.tender(user) # payment payment = Payment() payment.payments_pop_by_invoice_user(user, inv, inv.guid) payment.mark_as_paid() payment.method = job.payment_method payment.save(user) # this will make accounting entry inv.make_payment(user, payment.amount)
def pay_online(request, invoice_id, guid="", template_name="payments/pay_online.html"): # check if they have the right to view the invoice invoice = get_object_or_404(Invoice, pk=invoice_id) if not invoice.allow_view_by(request.user, guid): raise Http403 # tender the invoice if not invoice.is_tendered: invoice.tender(request.user) # log an event for invoice edit EventLog.objects.log(instance=invoice) # check payment exist payments = Payment.objects.filter(Q(invoice_id=invoice_id)) if payments and payments.count() > 0 and payments[0].invoice_id == invoice_id: template_name="payments/thankyou.html" payment = payments[0] return render_to_response(template_name, {'payment': payment}, context_instance=RequestContext(request)) # generate the payment payment = Payment() boo = payment.payments_pop_by_invoice_user(request.user, invoice, guid) # log an event for payment add EventLog.objects.log(instance=payment) # post payment form to gateway and redirect to the vendor so customer can pay from there if boo: merchant_account = (get_setting("site", "global", "merchantaccount")).lower() if merchant_account == 'stripe': return HttpResponseRedirect(reverse('stripe.payonline', args=[payment.id])) elif merchant_account == "authorizenet": form = prepare_authorizenet_sim_form(request, payment) post_url = settings.AUTHNET_POST_URL elif merchant_account == 'firstdata': from tendenci.apps.payments.firstdata.utils import prepare_firstdata_form form = prepare_firstdata_form(request, payment) post_url = settings.FIRSTDATA_POST_URL elif merchant_account == 'firstdatae4': from tendenci.apps.payments.firstdatae4.utils import prepare_firstdatae4_form form = prepare_firstdatae4_form(request, payment) post_url = settings.FIRSTDATAE4_POST_URL elif merchant_account == 'paypalpayflowlink': from tendenci.apps.payments.payflowlink.utils import prepare_payflowlink_form form = prepare_payflowlink_form(request, payment) post_url = settings.PAYFLOWLINK_POST_URL elif merchant_account == 'paypal': from tendenci.apps.payments.paypal.utils import prepare_paypal_form form = prepare_paypal_form(request, payment) post_url = settings.PAYPAL_POST_URL elif merchant_account == 'wechat-pay': wechatpay_config = get_wechatpay_config() if wechatpay_config == None: return HttpResponseRedirect(reverse('settings.index', args=['site', 'global']) + '#id_sitewebmaster') params = { # urlencode to wechatpay api get params ,body max length is 128 #'body': urlencode({'xyz1': payment.description[0:128]}).replace('xyz1=',''), # 商品或支付单简要描述,例如:Ipad mini 16G 白色 # 'body': u'%s' % payment.description[0:128], 'body': u'Ipad mini 16G 白色', 'out_trade_no': payment.guid.replace('-', ''), # 商户系统内部的订单号,32个字符内、可包含字母 'total_fee': int(payment.amount * 100), # 订单总金额,单位为分 'product_id': invoice_id, # 商品ID 'notify_url': 'https://www.kunshanfa.com/payments/wxcallback/', 'trade_type': 'NATIVE', } wxpay = WxPayBasic(wechatpay_config) code_url = wxpay.unifiedorder2_get_code_url(**params) print(code_url) template_name = 'payments/wechatpay.html' return render_to_response(template_name, {'code_url': code_url, 'payment': payment}, context_instance=RequestContext(request)) else: # more vendors form = None post_url = "" else: form = None post_url = "" return render_to_response(template_name, {'form': form, 'post_url': post_url }, context_instance=RequestContext(request))
def make_payment_transaction(self, payment_profile_id, membership=None): """ Make a payment transaction. This includes: 1) Make an API call createCustomerProfileTransactionRequest 2) Create a payment transaction entry 3) Create a payment entry 4) If the transaction is successful, populate payment entry with the direct response and mark payment as paid """ amount = self.invoice.balance # tender the invoice self.invoice.tender(self.recurring_payment.user) # create a payment record payment = Payment() payment.payments_pop_by_invoice_user(self.recurring_payment.user, self.invoice, self.invoice.guid) if self.billing_cycle_start_dt and self.billing_cycle_end_dt: description = self.recurring_payment.description description += '(billing cycle from {0} to {1})'.format( self.billing_cycle_start_dt.strftime('%m/%d/%Y'), self.billing_cycle_end_dt.strftime('%m/%d/%Y')) else: description = payment.description # charge user if self.recurring_payment.platform == "stripe": stripe.api_key = getattr(settings, 'STRIPE_SECRET_KEY', '') params = { 'amount': math.trunc(amount * 100), # amount in cents, again 'currency': get_setting('site', 'global', 'currency'), 'description': description, 'customer': self.recurring_payment.customer_profile_id } success = False response_d = { 'status_detail': 'not approved', 'response_code': '0', 'response_reason_code': '0', 'result_code': 'Error', # Error, Ok 'message_code': '', # I00001, E00027 } try: charge_response = stripe.Charge.create(**params) success = True response_d['status_detail'] = 'approved' response_d['response_code'] = '1' response_d['response_subcode'] = '1' response_d['response_reason_code'] = '1' response_d['response_reason_text'] = 'This transaction has been approved. (Created# %s)' % charge_response.created response_d['trans_id'] = charge_response.id response_d['result_code'] = 'Ok' response_d['message_text'] = 'Successful.' except stripe.error.CardError as e: # it's a decline json_body = e.json_body err = json_body and json_body['error'] code = err and err['code'] message = err and err['message'] charge_response = '{message} status={status}, code={code}'.format( message=message, status=e.http_status, code=code) response_d['response_reason_text'] = charge_response response_d['message_code'] = code response_d['message_text'] = charge_response except Exception as e: charge_response = e.message response_d['response_reason_text'] = charge_response response_d['message_text'] = charge_response[:200] # update payment for key in response_d: if hasattr(payment, key): setattr(payment, key, response_d[key]) else: # make a transaction using CIM d = {'amount': amount, 'order': { 'invoice_number': str(payment.invoice_num), 'description': description, 'recurring_billing': 'true' } } cpt = CIMCustomerProfileTransaction(self.recurring_payment.customer_profile_id, payment_profile_id) success, response_d = cpt.create(**d) # update the payment entry with the direct response returned from payment gateway payment = payment_update_from_response(payment, response_d['direct_response']) if success: payment.mark_as_paid() payment.save() payment.invoice.make_payment(self.recurring_payment.user, Decimal(payment.amount)) # approve membership if membership: membership.approve() # send notification to user self.payment_received_dt = datetime.now() else: if payment.status_detail == '': payment.status_detail = 'not approved' payment.save() self.last_payment_failed_dt = datetime.now() self.save() # create a payment transaction record payment_transaction = PaymentTransaction( recurring_payment = self.recurring_payment, recurring_payment_invoice = self, payment_profile_id = payment_profile_id, trans_type='auth_capture', amount=amount, status=success) payment_transaction.payment = payment payment_transaction.result_code = response_d['result_code'] payment_transaction.message_code = response_d['message_code'] payment_transaction.message_text = response_d['message_text'] payment_transaction.save() return payment_transaction