Beispiel #1
0
def notify_payment(payment):
    invoice = payment.invoice
    member = invoice.member
    service = get_service_instance()
    config = service.config

    invoicing_config = get_invoicing_config_instance()
    try:
        invoice_pdf_file = generate_pdf_invoice(invoicing_config, invoice)
    except:
        invoice_pdf_file = None

    if member.email:
        invoice_url = service.url + reverse('billing:invoice_detail',
                                            args=(invoice.id, ))
        subject, message, sms_text = get_payment_confirmation_message(
            payment, member)
        html_content = get_mail_content(
            subject,
            message,
            template_name='billing/mails/notice.html',
            extra_context={
                'member_name': member.first_name,
                'invoice': invoice,
                'cta': _("View invoice"),
                'invoice_url': invoice_url
            })
        sender = '%s <no-reply@%s>' % (config.company_name, service.domain)
        msg = XEmailMessage(subject, html_content, sender, [member.email])
        if invoice_pdf_file:
            msg.attach_file(invoice_pdf_file)
        msg.content_subtype = "html"
        Thread(target=lambda m: m.send(), args=(msg, )).start()
Beispiel #2
0
def confirm_invoice_payment(request, *args, **kwargs):
    """
    This function has no URL associated with it.
    It serves as ikwen setting "MOMO_AFTER_CHECKOUT"
    """
    from echo.models import Balance
    from echo.utils import LOW_MAIL_LIMIT, notify_for_low_messaging_credit, notify_for_empty_messaging_credit
    tx = kwargs.get('transaction')
    now = datetime.now()
    service = get_service_instance()
    config = service.config
    invoicing_config = get_invoicing_config_instance()
    invoice_id = request.session['object_id']
    amount = request.session['amount']
    invoice = Invoice.objects.select_related('subscription').get(pk=invoice_id)
    invoice.paid += amount
    invoice.status = Invoice.PAID
    if invoicing_config.processing_fees_on_customer:
        invoice.processing_fees = config.ikwen_share_fixed
    invoice.save()
    payment = Payment.objects.create(invoice=invoice, method=Payment.MOBILE_MONEY,
                                     amount=amount, processor_tx_id=tx.processor_tx_id)
    subscription = invoice.subscription
    if invoicing_config.separate_billing_cycle:
        extra_months = request.session['extra_months']
        total_months = invoice.months_count + extra_months
        days = get_days_count(total_months)
    else:
        extra_months = 0
        days = invoice.subscription.product.duration
        total_months = None
    if subscription.status == Service.SUSPENDED:
        invoicing_config = get_invoicing_config_instance()
        days -= invoicing_config.tolerance  # Catch-up days that were offered before service suspension
        expiry = now + timedelta(days=days)
        expiry = expiry.date()
    elif subscription.expiry:
        expiry = subscription.expiry + timedelta(days=days)
    else:
        expiry = now + timedelta(days=days)
        expiry = expiry.date()
    subscription.expiry = expiry
    subscription.status = Service.ACTIVE
    subscription.save()
    mean = request.session['mean']
    share_payment_and_set_stats(invoice, total_months, mean)
    member = request.user
    sudo_group = Group.objects.using(UMBRELLA).get(name=SUDO)
    add_event(service, PAYMENT_CONFIRMATION, member=member, object_id=invoice.id)
    add_event(service, PAYMENT_CONFIRMATION, group_id=sudo_group.id, object_id=invoice.id)

    if invoicing_config.return_url:
        params = {'reference_id': subscription.reference_id, 'invoice_number': invoice.number,
                  'amount_paid': amount, 'processor_tx_id': tx.processor_tx_id, 'extra_months': extra_months}
        Thread(target=notify_event, args=(service, invoicing_config.return_url, params)).start()

    try:
        invoice_pdf_file = generate_pdf_invoice(invoicing_config, invoice)
    except:
        invoice_pdf_file = None

    balance, update = Balance.objects.using(WALLETS_DB_ALIAS).get_or_create(service_id=service.id)
    if member.email:
        if 0 < balance.mail_count < LOW_MAIL_LIMIT:
            notify_for_low_messaging_credit(service, balance)
        if balance.mail_count <= 0:
            notify_for_empty_messaging_credit(service, balance)
        else:
            try:
                currency = Currency.active.default().symbol
            except:
                currency = config.currency_code
            invoice_url = service.url + reverse('billing:invoice_detail', args=(invoice.id,))
            subject, message, sms_text = get_payment_confirmation_message(payment, member)
            html_content = get_mail_content(subject, message, template_name='billing/mails/notice.html',
                                            extra_context={'member_name': member.first_name, 'invoice': invoice,
                                                           'cta': _("View invoice"), 'invoice_url': invoice_url,
                                                           'currency': currency})
            sender = '%s <no-reply@%s>' % (config.company_name, service.domain)
            msg = XEmailMessage(subject, html_content, sender, [member.email])
            msg.content_subtype = "html"
            if invoice_pdf_file:
                msg.attach_file(invoice_pdf_file)
            balance.mail_count -= 1
            balance.save()
            Thread(target=lambda m: m.send(), args=(msg,)).start()
    return HttpResponseRedirect(request.session['return_url'])
