예제 #1
0
파일: pagseguro.py 프로젝트: b-dev/plata
    def process_order_confirmed(self, request, order):
        PAGSEGURO = settings.PAGSEGURO

        if not order.balance_remaining:
            return self.already_paid(order)

        logger.info("Processing order %s using PagSeguro" % order)

        payment = self.create_pending_payment(order)
        if plata.settings.PLATA_STOCK_TRACKING:
            StockTransaction = plata.stock_model()
            self.create_transactions(
                order,
                _("payment process reservation"),
                type=StockTransaction.PAYMENT_PROCESS_RESERVATION,
                negative=True,
                payment=payment,
            )

        return self.shop.render(
            request,
            "payment/pagseguro_form.html",
            {
                "order": order,
                "payment": payment,
                "HTTP_HOST": request.META.get("HTTP_HOST"),
                "post_url":
                "https://pagseguro.uol.com.br/v2/checkout/payment.html",
                "email": PAGSEGURO["EMAIL"],
            },
        )
예제 #2
0
파일: payson.py 프로젝트: b-dev/plata
    def update_payment(self, payment_details, request):
        order_id, payment_id = payment_details.trackingId.split("-")
        order = plata.shop.models.Order.objects.select_related("payments").get(
            pk=order_id
        )
        if order.status >= plata.shop.models.Order.PAID:
            return order

        payment = order.payments.get(pk=payment_id)
        if payment_details.status not in ("CREATED", "PENDING", "PROCESSING"):
            payment.status = plata.shop.models.OrderPayment.PROCESSED
        payment.currency = payment_details.currencyCode
        payment.amount = payment_details.amount
        payment.data = payment_details.post_data
        payment.transaction_id = payment_details.purchaseId
        payment.payment_method = payment_details.type
        payment.transaction_fee = payment_details.receiverFee
        if payment_details.status == "COMPLETED":
            payment.authorized = timezone.now()
            payment.status = plata.shop.models.OrderPayment.AUTHORIZED
        payment.save()
        order = order.reload()
        if payment.authorized and plata.settings.PLATA_STOCK_TRACKING:
            StockTransaction = plata.stock_model()
            self.create_transactions(
                order,
                _("sale"),
                type=StockTransaction.SALE,
                negative=True,
                payment=payment,
            )
        if not order.balance_remaining:
            self.order_paid(order, payment=payment, request=request)

        return order
예제 #3
0
    def order_payment_failure(self, request):
        """Handles order payment failures"""
        order = self.order_from_request(request)

        logger.warn('Order payment failure for %s' % order.order_id)

        if plata.settings.PLATA_STOCK_TRACKING:
            StockTransaction = plata.stock_model()

            for transaction in order.stock_transactions.filter(
                    type=StockTransaction.PAYMENT_PROCESS_RESERVATION):
                transaction.delete()

        order.payments.pending().delete()

        if order.payments.authorized().exists():
            # There authorized order payments around!
            messages.warning(request, _('Payment failed, please try again.'))
            logger.warn('Order %s is already partially paid, but payment'
                        ' failed anyway!' % order.order_id)
        elif order.status > order.CHECKOUT and order.status < order.PAID:
            order.update_status(
                order.CHECKOUT,
                'Order payment failure, going back to checkout')
            messages.info(
                request,
                _('Payment failed; you can continue editing your order and'
                  ' try again.'))

        return self.render(
            request, self.failure_template,
            self.get_context(request, {
                'order': order,
                'progress': 'failure',
            }))
예제 #4
0
    def process_order_confirmed(self, request, order):
        PAYPAL = settings.PAYPAL

        if not order.balance_remaining:
            return self.already_paid(order)

        logger.info('Processing order %s using Paypal' % order)

        payment = self.create_pending_payment(order)
        if plata.settings.PLATA_STOCK_TRACKING:
            StockTransaction = plata.stock_model()
            self.create_transactions(
                order, _('payment process reservation'),
                type=StockTransaction.PAYMENT_PROCESS_RESERVATION,
                negative=True, payment=payment)

        if PAYPAL['LIVE']:
            PP_URL = "https://www.paypal.com/cgi-bin/webscr"
        else:
            PP_URL = "https://www.sandbox.paypal.com/cgi-bin/webscr"

        return self.shop.render(request, 'payment/%s_form.html' % self.key, {
            'order': order,
            'payment': payment,
            'RETURN_SCHEME': PAYPAL.get(
                'RETURN_SCHEME',
                'https' if request.is_secure() else 'http'
            ),
            'IPN_SCHEME': PAYPAL.get('IPN_SCHEME', 'http'),
            'HTTP_HOST': request.META.get('HTTP_HOST'),
            'post_url': PP_URL,
            'business': PAYPAL['BUSINESS'],
        })
예제 #5
0
파일: base.py 프로젝트: pingyangtiaer/plata
    def create_transactions(self, order, stage, **kwargs):
        """
        Create transactions for all order items. The real work is offloaded
        to ``StockTransaction.objects.bulk_create``.
        """

        if not plata.settings.PLATA_STOCK_TRACKING:
            warnings.warn(
                'StockTransaction.objects.create_transactions'
                ' currently has no effect when PLATA_STOCK_TRACKING = False.'
                ' This will change in the future. Change your code to only'
                ' call create_transactions when'
                ' plata.settings.PLATA_STOCK_TRACKING = True',
                DeprecationWarning,
                stacklevel=2)
            return
        StockTransaction = plata.stock_model()
        StockTransaction.objects.bulk_create(
            order,
            notes=_('%(stage)s: %(order)s processed by %(payment_module)s') % {
                'stage': stage,
                'order': order,
                'payment_module': self.name,
            },
            **kwargs)
예제 #6
0
    def create_transactions(self, order, stage, **kwargs):
        """
        Create transactions for all order items. The real work is offloaded
        to ``StockTransaction.objects.bulk_create``.
        """

        if not plata.settings.PLATA_STOCK_TRACKING:
            warnings.warn(
                "StockTransaction.objects.create_transactions"
                " currently has no effect when PLATA_STOCK_TRACKING = False."
                " This will change in the future. Change your code to only"
                " call create_transactions when"
                " plata.settings.PLATA_STOCK_TRACKING = True",
                DeprecationWarning,
                stacklevel=2,
            )
            return
        StockTransaction = plata.stock_model()
        StockTransaction.objects.bulk_create(
            order,
            notes=_("%(stage)s: %(order)s processed by %(payment_module)s") % {
                "stage": stage,
                "order": order,
                "payment_module": self.name
            },
            **kwargs)
예제 #7
0
파일: cod.py 프로젝트: b-dev/plata
    def process_order_confirmed(self, request, order):
        if not order.balance_remaining:
            return self.already_paid(order, request=request)

        logger.info("Processing order %s using COD" % order)

        payment = self.create_pending_payment(order)

        payment.status = OrderPayment.AUTHORIZED
        payment.authorized = timezone.now()
        payment.save()
        order = order.reload()

        if plata.settings.PLATA_STOCK_TRACKING:
            StockTransaction = plata.stock_model()
            self.create_transactions(
                order,
                _("sale"),
                type=StockTransaction.SALE,
                negative=True,
                payment=payment,
            )
        self.order_paid(order, payment=payment, request=request)

        return self.shop.redirect("plata_order_success")
예제 #8
0
파일: ogone.py 프로젝트: fsw/plata
    def process_order_confirmed(self, request, order):
        OGONE = settings.OGONE

        if not order.balance_remaining:
            return self.already_paid(order)

        logger.info('Processing order %s using Ogone' % order)

        payment = self.create_pending_payment(order)
        if plata.settings.PLATA_STOCK_TRACKING:
            StockTransaction = plata.stock_model()
            self.create_transactions(order, _('payment process reservation'),
                type=StockTransaction.PAYMENT_PROCESS_RESERVATION,
                negative=True, payment=payment)

        # params that will be hashed
        form_params = {
            'PSPID': OGONE['PSPID'],
            'orderID': 'Order-%d-%d' % (order.id, payment.id),
            'amount': u'%s' % int(order.balance_remaining.quantize(Decimal('0.00'))*100),
            'currency': order.currency,
            'language': locale.normalize(to_locale(get_language())).split('.')[0],
            'CN': u'%s %s' % (order.billing_first_name, order.billing_last_name),
            'EMAIL': order.email,
            'ownerZIP': order.billing_zip_code,
            'owneraddress': order.billing_address,
            'ownertown': order.billing_city,
            'accepturl': u'http://%s%s' % (
                request.META.get('HTTP_HOST'),
                reverse('plata_order_success')),
            'declineurl': u'http://%s%s' % (
                request.META.get('HTTP_HOST'),
                reverse('plata_order_payment_failure')),
            'exceptionurl': u'http://%s%s' % (
                request.META.get('HTTP_HOST'),
                reverse('plata_order_payment_failure')),
            'cancelurl': u'http://%s%s' % (
                request.META.get('HTTP_HOST'),
                reverse('plata_order_payment_failure')),
        }
        # create hash
        value_strings = [u'{0}={1}{2}'.format(key.upper(), value, OGONE['SHA1_IN'])
                            for key, value in form_params.items()]
        hash_string = u''.join(sorted(value_strings))
        encoded_hash_string = sha1(hash_string.encode('utf-8')).hexdigest()

        # add hash and additional params
        form_params.update({
            'SHASign': encoded_hash_string.upper(),
            'mode': OGONE['LIVE'] and 'prod' or 'test',
        })

        return self.shop.render(request, 'payment/ogone_form.html', {
            'order': order,
            'HTTP_HOST': request.META.get('HTTP_HOST'),
            'form_params': form_params,
            'locale': form_params['language'],
            })
