Exemple #1
0
    def post(self, request):
        form = PledgeFormOld(request.POST)
        amount = request.POST.get('amount')
        partner_id = request.POST.get('recipient_org')
        partner_slug = PartnerCharity.objects.get(id=partner_id).slug_id
        components_data = {
            'form-TOTAL_FORMS': 1,
            'form-INITIAL_FORMS': 1,
            'form-0-id': None,
            'form-0-amount': amount,
            'form-0-partner_charity': partner_slug
        }
        component_formset = PledgeComponentFormSet(components_data)

        if form.is_valid() and component_formset.is_valid():
            pledge = form.save()
            for component in component_formset.forms:
                component.instance.pledge = pledge
            component_formset.save()
        else:
            return JsonResponse(
                {
                    'error': 'form-error',
                    'form_errors': form.errors
                },
                status=400)

        pledge = form.instance
        if pledge.recurring:
            pledge.recurring_frequency = RecurringFrequency.MONTHLY
            pledge.save()
        payment_method = request.POST.get('payment_method')
        response_data = {'payment_method': payment_method}

        if int(payment_method) == 1:
            # bank transaction
            response_data['bank_reference'] = pledge.generate_reference()
            send_bank_transfer_instructions_task.delay(pledge.id)
            return JsonResponse(response_data)
        elif int(payment_method) == 3:
            # Rate limiting
            ip = get_ip(request)
            if not rate_limiter.checked_insert(ip):
                # Pretend it's a PIN error to save us from handling it separately in the javascript.
                return JsonResponse(
                    {
                        'error':
                        'pin-error',
                        'pin_response':
                        "Our apologies: credit card donations are currently unavailable. "
                        +
                        "Please try again tomorrow or make a payment by bank transfer.",
                        'pin_response_text':
                        '',
                    },
                    status=400)

            transaction = PinTransaction()
            transaction.card_token = request.POST.get('card_token')
            transaction.ip_address = request.POST.get('ip_address')
            transaction.amount = pledge.amount  # Amount in dollars. Define with your own business logic.
            transaction.currency = 'AUD'  # Pin supports AUD and USD. Fees apply for currency conversion.
            transaction.description = 'Donation to Effective Altruism Australia'  # Define with your own business logic
            transaction.email_address = pledge.email
            transaction.pledge = pledge
            transaction.save()
            transaction.process_transaction(
            )  # Typically "Success" or an error message
            if transaction.succeeded:
                Receipt.objects.create_from_pin_transaction(transaction)
                response_data['succeeded'] = True
                receipt = transaction.receipt_set.first()
                response_data['receipt_url'] = reverse('download-receipt',
                                                       kwargs={
                                                           'pk': receipt.pk,
                                                           'secret':
                                                           receipt.secret
                                                       })
                return JsonResponse(response_data)
            else:
                return JsonResponse(
                    {
                        'error': 'pin-error',
                        'pin_response': transaction.pin_response,
                        'pin_response_text': transaction.pin_response_text,
                    },
                    status=400)
