def __Payment(ticket, *args, **kwargs):
    u = User.objects.get(userID=ticket.user.userID)
    if (not u):
        return HttpResponse("error")
    else:
        #Set daily price
        if (ticket.location.lotID == "Motor_Sipil"
                or ticket.location.lotID == "Motor_SR"):
            dailyPrice = 2000
        elif (ticket.location.lotID == "Mobil_SR"):
            dailyPrice = 5000
        else:
            dailyPrice = 0
        #Duration is defined as days that the parking lot is utilized
        dur = (ticket.exitTime - ticket.entryTime).days
        #Duration + 1 since the price is counted since day 0
        total = (dur + 1) * dailyPrice

        if (u.userBalance >= total):
            u.userBalance = u.userBalance - total
            u.save()
            p = Payment(userID=ticket.user,
                        ticketID=Ticket.objects.get(ticketID=ticket.ticketID),
                        duration=dur,
                        amount=total)
            p.save()
            return HttpResponse((
                "You paid IDR {:,} \n Payment successfull, you have IDR {:,} left"
            ).format(total, u.userBalance))
        else:
            ticket.exitTime = None
            ticket.save()
            return HttpResponse("Your balance is not sufficient, Amount = " +
                                str(total))
Example #2
0
def payment_process(request):
    order_id = request.session.get('order_id')
    order = get_object_or_404(Order, id=order_id)
    paystack_total = int(order.get_total_cost() * 100)
    data_key = settings.PAYSTACK_PUBLIC_KEY
    data_email = request.user.email

    if request.method == 'POST':

        try:
            payment = Payment()
            payment.paystack_id = request.POST['paystack-trxref']
            payment.customer = request.user
            payment.amount = order.get_total_cost()
            payment.save()

            order.paid = True
            order.ref = request.POST['paystack-trxref']
            order.amount = payment
            order.save()

        except ObjectDoesNotExist:
            pass
        return redirect('payment:success')

    context = {
        'order': order,
        'paystack_total': paystack_total,
        'data_key': data_key,
        'data_email': data_email,
    }
    return render(request, 'payment/process.html', context)
Example #3
0
    def submit_basket(self):
        # Selecting the customer
        customer_id = 1
        if self.selected_customer is not '':
            customer_id = int(self.selected_customer)
        else:
            print('Please select a customer')

        customer = Customer.objects.get(pk=customer_id)

        # Selecting the employee
        employee = User.objects.get(
            pk=1)  # TODO: Modify this after implementing the login

        # Creating the basket
        date_submitted = timezone.now()
        basket = Basket(date_submitted=date_submitted)
        basket.save()

        # Creating the basket lines
        lines_dict = self.products_in_basket
        for line in lines_dict:
            product = Product.objects.get(pk=int(line))
            quantity = lines_dict[line]
            price_excl_tax = product.selling_price
            price_incl_tax = float(product.selling_price) + (
                float(product.selling_price) * float(product.tax_rate)) / 100
            # TODO: This line has to be fed from the Basket Table,
            #  as user can modify prices at checkout
            basket_line = BasketLine(basket=basket,
                                     product=product,
                                     quantity=quantity,
                                     price_excl_tax=price_excl_tax,
                                     price_incl_tax=price_incl_tax)
            basket_line.save()

        # Selecting the payment
        payment_source_text = self.comboBox.currentText()
        payment_source = PaymentSource.objects.get(name=payment_source_text)
        payment_value_date = timezone.now()
        payment = Payment(source=payment_source,
                          date_value=payment_value_date,
                          amount=self.total_basket)
        payment.save()

        sale = Sale(basket=basket,
                    employee=employee,
                    payment=payment,
                    customer=customer)
        # TODO: Need to add Inventory Entries after submitting a sale

        sale.save()

        msg = MessageDialog('The sale has been submitted')
        msg.exec_()
        msg.show()

        self.clear_all()
 def create_payment(self):
     payment = Payment(phone='+441784938491',
                       address1='Address1',
                       address2='Address2',
                       city='London',
                       region='Middlesex',
                       post_code='Postcode',
                       country='country',
                       name_on_card='Test Payee',
                       cycle=self.get_cycle())
     payment.save()