예제 #9
0
 def reserve_stock_item(self, order, payment):
     if plata.settings.PLATA_STOCK_TRACKING:
         StockTransaction = plata.stock_model()
         self.create_transactions(
             order,
             _("payment process reservation"),
             type=StockTransaction.PAYMENT_PROCESS_RESERVATION,
             negative=True,
             payment=payment,
         )
예제 #10
0
파일: postfinance.py 프로젝트: b-dev/plata
    def process_order_confirmed(self, request, order):
        POSTFINANCE = settings.POSTFINANCE

        if not order.balance_remaining:
            return self.already_paid(order, request=request)

        logger.info("Processing order %s using Postfinance" % order)

        payment = self.create_pending_payment(order)
        if plata.settings.PLATA_STOCK_TRACKING:
            StockTransaction = plata.stock_model()
            self.create_transactions(
                order,
                _("payment process reservation"),
                type=StockTransaction.PAYMENT_PROCESS_RESERVATION,
                negative=True,
                payment=payment,
            )

        form_params = {
            "orderID":
            "Order-%d-%d" % (order.id, payment.id),
            "amount":
            "%s" %
            int(order.balance_remaining.quantize(Decimal("0.00")) * 100),
            "currency":
            order.currency,
            "PSPID":
            POSTFINANCE["PSPID"],
            "mode":
            POSTFINANCE["LIVE"] and "prod" or "test",
        }

        form_params["SHASign"] = sha1(("".join((
            form_params["orderID"],
            form_params["amount"],
            form_params["currency"],
            form_params["PSPID"],
            POSTFINANCE["SHA1_IN"],
        ))).encode("utf-8")).hexdigest()

        return self.shop.render(
            request,
            "payment/%s_form.html" % self.key,
            {
                "order":
                order,
                "HTTP_HOST":
                request.get_host(),
                "form_params":
                form_params,
                "locale":
                locale.normalize(to_locale(get_language())).split(".")[0],
            },
        )
예제 #11
0
파일: stripe.py 프로젝트: b-dev/plata
    def process_order_confirmed(self, request, order):
        STRIPE = settings.STRIPE
        stripe.api_key = STRIPE["SECRET_KEY"]
        if "template" in STRIPE:
            self.template = STRIPE["template"]
        self.amount = 0

        if not order.balance_remaining:
            return self.already_paid(order, request=request)

        logger.info("Processing order %s using %s" %
                    (order, self.default_name))

        payment = self.create_pending_payment(order)
        if plata.settings.PLATA_STOCK_TRACKING:
            StockTransaction = plata.stock_model()
            self.create_transactions(
                order,
                _("payment process reservation"),
                type=StockTransaction.PAYMENT_PROCESS_RESERVATION,
                negative=True,
                payment=payment,
            )

        for item in order.items.all():
            itemsum = 0
            if item.unit_price != item.line_item_discount:
                itemsum = item.unit_price
                if item.line_item_discount:
                    itemsum -= item.line_item_discount
            self.amount += itemsum * item.quantity
        self.amount += order.shipping
        if order.currency not in plata.settings.CURRENCIES_WITHOUT_CENTS:
            # only if currency has cents; Stripe takes only integer values
            # keyword zero-decimal currencies
            self.amount = int(self.amount * 100)

        self.order = order

        return self.shop.render(
            request,
            self.template,
            {
                "order": order,
                "payment": payment,
                "post_url":
                "/payment/%s/" % self.key,  # internal, gets payment token
                "amount": self.amount,
                "currency": order.currency.lower(),
                "public_key": STRIPE["PUBLIC_KEY"],
                "name": get_current_site(request).name,
                "description": _("Order %s") % order,
                "logo": STRIPE["LOGO"],
            },
        )
예제 #12
0
    def clear_pending_payments(self, order):
        """
        Clear pending payments
        """
        logger.info('Clearing pending payments on %s' % order)
        if plata.settings.PLATA_STOCK_TRACKING:
            StockTransaction = plata.stock_model()
            for transaction in order.stock_transactions.filter(
                    type=StockTransaction.PAYMENT_PROCESS_RESERVATION):
                transaction.delete()

        order.payments.pending().delete()
예제 #13
0
파일: base.py 프로젝트: pingyangtiaer/plata
    def clear_pending_payments(self, order):
        """
        Clear pending payments
        """
        logger.info('Clearing pending payments on %s' % order)
        if plata.settings.PLATA_STOCK_TRACKING:
            StockTransaction = plata.stock_model()
            for transaction in order.stock_transactions.filter(
                    type=StockTransaction.PAYMENT_PROCESS_RESERVATION):
                transaction.delete()

        order.payments.pending().delete()
예제 #14
0
    def process_order_confirmed(self, request, order):
        POSTFINANCE = settings.POSTFINANCE

        if not order.balance_remaining:
            return self.already_paid(order)

        logger.info('Processing order %s using Postfinance' % order)

        payment = self.create_pending_payment(order)
        if plata.settings.PLATA_STOCK_TRACKING:
            StockTransaction = plata.stock_model()
            self.create_transactions(
                order,
                _('payment process reservation'),
                type=StockTransaction.PAYMENT_PROCESS_RESERVATION,
                negative=True,
                payment=payment)

        form_params = {
            'orderID':
            'Order-%d-%d' % (order.id, payment.id),
            'amount':
            u'%s' %
            int(order.balance_remaining.quantize(Decimal('0.00')) * 100),
            'currency':
            order.currency,
            'PSPID':
            POSTFINANCE['PSPID'],
            'mode':
            POSTFINANCE['LIVE'] and 'prod' or 'test',
        }

        form_params['SHASign'] = sha1(u''.join((
            form_params['orderID'],
            form_params['amount'],
            form_params['currency'],
            form_params['PSPID'],
            POSTFINANCE['SHA1_IN'],
        ))).hexdigest()

        return self.shop.render(
            request, 'payment/%s_form.html' % self.key, {
                'order':
                order,
                'HTTP_HOST':
                request.META.get('HTTP_HOST'),
                'form_params':
                form_params,
                'locale':
                locale.normalize(to_locale(get_language())).split('.')[0],
            })
예제 #15
0
파일: views.py 프로젝트: b-dev/plata
    def order_payment_failure(self, request):
        """Handles order payment failures"""
        order = self.order_from_request(request)

        if not order:
            messages.info(
                request,
                _("Payment failed and order could not be found anymore. Sorry."
                  ),
            )
            return self.redirect("plata_shop_cart")

        logger.warn("Order payment failure for %s" % order.order_id)

        if plata.settings.PLATA_STOCK_TRACKING:
            StockTransaction = plata.stock_model()

            for transaction in order.stock_transactions.filter(
                    type=StockTransaction.PAYMENT_PROCESS_RESERVATION):
                transaction.delete()

        order.payments.pending().delete()

        if order.payments.authorized().exists():
            # There authorized order payments around!
            messages.warning(request, _("Payment failed, please try again."))
            logger.warn("Order %s is already partially paid, but payment"
                        " failed anyway!" % order.order_id)
        elif order.status > order.CHECKOUT and order.status < order.PAID:
            order.update_status(
                order.CHECKOUT,
                "Order payment failure, going back to checkout")
            messages.info(
                request,
                _("Payment failed; you can continue editing your order and"
                  " try again."),
            )

        return self.render(
            request,
            self.failure_template,
            self.get_context(request, {
                "order": order,
                "progress": "failure"
            }),
        )
예제 #16
0
파일: paypal.py 프로젝트: b-dev/plata
    def process_order_confirmed(self, request, order):
        PAYPAL = settings.PAYPAL

        if not order.balance_remaining:
            return self.already_paid(order, request=request)

        logger.info("Processing order %s using Paypal" % order)

        payment = self.create_pending_payment(order)
        if plata.settings.PLATA_STOCK_TRACKING:
            StockTransaction = plata.stock_model()
            self.create_transactions(
                order,
                _("payment process reservation"),
                type=StockTransaction.PAYMENT_PROCESS_RESERVATION,
                negative=True,
                payment=payment,
            )

        if PAYPAL["LIVE"]:
            PP_URL = "https://www.paypal.com/cgi-bin/webscr"
        else:
            PP_URL = "https://www.sandbox.paypal.com/cgi-bin/webscr"

        return self.shop.render(
            request,
            "payment/%s_form.html" % self.key,
            {
                "order":
                order,
                "payment":
                payment,
                "RETURN_SCHEME":
                PAYPAL.get("RETURN_SCHEME",
                           "https" if request.is_secure() else "http"),
                "IPN_SCHEME":
                PAYPAL.get("IPN_SCHEME", "http"),
                "HTTP_HOST":
                request.get_host(),
                "post_url":
                PP_URL,
                "business":
                PAYPAL["BUSINESS"],
            },
        )
