Exemple #1
0
    def get_backend_setting(cls, name, default=None):
        """
        Reads ``name`` setting from backend settings dictionary.

        If `default` value is omitted, raises ``ImproperlyConfigured`` when
        setting ``name`` is not available.
        """
        backend_settings = get_backend_settings(cls.BACKEND)
        if default is not None:
            return backend_settings.get(name, default)
        else:
            try:
                return backend_settings[name]
            except KeyError:
                raise ImproperlyConfigured("getpaid '%s' requires backend '%s' setting" % (cls.BACKEND, name))
Exemple #2
0
    def get_backend_setting(cls, name, default=None):
        """
        Reads ``name`` setting from backend settings dictionary.

        If `default` value is omitted, raises ``ImproperlyConfigured`` when
        setting ``name`` is not available.
        """
        backend_settings = get_backend_settings(cls.BACKEND)
        if default is not None:
            return backend_settings.get(name, default)
        else:
            try:
                return backend_settings[name]
            except KeyError:
                raise ImproperlyConfigured("getpaid '%s' requires backend '%s' setting" % (cls.BACKEND, name))
    def update_settings(self, data):
        settings = get_backend_settings('getpaid.backends.transferuj')
        settings.update(data)

        return {'getpaid.backends.transferuj': settings}
class PaymentProcessor(PaymentProcessorBase):
    BACKEND = 'epay'
    BACKEND_NAME = _('Kazkom Epay')

    BACKEND_ACCEPTED_CURRENCY_DICT = {
        'KZT': 398,
        'USD': 840,
        'EUR': 978,
    }
    BACKEND_ACCEPTED_CURRENCY = (u'KZT', u'USD', u'EUR')

    BACKEND_LOGO_URL = os.path.join(settings.STATIC_URL, 'epay/img/logo.png')

    backend_settings = get_backend_settings(BACKEND)
    epay = Epay(private_key=open(
        backend_settings.get('merchant_private_key',
                             DEFAULT_MERCHANT_PRIVATE_KEY), 'rb').read(),
                kkb_key=open(
                    backend_settings.get('kkb_pub_key', DEFAULT_KKB_PUB_KEY),
                    'rb').read(),
                **backend_settings)

    def get_scheme(self, request):
        scheme = self.get_backend_setting('scheme', 'https')
        if not scheme:
            if request.is_secure():
                scheme = 'https'
            else:
                scheme = 'http'
        return scheme

    def get_language(self, request):
        """
        :return: rus|eng depending on user request
        """
        if 'get_language' in self.backend_settings:
            return self.backend_settings['get_language'](request, self.payment)
        return "rus"

    def get_email(self, request):
        if 'get_email' in self.backend_settings:
            return self.backend_settings['get_email'](request, self.payment)
        if hasattr(self.payment.order, 'email'):
            return self.payment.order.email

    def get_template(self, request):
        if 'get_template' in self.backend_settings:
            return self.backend_settings['get_template'](request, self.payment)
        if 'template' in self.backend_settings:
            return self.backend_settings['template']

    def get_fail_backlink(self, request):
        if 'get_fail_backlink' in self.backend_settings:
            return self.backend_settings['get_fail_backlink'](request,
                                                              self.payment)

    def build_attrs(self, request, scheme='https', language="rus"):
        attrs = {
            'Signed_Order_B64':
            self.epay.sign_order(self.payment.id, self.payment.amount,
                                 self.payment.currency),
            'Language':
            language,
            'BackLink':
            self.get_backlink_url(request, scheme=scheme),
            'PostLink':
            self.get_postlink_url(request, scheme=scheme)
        }
        email = self.get_email(request)
        template = self.get_template(request)
        fail_back_link = self.get_fail_backlink(request)
        if email:
            attrs['email'] = email

        if template:
            attrs['template'] = template

        if fail_back_link:
            attrs['FailureBackLink'] = fail_back_link

        # TODO: support for FailurePostLink

        return attrs

    def get_gateway_url(self, request):
        return (self.epay.get_gateway_url(), "POST",
                self.build_attrs(request,
                                 self.get_scheme(request),
                                 language=self.get_language(request)))

    def get_backlink_url(self, request, scheme):
        if 'get_backlink_url' in self.backend_settings:
            return self.backend_settings['get_backlink_url'](request,
                                                             self.payment)
        return "{}://{}{}".format(scheme, get_domain(),
                                  self.payment.order.get_absolute_url())

    def get_postlink_url(self, request, **kw):
        return build_absolute_uri('epay:postlink', **kw)

    @staticmethod
    def amount_to_python(amount_str):
        return Decimal(amount_str)

    @staticmethod
    def callback(response):
        """
        Payment was confirmed.
        """
        epay = PaymentProcessor.epay
        Payment = apps.get_model('getpaid', 'Payment')
        EpayPayment = apps.get_model('epay', 'EpayPayment')
        with transaction.atomic():
            params = epay.handle_response(response)
            customer_params = params['customer']
            payment_params = params['results']['payment']
            order_params = customer_params['merchant']['order']
            payment_id = epay.unmodify_order_id(int(order_params['order_id']))

            payment = Payment.objects.get(id=payment_id)
            assert payment.status == 'in_progress',\
                "Can not confirm payment that was not accepted for processing"
            payment.external_id = payment_params['reference']
            amount = PaymentProcessor.amount_to_python(
                payment_params['amount'])
            payment.amount_paid = amount

            epay_payment = EpayPayment(
                payment=payment,
                merchant_id=payment_params.get('merchant_id', ''),
                card=payment_params.get('card', ''),
                reference=payment_params.get('reference', ''),
                approval_code=payment_params.get('approval_code', ''),
                response_code=payment_params.get('response_code', ''),
                is_secure=(payment_params.get('secure', 'No') == 'Yes'),
                card_bin=payment_params.get('card_bin', ''),
                c_hash=payment_params.get('c_hash', ''),
                customer_name=customer_params.get('name', ''),
                customer_mail=customer_params.get('mail', ''),
                customer_phone=customer_params.get('phone', ''),
            )
            epay_payment.save()
            res = payment.on_success(amount)
            if epay.auto_capture:
                PaymentProcessor.completed(epay_payment.pk)
            return res

    @staticmethod
    def completed(payment_id):
        """
        Confirming payment. Money is transfered from card to our account
        """
        epay = PaymentProcessor.epay
        EpayPayment = apps.get_model('epay', 'EpayPayment')
        with transaction.atomic():
            epay_payment = EpayPayment.objects.select_related('payment').get(
                payment_id=payment_id)
            payment = epay_payment.payment
            epay.capture(payment_id,
                         payment.amount,
                         epay_payment.approval_code,
                         epay_payment.reference,
                         currency=payment.currency)

            # epay_payment.change_status("caputred")
            epay_payment.update_from_kkb()
            return epay_payment

    @staticmethod
    def reversed(payment_id):
        """
        Reversing money if they are still in block
        """
        EpayPayment = apps.get_model('epay', 'EpayPayment')
        epay = PaymentProcessor.epay
        with transaction.atomic():
            epay_payment = EpayPayment.objects.select_related('payment').get(
                payment_id=payment_id)
            payment = epay_payment.payment
            epay.cancel(payment_id,
                        payment.amount,
                        epay_payment.approval_code,
                        epay_payment.reference,
                        currency=payment.currency)

            payment.change_status("cancelled")

            return epay_payment

    @staticmethod
    def refunded(payment_id):
        """
        Reversing money if they are still in block
        """
        EpayPayment = apps.get_model('epay', 'EpayPayment')
        epay = PaymentProcessor.epay
        with transaction.atomic():
            epay_payment = EpayPayment.objects.select_related('payment').get(
                payment_id=payment_id)
            payment = epay_payment.payment
            epay.refund(payment_id,
                        payment.amount,
                        epay_payment.approval_code,
                        epay_payment.reference,
                        currency=payment.currency)

            payment.change_status("cancelled")

            return epay_payment

    @staticmethod
    def get_status(payment_id):
        epay = PaymentProcessor.epay
        response = epay.get_status(payment_id)
        return response['response']

    @staticmethod
    def update_status(payment_id):
        """
        Reversing money if they are still in block
        """
        EpayPayment = apps.get_model('epay', 'EpayPayment')
        with transaction.atomic():
            response = PaymentProcessor.get_status(payment_id)
            epay_payment = EpayPayment.import_or_update(response,
                                                        payment_id=payment_id)
            return epay_payment