Example #5
0
def register_payment(payment: Payment) -> str:
    """
    - Registers the payment with netaxept.
    - Stores the newly created netaxept transaction_id in the Payment.
    - Records a Transaction representing the registration.

    :param payment: A payment to register.
    :return: The newly created netaxept transaction_id
    :raises NetaxeptException: If the payment was already registered or the registration fails
    """
    logger.info('netaxept-actions-register', payment_id=payment.id)

    if payment.token != '':  # The payment was already registered.
        if payment.is_authorized:
            raise PaymentAlreadyRegisteredAndAuthorized()
        else:
            # If payment was registered but not yet authorized we re-register it so that a later authorize can succeeed.
            # Otherwise when the user gets to the netaxept terminal page he sees a 'payment already processed' error.
            logger.info('netaxept-regegister-payment', payment_id=payment.id)

    _payment_gateway, gateway_config = get_payment_gateway(payment.gateway)
    netaxept_config = gateway_to_netaxept_config(gateway_config)

    try:
        register_response = netaxept_protocol.register(
            config=netaxept_config,
            order_number=payment.id,
            amount=payment.total,
            language='en',
            customer_email=payment.customer_email)
    except NetaxeptProtocolError as exception:
        Transaction.objects.create(payment=payment,
                                   kind=TransactionKind.REGISTER,
                                   token='',
                                   is_success=False,
                                   amount=payment.total,
                                   error=exception.error,
                                   gateway_response=exception.raw_response)
        raise NetaxeptException(exception.error)

    with transaction.atomic():
        payment.token = register_response.transaction_id
        payment.save()

        Transaction.objects.create(
            payment=payment,
            kind=TransactionKind.REGISTER,
            token=register_response.transaction_id,
            is_success=True,
            amount=payment.total,
            error=None,
            gateway_response=register_response.raw_response)

    return register_response.transaction_id
Example #6
0
def test_load_from_redis():
    p = Payment({
        'id': 'test',
        'app_id': 'test',
        'transaction_id': 'test',
        'recipient_address': 'test',
        'sender_address': 'test',
        'amount': 1
    })
    Payment(p.to_primitive())
    p.save()
    assert Payment.get('test').amount == p.amount
Example #7
0
def book(request, id):
    book = Book.objects.get(pk=id)
    if not request.user.has_perm('shop.view_book') and book.id == 5:
        pass
    p = Payment(amount=1000, user=request.user, description="Blah Blah")
    p.save()
    return p.pay()

    context = {
        'book': book,
    }
    return render(request, 'shop/book.html', context)
Example #8
0
    def insert(self, request_data):
        """ Record a new payment """

        payment = Payment()

        payment.expiration_date = request_data.get('expiration_date')
        payment.value = request_data.get('value')
        payment.branch_id = request_data.get('branch')

        self.__validate_insert(payment)

        payment.save()

        return Payment.objects.get(id=payment.id)
Example #9
0
def add_registration(request):
    check_events_happened()
    user = User.objects.get(pk=request.data['user'])
    event = Event.objects.get(pk=request.data['event'])
    p = Payment()
    p.event = event
    try:
        p.method = request.data['method'][0]
        if p.method == 'CashOnSpot':
            r_a = Decimal(0.0)
        else:
            r_a = Decimal(request.data['total_amount'])
    except KeyError:
        p.method = "FREE"
        r_a = Decimal(0.0)
    p.total_amount = Decimal(request.data['total_amount'])
    p.received_amount = r_a
    p.save()
    r = Registration()
    r.event_title = event.title
    r.user = user
    r.event = event
    r.payment = p
    r.number_of_tickets = request.data['number_of_tickets']
    r.price = request.data['price']
    r.voucher_code = ""
    r.total_price = Decimal(request.data['total_amount'])
    r.save()
    if p.method == 'CashOnSpot':
        r.voucher_code = "E" + str(event.id) + "R" + str(r.pk) + "P" + str(
            p.pk) + 'COS'
    else:
        r.voucher_code = "E" + str(event.id) + "R" + str(r.pk) + "P" + str(
            p.pk) + p.method[0]
    r.save()
    event.sold_tickets = event.sold_tickets + r.number_of_tickets
    event.remaining_tickets = event.total_tickets - event.sold_tickets
    event.save()
    return Response({'status': 'OK'})