예제 #17
0
    def process_order_confirmed(self, request, order):
        if not order.balance_remaining:
            return self.already_paid(order)

        logger.info('Processing order %s using CASH' % order)

        payment = self.create_pending_payment(order)

        payment.status = OrderPayment.PROCESSED
        payment.save()
        order = order.reload()

        if plata.settings.PLATA_STOCK_TRACKING:
            StockTransaction = plata.stock_model()
            self.create_transactions(
                order, _('sale'),
                type=StockTransaction.SALE, negative=True, payment=payment)

        return self.shop.redirect('plata_order_success')
예제 #18
0
파일: base.py 프로젝트: fsw/plata
    def already_paid(self, order):
        """
        Handles the case where a payment module is selected but the order
        is already completely paid for (f.e. because an amount discount has
        been used which covers the order).

        Does nothing if the order **status** is ``PAID`` already.
        """
        if order.status < order.PAID:
            logger.info('Order %s is already completely paid' % order)

            if plata.settings.PLATA_STOCK_TRACKING:
                StockTransaction = plata.stock_model()
                self.create_transactions(order, _('sale'),
                    type=StockTransaction.SALE, negative=True)

            self.order_paid(order)

        return self.shop.redirect('plata_order_success')
예제 #19
0
def product_xls():
    """
    Create a list of all product variations, including stock and aggregated
    stock transactions (by type)
    """

    from plata.product.stock.models import Period
    StockTransaction = plata.stock_model()

    xls = XLSDocument()
    xls.add_sheet(capfirst(_('products')))

    _transactions = StockTransaction.objects.filter(
        period=Period.objects.current(),
        ).order_by().values('product', 'type').annotate(Sum('change'))

    transactions = defaultdict(dict)
    for t in _transactions:
        transactions[t['product']][t['type']] = t['change__sum']

    titles = [
        capfirst(_('product')),
        _('SKU'),
        capfirst(_('stock')),
    ]
    titles.extend(
        unicode(name) for key, name in StockTransaction.TYPE_CHOICES)

    data = []

    for product in plata.product_model().objects.all().select_related():
        row = [
            product,
            getattr(product, 'sku', ''),
            getattr(product, 'items_in_stock', -1),
            ]
        row.extend(
            transactions[product.id].get(key, '')
            for key, name in StockTransaction.TYPE_CHOICES)
        data.append(row)

    xls.table(titles, data)
    return xls
예제 #20
0
파일: product.py 프로젝트: b-dev/plata
def product_xls():
    """
    Create a list of all product variations, including stock and aggregated
    stock transactions (by type)
    """

    from plata.product.stock.models import Period

    StockTransaction = plata.stock_model()

    xls = XLSXDocument()
    xls.add_sheet(capfirst(_("products")))

    _transactions = (
        StockTransaction.objects.filter(period=Period.objects.current())
        .order_by()
        .values("product", "type")
        .annotate(Sum("change"))
    )

    transactions = defaultdict(dict)
    for t in _transactions:
        transactions[t["product"]][t["type"]] = t["change__sum"]

    titles = [capfirst(_("product")), _("SKU"), capfirst(_("stock"))]
    titles.extend("%s" % row[1] for row in StockTransaction.TYPE_CHOICES)

    data = []

    for product in plata.product_model().objects.all().select_related():
        row = [
            product,
            getattr(product, "sku", ""),
            getattr(product, "items_in_stock", -1),
        ]
        row.extend(
            transactions[product.id].get(key, "")
            for key, name in StockTransaction.TYPE_CHOICES
        )
        data.append(row)

    xls.table(titles, data)
    return xls
예제 #21
0
def product_xls():
    """
    Create a list of all product variations, including stock and aggregated
    stock transactions (by type)
    """

    from plata.product.stock.models import Period
    StockTransaction = plata.stock_model()

    xls = XLSDocument()
    xls.add_sheet(capfirst(_('products')))

    _transactions = StockTransaction.objects.filter(
        period=Period.objects.current(), ).order_by().values(
            'product', 'type').annotate(Sum('change'))

    transactions = defaultdict(dict)
    for t in _transactions:
        transactions[t['product']][t['type']] = t['change__sum']

    titles = [
        capfirst(_('product')),
        _('SKU'),
        capfirst(_('stock')),
    ]
    titles.extend('%s' % row[1] for row in StockTransaction.TYPE_CHOICES)

    data = []

    for product in plata.product_model().objects.all().select_related():
        row = [
            product,
            getattr(product, 'sku', ''),
            getattr(product, 'items_in_stock', -1),
        ]
        row.extend(transactions[product.id].get(key, '')
                   for key, name in StockTransaction.TYPE_CHOICES)
        data.append(row)

    xls.table(titles, data)
    return xls
예제 #22
0
    def process_order_confirmed(self, request, order):
        PAYPAL = settings.PAYPAL

        if not order.balance_remaining:
            return self.already_paid(order)

        logger.info('Processing order %s using Paypal' % order)

        payment = self.create_pending_payment(order)
        if plata.settings.PLATA_STOCK_TRACKING:
            StockTransaction = plata.stock_model()
            self.create_transactions(
                order,
                _('payment process reservation'),
                type=StockTransaction.PAYMENT_PROCESS_RESERVATION,
                negative=True,
                payment=payment)

        if PAYPAL['LIVE']:
            PP_URL = "https://www.paypal.com/cgi-bin/webscr"
        else:
            PP_URL = "https://www.sandbox.paypal.com/cgi-bin/webscr"

        return self.shop.render(
            request, 'payment/%s_form.html' % self.key, {
                'order':
                order,
                'payment':
                payment,
                'RETURN_SCHEME':
                PAYPAL.get('RETURN_SCHEME',
                           'https' if request.is_secure() else 'http'),
                'IPN_SCHEME':
                PAYPAL.get('IPN_SCHEME', 'http'),
                'HTTP_HOST':
                request.META.get('HTTP_HOST'),
                'post_url':
                PP_URL,
                'business':
                PAYPAL['BUSINESS'],
            })
예제 #23
0
파일: base.py 프로젝트: pingyangtiaer/plata
    def already_paid(self, order):
        """
        Handles the case where a payment module is selected but the order
        is already completely paid for (f.e. because an amount discount has
        been used which covers the order).

        Does nothing if the order **status** is ``PAID`` already.
        """
        if order.status < order.PAID:
            logger.info('Order %s is already completely paid' % order)

            if plata.settings.PLATA_STOCK_TRACKING:
                StockTransaction = plata.stock_model()
                self.create_transactions(order,
                                         _('sale'),
                                         type=StockTransaction.SALE,
                                         negative=True)

            self.order_paid(order)

        return self.shop.redirect('plata_order_success')
예제 #24
0
    def process_order_confirmed(self, request, order):
        POSTFINANCE = settings.POSTFINANCE

        if not order.balance_remaining:
            return self.already_paid(order)

        logger.info('Processing order %s using Postfinance' % order)

        payment = self.create_pending_payment(order)
        if plata.settings.PLATA_STOCK_TRACKING:
            StockTransaction = plata.stock_model()
            self.create_transactions(
                order, _('payment process reservation'),
                type=StockTransaction.PAYMENT_PROCESS_RESERVATION,
                negative=True, payment=payment)

        form_params = {
            'orderID': 'Order-%d-%d' % (order.id, payment.id),
            'amount': u'%s' % int(
                order.balance_remaining.quantize(Decimal('0.00')) * 100),
            'currency': order.currency,
            'PSPID': POSTFINANCE['PSPID'],
            'mode': POSTFINANCE['LIVE'] and 'prod' or 'test',
        }

        form_params['SHASign'] = sha1(u''.join((
            form_params['orderID'],
            form_params['amount'],
            form_params['currency'],
            form_params['PSPID'],
            POSTFINANCE['SHA1_IN'],
        ))).hexdigest()

        return self.shop.render(request, 'payment/%s_form.html' % self.key, {
            'order': order,
            'HTTP_HOST': request.META.get('HTTP_HOST'),
            'form_params': form_params,
            'locale': locale.normalize(
                to_locale(get_language())).split('.')[0],
        })
예제 #25
0
    def order_payment_failure(self, request):
        """Handles order payment failures"""
        order = self.order_from_request(request)

        logger.warn('Order payment failure for %s' % order.order_id)

        if plata.settings.PLATA_STOCK_TRACKING:
            StockTransaction = plata.stock_model()

            for transaction in order.stock_transactions.filter(
                    type=StockTransaction.PAYMENT_PROCESS_RESERVATION):
                transaction.delete()

        order.payments.pending().delete()

        if order.payments.authorized().exists():
            # There authorized order payments around!
            messages.warning(request, _('Payment failed, please try again.'))
            logger.warn(
                'Order %s is already partially paid, but payment'
                ' failed anyway!' % order.order_id)
        elif order.status > order.CHECKOUT and order.status < order.PAID:
            order.update_status(
                order.CHECKOUT,
                'Order payment failure, going back to checkout')
            messages.info(request, _(
                'Payment failed; you can continue editing your order and'
                ' try again.'))

        return self.render(
            request,
            self.failure_template,
            self.get_context(
                request, {
                    'order': order,
                    'progress': 'failure',
                }
            )
        )
