def create_from_order(self, order, attrs=None): """ :param order: Order instance for this payment gateway session :param attrs: dict with any extra property to be set on the object :returns: Payment Gateway Session instance created :raises GOVUKPayAPIException: if there is a problem with GOV.UK Pay :raises Conflict: if the order is not in the allowed status """ # refresh ongoing sessions for this order first of all for session in self.filter(order=order).ongoing().select_for_update(): session.refresh_from_govuk_payment() # validate that the order is in `quote_accepted` order.refresh_from_db() validator = OrderInStatusSubValidator( allowed_statuses=(OrderStatus.QUOTE_ACCEPTED,), ) validator(order=order) # lock order to avoid race conditions order.__class__.objects.select_for_update().get(pk=order.pk) # cancel other ongoing sessions for session in self.filter(order=order).ongoing(): session.cancel() # create a new payment gateway session session_id = uuid.uuid4() pay = PayClient() govuk_payment = pay.create_payment( amount=order.total_cost, reference=f'{order.reference}-{str(session_id)[:8].upper()}', description=settings.GOVUK_PAY_PAYMENT_DESCRIPTION.format( reference=order.reference, ), return_url=settings.GOVUK_PAY_RETURN_URL.format( public_token=order.public_token, session_id=session_id, ), ) session = self.create( id=session_id, order=order, govuk_payment_id=govuk_payment['payment_id'], **(attrs or {}), ) return session
def _get_payment_from_govuk_pay(self): """ :returns: the GOV.UK payment data for this payment gateway session :raises GOVUKPayAPIException: if there is a problem with GOV.UK Pay """ return PayClient().get_payment_by_id(self.govuk_payment_id)
def cancel(self): """ Cancels this payment gateway session and the related GOV.UK payment. :raises GOVUKPayAPIException: if there is a problem with GOV.UK Pay """ PayClient().cancel_payment(self.govuk_payment_id) self.refresh_from_govuk_payment()