Example #10
0
    def subscribe_for_the_first_time(user, creator=None):
        from payment.models import Payment

        if isinstance(user, BlocklogicUser):
            try:
                subscription = Subscription.objects.get(user=user)

                for p in Payment.objects.filter(status=FIRST_TIME, type=FREE):
                    if subscription in p.subscription.all():
                        return False
            except Subscription.DoesNotExist:
                subscription = Subscription(user=user, days_left=31, created_by=creator)
                subscription.save()

        if isinstance(user, basestring):
            try:
                subscription = Subscription.objects.get(email=user)

                for p in Payment.objects.filter(status=FIRST_TIME, type=FREE):
                    if subscription in p.subscription.all():
                        return False
            except Subscription.DoesNotExist:
                subscription = Subscription(email=user, days_left=31, created_by=creator)
                subscription.save()

        payment = Payment(status=FIRST_TIME, type=FREE, total=0, payment_info=json.dumps({"subscription_duration": 1}), created_by=creator)
        payment.save()

        payment.subscription.add(subscription)
        payment.save()

        start_date = subscription.datetime_created.date()
        end_date = start_date + datetime.timedelta(days=31)

        subscriptions = Subscriptions(subscription=subscription, start_date=start_date, end_date=end_date, payment=payment, status="", period="1", created_by=creator)
        subscriptions.save()

        return True
Example #11
0
def register_payment(payment: Payment) -> str:
    """
    This part of the process is unique to netaxept so it cannot be implemented inside the
    payment generic SPI. This implies that a programmer who wants to use the netaxept gateway will have to know
    to call this specific function.

    This function:

    - Registers the payment with netaxept
    - Stores the newly created netaxept transaction_id in the Payment (the transaction_id represents the payment on
       the netaxept side, and needs to be passed to netaxept for further operations like capturing, refunding, etc)
    - Create a Transaction object representing the registration for auditing purposes.

    :param payment: A payment to register
    :return: The the newly created netaxept transaction id
    :raises NetaxeptException: If the payment was already registered or the registration fails
    """
    logger.info('netaxept-actions-register', payment_id=payment.id)

    if payment.token != '':  # The payment was already registered.
        if payment.is_authorized:
            raise PaymentAlreadyRegisteredAndAuthorized()
        else:
            # If payment was registered but not yet authorized we re-register it so that a later authorize can succeeed:
            # Otherwise when the user gets to the netaxept terminal page he sees a 'payment already processed' error.
            logger.info('netaxept-regegister-payment', payment_id=payment.id)

    _payment_gateway, gateway_config = get_payment_gateway(payment.gateway)
    netaxept_config = gateway_to_netaxept_config(gateway_config)

    try:
        register_response = netaxept_protocol.register(
            config=netaxept_config,
            order_number=payment.id,
            amount=payment.total,
            language='en',
            customer_email=payment.customer_email)
    except NetaxeptProtocolError as exception:
        Transaction.objects.create(
            payment=payment,
            kind=TransactionKind.REGISTER,
            token='',
            is_success=False,
            amount=payment.total,
            error=exception.error,
            gateway_response=exception.raw_response)
        raise NetaxeptException(exception.error)

    with transaction.atomic():
        payment.token = register_response.transaction_id
        payment.save()

        Transaction.objects.create(
            payment=payment,
            kind=TransactionKind.REGISTER,
            token=register_response.transaction_id,
            is_success=True,
            amount=payment.total,
            error=None,
            gateway_response=register_response.raw_response)

    return register_response.transaction_id