예제 #26
0
파일: base.py 프로젝트: fsw/plata
    def create_transactions(self, order, stage, **kwargs):
        """
        Create transactions for all order items. The real work is offloaded
        to ``StockTransaction.objects.bulk_create``.
        """

        if not plata.settings.PLATA_STOCK_TRACKING:
            warnings.warn('StockTransaction.objects.create_transactions'
                ' currently has no effect when PLATA_STOCK_TRACKING = False.'
                ' This will change in the future. Change your code to only'
                ' call create_transactions when'
                ' plata.settings.PLATA_STOCK_TRACKING = True',
                DeprecationWarning, stacklevel=2)
            return
        StockTransaction = plata.stock_model()
        StockTransaction.objects.bulk_create(order,
            notes=_('%(stage)s: %(order)s processed by %(payment_module)s') %{
                'stage': stage,
                'order': order,
                'payment_module': self.name,
                },
            **kwargs)
예제 #27
0
    def process_order_confirmed(self, request, order):
        DATATRANS = settings.DATATRANS

        if not order.balance_remaining:
            return self.already_paid(order, request=request)

        logger.info("Processing order %s using Datatrans" % order)

        payment = self.create_pending_payment(order)
        if plata.settings.PLATA_STOCK_TRACKING:
            StockTransaction = plata.stock_model()
            self.create_transactions(
                order,
                _("payment process reservation"),
                type=StockTransaction.PAYMENT_PROCESS_RESERVATION,
                negative=True,
                payment=payment,
            )

        if DATATRANS.get("LIVE", True):
            DT_URL = "https://payment.datatrans.biz/upp/jsp/upStart.jsp"
        else:
            DT_URL = "https://pilot.datatrans.biz/upp/jsp/upStart.jsp"

        return render(
            request,
            "payment/datatrans_form.html",
            {
                "order": order,
                "total_in_smallest_unit":
                payment.amount * SMALLEST_UNIT_FACTOR,
                "payment": payment,
                "HTTP_HOST": request.META.get("HTTP_HOST"),
                "post_url": DT_URL,
                "MERCHANT_ID": DATATRANS["MERCHANT_ID"],
            },
        )
예제 #28
0
    def ipn(self, request):
        if not request._read_started:
            if 'windows-1252' in request.body:
                if request.encoding != 'windows-1252':
                    request.encoding = 'windows-1252'
        else:  # middleware (or something else?) has triggered request reading
            if request.POST.get('charset') == 'windows-1252':
                if request.encoding != 'windows-1252':
                    # since the POST data has already been accessed,
                    # unicode characters may have already been lost and
                    # cannot be re-encoded.
                    # -- see https://code.djangoproject.com/ticket/14035
                    # Unfortunately, PayPal:
                    # a) defaults to windows-1252 encoding (why?!)
                    # b) doesn't indicate this in the Content-Type header
                    #    so Django cannot automatically detect it.
                    logger.warning(
                        'IPN received with charset=windows1252, however '
                        'the request encoding does not match. It may be '
                        'impossible to verify this IPN if the data contains '
                        'non-ASCII characters. Please either '
                        'a) update your PayPal preferences to use UTF-8 '
                        'b) configure your site so that IPN requests are '
                        'not ready before they reach the hanlder'
                    )

        PAYPAL = settings.PAYPAL

        if PAYPAL['LIVE']:
            PP_URL = "https://www.paypal.com/cgi-bin/webscr"
        else:
            PP_URL = "https://www.sandbox.paypal.com/cgi-bin/webscr"

        parameters = None

        try:
            parameters = request.POST.copy()
            parameters_repr = repr(parameters).encode('utf-8')

            if parameters:
                logger.info(
                    'IPN: Processing request data %s' % parameters_repr)

                querystring = 'cmd=_notify-validate&%s' % (
                    request.POST.urlencode()
                )
                status = urllib2.urlopen(PP_URL, querystring).read()

                if not status == "VERIFIED":
                    logger.error(
                        'IPN: Received status %s, '
                        'could not verify parameters %s' % (
                            status,
                            parameters_repr
                        )
                    )
                    logger.debug('Destination: %r ? %r', PP_URL, querystring)
                    logger.debug('Request: %r', request)
                    return HttpResponseForbidden('Unable to verify')

            if parameters:
                logger.info('IPN: Verified request %s' % parameters_repr)
                reference = parameters['txn_id']
                invoice_id = parameters['invoice']
                currency = parameters['mc_currency']
                amount = parameters['mc_gross']

                try:
                    order, order_id, payment_id = invoice_id.split('-')
                except ValueError:
                    logger.error(
                        'IPN: Error getting order for %s' % invoice_id)
                    return HttpResponseForbidden('Malformed order ID')

                try:
                    order = self.shop.order_model.objects.get(pk=order_id)
                except (self.shop.order_model.DoesNotExist, ValueError):
                    logger.error('IPN: Order %s does not exist' % order_id)
                    return HttpResponseForbidden(
                        'Order %s does not exist' % order_id)

                try:
                    payment = order.payments.get(pk=payment_id)
                except (order.payments.model.DoesNotExist, ValueError):
                    payment = order.payments.model(
                        order=order,
                        payment_module=u'%s' % self.name,
                    )

                payment.status = OrderPayment.PROCESSED
                payment.currency = currency
                payment.amount = Decimal(amount)
                payment.data = request.POST.copy()
                payment.transaction_id = reference
                payment.payment_method = payment.payment_module

                if parameters['payment_status'] == 'Completed':
                    payment.authorized = timezone.now()
                    payment.status = OrderPayment.AUTHORIZED

                payment.save()
                order = order.reload()

                logger.info(
                    'IPN: Successfully processed IPN request for %s' % order)

                if payment.authorized and plata.settings.PLATA_STOCK_TRACKING:
                    StockTransaction = plata.stock_model()
                    self.create_transactions(
                        order,
                        _('sale'),
                        type=StockTransaction.SALE,
                        negative=True,
                        payment=payment)

                if not order.balance_remaining:
                    self.order_paid(order, payment=payment, request=request)

                return HttpResponse("Ok")

        except Exception, e:
            logger.error('IPN: Processing failure %s' % unicode(e))
            raise
예제 #29
0
    def process_order_confirmed(self, request, order):
        OGONE = settings.OGONE

        if not order.balance_remaining:
            return self.already_paid(order, request=request)

        logger.info("Processing order %s using Ogone" % order)

        payment = self.create_pending_payment(order)
        if plata.settings.PLATA_STOCK_TRACKING:
            StockTransaction = plata.stock_model()
            self.create_transactions(
                order,
                _("payment process reservation"),
                type=StockTransaction.PAYMENT_PROCESS_RESERVATION,
                negative=True,
                payment=payment,
            )

        # params that will be hashed
        form_params = {
            "PSPID":
            OGONE["PSPID"],
            "orderID":
            "Order-%d-%d" % (order.id, payment.id),
            "amount":
            "%s" %
            int(order.balance_remaining.quantize(Decimal("0.00")) * 100),
            "currency":
            order.currency,
            "language":
            locale.normalize(to_locale(get_language())).split(".")[0],
            "CN":
            "%s %s" % (order.billing_first_name, order.billing_last_name),
            "EMAIL":
            order.email,
            "ownerZIP":
            order.billing_zip_code,
            "owneraddress":
            order.billing_address,
            "ownertown":
            order.billing_city,
            "accepturl":
            "http://%s%s" %
            (request.get_host(), reverse("plata_order_success")),
            "declineurl":
            "http://%s%s" %
            (request.get_host(), reverse("plata_order_payment_failure")),
            "exceptionurl":
            "http://%s%s" %
            (request.get_host(), reverse("plata_order_payment_failure")),
            "cancelurl":
            "http://%s%s" %
            (request.get_host(), reverse("plata_order_payment_failure")),
        }
        # create hash
        value_strings = [
            "{0}={1}{2}".format(key.upper(), value, OGONE["SHA1_IN"])
            for key, value in form_params.items()
        ]
        hash_string = "".join(sorted(value_strings))
        encoded_hash_string = sha1(hash_string.encode("utf-8")).hexdigest()

        # add hash and additional params
        form_params.update({
            "SHASign": encoded_hash_string.upper(),
            "mode": OGONE["LIVE"] and "prod" or "test",
        })

        return self.shop.render(
            request,
            "payment/%s_form.html" % self.key,
            {
                "order": order,
                "HTTP_HOST": request.get_host(),
                "form_params": form_params,
                "locale": form_params["language"],
            },
        )