Beispiel #3
0
def confirm_service_invoice_payment(request, *args, **kwargs):
    """
    This view is run after successful user cashout "MOMO_AFTER_CHECKOUT"
    """
    status = request.GET['status']
    message = request.GET['message']
    operator_tx_id = request.GET['operator_tx_id']
    phone = request.GET['phone']
    tx_id = kwargs['tx_id']
    extra_months = int(kwargs['extra_months'])
    try:
        tx = MoMoTransaction.objects.using(WALLETS_DB_ALIAS).get(pk=tx_id, is_running=True)
        if not getattr(settings, 'DEBUG', False):
            tx_timeout = getattr(settings, 'IKWEN_PAYMENT_GATEWAY_TIMEOUT', 15) * 60
            expiry = tx.created_on + timedelta(seconds=tx_timeout)
            if datetime.now() > expiry:
                return HttpResponse("Transaction %s timed out." % tx_id)

        tx.status = status
        tx.message = 'OK' if status == MoMoTransaction.SUCCESS else message
        tx.processor_tx_id = operator_tx_id
        tx.phone = phone
        tx.is_running = False
        tx.save()
    except:
        raise Http404("Transaction %s not found" % tx_id)
    if status != MoMoTransaction.SUCCESS:
        return HttpResponse("Notification for transaction %s received with status %s" % (tx_id, status))
    invoice_id = tx.object_id
    amount = tx.amount
    signature = tx.task_id

    callback_signature = kwargs.get('signature')
    no_check_signature = request.GET.get('ncs')
    if getattr(settings, 'DEBUG', False):
        if not no_check_signature:
            if callback_signature != signature:
                return HttpResponse('Invalid transaction signature')
    else:
        if callback_signature != signature:
            return HttpResponse('Invalid transaction signature')
    now = datetime.now()
    ikwen_service = get_service_instance()
    invoice = Invoice.objects.get(pk=invoice_id)
    invoice.paid += amount
    invoice.status = Invoice.PAID
    invoice.save()
    payment = Payment.objects.create(invoice=invoice, method=Payment.MOBILE_MONEY,
                                     amount=amount, processor_tx_id=tx.processor_tx_id)
    service = invoice.service
    total_months = invoice.months_count + extra_months
    days = get_days_count(total_months)
    invoicing_config = get_invoicing_config_instance()
    if service.status == Service.SUSPENDED:
        days -= invoicing_config.tolerance  # Catch-up days that were offered before service suspension
        expiry = now + timedelta(days=days)
        expiry = expiry.date()
    elif service.expiry:
        expiry = service.expiry + timedelta(days=days)
    else:
        expiry = now + timedelta(days=days)
        expiry = expiry.date()
    service.expiry = expiry
    service.status = Service.ACTIVE
    if invoice.is_one_off:
        service.version = Service.FULL
        try:
            support_bundle = SupportBundle.objects.get(type=SupportBundle.TECHNICAL, channel=SupportBundle.PHONE, cost=0)
            token = ''.join([random.SystemRandom().choice(string.digits) for i in range(6)])
            support_expiry = now + timedelta(days=support_bundle.duration)
            SupportCode.objects.create(service=service, token=token, bundle=support_bundle,
                                       balance=support_bundle.quantity, expiry=support_expiry)
            logger.debug("Free Support Code created for %s" % service)
        except SupportBundle.DoesNotExist:
            logger.error("Free Support Code not created for %s" % service, exc_info=True)
    service.save()
    mean = tx.wallet
    is_early_payment = False
    if service.app.slug == 'kakocase' or service.app.slug == 'webnode':
        if invoice.due_date <= now.date():
            is_early_payment = True
        refill_tsunami_messaging_bundle(service, is_early_payment)
    share_payment_and_set_stats(invoice, total_months, mean)
    member = service.member
    vendor = service.retailer
    vendor_is_dara = vendor and vendor.app.slug == DARAJA
    if vendor and not vendor_is_dara:
        add_database_to_settings(vendor.database)
        sudo_group = Group.objects.using(vendor.database).get(name=SUDO)
    else:
        vendor = ikwen_service
        sudo_group = Group.objects.using(UMBRELLA).get(name=SUDO)
    add_event(vendor, PAYMENT_CONFIRMATION, member=member, object_id=invoice.id)
    add_event(vendor, PAYMENT_CONFIRMATION, group_id=sudo_group.id, object_id=invoice.id)

    try:
        invoice_pdf_file = generate_pdf_invoice(invoicing_config, invoice)
    except:
        invoice_pdf_file = None

    if member.email:
        activate(member.language)
        invoice_url = service.url + reverse('billing:invoice_detail', args=(invoice.id,))
        subject, message, sms_text = get_payment_confirmation_message(payment, member)
        html_content = get_mail_content(subject, message, service=vendor, template_name='billing/mails/notice.html',
                                        extra_context={'member_name': member.first_name, 'invoice': invoice,
                                                       'cta': _("View invoice"), 'invoice_url': invoice_url,
                                                       'early_payment': is_early_payment})
        sender = '%s <no-reply@%s>' % (vendor.config.company_name, ikwen_service.domain)
        msg = XEmailMessage(subject, html_content, sender, [member.email])
        if vendor != ikwen_service and not vendor_is_dara:
            msg.service = vendor
        if invoice_pdf_file:
            msg.attach_file(invoice_pdf_file)
        msg.content_subtype = "html"
        if getattr(settings, 'UNIT_TESTING', False):
            msg.send()
        else:
            Thread(target=lambda m: m.send(), args=(msg,)).start()
    return HttpResponse("Notification received")
