コード例 #1
0
    def get(self, request, *args, **kwargs):
        payment_ref = self.request.GET.get('payment_ref')
        try:
            # check payment status
            payment_client = PaymentClient()
            payment = payment_client.get_payment(payment_ref)
            if not payment or payment['status'] != 'pending':
                # bail out if accessed without specifying a payment in pending state
                return clear_session_view(request)

            kwargs.update({
                'short_payment_ref': payment_ref[:8].upper(),
                'prisoner_name': payment['recipient_name'],
                'amount': decimal.Decimal(payment['amount']) / 100,
                'email_sent': False,
            })

            # check gov.uk payment status
            govuk_id = payment['processor_id']
            self.success, kwargs = payment_client.check_govuk_payment_status(
                payment_ref, govuk_id, kwargs
            )
            if not self.success:
                return redirect(self.build_view_url(DebitCardCheckView.url_name))
        except OAuth2Error:
            logger.exception('Authentication error while processing %s' % payment_ref)
        except SlumberHttpBaseException as error:
            error_message = 'Error while processing %s' % payment_ref
            if hasattr(error, 'content'):
                error_message += '\nReceived: %s' % error.content
            logger.exception(error_message)
        except RequestsTimeout:
            logger.exception('GOV.UK Pay payment check timed out for %s' % payment_ref)
        except RequestException as error:
            error_message = 'GOV.UK Pay payment check failed for %s' % payment_ref
            if hasattr(error, 'response') and hasattr(error.response, 'content'):
                error_message += '\nReceived: %s' % error.response.content
            logger.exception(error_message)
        except GovUkPaymentStatusException:
            logger.exception('GOV.UK Pay payment status incomplete for %s' % payment_ref)

        response = super().get(request, *args, **kwargs)
        request.session.flush()
        return response
コード例 #2
0
    def get(self, request, *args, **kwargs):
        payment_ref = self.request.GET.get('payment_ref')
        if not payment_ref:
            return clear_session_view(request)
        kwargs['short_payment_ref'] = payment_ref[:8].upper()
        try:
            # check payment status
            payment_client = PaymentClient()
            payment = payment_client.get_payment(payment_ref)

            # only continue if:
            # - the MTP payment is in pending (it moves to the 'taken' state by the cronjob x mins after
            #   the gov.uk payment succeeds)
            #   OR
            # - the MTP payment is in the 'taken' state (by the cronjob x mins after the gov.uk payment succeeded)
            #   but only for a limited period of time
            if not payment or not is_active_payment(payment):
                return clear_session_view(request)

            kwargs.update({
                'prisoner_name': payment['recipient_name'],
                'prisoner_number': payment['prisoner_number'],
                'amount': decimal.Decimal(payment['amount']) / 100,
            })

            if payment['status'] == 'taken':
                self.status = GovUkPaymentStatus.success
            else:
                # check gov.uk payment status
                govuk_id = payment['processor_id']
                govuk_payment = payment_client.get_govuk_payment(govuk_id)

                self.status = payment_client.complete_payment_if_necessary(
                    payment, govuk_payment)

                # here status can be either created, started, submitted, capturable, success, failed, cancelled, error
                # or None

                error_code = govuk_payment and govuk_payment.get(
                    'state', {}).get('code')

                # payment was cancelled programmatically (this would not currently happen)
                if self.status == GovUkPaymentStatus.cancelled:
                    # error_code is expected to be P0040
                    error_code == 'P0040' or logger.error(
                        f'Unexpected code for cancelled GOV.UK Pay payment {payment_ref}: {error_code}'
                    )
                    return render(request,
                                  'send_money/debit-card-cancelled.html')

                # the user cancelled the payment
                if self.status == GovUkPaymentStatus.failed and error_code == 'P0030':
                    return render(request,
                                  'send_money/debit-card-cancelled.html')

                # GOV.UK Pay session expired
                if self.status == GovUkPaymentStatus.failed and error_code == 'P0020':
                    return render(
                        request, 'send_money/debit-card-session-expired.html')

                # payment method was rejected by card issuer or processor
                # e.g. due to insufficient funds or risk management
                if self.status == GovUkPaymentStatus.failed:
                    # error_code is expected to be P0010
                    error_code == 'P0010' or logger.error(
                        f'Unexpected code for failed GOV.UK Pay payment {payment_ref}: {error_code}'
                    )
                    return render(request,
                                  'send_money/debit-card-declined.html')

                # here status can be either created, started, submitted, capturable, success, error
                # or None

                # treat statuses created, started, submitted or None as error as they should have never got here
                if not self.status or self.status.is_awaiting_user_input():
                    self.status = GovUkPaymentStatus.error

                # here status can be either capturable, success, error

        except OAuth2Error:
            logger.exception(
                'Authentication error while processing %(payment_ref)s',
                {'payment_ref': payment_ref},
            )
            self.status = GovUkPaymentStatus.error
        except RequestException as error:
            response_content = get_requests_exception_for_logging(error)
            logger.exception(
                'Payment check failed for ref %(payment_ref)s. Received: %(response_content)s',
                {
                    'payment_ref': payment_ref,
                    'response_content': response_content
                },
            )
            self.status = GovUkPaymentStatus.error
        except GovUkPaymentStatusException:
            logger.exception(
                'GOV.UK Pay returned unexpected status for ref %(payment_ref)s',
                {'payment_ref': payment_ref},
            )
            self.status = GovUkPaymentStatus.error

        response = super().get(request, *args, **kwargs)
        request.session.flush()
        return response