예제 #30
0
    def process_order_confirmed(self, request, order):
        if not order.balance_remaining:
            return self.already_paid(order)

        logger.info(
            "Processing order %s using bank transfer in advance (prepay)" %
            order)

        payment = self.create_pending_payment(order)

        order.notes = str(uuid4())
        order.save()

        if plata.settings.PLATA_STOCK_TRACKING:
            StockTransaction = plata.stock_model()
            self.create_transactions(
                order,
                _("sale"),
                type=StockTransaction.SALE,
                negative=True,
                payment=payment,
            )
        current_site = Site.objects.get_current()
        confirm_link = "https://%s%s" % (
            current_site.domain,
            reverse("plata_payment_prepay_confirm",
                    kwargs={"uuid": order.notes}),
        )
        message = _(
            """The order %(order)s has been confirmed for bank transfer in advance.

Customer: %(first_name)s %(last_name)s <%(email)s>

Items: %(items)s

Amount due: %(remaining)s %(currency)s

Click on this link when the payment is received: %(confirm_link)s
""" % {
                "order": order,
                "first_name": order.user.first_name,
                "last_name": order.user.last_name,
                "email": order.email,
                "items": ", ".join(
                    ("%s" % item) for item in order.items.all()),
                "remaining": order.balance_remaining,
                "currency": order.currency,
                "confirm_link": confirm_link,
            })

        try:
            notification_emails = settings.PLATA_PAYMENT_PREPAY_NOTIFICATIONS.get(
                order.currency)
        except KeyError:
            notification_emails = settings.PLATA_PAYMENT_PREPAY_NOTIFICATIONS
        except AttributeError:
            raise Exception(
                _("Configure the notification emails in the"
                  " PLATA_PAYMENT_PREPAY_NOTIFICATIONS setting"))

        send_mail(
            _(
                "%(prefix)sNew order on bank transfer (%(order)s)" % {
                    "prefix": getattr(settings, "EMAIL_SUBJECT_PREFIX", ""),
                    "order": order,
                }),
            message,
            settings.SERVER_EMAIL,
            notification_emails,
        )

        return self.shop.render(
            request,
            "payment/prepay_informations.html",
            {
                "order": order,
                "payment": payment,
                "HTTP_HOST": request.META.get("HTTP_HOST"),
            },
        )
예제 #31
0
    def ipn(self, request):
        if not request._read_started:
            if "windows-1252" in request.body.decode("windows-1252", "ignore"):
                if request.encoding != "windows-1252":
                    request.encoding = "windows-1252"
        else:  # middleware (or something else?) has triggered request reading
            if request.POST.get("charset") == "windows-1252":
                if request.encoding != "windows-1252":
                    # since the POST data has already been accessed,
                    # unicode characters may have already been lost and
                    # cannot be re-encoded.
                    # -- see https://code.djangoproject.com/ticket/14035
                    # Unfortunately, PayPal:
                    # a) defaults to windows-1252 encoding (why?!)
                    # b) doesn't indicate this in the Content-Type header
                    #    so Django cannot automatically detect it.
                    logger.warning(
                        "IPN received with charset=windows1252, however "
                        "the request encoding does not match. It may be "
                        "impossible to verify this IPN if the data contains "
                        "non-ASCII characters. Please either "
                        "a) update your PayPal preferences to use UTF-8 "
                        "b) configure your site so that IPN requests are "
                        "not ready before they reach the handler"
                    )

        PAYPAL = settings.PAYPAL

        if PAYPAL["LIVE"]:
            PP_URL = "https://www.paypal.com/cgi-bin/webscr"
        else:
            PP_URL = "https://www.sandbox.paypal.com/cgi-bin/webscr"

        parameters = None

        try:
            parameters = request.POST.copy()
            parameters_repr = repr(parameters).encode("utf-8")

            if parameters:
                logger.info("IPN: Processing request data %s" % parameters_repr)

                querystring = "cmd=_notify-validate&%s" % (request.POST.urlencode())
                status = urlopen(PP_URL, querystring).read()

                if not status == b"VERIFIED":
                    logger.error(
                        "IPN: Received status %s, "
                        "could not verify parameters %s" % (status, parameters_repr)
                    )
                    logger.debug("Destination: %r ? %r", PP_URL, querystring)
                    logger.debug("Request: %r", request)
                    return HttpResponseForbidden("Unable to verify")

            if parameters:
                logger.info("IPN: Verified request %s" % parameters_repr)
                reference = parameters["txn_id"]
                invoice_id = parameters["invoice"]
                currency = parameters["mc_currency"]
                amount = parameters["mc_gross"]

                try:
                    order, order_id, payment_id = invoice_id.split("-")
                except ValueError:
                    logger.error("IPN: Error getting order for %s" % invoice_id)
                    return HttpResponseForbidden("Malformed order ID")

                try:
                    order = self.shop.order_model.objects.get(pk=order_id)
                except (self.shop.order_model.DoesNotExist, ValueError):
                    logger.error("IPN: Order %s does not exist" % order_id)
                    return HttpResponseForbidden("Order %s does not exist" % order_id)

                try:
                    payment = order.payments.get(pk=payment_id)
                except (order.payments.model.DoesNotExist, ValueError):
                    payment = order.payments.model(
                        order=order, payment_module="%s" % self.name
                    )

                payment.status = OrderPayment.PROCESSED
                payment.currency = currency
                payment.amount = Decimal(amount)
                payment.data = request.POST.copy()
                payment.transaction_id = reference
                payment.payment_method = payment.payment_module

                if parameters["payment_status"] == "Completed":
                    payment.authorized = timezone.now()
                    payment.status = OrderPayment.AUTHORIZED

                payment.save()
                order = order.reload()

                logger.info("IPN: Successfully processed IPN request for %s" % order)

                if payment.authorized and plata.settings.PLATA_STOCK_TRACKING:
                    StockTransaction = plata.stock_model()
                    self.create_transactions(
                        order,
                        _("sale"),
                        type=StockTransaction.SALE,
                        negative=True,
                        payment=payment,
                    )

                if not order.balance_remaining:
                    self.order_paid(order, payment=payment, request=request)

                return HttpResponse("Ok")

        except Exception as e:
            logger.error("IPN: Processing failure %s" % e)
            raise
        else:
            logger.warning("IPN received without POST parameters")
            return HttpResponseForbidden("No parameters provided")
예제 #32
0
    def process_order_confirmed(self, request, order):
        OGONE = settings.OGONE

        if not order.balance_remaining:
            return self.already_paid(order)

        logger.info('Processing order %s using Ogone' % order)

        payment = self.create_pending_payment(order)
        if plata.settings.PLATA_STOCK_TRACKING:
            StockTransaction = plata.stock_model()
            self.create_transactions(
                order,
                _('payment process reservation'),
                type=StockTransaction.PAYMENT_PROCESS_RESERVATION,
                negative=True,
                payment=payment)

        # params that will be hashed
        form_params = {
            'PSPID':
            OGONE['PSPID'],
            'orderID':
            'Order-%d-%d' % (order.id, payment.id),
            'amount':
            u'%s' %
            int(order.balance_remaining.quantize(Decimal('0.00')) * 100),
            'currency':
            order.currency,
            'language':
            locale.normalize(to_locale(get_language())).split('.')[0],
            'CN':
            u'%s %s' % (order.billing_first_name, order.billing_last_name),
            'EMAIL':
            order.email,
            'ownerZIP':
            order.billing_zip_code,
            'owneraddress':
            order.billing_address,
            'ownertown':
            order.billing_city,
            'accepturl':
            u'http://%s%s' %
            (request.META.get('HTTP_HOST'), reverse('plata_order_success')),
            'declineurl':
            u'http://%s%s' % (request.META.get('HTTP_HOST'),
                              reverse('plata_order_payment_failure')),
            'exceptionurl':
            u'http://%s%s' % (request.META.get('HTTP_HOST'),
                              reverse('plata_order_payment_failure')),
            'cancelurl':
            u'http://%s%s' % (request.META.get('HTTP_HOST'),
                              reverse('plata_order_payment_failure')),
        }
        # create hash
        value_strings = [
            u'{0}={1}{2}'.format(key.upper(), value, OGONE['SHA1_IN'])
            for key, value in form_params.items()
        ]
        hash_string = u''.join(sorted(value_strings))
        encoded_hash_string = sha1(hash_string.encode('utf-8')).hexdigest()

        # add hash and additional params
        form_params.update({
            'SHASign': encoded_hash_string.upper(),
            'mode': OGONE['LIVE'] and 'prod' or 'test',
        })

        return self.shop.render(
            request, 'payment/%s_form.html' % self.key, {
                'order': order,
                'HTTP_HOST': request.META.get('HTTP_HOST'),
                'form_params': form_params,
                'locale': form_params['language'],
            })