Beispiel #4
0
def confirm_invoice_payment(request, *args, **kwargs):
    tx = kwargs[
        'tx']  # Decoration with @momo_gateway_callback makes 'tx' available in kwargs
    school = Service.objects.get(pk=tx.service_id)
    school_config = SchoolConfig.objects.get(service=school)
    ikwen_charges = tx.amount * school_config.ikwen_share_rate / 100

    tx.fees = ikwen_charges
    tx.save()
    mean = tx.wallet
    db = school.database
    add_database(db)
    invoice = Invoice.objects.using(db).get(pk=tx.object_id)
    payment = Payment.objects.using(db).create(
        invoice=invoice,
        method=Payment.MOBILE_MONEY,
        amount=tx.amount,
        processor_tx_id=tx.processor_tx_id)
    invoice.paid = tx.amount
    invoice.status = Invoice.PAID
    invoice.save()
    student = invoice.student
    if not school_config.is_public or (school_config.is_public
                                       and not invoice.is_tuition):
        amount = tx.amount - ikwen_charges
        school.raise_balance(amount, provider=mean)
    else:
        amount = tx.amount
    student.set_has_new(using=school.database)
    student.save(using='default')

    set_counters(school)
    increment_history_field(school, 'turnover_history', tx.amount)
    increment_history_field(school, 'earnings_history', amount)
    increment_history_field(school, 'transaction_count_history')
    increment_history_field(school, 'transaction_earnings_history', amount)

    member = invoice.member
    if member.email:
        try:
            currency = Currency.active.default().symbol
        except:
            currency = school_config.currency_code
        invoice_url = school.url + reverse('billing:invoice_detail',
                                           args=(invoice.id, ))
        subject, message, sms_text = get_payment_confirmation_message(
            payment, member)
        html_content = get_mail_content(
            subject,
            message,
            template_name='billing/mails/notice.html',
            extra_context={
                'member_name': member.first_name,
                'invoice': invoice,
                'cta': _("View invoice"),
                'invoice_url': invoice_url,
                'currency': currency
            })
        sender = '%s <no-reply@%s>' % (school_config.company_name,
                                       school.domain)
        msg = XEmailMessage(subject, html_content, sender, [member.email])
        msg.content_subtype = "html"
        bcc = [
            email.strip()
            for email in school_config.notification_emails.split(',')
            if email.strip()
        ]
        bcc += [school_config.contact_email, school.member.email]
        msg.bcc = list(set(bcc))
        try:
            invoicing_config = get_invoicing_config_instance()
            invoice_pdf_file = generate_pdf_invoice(invoicing_config, invoice)
            msg.attach_file(invoice_pdf_file)
        except:
            pass
    return HttpResponse(
        "Notification for transaction %s received with status %s" %
        (tx.id, tx.status))
