def post(self, request, *args, **kwargs): user = request.user email = user.email customer_id = user.tracking_context['customer_id'] customer = stripe.Customer.retrieve(customer_id) user_basket = Basket.objects.filter(owner=request.user, status="Commited").last() if user_basket: user_basket.strategy = Selector().strategy(user=self.request.user) else: return Response({ "message": "No item found in cart.", "status": False, "result": {}, "status_code": 400 }) if waffle.flag_is_active( request, DYNAMIC_DISCOUNT_FLAG) and user_basket.lines.count() > 0: discount_lms_url = get_lms_url('/api/discounts/') lms_discount_client = EdxRestApiClient( discount_lms_url, jwt=request.site.siteconfiguration.access_token) ck = user_basket.lines.first().product.course_id user_id = user_basket.owner.lms_user_id response = lms_discount_client.course(ck).get() jwt = jwt_decode_handler(response.get('jwt')) if jwt['discount_applicable']: offers = Applicator().get_offers(user_basket, request.user, request) user_basket.strategy = request.strategy discount_benefit = DynamicPercentageDiscountBenefit() percentage = jwt['discount_percent'] discount_benefit.apply(user_basket, 'dynamic_discount_condition', offers[0], discount_percent=percentage) Applicator().apply(user_basket, self.request.user, self.request) if user_basket.status == "Commited": total_amount = int(user_basket.total_incl_tax) if total_amount > 0: try: with transaction.atomic(): payment_response = self.make_stripe_payment_for_mobile( None, user_basket) response = {"total_amount": payment_response.total, "transaction_id": payment_response.transaction_id, \ "currency": payment_response.currency, "client_secret": payment_response.client_secret} # Freezing basket to prevent student from getting enrolled to possibily unpaid courses user_basket.status = Basket.FROZEN user_basket.save() return Response({ "message": "Payment completed.", "status": True, "result": response, "status_code": 200 }) except Exception as e: logger.exception(e) msg = 'Attempts to handle payment for basket ' + str( user_basket.id) + ' failed.' return Response({ "message": msg, "status": False, "result": {}, "status_code": 400 }) else: return Response({ "message": "Total amount must be greater than 0.", "status": False, "result": {}, "status_code": 400 }) else: return Response({ "message": "No item found in cart.", "status": False, "result": {}, "status_code": 400 })
class EnrollmentApiClient(object): """ Object builds an API client to make calls to the edxapp Enrollment API. Authenticates using settings.OPENEDX_EDX_API_KEY. """ API_BASE_URL = settings.OPENEDX_ENROLLMENT_API_URI APPEND_SLASH = False CACHE_ACCOUNTS_PREFIX = "enrollmentapi_data__" def __init__(self): """ Create an LMS API client, authenticated with the OAuth2 token for client in settings """ # session = Session() # # session.headers = {"X-Edx-Api-Key": settings.OPENEDX_EDX_API_KEY} token = EdxRestApiClient.get_oauth_access_token( url="{}{}".format(settings.OPENEDX_PLATFORM_URI, constants.OPENEDX_OAUTH2_TOKEN_URL), client_id=settings.OPENEDX_OAUTH2_CLIENT_ID, client_secret=settings.OPENEDX_OAUTH2_CLIENT_SECRET, ) self.cache = False if settings.LMS_API_USE_MEMCACHED: self.cache = memcache.Client([settings.MEMCACHED_ADDRESS], debug=0) self.client = EdxRestApiClient(self.API_BASE_URL, append_slash=self.APPEND_SLASH, username="******", oauth_access_token=token[0]) def get_course_info(self, course_id, unti=False): """ Query the Enrollment API for the course details of the given course_id. unti is flag for University 2035 LRS data inegration """ try: resp = self.client.course( u'{}?include_expired=1'.format(course_id)).get() if resp: data = { 'name': resp['course_name'], 'description': resp['description'] } if unti and resp['integrate_2035_id'].strip(): data.update({'2035_id': resp['integrate_2035_id']}) logger.error('get_course_info {}'.format(data)) return data #if unti and resp: # if resp['integrate_2035_id'].strip(): # return {'name': resp['course_name'], '2035_id': resp['integrate_2035_id'], 'description': resp['description']} # else: # message = 'Course {} not found in University 2035 database'.format(course_id) # raise exceptions.XAPIBridgeCourseNotFoundError(message) #elif resp: # return {'name': resp['course_name'], 'description': resp['description']} else: # TODO: look at other reasons for no resp.success message = 'Failed to retrieve course details for course id {}. Course not found in LMS'.format( course_id) raise exceptions.XAPIBridgeCourseNotFoundError(message) except (SlumberBaseException, ConnectionError, Timeout, HttpClientError) as e: message = 'Failed to retrieve course details for course id {} due to: {}'.format( course_id, str(e)) e = exceptions.XAPIBridgeConnectionError(message) e.err_continue_exc() raise exceptions.XAPIBridgeCourseNotFoundError(message)
def form_valid(self, form): form_data = form.cleaned_data #basket = form_data['basket'] committed_basket = Basket.objects.filter(owner=self.request.user, status="Commited").last() committed_basket.strategy = self.request.strategy committed_basket.save() token = form_data['stripe_token'] order_number = committed_basket.order_number if waffle.flag_is_active( self.request, DYNAMIC_DISCOUNT_FLAG) and committed_basket.lines.count() == 1: discount_lms_url = get_lms_url('/api/discounts/') lms_discount_client = EdxRestApiClient( discount_lms_url, jwt=self.request.site.siteconfiguration.access_token) ck = committed_basket.lines.first().product.course_id user_id = committed_basket.owner.lms_user_id response = lms_discount_client.course(ck).get() self.request.GET = self.request.GET.copy() self.request.GET['discount_jwt'] = response.get('jwt') self.request.POST = self.request.POST.copy() self.request.POST['discount_jwt'] = response.get('jwt') Applicator().apply(committed_basket, self.request.user, self.request) basket_add_organization_attribute(committed_basket, self.request.POST) committed_basket.freeze() try: billing_address = self.payment_processor.get_address_from_token( token) except Exception: # pylint: disable=broad-except logger.exception( 'An error occurred while parsing the billing address for basket [%d]. No billing address will be ' 'stored for the resulting order [%s].', committed_basket.id, order_number) billing_address = None try: self.handle_payment(token, committed_basket) except Exception: # pylint: disable=broad-except logger.exception( 'An error occurred while processing the Stripe payment for basket [%d].', committed_basket.id) return JsonResponse({}, status=400) # Remove paid items from last open baskets user_baskets = Basket.objects.filter(owner=self.request.user, status="Open") if user_baskets.exists(): last_open_basket = user_baskets.last() del_lines = committed_basket.all_lines() open_lines = last_open_basket.all_lines() for line in del_lines: product = line.product filtered_lines = open_lines.filter(product_id=product.id) if filtered_lines.exists(): filtered_lines.delete() last_open_basket.save() try: order = self.create_order(self.request, committed_basket, billing_address=billing_address) send_confirm_purchase_email(None, user=self.request.user, order=order) except Exception: # pylint: disable=broad-except logger.exception( 'An error occurred while processing the Stripe payment for basket [%d].', committed_basket.id) return JsonResponse({}, status=400) self.handle_post_order(order) receipt_url = get_receipt_page_url( site_configuration=self.request.site.siteconfiguration, order_number=order_number, disable_back_button=True, ) return JsonResponse({'url': receipt_url}, status=201)