예제 #33
0
    def ipn(self, request):
        OGONE = settings.OGONE

        try:
            parameters_repr = repr(request.POST.copy()).encode('utf-8')
            logger.info('IPN: Processing request data %s' % parameters_repr)

            try:
                orderID = request.POST['orderID']
                currency = request.POST['currency']
                amount = request.POST['amount']
                STATUS = request.POST['STATUS']
                PAYID = request.POST['PAYID']
                BRAND = request.POST['BRAND']
                SHASIGN = request.POST['SHASIGN']
            except KeyError, e:
                logger.error('IPN: Missing data in %s' % parameters_repr)
                return HttpResponseForbidden('Missing data')

            value_strings = [
                u'{0}={1}{2}'.format(key.upper(), value, OGONE['SHA1_OUT'])
                for key, value in request.POST.iteritems()
                if value and not key == 'SHASIGN'
            ]
            sha1_out = sha1(
                (u''.join(sorted(value_strings))).encode('utf-8')).hexdigest()

            if sha1_out.lower() != SHASIGN.lower():
                logger.error('IPN: Invalid hash in %s' % parameters_repr)
                return HttpResponseForbidden('Hash did not validate')

            try:
                order, order_id, payment_id = orderID.split('-')
            except ValueError:
                logger.error('IPN: Error getting order for %s' % orderID)
                return HttpResponseForbidden('Malformed order ID')

            # Try fetching the order and order payment objects
            # We create a new order payment object in case the old one
            # cannot be found.
            try:
                order = self.shop.order_model.objects.get(pk=order_id)
            except self.shop.order_model.DoesNotExist:
                logger.error('IPN: Order %s does not exist' % order_id)
                return HttpResponseForbidden('Order %s does not exist' %
                                             order_id)

            try:
                payment = order.payments.get(pk=payment_id)
            except order.payments.model.DoesNotExist:
                payment = order.payments.model(
                    order=order,
                    payment_module=u'%s' % self.name,
                )

            payment.status = OrderPayment.PROCESSED
            payment.currency = currency
            payment.amount = Decimal(amount)
            payment.data = request.POST.copy()
            payment.transaction_id = PAYID
            payment.payment_method = BRAND
            payment.notes = STATUS_DICT.get(STATUS)

            if STATUS in ('5', '9'):
                payment.authorized = timezone.now()
                payment.status = OrderPayment.AUTHORIZED

            payment.save()
            order = order.reload()

            logger.info('IPN: Successfully processed IPN request for %s' %
                        order)

            if payment.authorized and plata.settings.PLATA_STOCK_TRACKING:
                StockTransaction = plata.stock_model()
                self.create_transactions(order,
                                         _('sale'),
                                         type=StockTransaction.SALE,
                                         negative=True,
                                         payment=payment)

            if not order.balance_remaining:
                self.order_paid(order, payment=payment, request=request)

            return HttpResponse('OK')
예제 #34
0
    def ipn(self, request):
        OGONE = settings.OGONE

        try:
            parameters_repr = repr(request.POST.copy()).encode('utf-8')
            logger.info('IPN: Processing request data %s' % parameters_repr)

            try:
                orderID = request.POST['orderID']
                currency = request.POST['currency']
                amount = request.POST['amount']
                STATUS = request.POST['STATUS']
                PAYID = request.POST['PAYID']
                BRAND = request.POST['BRAND']
                SHASIGN = request.POST['SHASIGN']
            except KeyError, e:
                logger.error('IPN: Missing data in %s' % parameters_repr)
                return HttpResponseForbidden('Missing data')

            value_strings = [
                u'{0}={1}{2}'.format(key.upper(), value, OGONE['SHA1_OUT'])
                for key, value in request.POST.iteritems()
                if value and not key == 'SHASIGN']
            sha1_out = sha1(
                (u''.join(sorted(value_strings))).encode('utf-8')).hexdigest()

            if sha1_out.lower() != SHASIGN.lower():
                logger.error('IPN: Invalid hash in %s' % parameters_repr)
                return HttpResponseForbidden('Hash did not validate')

            try:
                order, order_id, payment_id = orderID.split('-')
            except ValueError:
                logger.error('IPN: Error getting order for %s' % orderID)
                return HttpResponseForbidden('Malformed order ID')

            # Try fetching the order and order payment objects
            # We create a new order payment object in case the old one
            # cannot be found.
            try:
                order = self.shop.order_model.objects.get(pk=order_id)
            except self.shop.order_model.DoesNotExist:
                logger.error('IPN: Order %s does not exist' % order_id)
                return HttpResponseForbidden(
                    'Order %s does not exist' % order_id)

            try:
                payment = order.payments.get(pk=payment_id)
            except order.payments.model.DoesNotExist:
                payment = order.payments.model(
                    order=order,
                    payment_module=u'%s' % self.name,
                )

            payment.status = OrderPayment.PROCESSED
            payment.currency = currency
            payment.amount = Decimal(amount)
            payment.data = request.POST.copy()
            payment.transaction_id = PAYID
            payment.payment_method = BRAND
            payment.notes = STATUS_DICT.get(STATUS)

            if STATUS in ('5', '9'):
                payment.authorized = timezone.now()
                payment.status = OrderPayment.AUTHORIZED

            payment.save()
            order = order.reload()

            logger.info(
                'IPN: Successfully processed IPN request for %s' % order)

            if payment.authorized and plata.settings.PLATA_STOCK_TRACKING:
                StockTransaction = plata.stock_model()
                self.create_transactions(
                    order, _('sale'),
                    type=StockTransaction.SALE, negative=True, payment=payment)

            if not order.balance_remaining:
                self.order_paid(order, payment=payment, request=request)

            return HttpResponse('OK')
예제 #35
0
    def ipn(self, request):
        POSTFINANCE = settings.POSTFINANCE

        try:
            parameters_repr = repr(request.POST.copy()).encode('utf-8')
            logger.info('IPN: Processing request data %s' % parameters_repr)

            try:
                orderID = request.POST['orderID']
                currency = request.POST['currency']
                amount = request.POST['amount']
                PM = request.POST['PM']
                ACCEPTANCE = request.POST['ACCEPTANCE']
                STATUS = request.POST['STATUS']
                CARDNO = request.POST['CARDNO']
                PAYID = request.POST['PAYID']
                NCERROR = request.POST['NCERROR']
                BRAND = request.POST['BRAND']
                SHASIGN = request.POST['SHASIGN']
            except KeyError:
                logger.error('IPN: Missing data in %s' % parameters_repr)
                return HttpResponseForbidden('Missing data')

            sha1_source = u''.join((
                orderID,
                currency,
                amount,
                PM,
                ACCEPTANCE,
                STATUS,
                CARDNO,
                PAYID,
                NCERROR,
                BRAND,
                POSTFINANCE['SHA1_OUT'],
            ))

            sha1_out = sha1(sha1_source).hexdigest()

            if sha1_out.lower() != SHASIGN.lower():
                logger.error('IPN: Invalid hash in %s' % parameters_repr)
                return HttpResponseForbidden('Hash did not validate')

            try:
                order, order_id, payment_id = orderID.split('-')
            except ValueError:
                logger.error('IPN: Error getting order for %s' % orderID)
                return HttpResponseForbidden('Malformed order ID')

            # Try fetching the order and order payment objects
            # We create a new order payment object in case the old one
            # cannot be found.
            try:
                order = self.shop.order_model.objects.get(pk=order_id)
            except self.shop.order_model.DoesNotExist:
                logger.error('IPN: Order %s does not exist' % order_id)
                return HttpResponseForbidden(
                    'Order %s does not exist' % order_id)

            try:
                payment = order.payments.get(pk=payment_id)
            except order.payments.model.DoesNotExist:
                payment = order.payments.model(
                    order=order,
                    payment_module=u'%s' % self.name,
                )

            payment.status = OrderPayment.PROCESSED
            payment.currency = currency
            payment.amount = Decimal(amount)
            payment.data = request.POST.copy()
            payment.transaction_id = PAYID
            payment.payment_method = BRAND
            payment.notes = STATUS_DICT.get(STATUS)

            if STATUS in ('5', '9'):
                payment.authorized = timezone.now()
                payment.status = OrderPayment.AUTHORIZED

            payment.save()
            order = order.reload()

            logger.info(
                'IPN: Successfully processed IPN request for %s' % order)

            if payment.authorized and plata.settings.PLATA_STOCK_TRACKING:
                StockTransaction = plata.stock_model()
                self.create_transactions(
                    order, _('sale'),
                    type=StockTransaction.SALE, negative=True, payment=payment)

            if not order.balance_remaining:
                self.order_paid(order, payment=payment, request=request)

            return HttpResponse('OK')
        except Exception, e:
            logger.error('IPN: Processing failure %s' % unicode(e))
            raise