Example #12
0
def process_no_card_payment(request):
    """ Process payment of order using non-card (credit amount) transaction"""
    user = User.objects.get(email=request.user.email)

    # create dummy Payment to indicate a simple credit transaction
    payment = Payment(full_name="Credit payment for " + request.user.username +
                      " @ " + request.user.email,
                      phone_number="n/a",
                      country="n/a",
                      postcode="n/a",
                      town_or_city="n/a",
                      street_address1="n/a",
                      street_address2="n/a",
                      date=timezone.now())
    payment.save()

    total = 0
    user = User.objects.get(email=request.user.email)
    share_order = request.session.get('share_order', {})

    # process each share purchase in the order
    for id, quantity in share_order.items():
        share = get_object_or_404(Share, pk=id)
        total += quantity * share.price
        payment_share_item = PaymentShareItem(payment=payment,
                                              share=share,
                                              quantity=quantity)
        payment_share_item.save()

        # calculate the new price for the share as a result of this purchase
        new_share_price = process_new_price(share.price, quantity, True)
        share.previous_price = share.price
        share.price = new_share_price
        share.save()

        # add to the share quantity for the user
        # if one does not exist, create one
        share_purchase_set = SharePurchase.objects.filter(user=user,
                                                          share=share)
        if len(share_purchase_set) == 0:
            share_purchase = SharePurchase(user=user,
                                           share=share,
                                           quantity=quantity)
        else:
            share_purchase = share_purchase_set[0]
            share_purchase.quantity += quantity

        share_purchase.save()

        # create a history of the share transaction for chart analysis
        share_price_history = SharePriceHistory(
            share=share,
            old_price=share.previous_price,
            new_price=share.price,
            transaction_date=timezone.now())
        share_price_history.save()

    commodity_order = request.session.get('commodity_order', {})

    # process each commodity purchase in the order
    for id, quantity in commodity_order.items():
        commodity = get_object_or_404(Commodity, pk=id)
        total += quantity * commodity.price
        payment_commodity_item = PaymentCommodityItem(payment=payment,
                                                      commodity=commodity,
                                                      quantity=quantity)
        payment_commodity_item.save()

        # calculate the new price for the commodity as a result of this purchase
        new_commodity_price = process_new_price(commodity.price, quantity,
                                                True)
        commodity.previous_price = commodity.price
        commodity.price = new_commodity_price
        commodity.save()

        # add to the commodity quantity for the user
        # if one does not exist, create one
        commodity_purchase_set = CommodityPurchase.objects.filter(
            user=user, commodity=commodity)
        if len(commodity_purchase_set) == 0:
            commodity_purchase = CommodityPurchase(user=user,
                                                   commodity=commodity,
                                                   quantity=quantity)
        else:
            commodity_purchase = commodity_purchase_set[0]
            commodity_purchase.quantity += quantity

        commodity_purchase.save()

        # create a history of the commodity transaction for chart analysis
        commodity_price_history = CommodityPriceHistory(
            commodity=commodity,
            old_price=commodity.previous_price,
            new_price=commodity.price,
            transaction_date=timezone.now())
        commodity_price_history.save()

    messages.error(
        request,
        "You have successfully completed this credit transaction for " +
        str(total))
    wallet_set = Wallet.objects.filter(user=user)

    # Update the credit amount and reset the order
    # and credit amount variables
    wallet = wallet_set[0]
    wallet.credit_amount -= total
    wallet.save()
    request.session['share_order'] = {}
    request.session['commodity_order'] = {}
    request.session['credit_amount'] = str(wallet.credit_amount)
    return redirect(reverse('current_listing'))
