def checkout_with_shoppingcart(request, user, course_key, course_mode, amount): """ Create an order and trigger checkout using shoppingcart.""" cart = Order.get_cart_for_user(user) cart.clear() enrollment_mode = course_mode.slug CertificateItem.add_to_order(cart, course_key, amount, enrollment_mode) # Change the order's status so that we don't accidentally modify it later. # We need to do this to ensure that the parameters we send to the payment system # match what we store in the database. # (Ordinarily we would do this client-side when the user submits the form, but since # the JavaScript on this page does that immediately, we make the change here instead. # This avoids a second AJAX call and some additional complication of the JavaScript.) # If a user later re-enters the verification / payment flow, she will create a new order. cart.start_purchase() callback_url = request.build_absolute_uri( reverse("shoppingcart.views.postpay_callback") ) payment_data = { 'payment_processor_name': settings.CC_PROCESSOR_NAME, 'payment_page_url': get_purchase_endpoint(), 'payment_form_data': get_signed_purchase_params( cart, callback_url=callback_url, extra_data=[unicode(course_key), course_mode.slug] ), } return payment_data
def checkout_with_shoppingcart(request, user, course_key, course_mode, amount): """ Create an order and trigger checkout using shoppingcart.""" cart = Order.get_cart_for_user(user) cart.clear() enrollment_mode = course_mode.slug CertificateItem.add_to_order(cart, course_key, amount, enrollment_mode) # Change the order's status so that we don't accidentally modify it later. # We need to do this to ensure that the parameters we send to the payment system # match what we store in the database. # (Ordinarily we would do this client-side when the user submits the form, but since # the JavaScript on this page does that immediately, we make the change here instead. # This avoids a second AJAX call and some additional complication of the JavaScript.) # If a user later re-enters the verification / payment flow, she will create a new order. cart.start_purchase() callback_url = request.build_absolute_uri( reverse("shoppingcart.views.postpay_callback")) payment_data = { 'payment_processor_name': settings.CC_PROCESSOR_NAME, 'payment_page_url': get_purchase_endpoint(), 'payment_form_data': get_signed_purchase_params( cart, callback_url=callback_url, extra_data=[unicode(course_key), course_mode.slug]), } return payment_data
def create_order(request): """ Submit PhotoVerification and create a new Order for this verified cert """ if not SoftwareSecurePhotoVerification.user_has_valid_or_pending(request.user): attempt = SoftwareSecurePhotoVerification(user=request.user) b64_face_image = request.POST['face_image'].split(",")[1] b64_photo_id_image = request.POST['photo_id_image'].split(",")[1] attempt.upload_face_image(b64_face_image.decode('base64')) attempt.upload_photo_id_image(b64_photo_id_image.decode('base64')) attempt.mark_ready() attempt.save() course_id = request.POST['course_id'] course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) donation_for_course = request.session.get('donation_for_course', {}) current_donation = donation_for_course.get(course_id, decimal.Decimal(0)) contribution = request.POST.get("contribution", donation_for_course.get(course_id, 0)) try: amount = decimal.Decimal(contribution).quantize(decimal.Decimal('.01'), rounding=decimal.ROUND_DOWN) except decimal.InvalidOperation: return HttpResponseBadRequest(_("Selected price is not valid number.")) if amount != current_donation: donation_for_course[course_id] = amount request.session['donation_for_course'] = donation_for_course # prefer professional mode over verified_mode current_mode = CourseMode.verified_mode_for_course(course_id) if current_mode.slug == 'professional': amount = current_mode.min_price # make sure this course has a verified mode if not current_mode: return HttpResponseBadRequest(_("This course doesn't support verified certificates")) if amount < current_mode.min_price: return HttpResponseBadRequest(_("No selected price or selected price is below minimum.")) # I know, we should check this is valid. All kinds of stuff missing here cart = Order.get_cart_for_user(request.user) cart.clear() enrollment_mode = current_mode.slug CertificateItem.add_to_order(cart, course_id, amount, enrollment_mode) callback_url = request.build_absolute_uri( reverse("shoppingcart.views.postpay_callback") ) params = get_signed_purchase_params( cart, callback_url=callback_url ) return HttpResponse(json.dumps(params), content_type="text/json")
def create_order(request): course_id = request.POST['course_id'] course_id = CourseKey.from_string(course_id) contribution = request.POST.get("contribution") try: amount = decimal.Decimal(contribution).quantize(decimal.Decimal('.01'), rounding=decimal.ROUND_DOWN) except decimal.InvalidOperation: return HttpResponseBadRequest(_("Selected price is not valid number.")) request.session['donation_for_course'] = amount # prefer professional mode over verified_mode current_mode = CourseMode.verified_mode_for_course(course_id) # make sure this course has a verified mode if not current_mode: log.warn(u"Verification requested for course {course_id} without a verified mode.".format(course_id=course_id)) return HttpResponseBadRequest(_("This course doesn't support verified certificates")) if amount < current_mode.min_price: return HttpResponseBadRequest(_("No selected price or selected price is below minimum.")) # I know, we should check this is valid. All kinds of stuff missing here cart = Order.get_cart_for_user(request.user) cart.clear() enrollment_mode = current_mode.slug CertificateItem.add_to_order(cart, course_id, amount, enrollment_mode) # Change the order's status so that we don't accidentally modify it later. # We need to do this to ensure that the parameters we send to the payment system # match what we store in the database. # (Ordinarily we would do this client-side when the user submits the form, but since # the JavaScript on this page does that immediately, we make the change here instead. # This avoids a second AJAX call and some additional complication of the JavaScript.) # If a user later re-enters the verification / payment flow, she will create a new order. cart.start_purchase() callback_url = request.build_absolute_uri( reverse("shoppingcart.views.postpay_callback") ) params = get_signed_purchase_params( cart, callback_url=callback_url, extra_data=[unicode(course_id), current_mode.slug] ) params['success'] = True return HttpResponse(json.dumps(params), content_type="text/json")
def create_order(request): """ Submit PhotoVerification and create a new Order for this verified cert """ # Only submit photos if photo data is provided by the client. # TODO (ECOM-188): Once the A/B test of decoupling verified / payment # completes, we may be able to remove photo submission from this step # entirely. submit_photo = ( 'face_image' in request.POST and 'photo_id_image' in request.POST ) if ( submit_photo and not SoftwareSecurePhotoVerification.user_has_valid_or_pending(request.user) ): attempt = SoftwareSecurePhotoVerification(user=request.user) try: b64_face_image = request.POST['face_image'].split(",")[1] b64_photo_id_image = request.POST['photo_id_image'].split(",")[1] except IndexError: log.error(u"Invalid image data during photo verification.") context = { 'success': False, } return JsonResponse(context) attempt.upload_face_image(b64_face_image.decode('base64')) attempt.upload_photo_id_image(b64_photo_id_image.decode('base64')) attempt.mark_ready() attempt.save() course_id = request.POST['course_id'] course_id = CourseKey.from_string(course_id) donation_for_course = request.session.get('donation_for_course', {}) contribution = request.POST.get("contribution", donation_for_course.get(unicode(course_id), 0)) try: amount = decimal.Decimal(contribution).quantize(decimal.Decimal('.01'), rounding=decimal.ROUND_DOWN) except decimal.InvalidOperation: return HttpResponseBadRequest(_("Selected price is not valid number.")) current_mode = None paid_modes = CourseMode.paid_modes_for_course(course_id) # Check if there are more than 1 paid(mode with min_price>0 e.g verified/professional/no-id-professional) modes # for course exist then choose the first one if paid_modes: if len(paid_modes) > 1: log.warn(u"Multiple paid course modes found for course '%s' for create order request", course_id) current_mode = paid_modes[0] # Make sure this course has a paid mode if not current_mode: log.warn(u"Create order requested for course '%s' without a paid mode.", course_id) return HttpResponseBadRequest(_("This course doesn't support paid certificates")) if CourseMode.is_professional_mode(current_mode): amount = current_mode.min_price if amount < current_mode.min_price: return HttpResponseBadRequest(_("No selected price or selected price is below minimum.")) if current_mode.sku: return create_order_with_ecommerce_service(request.user, course_id, current_mode) # I know, we should check this is valid. All kinds of stuff missing here cart = Order.get_cart_for_user(request.user) cart.clear() enrollment_mode = current_mode.slug CertificateItem.add_to_order(cart, course_id, amount, enrollment_mode) # Change the order's status so that we don't accidentally modify it later. # We need to do this to ensure that the parameters we send to the payment system # match what we store in the database. # (Ordinarily we would do this client-side when the user submits the form, but since # the JavaScript on this page does that immediately, we make the change here instead. # This avoids a second AJAX call and some additional complication of the JavaScript.) # If a user later re-enters the verification / payment flow, she will create a new order. cart.start_purchase() callback_url = request.build_absolute_uri( reverse("shoppingcart.views.postpay_callback") ) params = get_signed_purchase_params( cart, callback_url=callback_url, extra_data=[unicode(course_id), current_mode.slug] ) params['success'] = True return HttpResponse(json.dumps(params), content_type="text/json")
def create_order(request): """ Submit PhotoVerification and create a new Order for this verified cert """ if not SoftwareSecurePhotoVerification.user_has_valid_or_pending( request.user): attempt = SoftwareSecurePhotoVerification(user=request.user) try: b64_face_image = request.POST['face_image'].split(",")[1] b64_photo_id_image = request.POST['photo_id_image'].split(",")[1] except IndexError: context = { 'success': False, } return JsonResponse(context) attempt.upload_face_image(b64_face_image.decode('base64')) attempt.upload_photo_id_image(b64_photo_id_image.decode('base64')) attempt.mark_ready() attempt.save() course_id = request.POST['course_id'] course_id = CourseKey.from_string(course_id) donation_for_course = request.session.get('donation_for_course', {}) current_donation = donation_for_course.get(unicode(course_id), decimal.Decimal(0)) contribution = request.POST.get( "contribution", donation_for_course.get(unicode(course_id), 0)) try: amount = decimal.Decimal(contribution).quantize( decimal.Decimal('.01'), rounding=decimal.ROUND_DOWN) except decimal.InvalidOperation: return HttpResponseBadRequest(_("Selected price is not valid number.")) if amount != current_donation: donation_for_course[unicode(course_id)] = amount request.session['donation_for_course'] = donation_for_course # prefer professional mode over verified_mode current_mode = CourseMode.verified_mode_for_course(course_id) # make sure this course has a verified mode if not current_mode: return HttpResponseBadRequest( _("This course doesn't support verified certificates")) if current_mode.slug == 'professional': amount = current_mode.min_price if amount < current_mode.min_price: return HttpResponseBadRequest( _("No selected price or selected price is below minimum.")) # I know, we should check this is valid. All kinds of stuff missing here cart = Order.get_cart_for_user(request.user) cart.clear() enrollment_mode = current_mode.slug CertificateItem.add_to_order(cart, course_id, amount, enrollment_mode) # Change the order's status so that we don't accidentally modify it later. # We need to do this to ensure that the parameters we send to the payment system # match what we store in the database. # (Ordinarily we would do this client-side when the user submits the form, but since # the JavaScript on this page does that immediately, we make the change here instead. # This avoids a second AJAX call and some additional complication of the JavaScript.) # If a user later re-enters the verification / payment flow, she will create a new order. cart.start_purchase() callback_url = request.build_absolute_uri( reverse("shoppingcart.views.postpay_callback")) params = get_signed_purchase_params(cart, callback_url=callback_url, extra_data=[unicode(course_id)]) params['success'] = True return HttpResponse(json.dumps(params), content_type="text/json")
def create_order(request): """ Submit PhotoVerification and create a new Order for this verified cert """ if not SoftwareSecurePhotoVerification.user_has_valid_or_pending(request.user): attempt = SoftwareSecurePhotoVerification(user=request.user) try: b64_face_image = request.POST['face_image'].split(",")[1] b64_photo_id_image = request.POST['photo_id_image'].split(",")[1] except IndexError: context = { 'success': False, } return JsonResponse(context) attempt.upload_face_image(b64_face_image.decode('base64')) attempt.upload_photo_id_image(b64_photo_id_image.decode('base64')) attempt.mark_ready() attempt.save() course_id = request.POST['course_id'] course_id = CourseKey.from_string(course_id) donation_for_course = request.session.get('donation_for_course', {}) current_donation = donation_for_course.get(unicode(course_id), decimal.Decimal(0)) contribution = request.POST.get("contribution", donation_for_course.get(unicode(course_id), 0)) try: amount = decimal.Decimal(contribution).quantize(decimal.Decimal('.01'), rounding=decimal.ROUND_DOWN) except decimal.InvalidOperation: return HttpResponseBadRequest(_("Selected price is not valid number.")) if amount != current_donation: donation_for_course[unicode(course_id)] = amount request.session['donation_for_course'] = donation_for_course # prefer professional mode over verified_mode current_mode = CourseMode.verified_mode_for_course(course_id) # make sure this course has a verified mode if not current_mode: return HttpResponseBadRequest(_("This course doesn't support verified certificates")) if current_mode.slug == 'professional': amount = current_mode.min_price if amount < current_mode.min_price: return HttpResponseBadRequest(_("No selected price or selected price is below minimum.")) # I know, we should check this is valid. All kinds of stuff missing here cart = Order.get_cart_for_user(request.user) cart.clear() enrollment_mode = current_mode.slug CertificateItem.add_to_order(cart, course_id, amount, enrollment_mode) # Change the order's status so that we don't accidentally modify it later. # We need to do this to ensure that the parameters we send to the payment system # match what we store in the database. # (Ordinarily we would do this client-side when the user submits the form, but since # the JavaScript on this page does that immediately, we make the change here instead. # This avoids a second AJAX call and some additional complication of the JavaScript.) # If a user later re-enters the verification / payment flow, she will create a new order. cart.start_purchase() callback_url = request.build_absolute_uri( reverse("shoppingcart.views.postpay_callback") ) params = get_signed_purchase_params( cart, callback_url=callback_url, extra_data=[unicode(course_id), current_mode.slug] ) params['success'] = True return HttpResponse(json.dumps(params), content_type="text/json")
def create_order(request): """ Submit PhotoVerification and create a new Order for this verified cert """ # Only submit photos if photo data is provided by the client. # TODO (ECOM-188): Once the A/B test of decoupling verified / payment # completes, we may be able to remove photo submission from this step # entirely. submit_photo = ( 'face_image' in request.POST and 'photo_id_image' in request.POST ) if ( submit_photo and not SoftwareSecurePhotoVerification.user_has_valid_or_pending(request.user) ): attempt = SoftwareSecurePhotoVerification(user=request.user) try: b64_face_image = request.POST['face_image'].split(",")[1] b64_photo_id_image = request.POST['photo_id_image'].split(",")[1] except IndexError: log.error(u"Invalid image data during photo verification.") context = { 'success': False, } return JsonResponse(context) attempt.upload_face_image(b64_face_image.decode('base64')) attempt.upload_photo_id_image(b64_photo_id_image.decode('base64')) attempt.mark_ready() attempt.save() course_id = request.POST['course_id'] course_id = CourseKey.from_string(course_id) donation_for_course = request.session.get('donation_for_course', {}) contribution = request.POST.get("contribution", donation_for_course.get(unicode(course_id), 0)) try: amount = decimal.Decimal(contribution).quantize(decimal.Decimal('.01'), rounding=decimal.ROUND_DOWN) except decimal.InvalidOperation: return HttpResponseBadRequest(_("Selected price is not valid number.")) current_mode = None paid_modes = CourseMode.paid_modes_for_course(course_id) # Check if there are more than 1 paid(mode with min_price>0 e.g verified/professional/no-id-professional) modes # for course exist then choose the first one if paid_modes: if len(paid_modes) > 1: log.warn(u"Multiple paid course modes found for course '%s' for create order request", course_id) current_mode = paid_modes[0] # Make sure this course has a paid mode if not current_mode: log.warn(u"Create order requested for course '%s' without a paid mode.", course_id) return HttpResponseBadRequest(_("This course doesn't support paid certificates")) if CourseMode.is_professional_mode(current_mode): amount = current_mode.min_price if amount < current_mode.min_price: return HttpResponseBadRequest(_("No selected price or selected price is below minimum.")) if current_mode.sku: return create_order_with_ecommerce_service(request.user, course_id, current_mode) # I know, we should check this is valid. All kinds of stuff missing here cart = Order.get_cart_for_user(request.user) cart.clear() enrollment_mode = current_mode.slug CertificateItem.add_to_order(cart, course_id, amount, enrollment_mode) # Change the order's status so that we don't accidentally modify it later. # We need to do this to ensure that the parameters we send to the payment system # match what we store in the database. # (Ordinarily we would do this client-side when the user submits the form, but since # the JavaScript on this page does that immediately, we make the change here instead. # This avoids a second AJAX call and some additional complication of the JavaScript.) # If a user later re-enters the verification / payment flow, she will create a new order. cart.start_purchase() callback_url = request.build_absolute_uri( reverse("shoppingcart.views.postpay_callback") ) params = get_signed_purchase_params( cart, callback_url=callback_url, extra_data=[unicode(course_id), current_mode.slug] ) params['success'] = True return HttpResponse(json.dumps(params), content_type="text/json")
def create_order(request): """ Submit PhotoVerification and create a new Order for this verified cert """ # Only submit photos if photo data is provided by the client. # TODO (ECOM-188): Once the A/B test of decoupling verified / payment # completes, we may be able to remove photo submission from this step # entirely. submit_photo = "face_image" in request.POST and "photo_id_image" in request.POST if submit_photo and not SoftwareSecurePhotoVerification.user_has_valid_or_pending(request.user): attempt = SoftwareSecurePhotoVerification(user=request.user) try: b64_face_image = request.POST["face_image"].split(",")[1] b64_photo_id_image = request.POST["photo_id_image"].split(",")[1] except IndexError: log.error(u"Invalid image data during photo verification.") context = {"success": False} return JsonResponse(context) attempt.upload_face_image(b64_face_image.decode("base64")) attempt.upload_photo_id_image(b64_photo_id_image.decode("base64")) attempt.mark_ready() attempt.save() course_id = request.POST["course_id"] course_id = CourseKey.from_string(course_id) donation_for_course = request.session.get("donation_for_course", {}) current_donation = donation_for_course.get(unicode(course_id), decimal.Decimal(0)) contribution = request.POST.get("contribution", donation_for_course.get(unicode(course_id), 0)) try: amount = decimal.Decimal(contribution).quantize(decimal.Decimal(".01"), rounding=decimal.ROUND_DOWN) except decimal.InvalidOperation: return HttpResponseBadRequest(_("Selected price is not valid number.")) if amount != current_donation: donation_for_course[unicode(course_id)] = amount request.session["donation_for_course"] = donation_for_course # prefer professional mode over verified_mode current_mode = CourseMode.verified_mode_for_course(course_id) # make sure this course has a verified mode if not current_mode: log.warn(u"Verification requested for course {course_id} without a verified mode.".format(course_id=course_id)) return HttpResponseBadRequest(_("This course doesn't support verified certificates")) if current_mode.slug == "professional": amount = current_mode.min_price if amount < current_mode.min_price: return HttpResponseBadRequest(_("No selected price or selected price is below minimum.")) # I know, we should check this is valid. All kinds of stuff missing here cart = Order.get_cart_for_user(request.user) cart.clear() enrollment_mode = current_mode.slug CertificateItem.add_to_order(cart, course_id, amount, enrollment_mode, currency=current_mode.currency) # Change the order's status so that we don't accidentally modify it later. # We need to do this to ensure that the parameters we send to the payment system # match what we store in the database. # (Ordinarily we would do this client-side when the user submits the form, but since # the JavaScript on this page does that immediately, we make the change here instead. # This avoids a second AJAX call and some additional complication of the JavaScript.) # If a user later re-enters the verification / payment flow, she will create a new order. cart.start_purchase() callback_url = request.build_absolute_uri(reverse("shoppingcart.views.postpay_callback")) params = get_signed_purchase_params( cart, callback_url=callback_url, extra_data=[unicode(course_id), current_mode.slug] ) # params['success'] = True # return HttpResponse(json.dumps(params), content_type="text/json") processor = settings.CC_PROCESSOR.get(settings.CC_PROCESSOR_NAME, {}) callback_data = { "description": "Верифікований сертифікат", "order_id": cart.id, "server_url": processor.get("SERVER_URL", ""), "currency": processor.get("CURRENCY", ""), "result_url": processor.get("RESULT_URL", ""), "public_key": processor.get("PUBLIC_KEY", ""), "language": processor.get("LANGUAGE", "en"), "pay_way": processor.get("PAY_WAY", ""), "amount": current_mode.min_price, "sandbox": processor.get("SANDBOX", 0), "version": processor.get("VERSION", 3), "type": "buy", } log.warn(json.dumps(callback_data)) # callback_data = { # "description": "Верифікований сертифікат", # "order_id": cart.id, # "server_url": "http://courses.prometheus.org.ua/shoppingcart/postpay_callback/", # "currency": "UAH", # "result_url": "http://courses.prometheus.org.ua/shoppingcart/postpay_callback/", # "public_key": "", # "language": "en", # "pay_way": "card,liqpay,privat24", # "amount": "5", # "sandbox": "1", # "version": 3, # "type": "buy" # } callback_data = base64.b64encode(json.dumps(callback_data)) private_key = processor.get("PRIVATE_KEY", "") callback_signature = base64.b64encode(sha.new(private_key + callback_data + private_key).digest()) params["data"] = callback_data params["signature"] = callback_signature return HttpResponse(json.dumps(params), content_type="text/json")