예제 #36
0
    def ipn(self, request):
        if not request._read_started:
            if 'windows-1252' in request.body:
                if request.encoding != 'windows-1252':
                    request.encoding = 'windows-1252'
        else:  # middleware (or something else?) has triggered request reading
            if request.POST.get('charset') == 'windows-1252':
                if request.encoding != 'windows-1252':
                    # since the POST data has already been accessed,
                    # unicode characters may have already been lost and
                    # cannot be re-encoded.
                    # -- see https://code.djangoproject.com/ticket/14035
                    # Unfortunately, PayPal:
                    # a) defaults to windows-1252 encoding (why?!)
                    # b) doesn't indicate this in the Content-Type header
                    #    so Django cannot automatically detect it.
                    logger.warning(
                        'IPN received with charset=windows1252, however '
                        'the request encoding does not match. It may be '
                        'impossible to verify this IPN if the data contains '
                        'non-ASCII characters. Please either '
                        'a) update your PayPal preferences to use UTF-8 '
                        'b) configure your site so that IPN requests are '
                        'not ready before they reach the hanlder')

        PAYPAL = settings.PAYPAL

        if PAYPAL['LIVE']:
            PP_URL = "https://www.paypal.com/cgi-bin/webscr"
        else:
            PP_URL = "https://www.sandbox.paypal.com/cgi-bin/webscr"

        parameters = None

        try:
            parameters = request.POST.copy()
            parameters_repr = repr(parameters).encode('utf-8')

            if parameters:
                logger.info('IPN: Processing request data %s' %
                            parameters_repr)

                querystring = 'cmd=_notify-validate&%s' % (
                    request.POST.urlencode())
                status = urllib2.urlopen(PP_URL, querystring).read()

                if not status == "VERIFIED":
                    logger.error('IPN: Received status %s, '
                                 'could not verify parameters %s' %
                                 (status, parameters_repr))
                    logger.debug('Destination: %r ? %r', PP_URL, querystring)
                    logger.debug('Request: %r', request)
                    return HttpResponseForbidden('Unable to verify')

            if parameters:
                logger.info('IPN: Verified request %s' % parameters_repr)
                reference = parameters['txn_id']
                invoice_id = parameters['invoice']
                currency = parameters['mc_currency']
                amount = parameters['mc_gross']

                try:
                    order, order_id, payment_id = invoice_id.split('-')
                except ValueError:
                    logger.error('IPN: Error getting order for %s' %
                                 invoice_id)
                    return HttpResponseForbidden('Malformed order ID')

                try:
                    order = self.shop.order_model.objects.get(pk=order_id)
                except (self.shop.order_model.DoesNotExist, ValueError):
                    logger.error('IPN: Order %s does not exist' % order_id)
                    return HttpResponseForbidden('Order %s does not exist' %
                                                 order_id)

                try:
                    payment = order.payments.get(pk=payment_id)
                except (order.payments.model.DoesNotExist, ValueError):
                    payment = order.payments.model(
                        order=order,
                        payment_module=u'%s' % self.name,
                    )

                payment.status = OrderPayment.PROCESSED
                payment.currency = currency
                payment.amount = Decimal(amount)
                payment.data = request.POST.copy()
                payment.transaction_id = reference
                payment.payment_method = payment.payment_module

                if parameters['payment_status'] == 'Completed':
                    payment.authorized = timezone.now()
                    payment.status = OrderPayment.AUTHORIZED

                payment.save()
                order = order.reload()

                logger.info('IPN: Successfully processed IPN request for %s' %
                            order)

                if payment.authorized and plata.settings.PLATA_STOCK_TRACKING:
                    StockTransaction = plata.stock_model()
                    self.create_transactions(order,
                                             _('sale'),
                                             type=StockTransaction.SALE,
                                             negative=True,
                                             payment=payment)

                if not order.balance_remaining:
                    self.order_paid(order, payment=payment, request=request)

                return HttpResponse("Ok")

        except Exception, e:
            logger.error('IPN: Processing failure %s' % unicode(e))
            raise
예제 #37
0
    def datatrans_success(self, request):
        DATATRANS = settings.DATATRANS
        if DATATRANS.get("LIVE", True):
            DT_URL = "https://payment.datatrans.biz/upp/jsp/XML_status.jsp"
        else:
            DT_URL = "https://pilot.datatrans.biz/upp/jsp/XML_status.jsp"

        parameters = None

        try:
            response = None
            parameters = request.POST.copy()
            parameters_repr = repr(parameters).encode("utf-8")
            if parameters:
                logger.info("IPN: Processing request data %s" %
                            parameters_repr)

                xml = """<?xml version="1.0" encoding="UTF-8" ?>
                <statusService version="1">
                  <body merchantId="%(merchant_id)s">
                    <transaction>
                      <request>
                        <uppTransactionId>%(transaction_id)s</uppTransactionId>
                      </request>
                    </transaction>
                  </body>
                </statusService>
                """ % {
                    "transaction_id": parameters["uppTransactionId"],
                    "merchant_id": DATATRANS["MERCHANT_ID"],
                }
                params = urllib.urlencode({"xmlRequest": xml})
                xml_response = urllib.urlopen(DT_URL, params).read()

                tree = ET.fromstring(xml_response)
                response = tree.find("body/transaction/response")
                response_code = response.find("responseCode").text
                if response_code not in ("1", "2", "3"):
                    logger.error(
                        "IPN: Received response_code %s, could not verify parameters %s"
                        % (response_code, parameters_repr))
                    parameters = None

            if response:
                refno = response.find("refno").text
                currency = response.find("currency").text
                amount = response.find("amount").text
                try:
                    order_id, payment_id = refno.split("-")
                except ValueError:
                    logger.error("IPN: Error getting order for %s" % refno)
                    return HttpResponseForbidden("Malformed order ID")
                try:
                    order = self.shop.order_model.objects.get(pk=order_id)
                except self.shop.order_model.DoesNotExist:
                    logger.error("IPN: Order %s does not exist" % order_id)
                    return HttpResponseForbidden("Order %s does not exist" %
                                                 order_id)

                try:
                    payment = order.payments.get(pk=payment_id)
                except order.payments.model.DoesNotExist:
                    return HttpResponseForbidden("Payment %s does not exist" %
                                                 payment_id)

                payment.status = OrderPayment.PROCESSED
                payment.currency = currency
                payment.amount = Decimal(float(amount) / SMALLEST_UNIT_FACTOR)
                payment.data = request.POST.copy()
                payment.transaction_id = refno
                payment.payment_method = payment.payment_module

                payment.authorized = now()
                payment.status = OrderPayment.AUTHORIZED

                payment.save()
                order = order.reload()

                logger.info("IPN: Successfully processed IPN request for %s" %
                            order)

                if payment.authorized and plata.settings.PLATA_STOCK_TRACKING:
                    StockTransaction = plata.stock_model()
                    self.create_transactions(
                        order,
                        _("sale"),
                        type=StockTransaction.SALE,
                        negative=True,
                        payment=payment,
                    )

                if not order.balance_remaining:
                    self.order_paid(order, payment=payment)

                return redirect("plata_order_success")

        except Exception as e:
            logger.error("IPN: Processing failure %s" % e)
            raise
예제 #38
0
    def ipn(self, request):
        POSTFINANCE = settings.POSTFINANCE

        try:
            parameters_repr = repr(request.POST.copy()).encode('utf-8')
            logger.info('IPN: Processing request data %s' % parameters_repr)

            try:
                orderID = request.POST['orderID']
                currency = request.POST['currency']
                amount = request.POST['amount']
                PM = request.POST['PM']
                ACCEPTANCE = request.POST['ACCEPTANCE']
                STATUS = request.POST['STATUS']
                CARDNO = request.POST['CARDNO']
                PAYID = request.POST['PAYID']
                NCERROR = request.POST['NCERROR']
                BRAND = request.POST['BRAND']
                SHASIGN = request.POST['SHASIGN']
            except KeyError:
                logger.error('IPN: Missing data in %s' % parameters_repr)
                return HttpResponseForbidden('Missing data')

            sha1_source = ''.join((
                orderID,
                currency,
                amount,
                PM,
                ACCEPTANCE,
                STATUS,
                CARDNO,
                PAYID,
                NCERROR,
                BRAND,
                POSTFINANCE['SHA1_OUT'],
            ))

            sha1_out = sha1(sha1_source.encode('utf-8')).hexdigest()

            if sha1_out.lower() != SHASIGN.lower():
                logger.error('IPN: Invalid hash in %s' % parameters_repr)
                return HttpResponseForbidden('Hash did not validate')

            try:
                order, order_id, payment_id = orderID.split('-')
            except ValueError:
                logger.error('IPN: Error getting order for %s' % orderID)
                return HttpResponseForbidden('Malformed order ID')

            # Try fetching the order and order payment objects
            # We create a new order payment object in case the old one
            # cannot be found.
            try:
                order = self.shop.order_model.objects.get(pk=order_id)
            except self.shop.order_model.DoesNotExist:
                logger.error('IPN: Order %s does not exist' % order_id)
                return HttpResponseForbidden(
                    'Order %s does not exist' % order_id)

            try:
                payment = order.payments.get(pk=payment_id)
            except order.payments.model.DoesNotExist:
                payment = order.payments.model(
                    order=order,
                    payment_module=u'%s' % self.name,
                )

            payment.status = OrderPayment.PROCESSED
            payment.currency = currency
            payment.amount = Decimal(amount)
            payment.data = request.POST.copy()
            payment.transaction_id = PAYID
            payment.payment_method = BRAND
            payment.notes = STATUS_DICT.get(STATUS)

            if STATUS in ('5', '9'):
                payment.authorized = timezone.now()
                payment.status = OrderPayment.AUTHORIZED

            payment.save()
            order = order.reload()

            logger.info(
                'IPN: Successfully processed IPN request for %s' % order)

            if payment.authorized and plata.settings.PLATA_STOCK_TRACKING:
                StockTransaction = plata.stock_model()
                self.create_transactions(
                    order, _('sale'),
                    type=StockTransaction.SALE, negative=True, payment=payment)

            if not order.balance_remaining:
                self.order_paid(order, payment=payment, request=request)

            return HttpResponse('OK')
        except Exception as e:
            logger.error('IPN: Processing failure %s' % e)
            raise