Example #13
0
File: bill.py Project: rokj/sellout
def create_bill_(request, c):
    def item_error(message, product):
        return JsonError(message + " " + _("(Item" + ": ") + product.name + ")")

    # check permissions
    if not has_permission(request.user, c, "bill", "edit"):
        return JsonError(_("You have no permission to create bills"))

    # get data
    data = JsonParse(request.POST.get("data"))
    if not data:
        return JsonError(_("No data received"))

    # see if we're updating an existing bill
    existing_bill = None
    try:
        existing_bill = Bill.objects.get(company=c, id=int(data.get("id")))
        if existing_bill.status == g.PAID:
            return JsonError(_("This bill has already been paid, editing is not possible"))
    except (ValueError, TypeError):
        pass
    except Bill.DoesNotExist:
        pass

    # current company (that will be fixed on this bill forever):
    # save a FK to BillCompany; the last company is the current one
    bill_company = BillCompany.objects.filter(company=c).order_by("-datetime_created")[0]

    # current register: get BillRegister with the same id as current one
    try:
        bill_registers = BillRegister.objects.filter(register__id=int(data.get("register_id")))
        if len(bill_registers) > 0:
            bill_register = bill_registers[0]
        else:
            raise Register.DoesNotExist
    except (TypeError, ValueError, Register.DoesNotExist):
        return JsonError(_("Invalid register specified."))

    # current contact: get BillContact with the same id as the requested contact
    if data.get("contact"):
        try:
            bill_contacts = BillContact.objects.get(contact__id=int(data.get("contact").get("id"))).order_by(
                "datetime_created"
            )
            if len(bill_contacts) > 0:
                bill_contact = bill_contacts[0]
            else:
                raise Contact.DoesNotExist
        except (Contact.DoesNotExist, ValueError, TypeError):
            return JsonError(_("Invalid contact"))
    else:
        bill_contact = None

    # save all validated stuff in bill to a dictionary and insert into database at the end
    # prepare data for insert
    bill = {
        "company": c,
        "issuer": bill_company,
        "register": bill_register,
        "contact": bill_contact,
        "user_id": request.user.id,
        "user_name": str(request.user),
        "notes": data.get("notes", "")[: max_field_length(Bill, "notes")],
        "type": g.CASH,
        "status": g.WAITING,
        "items": [],
        "currency": get_company_value(request.user, c, "pos_currency"),
        # numbers...
        "base": Decimal(0),
        "discount": Decimal(0),
        "tax": Decimal(0),
        "total": Decimal(0),
        "created_by": request.user,
    }

    # timestamp
    try:
        # timestamp: send in an array of number:
        # [year, month, day, hour, minute, second]
        tn = [int(n) for n in data.get("timestamp")]
        bill["timestamp"] = dtm(year=tn[0], month=tn[1], day=tn[2], hour=tn[3], minute=tn[4], second=tn[5])

    except (ValueError, TypeError):
        return JsonError(_("Invalid timestamp"))

    r = parse_decimal(request.user, c, data.get("total"))
    if not r["success"] or r["number"] <= Decimal("0"):
        return JsonError(_("Invalid grand total value"))
    else:
        bill["total"] = r["number"]

    # validate items
    for i in data.get("items"):
        # get product
        try:
            product = Product.objects.get(company=c, id=int(i.get("product_id")))
        except Product.DoesNotExist:
            return JsonError(_("Product with this id does not exist") + " (id=" + i.get("product_id") + ")")

        # parse quantity
        r = parse_decimal(request.user, c, i.get("quantity"), g.DECIMAL["quantity_digits"])
        if not r["success"]:
            return item_error(_("Invalid quantity value"), product)
        else:
            if r["number"] <= Decimal("0"):
                return item_error(_("Cannot add an item with zero or negative quantity"), product)
        quantity = r["number"]

        # remove from stock; TODO: check negative quantities (?)
        # actually we leave negative quantities as they are or
        # when stock is empty, we leave it at 0

        product.destockify(quantity)
        product.save()

        item = {
            "created_by": request.user,
            "code": product.code,
            "shortcut": product.shortcut,
            "name": product.name,
            "description": product.description,
            "private_notes": product.private_notes,
            "unit_type": product.get_unit_type_display(),  # ! display, not the 'code'
            "stock": product.stock,
            # 'bill':  not now, after bill is saved
            "product_id": product.id,
            "bill_notes": i.get("bill_notes"),
            "discounts": [],  # validated discounts (FK in database)
            # prices: will be calculated when discounts are ready
            "base": None,
            "quantity": None,
            "tax_rate": None,
            "batch": None,
            "discount": None,
            "net": None,
            "tax": None,
            "total": None,
        }

        bill["items"].append(item)

        for d in i["discounts"]:
            # check:
            # discount id: if it's -1, it's a unique discount on this item;
            #              if it's anything else, the discount must belong to this company
            #              and must be active and enabled
            d_id = int(d.get("id"))
            if d_id != -1:
                try:
                    dbd = Discount.objects.get(id=d_id, company=c)

                    if not dbd.is_active:
                        return item_error(_("The discount is not active"), product)
                except Discount.DoesNotExist:
                    return item_error(_("Chosen discount does not exist or is not valid"), product)

            # amount: parse number and check that percentage does not exceed 100%
            r = parse_decimal(request.user, c, d.get("amount"))
            if not r["success"]:
                return item_error(_("Invalid discount amount"), product)
            else:
                d_amount = r["number"]
                if d_amount < Decimal(0) or (d.get("type") == "Relative" and d_amount > Decimal(100)):
                    return item_error(_("Invalid discount amount"), product)

            # save data to bill
            discount = {
                "id": d_id,
                "code": d.get("code"),
                "description": d.get("description"),
                "type": d.get("type"),
                "amount": d_amount,
            }
            item["discounts"].append(discount)

        # save this item's prices to item's dictionary (will go into database later)
        try:
            item["base"] = parse_decimal_exc(request.user, c, i.get("base"), message=_("Invalid base price"))
            item["quantity"] = parse_decimal_exc(request.user, c, i.get("quantity"), message=_("Invalid quantity"))
            item["tax_rate"] = parse_decimal_exc(request.user, c, i.get("tax_rate"), message=_("Invalid tax rate"))
            item["batch"] = parse_decimal_exc(request.user, c, i.get("batch"), message=_("Invalid batch price"))
            item["discount"] = parse_decimal_exc(
                request.user, c, i.get("discount"), message=_("Invalid discount amount")
            )
            item["net"] = parse_decimal_exc(request.user, c, i.get("net"), message=_("Invalid net price"))
            item["tax"] = parse_decimal_exc(request.user, c, i.get("tax"), message=_("Invalid tax amount"))
            item["total"] = parse_decimal_exc(request.user, c, i.get("total"), message=_("Invalid total"))

            bill["base"] += item["batch"]
            bill["discount"] += item["discount"]
            bill["tax"] += item["tax"]
        except ValueError as e:
            return item_error(e.message, product)

    # at this point, everything is fine, insert into database
    if existing_bill:
        existing_bill.delete()

    bill_payment = Payment(
        type=g.CASH,
        total=bill["total"],
        currency=get_company_value(request.user, c, "pos_currency"),
        transaction_datetime=datetime.utcnow(),
        status=g.WAITING,
        created_by=request.user,
    )
    bill_payment.save()

    # create a new bill
    db_bill = Bill(
        created_by=request.user,
        company=c,  # current company, FK to Company object
        issuer=bill["issuer"],  # fixed company details at this moment, FK to BillCompany object
        user_id=bill["user_id"],  # id of user that created this bill, just an integer, not a FK
        user_name=bill["user_name"],  # copied user name in case that user gets 'fired'
        register=bill["register"],  # current settings of the register this bill was created on
        contact=bill["contact"],  # FK on BillContact, copy of the Contact object
        notes=bill["notes"],
        # timestamp=dtm.utcnow().replace(tzinfo=timezone(get_company_value(request.user, c, 'pos_timezone'))),
        timestamp=bill["timestamp"],
        payment=bill_payment,
        base=bill["base"],
        discount=bill["discount"],
        tax=bill["tax"],
    )
    db_bill.save()

    # create new items
    for item in bill["items"]:
        db_item = BillItem(
            created_by=item["created_by"],
            code=item["code"],
            shortcut=item["shortcut"],
            name=item["name"],
            description=item["description"],
            private_notes=item["private_notes"],
            unit_type=item["unit_type"],
            bill=db_bill,
            bill_notes=item["bill_notes"],
            product_id=item["product_id"],
            quantity=item["quantity"],
            base=item["base"],
            tax_rate=item["tax_rate"],
            batch=item["batch"],
            discount=item["discount"],
            net=item["net"],
            tax=item["tax"],
            total=item["total"],
        )
        db_item.save()

        # save discounts for this item
        for discount in item["discounts"]:
            db_discount = BillItemDiscount(
                created_by=request.user,
                bill_item=db_item,
                description=discount["description"],
                code=discount["code"],
                type=discount["type"],
                amount=discount["amount"],
            )
            db_discount.save()

    db_bill.save()

    d = {"bill": bill_to_dict(request.user, c, db_bill)}

    return JsonOk(extra=d)
    def handle(self, *args, **options):

        accounts = Account.objects.filter(payment_on_platform=True)

        month, year = get_last_month()

        for account in accounts:

            try:
                logger.info('Next account {} ({}).'.format(
                    account.id, account.get_name()))

                sync_usage_records(account.license)

                record = LicenseRecord.objects.get(license=account.license,
                                                   month=month,
                                                   year=year)

                logger.info('Last month\'s charge {}'.format(record.total_usd))

                details = {}
                for mac, count in record.details.iteritems():
                    details[mac] = [count, count * settings.PRICE_PER_LICENSE]

                payment = Payment(invoice_id=randint(100000000, 999999999),
                                  account=account,
                                  amount=record.total_usd,
                                  details=details,
                                  month=month,
                                  year=year)

                credits = account.credits.filter(expires__gt=timezone.now(),
                                                 remaining_amount__gt=0.00)

                # For now, we only support one valid credit object at a time
                if len(credits) == 1:

                    credit = credits[0]

                    if credit.remaining_amount > record.total_usd:
                        payment.credits_used = record.total_usd
                        credit.remaining_amount = credit.remaining_amount - record.total_usd

                    else:  # credit.remaining_amount <= self.balance:
                        payment.credits_used = credit.remaining_amount
                        credit.remaining_amount = 0.00

                    credit.save()

                payment.save()

                if len(StripeCustomer.objects.filter(account=account)) == 1:

                    customer = stripe.Customer.retrieve(
                        account.stripe.customer_id)
                    card_details = customer.sources.retrieve(
                        customer.default_source)
                    send_summary_email(payment, record, card_details.last4)

                else:
                    send_summary_email(payment, record)

            except ObjectDoesNotExist as e:
                logger.info(
                    'No license record found for account {}, {}'.format(
                        account, e))

            except Exception as e:
                logger.exception(e)
                logger.error('Billing failed: account {}, {}'.format(
                    account, e))
    def post(self, *args, **kwargs):

        form = PaymentForm(self.request.POST)

        userprofile = User.objects.get(user=self.request.user)
        if form.is_valid():
            data = form.cleaned_data
            token = data.get("stripeToken")
            save = data.get("save")
            use_default = data.get("use_default")

            if save:
                if userprofile.customer_id != "" and userprofile.customer_id is not None:
                    customer = stripe.Customer.retrieve(
                        userprofile.customer_id)
                    customer.sources.create(source=token)

                else:
                    customer = stripe.Customer.create(
                        email=self.request.user.email, )
                    customer.sources.create(source=token)
                    userprofile.stripe_customer_id = customer["id"]
                    userprofile.one_click_purchase = True
                    userprofile.save()
            order = Order.objects.get(user=self.request.user, ordered=False)
            amount = int(order.get_total() * 100)

            try:
                if use_default or save:
                    charge = stripe.Charge.create(
                        amount=amount,
                        currency="gbp",
                        customer=userprofile.stripe_customer_id)
                else:
                    charge = stripe.Charge.create(amount=amount,
                                                  currency="gbp",
                                                  source=token)

                payment = Payment()
                payment.stripe_bill_id = charge["id"]
                payment.user = self.request.user
                payment.amt = order.get_total()
                payment.save()

                order_items = order.products.all()
                order_items.update(ordered=True)
                for item in order_items:
                    item.save()

                order.ordered = True
                order.payment = payment
                order.orderid = generate_order_id()
                order.save()

                messages.success(self.request, "Your order was Successful!")
                return redirect("order_confirmation", orderid=order.orderid)

            except stripe.error.CardError as e:
                body = e.json_body
                err = body.get("error", {})
                messages.warning(self.request, f"{err.get('message')}")
                return redirect("/")

            except stripe.error.RateLimitError as e:
                messages.warning(self.request, "Rate limit error")
                return redirect("/")

            except stripe.error.InvalidRequestError as e:
                messages.warning(self.request, "Invalid parameters")
                return redirect("/")

            except stripe.error.AuthenticationError as e:
                messages.warning(self.request, "Not authenticated")
                return redirect("/")

            except stripe.error.APIConnectionError as e:
                messages.warning(self.request, "Network error")
                return redirect("/")

            except stripe.error.StripeError as e:
                messages.warning(
                    self.request,
                    "Something went wrong. Please try again. You haven't been Charged"
                )
                return redirect("/")

            except Exception as e:
                messages.warning(
                    self.request,
                    "A serious issue occurred. We have been notifed.")
                return redirect("/")

        messages.warning(self.request, "Invalid data received")
        return redirect("/payment/stripe/")