Beispiel #5
0
def confirm_my_kids_payment(request, *args, **kwargs):
    tx = kwargs['tx']
    invoice = Invoice.objects.get(pk=tx.object_id)
    school = invoice.school
    school_config = SchoolConfig.objects.get(service=school)
    ikwen_charges = tx.amount * school_config.my_kids_share_rate / 100
    tx.fees = ikwen_charges
    tx.save(using='wallets')
    mean = tx.wallet

    amount = tx.amount - ikwen_charges
    school.raise_balance(amount, provider=mean)
    share_payment_and_set_stats(invoice, mean, tx)

    invoice.paid = invoice.amount
    invoice.status = Invoice.PAID
    invoice.save()

    member = invoice.member
    student = invoice.student
    max_expiry = datetime(day=31, month=8, year=get_school_year() + 1)
    days = get_billing_cycle_days_count(invoice.my_kids_cycle)
    expiry = datetime.now() + timedelta(days=days)
    expiry = min(expiry, max_expiry)
    student.my_kids_expiry = expiry
    student.my_kids_expired = False
    student.save()

    db = school.database
    add_database(db)
    invoice.save(using=db)
    payment = Payment(invoice=invoice,
                      method=Payment.MOBILE_MONEY,
                      amount=tx.amount,
                      processor_tx_id=tx.processor_tx_id)
    if school_config.my_kids_share_rate < 100:
        # Payment appears in school log panel only if the have something to collect out of that
        payment.save(using=db)

    if member.email:
        try:
            currency = Currency.active.default().symbol
        except:
            currency = school_config.currency_code
        invoice_url = school.url + reverse('billing:invoice_detail',
                                           args=(invoice.id, ))
        subject, message, sms_text = get_payment_confirmation_message(
            payment, member)
        html_content = get_mail_content(
            subject,
            message,
            template_name='billing/mails/notice.html',
            extra_context={
                'member_name': member.first_name,
                'invoice': invoice,
                'cta': _("View invoice"),
                'invoice_url': invoice_url,
                'currency': currency
            })
        sender = '%s <no-reply@%s>' % (school_config.company_name,
                                       school.domain)
        msg = XEmailMessage(subject, html_content, sender, [member.email])
        msg.content_subtype = "html"
        try:
            invoicing_config = get_invoicing_config_instance()
            invoice_pdf_file = generate_pdf_invoice(invoicing_config, invoice)
            msg.attach_file(invoice_pdf_file)
        except:
            pass
    return HttpResponse(
        "Notification for transaction %s received with status %s" %
        (tx.id, tx.status))