예제 #39
0
파일: pagseguro.py 프로젝트: b-dev/plata
    def psnotify(self, request):
        request.encoding = "ISO-8859-1"
        PAGSEGURO = settings.PAGSEGURO

        data = None

        try:
            data = request.POST.copy()
            data = dict((k, v.encode("ISO-8859-1")) for k, v in data.items())

            if data:
                logger.info("Pagseguro: Processing request data %s" % data)

                if PAGSEGURO.get("LOG"):
                    f = open(PAGSEGURO["LOG"], "a+")
                    f.write("%s - notification: %s\n" % (time.ctime(), data))
                    f.close()

                notificationCode = data["notificationCode"]
                result = urllib.urlopen(
                    "https://ws.pagseguro.uol.com.br/v2/transactions/notifications/%s?email=%s&token=%s"  # noqa
                    % (notificationCode, PAGSEGURO["EMAIL"],
                       PAGSEGURO["TOKEN"])).read()

                if PAGSEGURO.get("LOG"):
                    f = open(PAGSEGURO["LOG"], "a")
                    f.write("%s - notification check: %s" %
                            (time.ctime(), result))
                    f.close()

                xml = minidom.parseString(result)
                try:
                    xmlTag = xml.getElementsByTagName("status")[0].toxml()
                    status = xmlTag.replace("<status>",
                                            "").replace("</status>", "")
                    xmlTag = xml.getElementsByTagName("reference")[0].toxml()
                    reference = xmlTag.replace("<reference>",
                                               "").replace("</reference>", "")
                    xmlTag = xml.getElementsByTagName("grossAmount")[0].toxml()
                    amount = xmlTag.replace("<grossAmount>",
                                            "").replace("</grossAmount>", "")
                except (ValueError, IndexError):
                    logger.error("Pagseguro: Can't verify notification: %s" %
                                 result.decode("ISO-8859-1"))
                    return HttpResponseForbidden("Order verification failed")

                if PAGSEGURO.get("LOG"):
                    f = open(PAGSEGURO.get("LOG"), "a")
                    f.write(
                        "%s - status: %s, ref: %s, code: %s\n" %
                        (time.ctime(), status, reference, notificationCode))
                    f.close()

                logger.info("Pagseguro: Verified request %s" % result)

                try:
                    order, order_id, payment_id = reference.split("-")
                except ValueError:
                    logger.error("Pagseguro: Error getting order for %s" %
                                 reference)
                    return HttpResponseForbidden(_("Malformed order ID"))

                try:
                    order = self.shop.order_model.objects.get(pk=order_id)
                except self.shop.order_model.DoesNotExist:
                    logger.error("Pagseguro: Order %s does not exist" %
                                 order_id)
                    return HttpResponseForbidden(
                        _("Order %s does not exist" % order_id))

                try:
                    payment = order.payments.get(pk=payment_id)
                except order.payments.model.DoesNotExist:
                    payment = order.payments.model(order=order,
                                                   payment_module="%s" %
                                                   self.name)

                payment.status = OrderPayment.PROCESSED
                payment.amount = Decimal(amount)
                payment.data = request.POST.copy()
                payment.transaction_id = notificationCode
                payment.payment_method = payment.payment_module

                if status == "3":
                    payment.authorized = datetime.now()
                    payment.status = OrderPayment.AUTHORIZED
                payment.save()

                order = order.reload()
                payment.amount = Decimal(amount)

                logger.info(
                    "Pagseguro: Successfully processed request for %s" % order)

                if payment.authorized and plata.settings.PLATA_STOCK_TRACKING:
                    StockTransaction = plata.stock_model()
                    self.create_transactions(
                        order,
                        _("sale"),
                        type=StockTransaction.SALE,
                        negative=True,
                        payment=payment,
                    )

                if not order.balance_remaining:
                    self.order_paid(order, payment=payment)

                return HttpResponse("OK")

        except Exception:
            logger.exception("Pagseguro: Processing failure")
            raise

        return HttpResponseForbidden("Bad request")
예제 #40
0
파일: paypal.py 프로젝트: fsw/plata
    def ipn(self, request):
        request.encoding = 'windows-1252'
        PAYPAL = settings.PAYPAL

        if PAYPAL['LIVE']:
            PP_URL = "https://www.paypal.com/cgi-bin/webscr"
        else:
            PP_URL = "https://www.sandbox.paypal.com/cgi-bin/webscr"

        parameters = None

        try:
            parameters = request.POST.copy()
            parameters_repr = repr(parameters).encode('utf-8')

            if parameters:
                logger.info('IPN: Processing request data %s' % parameters_repr)

                postparams = {'cmd': '_notify-validate'}
                for k, v in parameters.iteritems():
                    postparams[k] = v.encode('windows-1252')
                status = urllib.urlopen(PP_URL, urllib.urlencode(postparams)).read()

                if not status == "VERIFIED":
                    logger.error('IPN: Received status %s, could not verify parameters %s' % (
                        status, parameters_repr))
                    parameters = None

            if parameters:
                logger.info('IPN: Verified request %s' % parameters_repr)
                reference = parameters['txn_id']
                invoice_id = parameters['invoice']
                currency = parameters['mc_currency']
                amount = parameters['mc_gross']

                try:
                    order, order_id, payment_id = invoice_id.split('-')
                except ValueError:
                    logger.error('IPN: Error getting order for %s' % invoice_id)
                    return HttpResponseForbidden('Malformed order ID')

                try:
                    order = self.shop.order_model.objects.get(pk=order_id)
                except self.shop.order_model.DoesNotExist:
                    logger.error('IPN: Order %s does not exist' % order_id)
                    return HttpResponseForbidden('Order %s does not exist' % order_id)

                try:
                    payment = order.payments.get(pk=payment_id)
                except order.payments.model.DoesNotExist:
                    payment = order.payments.model(
                        order=order,
                        payment_module=u'%s' % self.name,
                        )

                payment.status = OrderPayment.PROCESSED
                payment.currency = currency
                payment.amount = Decimal(amount)
                payment.data = request.POST.copy()
                payment.transaction_id = reference
                payment.payment_method = payment.payment_module

                if parameters['payment_status'] == 'Completed':
                    payment.authorized = timezone.now()
                    payment.status = OrderPayment.AUTHORIZED

                payment.save()
                order = order.reload()

                logger.info('IPN: Successfully processed IPN request for %s' % order)

                if payment.authorized and plata.settings.PLATA_STOCK_TRACKING:
                    StockTransaction = plata.stock_model()
                    self.create_transactions(order, _('sale'),
                        type=StockTransaction.SALE, negative=True, payment=payment)

                if not order.balance_remaining:
                    self.order_paid(order, payment=payment)

                return HttpResponse("Ok")

        except Exception, e:
            logger.error('IPN: Processing failure %s' % unicode(e))
            raise
예제 #41
0
파일: postfinance.py 프로젝트: b-dev/plata
    def ipn(self, request):
        POSTFINANCE = settings.POSTFINANCE

        try:
            parameters_repr = repr(request.POST.copy()).encode("utf-8")
            logger.info("IPN: Processing request data %s" % parameters_repr)

            try:
                orderID = request.POST["orderID"]
                currency = request.POST["currency"]
                amount = request.POST["amount"]
                PM = request.POST["PM"]
                ACCEPTANCE = request.POST["ACCEPTANCE"]
                STATUS = request.POST["STATUS"]
                CARDNO = request.POST["CARDNO"]
                PAYID = request.POST["PAYID"]
                NCERROR = request.POST["NCERROR"]
                BRAND = request.POST["BRAND"]
                SHASIGN = request.POST["SHASIGN"]
            except KeyError:
                logger.error("IPN: Missing data in %s" % parameters_repr)
                return HttpResponseForbidden("Missing data")

            sha1_source = "".join((
                orderID,
                currency,
                amount,
                PM,
                ACCEPTANCE,
                STATUS,
                CARDNO,
                PAYID,
                NCERROR,
                BRAND,
                POSTFINANCE["SHA1_OUT"],
            ))

            sha1_out = sha1(sha1_source.encode("utf-8")).hexdigest()

            if sha1_out.lower() != SHASIGN.lower():
                logger.error("IPN: Invalid hash in %s" % parameters_repr)
                return HttpResponseForbidden("Hash did not validate")

            try:
                order, order_id, payment_id = orderID.split("-")
            except ValueError:
                logger.error("IPN: Error getting order for %s" % orderID)
                return HttpResponseForbidden("Malformed order ID")

            # Try fetching the order and order payment objects
            # We create a new order payment object in case the old one
            # cannot be found.
            try:
                order = self.shop.order_model.objects.get(pk=order_id)
            except self.shop.order_model.DoesNotExist:
                logger.error("IPN: Order %s does not exist" % order_id)
                return HttpResponseForbidden("Order %s does not exist" %
                                             order_id)

            try:
                payment = order.payments.get(pk=payment_id)
            except order.payments.model.DoesNotExist:
                payment = order.payments.model(order=order,
                                               payment_module="%s" % self.name)

            payment.status = OrderPayment.PROCESSED
            payment.currency = currency
            payment.amount = Decimal(amount)
            payment.data = request.POST.copy()
            payment.transaction_id = PAYID
            payment.payment_method = BRAND
            payment.notes = STATUS_DICT.get(STATUS)

            if STATUS in ("5", "9"):
                payment.authorized = timezone.now()
                payment.status = OrderPayment.AUTHORIZED

            payment.save()
            order = order.reload()

            logger.info("IPN: Successfully processed IPN request for %s" %
                        order)

            if payment.authorized and plata.settings.PLATA_STOCK_TRACKING:
                StockTransaction = plata.stock_model()
                self.create_transactions(
                    order,
                    _("sale"),
                    type=StockTransaction.SALE,
                    negative=True,
                    payment=payment,
                )

            if not order.balance_remaining:
                self.order_paid(order, payment=payment, request=request)

            return HttpResponse("OK")
        except Exception as e:
            logger.error("IPN: Processing failure %s" % e)
            raise