Example #16
0
def stripe_webhook(request):
    payload = request.body
    sig_header = request.META['HTTP_STRIPE_SIGNATURE']
    event = None

    try:
        event = stripe.Webhook.construct_event(payload, sig_header,
                                               settings.STRIPE_WEBHOOK_SECRET)
    except ValueError as e:
        # Invalid payload
        return HttpResponse(status=400)
    except stripe.error.SignatureVerificationError as e:
        # Invalid signature
        return HttpResponse(status=400)

    # Handle the checkout.session.completed event
    if event[
            'type'] == 'checkout.session.completed':  # or event['type'] == 'checkout.session.async_payment_succeeded':
        session = event['data']['object']

        # Fulfill the purchase...
        customer_email = session["customer_details"]["email"]
        payment_status = session["payment_status"]
        cacheData = session["metadata"]

        if cacheData and payment_status == 'paid':
            get_session = Session.objects.get(id=cacheData['session_id'])
            patient_email = cacheData['patient_email']
            start_time = cacheData['start_time']
            duration = cacheData['duration']

            try:
                userObject = User.objects.get(email=patient_email)
                patientObject = Patient.objects.get(user=userObject)
            except (User.DoesNotExist, Patient.DoesNotExist):
                # new patient enrolment into the system.
                temp_pass = ''.join(
                    random.choice(string.ascii_uppercase + string.digits)
                    for _ in range(20))
                userObject = createNewUser(patient_email, temp_pass)
                patientObject = createNewPatient(userObject)
                sendMailToNewUser(patient_email, temp_pass)

            if cacheData['consultant'] == 'doctor' and cacheData[
                    'event_type'] == 'single-event':
                doctor = Doctor.objects.get(id=cacheData['consultant_id'])
                new_start_time = datetime.strptime(start_time,
                                                   '%Y-%m-%dT%H:%M:%S')
                new_end_time = new_start_time + timedelta(
                    minutes=int(duration))

                app = Appointment(
                    doctor=doctor,
                    start_time=new_start_time,
                    end_time=new_end_time,
                    session_type=get_session,
                    zoom_link='',
                )
                app.save()
                app.patients.add(patientObject)

            elif cacheData['consultant'] == 'therapist' and cacheData[
                    'event_type'] == 'single-event':
                therapist = Therapist.objects.get(
                    id=cacheData['consultant_id'])
                new_start_time = datetime.strptime(start_time,
                                                   '%Y-%m-%dT%H:%M:%S')
                new_end_time = new_start_time + timedelta(
                    minutes=int(duration))

                app = Appointment(
                    therapist=therapist,
                    start_time=new_start_time,
                    end_time=new_end_time,
                    session_type=get_session,
                    zoom_link='',
                )
                app.save()
                app.patients.add(patientObject)

            elif cacheData['consultant'] == 'doctor' and cacheData[
                    'event_type'] == 'multiple-event':
                doctor = Doctor.objects.get(id=cacheData['consultant_id'])
                start_date_and_time = cacheData['start_time']

                for i in range(int(cacheData['number_of_appointments'])):
                    new_start_time = datetime.strptime(start_date_and_time,
                                                       '%Y-%m-%dT%H:%M:%S')
                    start_dt_for_each_week = new_start_time + timedelta(
                        weeks=i)
                    end_dt_for_each_week = start_dt_for_each_week + timedelta(
                        minutes=int(duration))

                    app = Appointment(
                        doctor=doctor,
                        start_time=start_dt_for_each_week,
                        end_time=end_dt_for_each_week,
                        session_type=get_session,
                        zoom_link='',
                    )
                    app.save()
                    app.patients.add(patientObject)

                    # checking if appointment overlapping.
                    # if Appointment(doctor=doctor, start_time__lt=start_dt_for_each_week, end_time__gt=start_dt_for_each_week).count()>1:
                    # 	print("overlapping")
                    # elif Appointment(doctor=doctor, start_time__lt=end_dt_for_each_week, end_time__gt=end_dt_for_each_week).count()>1:
                    # 	print("overlapping")
                    # elif Appointment(doctor=doctor, start_time__gt=start_dt_for_each_week, end_time__lt=end_dt_for_each_week).count()>1:
                    # 	print("overlapping")
                    # elif Appointment(doctor=doctor, start_time__lt=start_dt_for_each_week, end_time__gt=end_dt_for_each_week).count()>1:
                    # 	print("overlapping")
                    # else:
                    # 	print("clear")

            elif cacheData['consultant'] == 'therapist' and cacheData[
                    'event_type'] == 'multiple-event':
                therapist = Therapist.objects.get(
                    id=cacheData['consultant_id'])
                start_date_and_time = cacheData['start_time']

                for i in range(int(cacheData['number_of_appointments'])):
                    new_start_time = datetime.strptime(start_date_and_time,
                                                       '%Y-%m-%dT%H:%M:%S')
                    start_dt_for_each_week = new_start_time + timedelta(
                        weeks=i)
                    end_dt_for_each_week = start_dt_for_each_week + timedelta(
                        minutes=int(duration))

                    app = Appointment(
                        therapist=therapist,
                        start_time=start_dt_for_each_week,
                        end_time=end_dt_for_each_week,
                        session_type=get_session,
                        zoom_link='',
                    )
                    app.save()
                    app.patients.add(patientObject)

            pay = Payment(user=userObject,
                          payment_status=payment_status.upper(),
                          paymentID=''.join(
                              random.choice(string.ascii_uppercase +
                                            string.digits) for _ in range(10)),
                          session_type=get_session,
                          amount=get_session.get_display_price())
            pay.save()

    # Passed signature verification
    return HttpResponse(status=200)