Beispiel #6
0
def confirm_service_invoice_payment(request, *args, **kwargs):
    """
    This view is run after successful user cashout "MOMO_AFTER_CHECKOUT"
    """
    tx = kwargs[
        'tx']  # Decoration with @momo_gateway_callback makes 'tx' available in kwargs
    extra_months = int(kwargs['extra_months'])
    payment = Payment.objects.select_related().get(pk=tx.object_id)
    payment.processor_tx_id = tx.processor_tx_id
    payment.save()
    invoice = payment.invoice
    now = datetime.now()
    ikwen_service = get_service_instance()
    invoice.paid += tx.amount
    if invoice.paid >= invoice.amount:
        invoice.status = Invoice.PAID
    invoice.save()
    service = invoice.service
    total_months = invoice.months_count + extra_months
    days = get_days_count(total_months)
    invoicing_config = get_invoicing_config_instance()
    if service.status == Service.SUSPENDED:
        days -= invoicing_config.tolerance  # Catch-up days that were offered before service suspension
        expiry = now + timedelta(days=days)
        expiry = expiry.date()
    elif service.expiry:
        expiry = service.expiry + timedelta(days=days)
    else:
        expiry = now + timedelta(days=days)
        expiry = expiry.date()
    service.expiry = expiry
    service.status = Service.ACTIVE
    if invoice.is_one_off:
        service.version = Service.FULL
        try:
            support_bundle = SupportBundle.objects.get(
                type=SupportBundle.TECHNICAL,
                channel=SupportBundle.PHONE,
                cost=0)
            token = ''.join([
                random.SystemRandom().choice(string.digits) for i in range(6)
            ])
            support_expiry = now + timedelta(days=support_bundle.duration)
            SupportCode.objects.create(service=service,
                                       token=token,
                                       bundle=support_bundle,
                                       balance=support_bundle.quantity,
                                       expiry=support_expiry)
            logger.debug("Free Support Code created for %s" % service)
        except SupportBundle.DoesNotExist:
            logger.error("Free Support Code not created for %s" % service,
                         exc_info=True)
    service.save()
    mean = tx.wallet
    is_early_payment = False
    if service.app.slug == 'kakocase' or service.app.slug == 'webnode':
        if invoice.due_date <= now.date():
            is_early_payment = True
        refill_tsunami_messaging_bundle(service, is_early_payment)
    share_payment_and_set_stats(invoice, total_months, mean, tx)
    member = service.member
    vendor = service.retailer
    vendor_is_dara = vendor and vendor.app.slug == DARAJA
    if vendor and not vendor_is_dara:
        add_database_to_settings(vendor.database)
        sudo_group = Group.objects.using(vendor.database).get(name=SUDO)
    else:
        vendor = ikwen_service
        sudo_group = Group.objects.using(UMBRELLA).get(name=SUDO)
    add_event(vendor,
              PAYMENT_CONFIRMATION,
              member=member,
              object_id=invoice.id)
    add_event(vendor,
              PAYMENT_CONFIRMATION,
              group_id=sudo_group.id,
              object_id=invoice.id)

    try:
        invoice_pdf_file = generate_pdf_invoice(invoicing_config, invoice)
    except:
        invoice_pdf_file = None

    if member.email:
        activate(member.language)
        invoice_url = ikwen_service.url + reverse('billing:invoice_detail',
                                                  args=(invoice.id, ))
        subject, message, sms_text = get_payment_confirmation_message(
            payment, member)
        html_content = get_mail_content(
            subject,
            message,
            service=vendor,
            template_name='billing/mails/notice.html',
            extra_context={
                'member_name': member.first_name,
                'invoice': invoice,
                'cta': _("View invoice"),
                'invoice_url': invoice_url,
                'early_payment': is_early_payment
            })
        sender = '%s <no-reply@%s>' % (vendor.config.company_name,
                                       ikwen_service.domain)
        msg = XEmailMessage(subject, html_content, sender, [member.email])
        if vendor != ikwen_service and not vendor_is_dara:
            msg.service = vendor
        if invoice_pdf_file:
            msg.attach_file(invoice_pdf_file)
        msg.content_subtype = "html"
        if getattr(settings, 'UNIT_TESTING', False):
            msg.send()
        else:
            Thread(target=lambda m: m.send(), args=(msg, )).start()
    return HttpResponse("Notification received")