Exemple #2
0
    def post(self, request):
        body = json.loads(request.body.decode('utf-8'))
        pledge_form = PledgeForm(body)
        component_formset = PledgeComponentFormSet(body)

        if not (pledge_form.is_valid() and component_formset.is_valid()):
            client.captureMessage(str(pledge_form.errors) +
                                  str(component_formset.errors),
                                  data=body)
            return JsonResponse(
                {
                    'error_message':
                    "There was a problem submitting your donation. Please contact [email protected] if problems persist."
                },
                status=400)

        total = sum([
            component.instance.amount for component in component_formset.forms
        ])
        if total < 2:
            return JsonResponse(
                {
                    'error_message': "The minimum donation possible is $2.",
                },
                status=400)

        with django_transaction.atomic():
            pledge = pledge_form.save()
            for component in component_formset.forms:
                component.instance.pledge = pledge
            component_formset.save()

        response_data = {}

        if pledge.payment_method == PaymentMethod.BANK:
            response_data['bank_reference'] = pledge.generate_reference()
            send_bank_transfer_instructions_task.delay(pledge.id)
            return JsonResponse(response_data)

        elif pledge.payment_method == PaymentMethod.CREDIT_CARD:
            ip = get_ip(request)
            if not rate_limiter.checked_insert(
                    ip
            ) and not settings.DEBUG and settings.CREDIT_CARD_RATE_LIMIT_ENABLED:
                client.captureMessage('Hit rate limiter for ip: %s' % ip)
                return JsonResponse(
                    {
                        'error_message':
                        "Our apologies: credit card donations are currently unavailable. "
                        "Please try again tomorrow or make a payment by bank transfer.",
                    },
                    status=400)

            if pledge.amount > 6000:
                client.captureMessage(
                    'User attempted credit card donation over $6K')
                return JsonResponse(
                    {
                        'error_message':
                        "Our apologies: we can only accept credit card donations of up to $6000 AUD.  "
                        "Please use bank transfer or make multiple smaller donations.",
                    },
                    status=400)

            pin_data = body.get('pin_response')
            pin_data['amount'] = pledge.amount
            pin_data['pledge'] = pledge.id
            pin_form = PinTransactionForm(pin_data)
            if not pin_form.is_valid():
                client.captureMessage(str(pin_form.errors))
                return JsonResponse(
                    {
                        'error_message':
                        "There was a problem submitting your donation. Please contact [email protected] if problems persist."
                    },
                    status=400)

            transaction = pin_form.save()
            transaction.process_transaction()
            if transaction.succeeded:
                Receipt.objects.create_from_pin_transaction(transaction)
                response_data['succeeded'] = True
                receipt = transaction.receipt_set.first()
                response_data['receipt_url'] = reverse('download-receipt',
                                                       kwargs={
                                                           'pk': receipt.pk,
                                                           'secret':
                                                           receipt.secret
                                                       })
                return JsonResponse(response_data)
            else:
                pin_repsonse_dict = json.loads(transaction.pin_response_text)
                client.captureMessage(pin_repsonse_dict['error_description'])
                return JsonResponse(
                    {
                        'error_message':
                        "There was a problem submitting your donation. Please contact [email protected] if problems persist.",
                    },
                    status=400)

        else:
            raise StandardError(
                'We currently only support new donations via credit card or bank transfer.'
            )
Exemple #3
0
    def post(self, request):
        body = json.loads(request.body.decode('utf-8'))
        pledge_form = PledgeForm(body)
        component_formset = PledgeComponentFormSet(body)

        if not (pledge_form.is_valid() and component_formset.is_valid()):
            client.captureMessage(str(pledge_form.errors) +
                                  str(component_formset.errors),
                                  data=body)
            return JsonResponse(
                {
                    'error_message':
                    "There was a problem submitting your donation. Please contact [email protected] if problems persist."
                },
                status=400)

        total = sum([
            component.instance.amount for component in component_formset.forms
        ])
        if total < 2:
            return JsonResponse(
                {
                    'error_message': "The minimum donation possible is $2.",
                },
                status=400)

        with django_transaction.atomic():
            pledge = pledge_form.save()
            if pledge.recurring_frequency == RecurringFrequency.MONTHLY:
                pledge.recurring = True

            pledge.ip = get_client_ip(request)
            if pledge.ip[0:4] == '45.9':
                if not rate_limiter.checked_insert(pledge.ip[0:4]):
                    pledge.delete()
                    return JsonResponse(
                        {
                            'error_message':
                            "This transaction looks suspicious.  Please contact us at [email protected] if you are a human!",
                        },
                        status=400)
            pledge.save()
            for component in component_formset.forms:
                component.instance.pledge = pledge
            component_formset.save()

        response_data = {}

        if pledge.payment_method == PaymentMethod.BANK:
            response_data['bank_reference'] = pledge.generate_reference()
            send_bank_transfer_instructions_task.delay(pledge.id)
            return JsonResponse(response_data)

        elif pledge.payment_method == PaymentMethod.CREDIT_CARD:
            line_items = []
            for pledge_component in pledge.components.all():
                line_items.append({
                    'price_data': {
                        'currency': 'aud',
                        'product':
                        pledge_component.partner_charity.stripe_product_id,
                        'unit_amount':
                        int(float(pledge_component.amount) * 100),
                        'recurring': {
                            'interval': 'month'
                        } if pledge.recurring_frequency
                        == RecurringFrequency.MONTHLY else None
                    },
                    'quantity': 1,
                })
            session = stripe.checkout.Session.create(
                payment_method_types=['card'],
                line_items=line_items,
                mode='subscription' if pledge.recurring_frequency
                == RecurringFrequency.MONTHLY else 'payment',
                success_url='https://effectivealtruism.org.au/donate/?thankyou',
                cancel_url='https://effectivealtruism.org.au/donate/',
            )
            print(session.__dict__)
            pledge.stripe_checkout_id = session.id
            pledge.save()
            return JsonResponse({'id': session.id})
        else:
            raise StandardError(
                'We currently only support new donations via credit card or bank transfer.'
            )