def create_transaction(request): """This view is called by the phone app to initiate a new transaction""" if request.method != 'POST' or 'data' not in request.POST: raise PermissionDenied transaction = json.loads(request.POST['data']) product = transaction.get('product', '') if transaction['ticket'] is not None and request.user.is_anonymous(): # Ticket operations require that the user is authenticated return HttpResponseBadRequest(json.dumps({ 'errors': [{ 'message': 'Cannot apply ticket operation when user is not authenticated', 'code': error_codes.TICKET_OPERATION_WHILE_NOT_AUTHENTICATED, }] })) if transaction['ticket'] == 'kun_lagre': order = Order( ticket_transaction=True, amount=0, user=request.user, language_code=transaction['språk'], ) order.save() elif product == 'cabin_visit': order = cabin_visit(transaction, request.user) else: return HttpResponseBadRequest(json.dumps({ 'errors': [{ 'message': "Unknown product '%s'" % product, 'code': error_codes.USER_HAS_NO_TICKET, }] })) cancel_return_url = 'https://%s%s' % ( request.site.domain, reverse('payment:postmessage_callback'), ) accept_return_url = 'https://%s%s' % ( request.site.domain, reverse('payment:postmessage_callback'), ) server_callback_url = 'https://%s%s' % ( request.site.domain, reverse('payment:payment_provider_callback'), ) input_parameters = { 'merchant': settings.DIBS_MERCHANT_ID, 'orderId': order.get_order_id(), 'amount': order.amount, # The sum is provided in øre 'currency': 'NOK', # ISO 4217 'captureNow': 1, 'acceptReturnUrl': accept_return_url, 'cancelReturnUrl': cancel_return_url, 'callbackUrl': server_callback_url, 'language': transaction['språk'], } # # Ticket (stored payment card) handling # if transaction['ticket'] is not None: if transaction['ticket'] == 'lagre': # User uses card, but wants to save their ticket input_parameters['createTicketAndAuth'] = 1 elif transaction['ticket'] == 'bruk_lagret': # User claims to have a saved ticket if request.user.dibs_payment_ticket is None: # They thought they did, but they don't return HttpResponseBadRequest(json.dumps({ 'errors': [{ 'message': 'User has no ticket stored', 'code': error_codes.USER_HAS_NO_TICKET, }] })) # We'll perform the DIBS server-to-server call here and return the response to the client try: dibs_response, order, payment_accepted = dibs.authorize_ticket(request, order) if payment_accepted and not order.ticket_transaction: order.try_to_send_email_receipt() return HttpResponse(json.dumps(dibs_response)) except: # Downstream handles exception logging, so just return an error message return { 'errors': [{ 'message': 'Internal error during ticket authorization, please try again', 'code': error_codes.INTERNAL_SERVER_ERROR, }] } elif transaction['ticket'] == 'kun_lagre': # Just create and save a new ticket; no transaction input_parameters['createTicket'] = 1 # Force amount to 1 since DIBS doesn't allow 0 even though it is irrelevant in this situation input_parameters['amount'] = 1 del input_parameters['captureNow'] # # End ticket handling # input_parameters['MAC'] = dibs.calculate_hmac(input_parameters) return HttpResponse(json.dumps(input_parameters))