diff --git a/common/djangoapps/student/views.py b/common/djangoapps/student/views.py
index 14be87b3000a12f6499a3efef8177d534b9a4b32..94a81590e4fd813c35ce37ff038a80f4dcfb5786 100644
--- a/common/djangoapps/student/views.py
+++ b/common/djangoapps/student/views.py
@@ -446,13 +446,17 @@ def is_course_blocked(request, redeemed_registration_codes, course_key):
     """Checking either registration is blocked or not ."""
     blocked = False
     for redeemed_registration in redeemed_registration_codes:
-        if not getattr(redeemed_registration.invoice, 'is_valid'):
-            blocked = True
-            # disabling email notifications for unpaid registration courses
-            Optout.objects.get_or_create(user=request.user, course_id=course_key)
-            log.info(u"User {0} ({1}) opted out of receiving emails from course {2}".format(request.user.username, request.user.email, course_key))
-            track.views.server_track(request, "change-email1-settings", {"receive_emails": "no", "course": course_key.to_deprecated_string()}, page='dashboard')
-            break
+        # registration codes may be generated via Bulk Purchase Scenario
+        # we have to check only for the invoice generated registration codes
+        # that their invoice is valid or not
+        if redeemed_registration.invoice:
+            if not getattr(redeemed_registration.invoice, 'is_valid'):
+                blocked = True
+                # disabling email notifications for unpaid registration courses
+                Optout.objects.get_or_create(user=request.user, course_id=course_key)
+                log.info(u"User {0} ({1}) opted out of receiving emails from course {2}".format(request.user.username, request.user.email, course_key))
+                track.views.server_track(request, "change-email1-settings", {"receive_emails": "no", "course": course_key.to_deprecated_string()}, page='dashboard')
+                break
 
     return blocked
 
diff --git a/lms/djangoapps/courseware/views.py b/lms/djangoapps/courseware/views.py
index f92326690a87afca5e91f5ca4ec88d15923e3915..520c2f7db4af99b1f30b896c6650879097ef1299 100644
--- a/lms/djangoapps/courseware/views.py
+++ b/lms/djangoapps/courseware/views.py
@@ -39,7 +39,7 @@ from course_modes.models import CourseMode
 
 from open_ended_grading import open_ended_notifications
 from student.models import UserTestGroup, CourseEnrollment
-from student.views import single_course_reverification_info
+from student.views import single_course_reverification_info, is_course_blocked
 from util.cache import cache, cache_if_anonymous
 from xblock.fragment import Fragment
 from xmodule.modulestore.django import modulestore
@@ -277,12 +277,22 @@ def index(request, course_id, chapter=None, section=None,
 
     user = User.objects.prefetch_related("groups").get(id=request.user.id)
 
-    # Redirecting to dashboard if the course is blocked due to un payment.
-    redeemed_registration_codes = CourseRegistrationCode.objects.filter(course_id=course_key, registrationcoderedemption__redeemed_by=request.user)
-    for redeemed_registration in redeemed_registration_codes:
-        if not getattr(redeemed_registration.invoice, 'is_valid'):
-            log.warning(u'User %s cannot access the course %s because payment has not yet been received', user, course_key.to_deprecated_string())
-            return redirect(reverse('dashboard'))
+    redeemed_registration_codes = CourseRegistrationCode.objects.filter(
+        course_id=course_key,
+        registrationcoderedemption__redeemed_by=request.user
+    )
+
+    # Redirect to dashboard if the course is blocked due to non-payment.
+    if is_course_blocked(request, redeemed_registration_codes, course_key):
+        # registration codes may be generated via Bulk Purchase Scenario
+        # we have to check only for the invoice generated registration codes
+        # that their invoice is valid or not
+        log.warning(
+            u'User %s cannot access the course %s because payment has not yet been received',
+            user,
+            course_key.to_deprecated_string()
+        )
+        return redirect(reverse('dashboard'))
 
     request.user = user  # keep just one instance of User
     with modulestore().bulk_operations(course_key):
@@ -703,7 +713,8 @@ def course_about(request, course_id):
                                                                       settings.PAID_COURSE_REGISTRATION_CURRENCY[0])
         if request.user.is_authenticated():
             cart = shoppingcart.models.Order.get_cart_for_user(request.user)
-            in_cart = shoppingcart.models.PaidCourseRegistration.contained_in_order(cart, course_key)
+            in_cart = shoppingcart.models.PaidCourseRegistration.contained_in_order(cart, course_key) or \
+                shoppingcart.models.CourseRegCodeItem.contained_in_order(cart, course_key)
 
         reg_then_add_to_cart_link = "{reg_url}?course_id={course_id}&enrollment_action=add_to_cart".format(
             reg_url=reverse('register_user'), course_id=course.id.to_deprecated_string())
diff --git a/lms/djangoapps/instructor/tests/test_api.py b/lms/djangoapps/instructor/tests/test_api.py
index 480622672b45ebce33d521cb9b5536a2726baabf..94c980fa5ae0a58b0b38021a96a581077b754277 100644
--- a/lms/djangoapps/instructor/tests/test_api.py
+++ b/lms/djangoapps/instructor/tests/test_api.py
@@ -1448,6 +1448,21 @@ class TestInstructorAPILevelsDataDump(ModuleStoreTestCase, LoginEnrollmentTestCa
         response = self.client.get(url + '/csv', {})
         self.assertEqual(response['Content-Type'], 'text/csv')
 
+    def test_get_sale_order_records_features_csv(self):
+        """
+        Test that the response from get_sale_order_records is in csv format.
+        """
+        self.cart.order_type = 'business'
+        self.cart.save()
+        self.cart.add_billing_details(company_name='Test Company', company_contact_name='Test',
+                                      company_contact_email='test@123', recipient_name='R1',
+                                      recipient_email='', customer_reference_number='PO#23')
+        PaidCourseRegistration.add_to_order(self.cart, self.course.id)
+        self.cart.purchase()
+        sale_order_url = reverse('get_sale_order_records', kwargs={'course_id': self.course.id.to_deprecated_string()})
+        response = self.client.get(sale_order_url)
+        self.assertEqual(response['Content-Type'], 'text/csv')
+
     def test_get_sale_records_features_csv(self):
         """
         Test that the response from get_sale_records is in csv format.
diff --git a/lms/djangoapps/instructor/views/api.py b/lms/djangoapps/instructor/views/api.py
index c395823a149f4693f77e8b64faa98c5adc9aee53..7b92a1351648455ccc8ed80d7302bd6b5f3cc64a 100644
--- a/lms/djangoapps/instructor/views/api.py
+++ b/lms/djangoapps/instructor/views/api.py
@@ -588,7 +588,47 @@ def get_sale_records(request, course_id, csv=False):  # pylint: disable=W0613, W
         return JsonResponse(response_payload)
     else:
         header, datarows = instructor_analytics.csvs.format_dictlist(sale_data, query_features)
-        return instructor_analytics.csvs.create_csv_response("e-commerce_sale_records.csv", header, datarows)
+        return instructor_analytics.csvs.create_csv_response("e-commerce_sale_invoice_records.csv", header, datarows)
+
+
+@ensure_csrf_cookie
+@cache_control(no_cache=True, no_store=True, must_revalidate=True)
+@require_level('staff')
+def get_sale_order_records(request, course_id):  # pylint: disable=W0613, W0621
+    """
+    return the summary of all sales records for a particular course
+    """
+    course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id)
+    query_features = [
+        ('id', 'Order Id'),
+        ('company_name', 'Company Name'),
+        ('company_contact_name', 'Company Contact Name'),
+        ('company_contact_email', 'Company Contact Email'),
+        ('total_amount', 'Total Amount'),
+        ('total_codes', 'Total Codes'),
+        ('total_used_codes', 'Total Used Codes'),
+        ('logged_in_username', 'Login Username'),
+        ('logged_in_email', 'Login User Email'),
+        ('purchase_time', 'Date of Sale'),
+        ('customer_reference_number', 'Customer Reference Number'),
+        ('recipient_name', 'Recipient Name'),
+        ('recipient_email', 'Recipient Email'),
+        ('bill_to_street1', 'Street 1'),
+        ('bill_to_street2', 'Street 2'),
+        ('bill_to_city', 'City'),
+        ('bill_to_state', 'State'),
+        ('bill_to_postalcode', 'Postal Code'),
+        ('bill_to_country', 'Country'),
+        ('order_type', 'Order Type'),
+        ('codes', 'Registration Codes'),
+        ('course_id', 'Course Id')
+    ]
+
+    db_columns = [x[0] for x in query_features]
+    csv_columns = [x[1] for x in query_features]
+    sale_data = instructor_analytics.basic.sale_order_record_features(course_id, db_columns)
+    header, datarows = instructor_analytics.csvs.format_dictlist(sale_data, db_columns)  # pylint: disable=W0612
+    return instructor_analytics.csvs.create_csv_response("e-commerce_sale_order_records.csv", csv_columns, datarows)
 
 
 @require_level('staff')
@@ -766,7 +806,7 @@ def get_coupon_codes(request, course_id):  # pylint: disable=W0613
     return instructor_analytics.csvs.create_csv_response('Coupons.csv', header, data_rows)
 
 
-def save_registration_codes(request, course_id, generated_codes_list, invoice):
+def save_registration_code(user, course_id, invoice=None, order=None):
     """
     recursive function that generate a new code every time and saves in the Course Registration Table
     if validation check passes
@@ -776,16 +816,16 @@ def save_registration_codes(request, course_id, generated_codes_list, invoice):
     # check if the generated code is in the Coupon Table
     matching_coupons = Coupon.objects.filter(code=code, is_active=True)
     if matching_coupons:
-        return save_registration_codes(request, course_id, generated_codes_list, invoice)
+        return save_registration_code(user, course_id, invoice, order)
 
     course_registration = CourseRegistrationCode(
-        code=code, course_id=course_id.to_deprecated_string(), created_by=request.user, invoice=invoice
+        code=code, course_id=course_id.to_deprecated_string(), created_by=user, invoice=invoice, order=order
     )
     try:
         course_registration.save()
-        generated_codes_list.append(course_registration)
+        return course_registration
     except IntegrityError:
-        return save_registration_codes(request, course_id, generated_codes_list, invoice)
+        return save_registration_code(user, course_id, invoice, order)
 
 
 def registration_codes_csv(file_name, codes_list, csv_type=None):
@@ -851,7 +891,6 @@ def generate_registration_codes(request, course_id):
     Respond with csv which contains a summary of all Generated Codes.
     """
     course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id)
-    course_registration_codes = []
     invoice_copy = False
 
     # covert the course registration code number into integer
@@ -888,8 +927,10 @@ def generate_registration_codes(request, course_id):
         address_line_3=address_line_3, city=city, state=state, zip=zip_code, country=country,
         internal_reference=internal_reference, customer_reference_number=customer_reference_number
     )
+    registration_codes = []
     for _ in range(course_code_number):  # pylint: disable=W0621
-        save_registration_codes(request, course_id, course_registration_codes, sale_invoice)
+        generated_registration_code = save_registration_code(request.user, course_id, sale_invoice, order=None)
+        registration_codes.append(generated_registration_code)
 
     site_name = microsite.get_value('SITE_NAME', 'localhost')
     course = get_course_by_id(course_id, depth=None)
@@ -916,7 +957,7 @@ def generate_registration_codes(request, course_id):
         'discount': discount,
         'sale_price': sale_price,
         'quantity': quantity,
-        'registration_codes': course_registration_codes,
+        'registration_codes': registration_codes,
         'course_url': course_url,
         'platform_name': microsite.get_value('platform_name', settings.PLATFORM_NAME),
         'dashboard_url': dashboard_url,
@@ -934,7 +975,7 @@ def generate_registration_codes(request, course_id):
     #send_mail(subject, message, from_address, recipient_list, fail_silently=False)
     csv_file = StringIO.StringIO()
     csv_writer = csv.writer(csv_file)
-    for registration_code in course_registration_codes:
+    for registration_code in registration_codes:
         csv_writer.writerow([registration_code.code])
 
     # send a unique email for each recipient, don't put all email addresses in a single email
@@ -948,7 +989,7 @@ def generate_registration_codes(request, course_id):
         email.attach(u'Invoice.txt', invoice_attachment, 'text/plain')
         email.send()
 
-    return registration_codes_csv("Registration_Codes.csv", course_registration_codes)
+    return registration_codes_csv("Registration_Codes.csv", registration_codes)
 
 
 @ensure_csrf_cookie
diff --git a/lms/djangoapps/instructor/views/api_urls.py b/lms/djangoapps/instructor/views/api_urls.py
index 3bf9ba651f5890fd5a841ab5e96503253772e22b..4968f1b1045a85eccb753530b89695b4d915c0ee 100644
--- a/lms/djangoapps/instructor/views/api_urls.py
+++ b/lms/djangoapps/instructor/views/api_urls.py
@@ -23,6 +23,8 @@ urlpatterns = patterns('',  # nopep8
         'instructor.views.api.get_user_invoice_preference', name="get_user_invoice_preference"),
     url(r'^get_sale_records(?P<csv>/csv)?$',
         'instructor.views.api.get_sale_records', name="get_sale_records"),
+    url(r'^get_sale_order_records$',
+        'instructor.views.api.get_sale_order_records', name="get_sale_order_records"),
     url(r'^sale_validation_url$',
         'instructor.views.api.sale_validation', name="sale_validation"),
     url(r'^get_anon_ids$',
diff --git a/lms/djangoapps/instructor/views/coupons.py b/lms/djangoapps/instructor/views/coupons.py
index 48f9828863076a4ae15e49b31d3e9fe29f2f14a1..c4ec58d9d246e8874589e6cae1504f17c32a9f62 100644
--- a/lms/djangoapps/instructor/views/coupons.py
+++ b/lms/djangoapps/instructor/views/coupons.py
@@ -62,27 +62,36 @@ def add_coupon(request, course_id):  # pylint: disable=W0613
         # check if the coupon code is in the CourseRegistrationCode Table
         course_registration_code = CourseRegistrationCode.objects.filter(code=code)
         if course_registration_code:
-            return HttpResponseNotFound(_(
-                "The code ({code}) that you have tried to define is already in use as a registration code").format(code=code)
-            )
+            return JsonResponse(
+                {'message': _("The code ({code}) that you have tried to define is already in use as a registration code").format(code=code)},
+                status=400)  # status code 400: Bad Request
 
         description = request.POST.get('description')
         course_id = request.POST.get('course_id')
         try:
             discount = int(request.POST.get('discount'))
         except ValueError:
-            return HttpResponseNotFound(_("Please Enter the Integer Value for Coupon Discount"))
+            return JsonResponse({
+                'message': _("Please Enter the Integer Value for Coupon Discount")
+            }, status=400)  # status code 400: Bad Request
+
         if discount > 100 or discount < 0:
-            return HttpResponseNotFound(_("Please Enter the Coupon Discount Value Less than or Equal to 100"))
+            return JsonResponse({
+                'message': _("Please Enter the Coupon Discount Value Less than or Equal to 100")
+            }, status=400)  # status code 400: Bad Request
         coupon = Coupon(
             code=code, description=description, course_id=course_id,
             percentage_discount=discount, created_by_id=request.user.id
         )
         coupon.save()
-        return HttpResponse(_("coupon with the coupon code ({code}) added successfully").format(code=code))
+        return JsonResponse(
+            {'message': _("coupon with the coupon code ({code}) added successfully").format(code=code)}
+        )
 
     if coupon:
-        return HttpResponseNotFound(_("coupon with the coupon code ({code}) already exists for this course").format(code=code))
+        return JsonResponse(
+            {'message': _("coupon with the coupon code ({code}) already exists for this course").format(code=code)},
+            status=400)  # status code 400: Bad Request
 
 
 @require_POST
@@ -93,17 +102,21 @@ def update_coupon(request, course_id):  # pylint: disable=W0613
     """
     coupon_id = request.POST.get('coupon_id', None)
     if not coupon_id:
-        return HttpResponseNotFound(_("coupon id not found"))
+        return JsonResponse({'message': _("coupon id not found")}, status=400)  # status code 400: Bad Request
 
     try:
         coupon = Coupon.objects.get(pk=coupon_id)
     except ObjectDoesNotExist:
-        return HttpResponseNotFound(_("coupon with the coupon id ({coupon_id}) DoesNotExist").format(coupon_id=coupon_id))
+        return JsonResponse(
+            {'message': _("coupon with the coupon id ({coupon_id}) DoesNotExist").format(coupon_id=coupon_id)},
+            status=400)  # status code 400: Bad Request
 
     description = request.POST.get('description')
     coupon.description = description
     coupon.save()
-    return HttpResponse(_("coupon with the coupon id ({coupon_id}) updated Successfully").format(coupon_id=coupon_id))
+    return JsonResponse(
+        {'message': _("coupon with the coupon id ({coupon_id}) updated Successfully").format(coupon_id=coupon_id)}
+    )
 
 
 @require_POST
diff --git a/lms/djangoapps/instructor/views/instructor_dashboard.py b/lms/djangoapps/instructor/views/instructor_dashboard.py
index af1959f20931806556eab9f51d38d63e83c20948..12e01a32c379ec0c3c756f862f2b13f62d51a97b 100644
--- a/lms/djangoapps/instructor/views/instructor_dashboard.py
+++ b/lms/djangoapps/instructor/views/instructor_dashboard.py
@@ -17,6 +17,7 @@ from django.core.urlresolvers import reverse
 from django.utils.html import escape
 from django.http import Http404, HttpResponse, HttpResponseNotFound
 from django.conf import settings
+from util.json_request import JsonResponse
 
 from lms.lib.xblock.runtime import quote_slashes
 from xmodule_modifiers import wrap_xblock
@@ -158,6 +159,7 @@ def _section_e_commerce(course, access):
         'ajax_add_coupon': reverse('add_coupon', kwargs={'course_id': course_key.to_deprecated_string()}),
         'get_purchase_transaction_url': reverse('get_purchase_transaction', kwargs={'course_id': course_key.to_deprecated_string()}),
         'get_sale_records_url': reverse('get_sale_records', kwargs={'course_id': course_key.to_deprecated_string()}),
+        'get_sale_order_records_url': reverse('get_sale_order_records', kwargs={'course_id': course_key.to_deprecated_string()}),
         'instructor_url': reverse('instructor_dashboard', kwargs={'course_id': course_key.to_deprecated_string()}),
         'get_registration_code_csv_url': reverse('get_registration_codes', kwargs={'course_id': course_key.to_deprecated_string()}),
         'generate_registration_code_csv_url': reverse('generate_registration_codes', kwargs={'course_id': course_key.to_deprecated_string()}),
@@ -183,15 +185,19 @@ def set_course_mode_price(request, course_id):
     try:
         course_price = int(request.POST['course_price'])
     except ValueError:
-        return HttpResponseNotFound(_("Please Enter the numeric value for the course price"))
+        return JsonResponse(
+            {'message': _("Please Enter the numeric value for the course price")},
+            status=400)  # status code 400: Bad Request
+
     currency = request.POST['currency']
     course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
 
     course_honor_mode = CourseMode.objects.filter(mode_slug='honor', course_id=course_key)
     if not course_honor_mode:
-        return HttpResponseNotFound(
-            _("CourseMode with the mode slug({mode_slug}) DoesNotExist").format(mode_slug='honor')
-        )
+        return JsonResponse(
+            {'message': _("CourseMode with the mode slug({mode_slug}) DoesNotExist").format(mode_slug='honor')},
+            status=400)  # status code 400: Bad Request
+
     CourseModesArchive.objects.create(
         course_id=course_id, mode_slug='honor', mode_display_name='Honor Code Certificate',
         min_price=getattr(course_honor_mode[0], 'min_price'), currency=getattr(course_honor_mode[0], 'currency'),
@@ -201,7 +207,7 @@ def set_course_mode_price(request, course_id):
         min_price=course_price,
         currency=currency
     )
-    return HttpResponse(_("CourseMode price updated successfully"))
+    return JsonResponse({'message': _("CourseMode price updated successfully")})
 
 
 def _section_course_info(course, access):
diff --git a/lms/djangoapps/instructor_analytics/basic.py b/lms/djangoapps/instructor_analytics/basic.py
index eecede860ae5b977fc973ec35892637c8f2cffe4..f26ccde17a0236512b4a5512dfd39396d5fe1355 100644
--- a/lms/djangoapps/instructor_analytics/basic.py
+++ b/lms/djangoapps/instructor_analytics/basic.py
@@ -3,7 +3,10 @@ Student and course analytics.
 
 Serve miscellaneous course and student data
 """
-from shoppingcart.models import PaidCourseRegistration, CouponRedemption, Invoice, RegistrationCodeRedemption
+from shoppingcart.models import (
+    PaidCourseRegistration, CouponRedemption, Invoice, CourseRegCodeItem,
+    OrderTypes, RegistrationCodeRedemption, CourseRegistrationCode
+)
 from django.contrib.auth.models import User
 import xmodule.graders as xmgraders
 from django.core.exceptions import ObjectDoesNotExist
@@ -18,11 +21,77 @@ ORDER_FEATURES = ('purchase_time',)
 SALE_FEATURES = ('total_amount', 'company_name', 'company_contact_name', 'company_contact_email', 'recipient_name',
                  'recipient_email', 'customer_reference_number', 'internal_reference')
 
+SALE_ORDER_FEATURES = ('id', 'company_name', 'company_contact_name', 'company_contact_email', 'purchase_time',
+                       'customer_reference_number', 'recipient_name', 'recipient_email', 'bill_to_street1',
+                       'bill_to_street2', 'bill_to_city', 'bill_to_state', 'bill_to_postalcode',
+                       'bill_to_country', 'order_type',)
+
 AVAILABLE_FEATURES = STUDENT_FEATURES + PROFILE_FEATURES
 COURSE_REGISTRATION_FEATURES = ('code', 'course_id', 'created_by', 'created_at')
 COUPON_FEATURES = ('course_id', 'percentage_discount', 'description')
 
 
+def sale_order_record_features(course_id, features):
+    """
+    Return list of sale orders features as dictionaries.
+
+    sales_records(course_id, ['company_name, total_codes', total_amount])
+    would return [
+        {'company_name': 'group_A', 'total_codes': '1', total_amount:'total_amount1 in decimal'.}
+        {'company_name': 'group_B', 'total_codes': '2', total_amount:'total_amount2 in decimal'.}
+        {'company_name': 'group_C', 'total_codes': '3', total_amount:'total_amount3 in decimal'.}
+    ]
+    """
+    purchased_courses = PaidCourseRegistration.objects.filter(course_id=course_id, status='purchased').order_by('order')
+    purchased_course_reg_codes = CourseRegCodeItem.objects.filter(course_id=course_id, status='purchased').order_by('order')
+
+    def sale_order_info(purchased_course, features):
+        """
+        convert purchase transactions to dictionary
+        """
+
+        sale_order_features = [x for x in SALE_ORDER_FEATURES if x in features]
+        course_reg_features = [x for x in COURSE_REGISTRATION_FEATURES if x in features]
+
+        # Extracting order information
+        sale_order_dict = dict((feature, getattr(purchased_course.order, feature))
+                               for feature in sale_order_features)
+
+        quantity = int(getattr(purchased_course, 'qty'))
+        unit_cost = float(getattr(purchased_course, 'unit_cost'))
+        sale_order_dict.update({"total_amount": quantity * unit_cost})
+
+        sale_order_dict.update({"logged_in_username": purchased_course.order.user.username})
+        sale_order_dict.update({"logged_in_email": purchased_course.order.user.email})
+
+        sale_order_dict.update({"total_codes": 'N/A'})
+        sale_order_dict.update({'total_used_codes': 'N/A'})
+
+        if getattr(purchased_course.order, 'order_type') == OrderTypes.BUSINESS:
+            registration_codes = CourseRegistrationCode.objects.filter(order=purchased_course.order, course_id=course_id)
+            sale_order_dict.update({"total_codes": registration_codes.count()})
+            sale_order_dict.update({'total_used_codes': RegistrationCodeRedemption.objects.filter(registration_code__in=registration_codes).count()})
+
+            codes = list()
+            for reg_code in registration_codes:
+                codes.append(reg_code.code)
+
+            # Extracting registration code information
+            obj_course_reg_code = registration_codes.all()[:1].get()
+            course_reg_dict = dict((feature, getattr(obj_course_reg_code, feature))
+                                   for feature in course_reg_features)
+
+            course_reg_dict['course_id'] = course_id.to_deprecated_string()
+            course_reg_dict.update({'codes': ", ".join(codes)})
+            sale_order_dict.update(dict(course_reg_dict.items()))
+
+        return sale_order_dict
+
+    csv_data = [sale_order_info(purchased_course, features) for purchased_course in purchased_courses]
+    csv_data.extend([sale_order_info(purchased_course_reg_code, features) for purchased_course_reg_code in purchased_course_reg_codes])
+    return csv_data
+
+
 def sale_record_features(course_id, features):
     """
     Return list of sales features as dictionaries.
@@ -73,7 +142,7 @@ def purchase_transactions(course_id, features):
     """
     Return list of purchased transactions features as dictionaries.
 
-    purchase_transactions(course_id, ['username, email', unit_cost])
+    purchase_transactions(course_id, ['username, email','created_by', unit_cost])
     would return [
         {'username': 'username1', 'email': 'email1', unit_cost:'cost1 in decimal'.}
         {'username': 'username2', 'email': 'email2', unit_cost:'cost2 in decimal'.}
diff --git a/lms/djangoapps/instructor_analytics/tests/test_basic.py b/lms/djangoapps/instructor_analytics/tests/test_basic.py
index 788c55fb12c7e770da2848bc682f84a56fb55b81..ad735de250ad02a46cf062b6db67df928750b0e0 100644
--- a/lms/djangoapps/instructor_analytics/tests/test_basic.py
+++ b/lms/djangoapps/instructor_analytics/tests/test_basic.py
@@ -7,11 +7,11 @@ from student.models import CourseEnrollment
 from django.core.urlresolvers import reverse
 from student.tests.factories import UserFactory
 from opaque_keys.edx.locations import SlashSeparatedCourseKey
-from shoppingcart.models import CourseRegistrationCode, RegistrationCodeRedemption, Order, Invoice, Coupon
+from shoppingcart.models import CourseRegistrationCode, RegistrationCodeRedemption, Order, Invoice, Coupon, CourseRegCodeItem
 
 from instructor_analytics.basic import (
-    sale_record_features, enrolled_students_features, course_registration_features, coupon_codes_features,
-    AVAILABLE_FEATURES, STUDENT_FEATURES, PROFILE_FEATURES
+    sale_record_features, sale_order_record_features, enrolled_students_features, course_registration_features,
+    coupon_codes_features, AVAILABLE_FEATURES, STUDENT_FEATURES, PROFILE_FEATURES
 )
 from course_groups.tests.helpers import CohortFactory
 from course_groups.models import CourseUserGroup
@@ -137,6 +137,57 @@ class TestCourseSaleRecordsAnalyticsBasic(ModuleStoreTestCase):
             self.assertEqual(sale_record['total_used_codes'], 0)
             self.assertEqual(sale_record['total_codes'], 5)
 
+    def test_sale_order_features(self):
+        """
+         Test Order Sales Report CSV
+        """
+        query_features = [
+            ('id', 'Order Id'),
+            ('company_name', 'Company Name'),
+            ('company_contact_name', 'Company Contact Name'),
+            ('company_contact_email', 'Company Contact Email'),
+            ('total_amount', 'Total Amount'),
+            ('total_codes', 'Total Codes'),
+            ('total_used_codes', 'Total Used Codes'),
+            ('logged_in_username', 'Login Username'),
+            ('logged_in_email', 'Login User Email'),
+            ('purchase_time', 'Date of Sale'),
+            ('customer_reference_number', 'Customer Reference Number'),
+            ('recipient_name', 'Recipient Name'),
+            ('recipient_email', 'Recipient Email'),
+            ('bill_to_street1', 'Street 1'),
+            ('bill_to_street2', 'Street 2'),
+            ('bill_to_city', 'City'),
+            ('bill_to_state', 'State'),
+            ('bill_to_postalcode', 'Postal Code'),
+            ('bill_to_country', 'Country'),
+            ('order_type', 'Order Type'),
+            ('codes', 'Registration Codes'),
+            ('course_id', 'Course Id')
+        ]
+
+        order = Order.get_cart_for_user(self.instructor)
+        order.order_type = 'business'
+        order.save()
+        order.add_billing_details(company_name='Test Company', company_contact_name='Test',
+                                  company_contact_email='test@123', recipient_name='R1',
+                                  recipient_email='', customer_reference_number='PO#23')
+        CourseRegCodeItem.add_to_order(order, self.course.id, 4)
+        order.purchase()
+
+        db_columns = [x[0] for x in query_features]
+        sale_order_records_list = sale_order_record_features(self.course.id, db_columns)
+
+        for sale_order_record in sale_order_records_list:
+            self.assertEqual(sale_order_record['recipient_email'], order.recipient_email)
+            self.assertEqual(sale_order_record['recipient_name'], order.recipient_name)
+            self.assertEqual(sale_order_record['company_name'], order.company_name)
+            self.assertEqual(sale_order_record['company_contact_name'], order.company_contact_name)
+            self.assertEqual(sale_order_record['company_contact_email'], order.company_contact_email)
+            self.assertEqual(sale_order_record['customer_reference_number'], order.customer_reference_number)
+            self.assertEqual(sale_order_record['total_used_codes'], order.registrationcoderedemption_set.all().count())
+            self.assertEqual(sale_order_record['total_codes'], len(CourseRegistrationCode.objects.filter(order=order)))
+
 
 class TestCourseRegistrationCodeAnalyticsBasic(ModuleStoreTestCase):
     """ Test basic course registration codes analytics functions. """
diff --git a/lms/djangoapps/shoppingcart/context_processor.py b/lms/djangoapps/shoppingcart/context_processor.py
index 540ab6a2f32321a7aea6b1411439a04870169d1c..df667569d0859b9127aa153917429b6f41ab42f2 100644
--- a/lms/djangoapps/shoppingcart/context_processor.py
+++ b/lms/djangoapps/shoppingcart/context_processor.py
@@ -21,6 +21,6 @@ def user_has_cart_context_processor(request):
         settings.FEATURES.get('ENABLE_SHOPPING_CART') and             # settings enable shopping cart and
         shoppingcart.models.Order.user_cart_has_items(
             request.user,
-            shoppingcart.models.PaidCourseRegistration
+            [shoppingcart.models.PaidCourseRegistration, shoppingcart.models.CourseRegCodeItem]
         )  # user's cart has PaidCourseRegistrations
     )}
diff --git a/lms/djangoapps/shoppingcart/migrations/0020_auto__add_courseregcodeitem__add_courseregcodeitemannotation__add_fiel.py b/lms/djangoapps/shoppingcart/migrations/0020_auto__add_courseregcodeitem__add_courseregcodeitemannotation__add_fiel.py
new file mode 100644
index 0000000000000000000000000000000000000000..ce99fdb642e5f634ae95f6a84f2ec23ef14bb00a
--- /dev/null
+++ b/lms/djangoapps/shoppingcart/migrations/0020_auto__add_courseregcodeitem__add_courseregcodeitemannotation__add_fiel.py
@@ -0,0 +1,284 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding model 'CourseRegCodeItem'
+        db.create_table('shoppingcart_courseregcodeitem', (
+            ('orderitem_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['shoppingcart.OrderItem'], unique=True, primary_key=True)),
+            ('course_id', self.gf('xmodule_django.models.CourseKeyField')(max_length=128, db_index=True)),
+            ('mode', self.gf('django.db.models.fields.SlugField')(default='honor', max_length=50)),
+        ))
+        db.send_create_signal('shoppingcart', ['CourseRegCodeItem'])
+
+        # Adding model 'CourseRegCodeItemAnnotation'
+        db.create_table('shoppingcart_courseregcodeitemannotation', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('course_id', self.gf('xmodule_django.models.CourseKeyField')(unique=True, max_length=128, db_index=True)),
+            ('annotation', self.gf('django.db.models.fields.TextField')(null=True)),
+        ))
+        db.send_create_signal('shoppingcart', ['CourseRegCodeItemAnnotation'])
+
+        # Adding field 'Order.company_name'
+        db.add_column('shoppingcart_order', 'company_name',
+                      self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True),
+                      keep_default=False)
+
+        # Adding field 'Order.company_contact_name'
+        db.add_column('shoppingcart_order', 'company_contact_name',
+                      self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True),
+                      keep_default=False)
+
+        # Adding field 'Order.company_contact_email'
+        db.add_column('shoppingcart_order', 'company_contact_email',
+                      self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True),
+                      keep_default=False)
+
+        # Adding field 'Order.recipient_name'
+        db.add_column('shoppingcart_order', 'recipient_name',
+                      self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True),
+                      keep_default=False)
+
+        # Adding field 'Order.recipient_email'
+        db.add_column('shoppingcart_order', 'recipient_email',
+                      self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True),
+                      keep_default=False)
+
+        # Adding field 'Order.customer_reference_number'
+        db.add_column('shoppingcart_order', 'customer_reference_number',
+                      self.gf('django.db.models.fields.CharField')(max_length=63, null=True, blank=True),
+                      keep_default=False)
+
+        # Adding field 'Order.order_type'
+        db.add_column('shoppingcart_order', 'order_type',
+                      self.gf('django.db.models.fields.CharField')(default='personal', max_length=32),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting model 'CourseRegCodeItem'
+        db.delete_table('shoppingcart_courseregcodeitem')
+
+        # Deleting model 'CourseRegCodeItemAnnotation'
+        db.delete_table('shoppingcart_courseregcodeitemannotation')
+
+        # Deleting field 'Order.company_name'
+        db.delete_column('shoppingcart_order', 'company_name')
+
+        # Deleting field 'Order.company_contact_name'
+        db.delete_column('shoppingcart_order', 'company_contact_name')
+
+        # Deleting field 'Order.company_contact_email'
+        db.delete_column('shoppingcart_order', 'company_contact_email')
+
+        # Deleting field 'Order.recipient_name'
+        db.delete_column('shoppingcart_order', 'recipient_name')
+
+        # Deleting field 'Order.recipient_email'
+        db.delete_column('shoppingcart_order', 'recipient_email')
+
+        # Deleting field 'Order.customer_reference_number'
+        db.delete_column('shoppingcart_order', 'customer_reference_number')
+
+        # Deleting field 'Order.order_type'
+        db.delete_column('shoppingcart_order', 'order_type')
+
+
+    models = {
+        'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        'auth.permission': {
+            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        'auth.user': {
+            'Meta': {'object_name': 'User'},
+            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        'contenttypes.contenttype': {
+            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        'shoppingcart.certificateitem': {
+            'Meta': {'object_name': 'CertificateItem', '_ormbases': ['shoppingcart.OrderItem']},
+            'course_enrollment': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['student.CourseEnrollment']"}),
+            'course_id': ('xmodule_django.models.CourseKeyField', [], {'max_length': '128', 'db_index': 'True'}),
+            'mode': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
+            'orderitem_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['shoppingcart.OrderItem']", 'unique': 'True', 'primary_key': 'True'})
+        },
+        'shoppingcart.coupon': {
+            'Meta': {'object_name': 'Coupon'},
+            'code': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
+            'course_id': ('xmodule_django.models.CourseKeyField', [], {'max_length': '255'}),
+            'created_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2014, 10, 16, 0, 0)'}),
+            'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
+            'description': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'percentage_discount': ('django.db.models.fields.IntegerField', [], {'default': '0'})
+        },
+        'shoppingcart.couponredemption': {
+            'Meta': {'object_name': 'CouponRedemption'},
+            'coupon': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['shoppingcart.Coupon']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'order': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['shoppingcart.Order']"}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+        },
+        'shoppingcart.courseregcodeitem': {
+            'Meta': {'object_name': 'CourseRegCodeItem', '_ormbases': ['shoppingcart.OrderItem']},
+            'course_id': ('xmodule_django.models.CourseKeyField', [], {'max_length': '128', 'db_index': 'True'}),
+            'mode': ('django.db.models.fields.SlugField', [], {'default': "'honor'", 'max_length': '50'}),
+            'orderitem_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['shoppingcart.OrderItem']", 'unique': 'True', 'primary_key': 'True'})
+        },
+        'shoppingcart.courseregcodeitemannotation': {
+            'Meta': {'object_name': 'CourseRegCodeItemAnnotation'},
+            'annotation': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+            'course_id': ('xmodule_django.models.CourseKeyField', [], {'unique': 'True', 'max_length': '128', 'db_index': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
+        },
+        'shoppingcart.courseregistrationcode': {
+            'Meta': {'object_name': 'CourseRegistrationCode'},
+            'code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32', 'db_index': 'True'}),
+            'course_id': ('xmodule_django.models.CourseKeyField', [], {'max_length': '255', 'db_index': 'True'}),
+            'created_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2014, 10, 16, 0, 0)'}),
+            'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'created_by_user'", 'to': "orm['auth.User']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'invoice': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['shoppingcart.Invoice']", 'null': 'True'}),
+            'order': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'purchase_order'", 'null': 'True', 'to': "orm['shoppingcart.Order']"})
+        },
+        'shoppingcart.donation': {
+            'Meta': {'object_name': 'Donation', '_ormbases': ['shoppingcart.OrderItem']},
+            'course_id': ('xmodule_django.models.CourseKeyField', [], {'max_length': '255', 'db_index': 'True'}),
+            'donation_type': ('django.db.models.fields.CharField', [], {'default': "'general'", 'max_length': '32'}),
+            'orderitem_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['shoppingcart.OrderItem']", 'unique': 'True', 'primary_key': 'True'})
+        },
+        'shoppingcart.donationconfiguration': {
+            'Meta': {'object_name': 'DonationConfiguration'},
+            'change_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'changed_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.PROTECT'}),
+            'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
+        },
+        'shoppingcart.invoice': {
+            'Meta': {'object_name': 'Invoice'},
+            'address_line_1': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'address_line_2': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+            'address_line_3': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+            'city': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+            'company_contact_email': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'company_contact_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'company_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'country': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True'}),
+            'course_id': ('xmodule_django.models.CourseKeyField', [], {'max_length': '255', 'db_index': 'True'}),
+            'customer_reference_number': ('django.db.models.fields.CharField', [], {'max_length': '63', 'null': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'internal_reference': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+            'is_valid': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'recipient_email': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'recipient_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'state': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+            'total_amount': ('django.db.models.fields.FloatField', [], {}),
+            'zip': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True'})
+        },
+        'shoppingcart.order': {
+            'Meta': {'object_name': 'Order'},
+            'bill_to_cardtype': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}),
+            'bill_to_ccnum': ('django.db.models.fields.CharField', [], {'max_length': '8', 'blank': 'True'}),
+            'bill_to_city': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
+            'bill_to_country': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
+            'bill_to_first': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
+            'bill_to_last': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
+            'bill_to_postalcode': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}),
+            'bill_to_state': ('django.db.models.fields.CharField', [], {'max_length': '8', 'blank': 'True'}),
+            'bill_to_street1': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}),
+            'bill_to_street2': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}),
+            'company_contact_email': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'company_contact_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'company_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'currency': ('django.db.models.fields.CharField', [], {'default': "'usd'", 'max_length': '8'}),
+            'customer_reference_number': ('django.db.models.fields.CharField', [], {'max_length': '63', 'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'order_type': ('django.db.models.fields.CharField', [], {'default': "'personal'", 'max_length': '32'}),
+            'processor_reply_dump': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'purchase_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+            'recipient_email': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'recipient_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'refunded_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+            'status': ('django.db.models.fields.CharField', [], {'default': "'cart'", 'max_length': '32'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+        },
+        'shoppingcart.orderitem': {
+            'Meta': {'object_name': 'OrderItem'},
+            'currency': ('django.db.models.fields.CharField', [], {'default': "'usd'", 'max_length': '8'}),
+            'fulfilled_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'db_index': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'line_desc': ('django.db.models.fields.CharField', [], {'default': "'Misc. Item'", 'max_length': '1024'}),
+            'list_price': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '30', 'decimal_places': '2'}),
+            'order': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['shoppingcart.Order']"}),
+            'qty': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+            'refund_requested_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'db_index': 'True'}),
+            'report_comments': ('django.db.models.fields.TextField', [], {'default': "''"}),
+            'service_fee': ('django.db.models.fields.DecimalField', [], {'default': '0.0', 'max_digits': '30', 'decimal_places': '2'}),
+            'status': ('django.db.models.fields.CharField', [], {'default': "'cart'", 'max_length': '32', 'db_index': 'True'}),
+            'unit_cost': ('django.db.models.fields.DecimalField', [], {'default': '0.0', 'max_digits': '30', 'decimal_places': '2'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+        },
+        'shoppingcart.paidcourseregistration': {
+            'Meta': {'object_name': 'PaidCourseRegistration', '_ormbases': ['shoppingcart.OrderItem']},
+            'course_id': ('xmodule_django.models.CourseKeyField', [], {'max_length': '128', 'db_index': 'True'}),
+            'mode': ('django.db.models.fields.SlugField', [], {'default': "'honor'", 'max_length': '50'}),
+            'orderitem_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['shoppingcart.OrderItem']", 'unique': 'True', 'primary_key': 'True'})
+        },
+        'shoppingcart.paidcourseregistrationannotation': {
+            'Meta': {'object_name': 'PaidCourseRegistrationAnnotation'},
+            'annotation': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+            'course_id': ('xmodule_django.models.CourseKeyField', [], {'unique': 'True', 'max_length': '128', 'db_index': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
+        },
+        'shoppingcart.registrationcoderedemption': {
+            'Meta': {'object_name': 'RegistrationCodeRedemption'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'order': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['shoppingcart.Order']", 'null': 'True'}),
+            'redeemed_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2014, 10, 16, 0, 0)', 'null': 'True'}),
+            'redeemed_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
+            'registration_code': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['shoppingcart.CourseRegistrationCode']"})
+        },
+        'student.courseenrollment': {
+            'Meta': {'ordering': "('user', 'course_id')", 'unique_together': "(('user', 'course_id'),)", 'object_name': 'CourseEnrollment'},
+            'course_id': ('xmodule_django.models.CourseKeyField', [], {'max_length': '255', 'db_index': 'True'}),
+            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'null': 'True', 'db_index': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'mode': ('django.db.models.fields.CharField', [], {'default': "'honor'", 'max_length': '100'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+        }
+    }
+
+    complete_apps = ['shoppingcart']
\ No newline at end of file
diff --git a/lms/djangoapps/shoppingcart/models.py b/lms/djangoapps/shoppingcart/models.py
index 6bcab0d280ffe708762cc3b2f65a0a7e677a5208..2b27dcc252349408d2817c8688251ec44e5bed22 100644
--- a/lms/djangoapps/shoppingcart/models.py
+++ b/lms/djangoapps/shoppingcart/models.py
@@ -6,7 +6,9 @@ from decimal import Decimal
 import pytz
 import logging
 import smtplib
-
+import StringIO
+import csv
+from courseware.courses import get_course_by_id
 from boto.exception import BotoServerError  # this is a super-class of SESError and catches connection errors
 from django.dispatch import receiver
 from django.db import models
@@ -19,6 +21,7 @@ from django.db import transaction
 from django.db.models import Sum
 from django.core.urlresolvers import reverse
 from model_utils.managers import InheritanceManager
+from django.core.mail.message import EmailMessage
 
 from xmodule.modulestore.django import modulestore
 
@@ -62,6 +65,19 @@ ORDER_STATUSES = (
 OrderItemSubclassPK = namedtuple('OrderItemSubclassPK', ['cls', 'pk'])  # pylint: disable=C0103
 
 
+class OrderTypes(object):
+    """
+    This class specify purchase OrderTypes.
+    """
+    PERSONAL = 'personal'
+    BUSINESS = 'business'
+
+    ORDER_TYPES = (
+        (PERSONAL, 'personal'),
+        (BUSINESS, 'business'),
+    )
+
+
 class Order(models.Model):
     """
     This is the model for an order.  Before purchase, an Order and its related OrderItems are used
@@ -88,6 +104,15 @@ class Order(models.Model):
     # a JSON dump of the CC processor response, for completeness
     processor_reply_dump = models.TextField(blank=True)
 
+    # bulk purchase registration code workflow billing details
+    company_name = models.CharField(max_length=255, null=True, blank=True)
+    company_contact_name = models.CharField(max_length=255, null=True, blank=True)
+    company_contact_email = models.CharField(max_length=255, null=True, blank=True)
+    recipient_name = models.CharField(max_length=255, null=True, blank=True)
+    recipient_email = models.CharField(max_length=255, null=True, blank=True)
+    customer_reference_number = models.CharField(max_length=63, null=True, blank=True)
+    order_type = models.CharField(max_length=32, default='personal', choices=OrderTypes.ORDER_TYPES)
+
     @classmethod
     def get_cart_for_user(cls, user):
         """
@@ -102,7 +127,7 @@ class Order(models.Model):
         return cart_order
 
     @classmethod
-    def user_cart_has_items(cls, user, item_type=None):
+    def user_cart_has_items(cls, user, item_types=None):
         """
         Returns true if the user (anonymous user ok) has
         a cart with items in it.  (Which means it should be displayed.
@@ -112,7 +137,17 @@ class Order(models.Model):
         if not user.is_authenticated():
             return False
         cart = cls.get_cart_for_user(user)
-        return cart.has_items(item_type)
+
+        if not item_types:
+            # check to see if the cart has at least some item in it
+            return cart.has_items()
+        else:
+            # if the caller is explicitly asking to check for particular types
+            for item_type in item_types:
+                if cart.has_items(item_type):
+                    return True
+
+        return False
 
     @property
     def total_cost(self):
@@ -130,17 +165,27 @@ class Order(models.Model):
         if not item_type:
             return self.orderitem_set.exists()  # pylint: disable=E1101
         else:
-            items = self.orderitem_set.all().select_subclasses()
+            items = self.orderitem_set.all().select_subclasses()  # pylint: disable=E1101
             for item in items:
                 if isinstance(item, item_type):
                     return True
             return False
 
+    def reset_cart_items_prices(self):
+        """
+        Reset the items price state in the user cart
+        """
+        for item in self.orderitem_set.all():  # pylint: disable=E1101
+            if item.list_price:
+                item.unit_cost = item.list_price
+                item.list_price = None
+                item.save()
+
     def clear(self):
         """
         Clear out all the items in the cart
         """
-        self.orderitem_set.all().delete()
+        self.orderitem_set.all().delete()  # pylint: disable=E1101
 
     @transaction.commit_on_success
     def start_purchase(self):
@@ -158,6 +203,122 @@ class Order(models.Model):
             for item in OrderItem.objects.filter(order=self).select_subclasses():
                 item.start_purchase()
 
+    def update_order_type(self):
+        """
+        updating order type. This method wil inspect the quantity associated with the OrderItem.
+        In the application, it is implied that when qty > 1, then the user is to purchase
+        'RegistrationCodes' which are randomly generated strings that users can distribute to
+        others in order for them to enroll in paywalled courses.
+
+        The UI/UX may change in the future to make the switching between PaidCourseRegistration
+        and CourseRegCodeItems a more explicit UI gesture from the purchaser
+        """
+        cart_items = self.orderitem_set.all()  # pylint: disable=E1101
+        is_order_type_business = False
+        for cart_item in cart_items:
+            if cart_item.qty > 1:
+                is_order_type_business = True
+
+        items_to_delete = []
+        if is_order_type_business:
+            for cart_item in cart_items:
+                if hasattr(cart_item, 'paidcourseregistration'):
+                    CourseRegCodeItem.add_to_order(self, cart_item.paidcourseregistration.course_id, cart_item.qty)
+                    items_to_delete.append(cart_item)
+        else:
+            for cart_item in cart_items:
+                if hasattr(cart_item, 'courseregcodeitem'):
+                    PaidCourseRegistration.add_to_order(self, cart_item.courseregcodeitem.course_id)
+                    items_to_delete.append(cart_item)
+                    # CourseRegCodeItem.add_to_order
+
+        for item in items_to_delete:
+            item.delete()
+
+        self.order_type = OrderTypes.BUSINESS if is_order_type_business else OrderTypes.PERSONAL
+        self.save()
+
+    def generate_registration_codes_csv(self, orderitems, site_name):
+        """
+        this function generates the csv file
+        """
+        course_info = []
+        csv_file = StringIO.StringIO()
+        csv_writer = csv.writer(csv_file)
+        csv_writer.writerow(['Course Name', 'Registration Code', 'URL'])
+        for item in orderitems:
+            course_id = item.course_id
+            course = get_course_by_id(getattr(item, 'course_id'), depth=0)
+            registration_codes = CourseRegistrationCode.objects.filter(course_id=course_id, order=self)
+            course_info.append((course.display_name, ' (' + course.start_date_text + '-' + course.end_date_text + ')'))
+            for registration_code in registration_codes:
+                redemption_url = reverse('register_code_redemption', args=[registration_code.code])
+                url = '{base_url}{redemption_url}'.format(base_url=site_name, redemption_url=redemption_url)
+                csv_writer.writerow([course.display_name, registration_code.code, url])
+
+        return csv_file, course_info
+
+    def send_confirmation_emails(self, orderitems, is_order_type_business, csv_file, site_name, courses_info):
+        """
+        send confirmation e-mail
+        """
+        recipient_list = [(self.user.username, getattr(self.user, 'email'), 'user')]  # pylint: disable=E1101
+        if self.company_contact_email:
+            recipient_list.append((self.company_contact_name, self.company_contact_email, 'company_contact'))
+        joined_course_names = ""
+        if self.recipient_email:
+            recipient_list.append((self.recipient_name, self.recipient_email, 'email_recipient'))
+            courses_names_with_dates = [course_info[0] + course_info[1] for course_info in courses_info]
+            joined_course_names = " " + ", ".join(courses_names_with_dates)
+
+        if not is_order_type_business:
+            subject = _("Order Payment Confirmation")
+        else:
+            subject = _('Confirmation and Registration Codes for the following courses: {course_name_list}').format(
+                course_name_list=joined_course_names
+            )
+
+        dashboard_url = '{base_url}{dashboard}'.format(
+            base_url=site_name,
+            dashboard=reverse('dashboard')
+        )
+        try:
+            from_address = microsite.get_value(
+                'email_from_address',
+                settings.PAYMENT_SUPPORT_EMAIL
+            )
+            # send a unique email for each recipient, don't put all email addresses in a single email
+            for recipient in recipient_list:
+                message = render_to_string(
+                    'emails/business_order_confirmation_email.txt' if is_order_type_business else 'emails/order_confirmation_email.txt',
+                    {
+                        'order': self,
+                        'recipient_name': recipient[0],
+                        'recipient_type': recipient[2],
+                        'site_name': site_name,
+                        'order_items': orderitems,
+                        'course_names': ", ".join([course_info[0] for course_info in courses_info]),
+                        'dashboard_url': dashboard_url,
+                        'order_placed_by': '{username} ({email})'.format(username=self.user.username, email=getattr(self.user, 'email')),  # pylint: disable=E1101
+                        'has_billing_info': settings.FEATURES['STORE_BILLING_INFO'],
+                        'platform_name': microsite.get_value('platform_name', settings.PLATFORM_NAME),
+                        'payment_support_email': microsite.get_value('payment_support_email', settings.PAYMENT_SUPPORT_EMAIL),
+                        'payment_email_signature': microsite.get_value('payment_email_signature'),
+                    }
+                )
+                email = EmailMessage(
+                    subject=subject,
+                    body=message,
+                    from_email=from_address,
+                    to=[recipient[1]]
+                )
+                email.content_subtype = "html"
+                if csv_file:
+                    email.attach(u'RegistrationCodesRedemptionUrls.csv', csv_file.getvalue(), 'text/csv')
+                email.send()
+        except (smtplib.SMTPException, BotoServerError):  # sadly need to handle diff. mail backends individually
+            log.error('Failed sending confirmation e-mail for order %d', self.id)  # pylint: disable=E1101
+
     def purchase(self, first='', last='', street1='', street2='', city='', state='', postalcode='',
                  country='', ccnum='', cardtype='', processor_reply_dump=''):
         """
@@ -200,29 +361,48 @@ class Order(models.Model):
         # this should return all of the objects with the correct types of the
         # subclasses
         orderitems = OrderItem.objects.filter(order=self).select_subclasses()
+        site_name = microsite.get_value('SITE_NAME', settings.SITE_NAME)
+
+        if self.order_type == OrderTypes.BUSINESS:
+            self.update_order_type()
+
         for item in orderitems:
             item.purchase_item()
 
-        # send confirmation e-mail
-        subject = _("Order Payment Confirmation")
-        message = render_to_string(
-            'emails/order_confirmation_email.txt',
-            {
-                'order': self,
-                'order_items': orderitems,
-                'has_billing_info': settings.FEATURES['STORE_BILLING_INFO']
-            }
-        )
-        try:
-            from_address = microsite.get_value(
-                'email_from_address',
-                settings.DEFAULT_FROM_EMAIL
-            )
+        csv_file = None
+        courses_info = []
+        if self.order_type == OrderTypes.BUSINESS:
+            #
+            # Generate the CSV file that contains all of the RegistrationCodes that have already been
+            # generated when the purchase has transacted
+            #
+            csv_file, courses_info = self.generate_registration_codes_csv(orderitems, site_name)
 
-            send_mail(subject, message,
-                      from_address, [self.user.email])  # pylint: disable=E1101
-        except (smtplib.SMTPException, BotoServerError):  # sadly need to handle diff. mail backends individually
-            log.error('Failed sending confirmation e-mail for order %d', self.id)  # pylint: disable=E1101
+        self.send_confirmation_emails(orderitems, self.order_type == OrderTypes.BUSINESS, csv_file, site_name, courses_info)
+
+    def add_billing_details(self, company_name='', company_contact_name='', company_contact_email='', recipient_name='',
+                            recipient_email='', customer_reference_number=''):
+        """
+        This function is called after the user selects a purchase type of "Business" and
+        is asked to enter the optional billing details. The billing details are updated
+        for that order.
+
+        company_name - Name of purchasing organization
+        company_contact_name - Name of the key contact at the company the sale was made to
+        company_contact_email - Email of the key contact at the company the sale was made to
+        recipient_name - Name of the company should the invoice be sent to
+        recipient_email - Email of the company should the invoice be sent to
+        customer_reference_number - purchase order number of the organization associated with this Order
+        """
+
+        self.company_name = company_name
+        self.company_contact_name = company_contact_name
+        self.company_contact_email = company_contact_email
+        self.recipient_name = recipient_name
+        self.recipient_email = recipient_email
+        self.customer_reference_number = customer_reference_number
+
+        self.save()
 
     def generate_receipt_instructions(self):
         """
@@ -420,6 +600,16 @@ class RegistrationCodeRedemption(models.Model):
     redeemed_by = models.ForeignKey(User, db_index=True)
     redeemed_at = models.DateTimeField(default=datetime.now(pytz.utc), null=True)
 
+    @classmethod
+    def delete_registration_redemption(cls, user, cart):
+        """
+        This method delete registration redemption
+        """
+        reg_code_redemption = cls.objects.filter(redeemed_by=user, order=cart)
+        if reg_code_redemption:
+            reg_code_redemption.delete()
+            log.info('Registration code redemption entry removed for user {0} for order {1}'.format(user, cart.id))
+
     @classmethod
     def add_reg_code_redemption(cls, course_reg_code, order):
         """
@@ -502,6 +692,16 @@ class CouponRedemption(models.Model):
     user = models.ForeignKey(User, db_index=True)
     coupon = models.ForeignKey(Coupon, db_index=True)
 
+    @classmethod
+    def delete_coupon_redemption(cls, user, cart):
+        """
+        This method delete coupon redemption
+        """
+        coupon_redemption = cls.objects.filter(user=user, order=cart)
+        if coupon_redemption:
+            coupon_redemption.delete()
+            log.info('Coupon redemption entry removed for user {0} for order {1}'.format(user, cart.id))
+
     @classmethod
     def get_discount_price(cls, percentage_discount, value):
         """
@@ -665,6 +865,142 @@ class PaidCourseRegistration(OrderItem):
             return u""
 
 
+class CourseRegCodeItem(OrderItem):
+    """
+    This is an inventory item for paying for
+    generating course registration codes
+    """
+    course_id = CourseKeyField(max_length=128, db_index=True)
+    mode = models.SlugField(default=CourseMode.DEFAULT_MODE_SLUG)
+
+    @classmethod
+    def contained_in_order(cls, order, course_id):
+        """
+        Is the course defined by course_id contained in the order?
+        """
+        return course_id in [
+            item.course_id
+            for item in order.orderitem_set.all().select_subclasses("courseregcodeitem")
+            if isinstance(item, cls)
+        ]
+
+    @classmethod
+    def get_total_amount_of_purchased_item(cls, course_key):
+        """
+        This will return the total amount of money that a purchased course generated
+        """
+        total_cost = 0
+        result = cls.objects.filter(course_id=course_key, status='purchased').aggregate(total=Sum('unit_cost', field='qty * unit_cost'))  # pylint: disable=E1101
+
+        if result['total'] is not None:
+            total_cost = result['total']
+
+        return total_cost
+
+    @classmethod
+    @transaction.commit_on_success
+    def add_to_order(cls, order, course_id, qty, mode_slug=CourseMode.DEFAULT_MODE_SLUG, cost=None, currency=None):  # pylint: disable=W0221
+        """
+        A standardized way to create these objects, with sensible defaults filled in.
+        Will update the cost if called on an order that already carries the course.
+
+        Returns the order item
+        """
+        # First a bunch of sanity checks
+        course = modulestore().get_course(course_id)  # actually fetch the course to make sure it exists, use this to
+                                                # throw errors if it doesn't
+        if not course:
+            log.error("User {} tried to add non-existent course {} to cart id {}"
+                      .format(order.user.email, course_id, order.id))
+            raise CourseDoesNotExistException
+
+        if cls.contained_in_order(order, course_id):
+            log.warning("User {} tried to add PaidCourseRegistration for course {}, already in cart id {}"
+                        .format(order.user.email, course_id, order.id))
+            raise ItemAlreadyInCartException
+
+        if CourseEnrollment.is_enrolled(user=order.user, course_key=course_id):
+            log.warning("User {} trying to add course {} to cart id {}, already registered"
+                        .format(order.user.email, course_id, order.id))
+            raise AlreadyEnrolledInCourseException
+
+        ### Validations done, now proceed
+        ### handle default arguments for mode_slug, cost, currency
+        course_mode = CourseMode.mode_for_course(course_id, mode_slug)
+        if not course_mode:
+            # user could have specified a mode that's not set, in that case return the DEFAULT_MODE
+            course_mode = CourseMode.DEFAULT_MODE
+        if not cost:
+            cost = course_mode.min_price
+        if not currency:
+            currency = course_mode.currency
+
+        super(CourseRegCodeItem, cls).add_to_order(order, course_id, cost, currency=currency)
+
+        item, created = cls.objects.get_or_create(order=order, user=order.user, course_id=course_id)  # pylint: disable=W0612
+        item.status = order.status
+        item.mode = course_mode.slug
+        item.unit_cost = cost
+        item.qty = qty
+        item.line_desc = _(u'Enrollment codes for Course: {course_name}').format(
+            course_name=course.display_name_with_default)
+        item.currency = currency
+        order.currency = currency
+        item.report_comments = item.csv_report_comments
+        order.save()
+        item.save()
+        log.info("User {} added course registration {} to cart: order {}"
+                 .format(order.user.email, course_id, order.id))
+        return item
+
+    def purchased_callback(self):
+        """
+        The purchase is completed, this OrderItem type will generate Registration Codes that will
+        be redeemed by users
+        """
+        if not modulestore().has_course(self.course_id):
+            raise PurchasedCallbackException(
+                "The customer purchased Course {0}, but that course doesn't exist!".format(self.course_id))
+        total_registration_codes = int(self.qty)
+
+        # we need to import here because of a circular dependency
+        # we should ultimately refactor code to have save_registration_code in this models.py
+        # file, but there's also a shared dependency on a random string generator which
+        # is in another PR (for another feature)
+        from instructor.views.api import save_registration_code
+        for i in range(total_registration_codes):  # pylint: disable=W0612
+            save_registration_code(self.user, self.course_id, invoice=None, order=self.order)
+
+        log.info("Enrolled {0} in paid course {1}, paid ${2}"
+                 .format(self.user.email, self.course_id, self.line_cost))  # pylint: disable=E1101
+
+    @property
+    def csv_report_comments(self):
+        """
+        Tries to fetch an annotation associated with the course_id from the database.  If not found, returns u"".
+        Otherwise returns the annotation
+        """
+        try:
+            return CourseRegCodeItemAnnotation.objects.get(course_id=self.course_id).annotation
+        except CourseRegCodeItemAnnotation.DoesNotExist:
+            return u""
+
+
+class CourseRegCodeItemAnnotation(models.Model):
+    """
+    A model that maps course_id to an additional annotation.  This is specifically needed because when Stanford
+    generates report for the paid courses, each report item must contain the payment account associated with a course.
+    And unfortunately we didn't have the concept of a "SKU" or stock item where we could keep this association,
+    so this is to retrofit it.
+    """
+    course_id = CourseKeyField(unique=True, max_length=128, db_index=True)
+    annotation = models.TextField(null=True)
+
+    def __unicode__(self):
+        # pylint: disable=no-member
+        return u"{} : {}".format(self.course_id.to_deprecated_string(), self.annotation)
+
+
 class PaidCourseRegistrationAnnotation(models.Model):
     """
     A model that maps course_id to an additional annotation.  This is specifically needed because when Stanford
@@ -1011,3 +1347,9 @@ class Donation(OrderItem):
         # The donation is for the organization as a whole, not a specific course
         else:
             return _(u"Donation for {platform_name}").format(platform_name=settings.PLATFORM_NAME)
+
+    @property
+    def single_item_receipt_context(self):
+        return {
+            'receipt_has_donation_item': True,
+        }
diff --git a/lms/djangoapps/shoppingcart/tests/test_models.py b/lms/djangoapps/shoppingcart/tests/test_models.py
index 14f2369a4df9fee92b8d1d56f8ca4456d53e77c8..d2d992b89fe079dfcce9491dbe1f1e16fab01e2a 100644
--- a/lms/djangoapps/shoppingcart/tests/test_models.py
+++ b/lms/djangoapps/shoppingcart/tests/test_models.py
@@ -19,15 +19,17 @@ from xmodule.modulestore.tests.django_utils import (
     ModuleStoreTestCase, mixed_store_config
 )
 from xmodule.modulestore.tests.factories import CourseFactory
+
 from shoppingcart.models import (
     Order, OrderItem, CertificateItem,
-    InvalidCartItem, PaidCourseRegistration,
+    InvalidCartItem, CourseRegistrationCode, PaidCourseRegistration, CourseRegCodeItem,
     Donation, OrderItemSubclassPK
 )
 from student.tests.factories import UserFactory
 from student.models import CourseEnrollment
 from course_modes.models import CourseMode
-from shoppingcart.exceptions import PurchasedCallbackException, CourseDoesNotExistException
+from shoppingcart.exceptions import (PurchasedCallbackException, CourseDoesNotExistException,
+                                     ItemAlreadyInCartException, AlreadyEnrolledInCourseException)
 
 from opaque_keys.edx.locator import CourseLocator
 
@@ -63,21 +65,21 @@ class OrderTest(ModuleStoreTestCase):
         item = OrderItem(order=cart, user=self.user)
         item.save()
         self.assertTrue(Order.user_cart_has_items(self.user))
-        self.assertFalse(Order.user_cart_has_items(self.user, CertificateItem))
-        self.assertFalse(Order.user_cart_has_items(self.user, PaidCourseRegistration))
+        self.assertFalse(Order.user_cart_has_items(self.user, [CertificateItem]))
+        self.assertFalse(Order.user_cart_has_items(self.user, [PaidCourseRegistration]))
 
     def test_user_cart_has_paid_course_registration_items(self):
         cart = Order.get_cart_for_user(self.user)
         item = PaidCourseRegistration(order=cart, user=self.user)
         item.save()
-        self.assertTrue(Order.user_cart_has_items(self.user, PaidCourseRegistration))
-        self.assertFalse(Order.user_cart_has_items(self.user, CertificateItem))
+        self.assertTrue(Order.user_cart_has_items(self.user, [PaidCourseRegistration]))
+        self.assertFalse(Order.user_cart_has_items(self.user, [CertificateItem]))
 
     def test_user_cart_has_certificate_items(self):
         cart = Order.get_cart_for_user(self.user)
         CertificateItem.add_to_order(cart, self.course_key, self.cost, 'honor')
-        self.assertTrue(Order.user_cart_has_items(self.user, CertificateItem))
-        self.assertFalse(Order.user_cart_has_items(self.user, PaidCourseRegistration))
+        self.assertTrue(Order.user_cart_has_items(self.user, [CertificateItem]))
+        self.assertFalse(Order.user_cart_has_items(self.user, [PaidCourseRegistration]))
 
     def test_cart_clear(self):
         cart = Order.get_cart_for_user(user=self.user)
@@ -189,7 +191,7 @@ class OrderTest(ModuleStoreTestCase):
     def test_purchase_item_email_smtp_failure(self, error_logger):
         cart = Order.get_cart_for_user(user=self.user)
         CertificateItem.add_to_order(cart, self.course_key, self.cost, 'honor')
-        with patch('shoppingcart.models.send_mail', side_effect=smtplib.SMTPException):
+        with patch('shoppingcart.models.EmailMessage.send', side_effect=smtplib.SMTPException):
             cart.purchase()
             self.assertTrue(error_logger.called)
 
@@ -326,6 +328,15 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase):
 
         self.assertEqual(self.cart.total_cost, self.cost)
 
+    def test_cart_type_business(self):
+        self.cart.order_type = 'business'
+        self.cart.save()
+        item = CourseRegCodeItem.add_to_order(self.cart, self.course_key, 2)
+        self.cart.purchase()
+        self.assertFalse(CourseEnrollment.is_enrolled(self.user, self.course_key))
+        # check that the registration codes are generated against the order
+        self.assertEqual(len(CourseRegistrationCode.objects.filter(order=self.cart)), item.qty)
+
     def test_add_with_default_mode(self):
         """
         Tests add_to_cart where the mode specified in the argument is NOT in the database
@@ -341,6 +352,31 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase):
         self.assertEqual(self.cart.total_cost, 0)
         self.assertTrue(PaidCourseRegistration.contained_in_order(self.cart, self.course_key))
 
+        course_reg_code_item = CourseRegCodeItem.add_to_order(self.cart, self.course_key, 2, mode_slug="DNE")
+
+        self.assertEqual(course_reg_code_item.unit_cost, 0)
+        self.assertEqual(course_reg_code_item.line_cost, 0)
+        self.assertEqual(course_reg_code_item.mode, "honor")
+        self.assertEqual(course_reg_code_item.user, self.user)
+        self.assertEqual(course_reg_code_item.status, "cart")
+        self.assertEqual(self.cart.total_cost, 0)
+        self.assertTrue(CourseRegCodeItem.contained_in_order(self.cart, self.course_key))
+
+    def test_add_course_reg_item_with_no_course_item(self):
+        fake_course_id = CourseLocator(org="edx", course="fake", run="course")
+        with self.assertRaises(CourseDoesNotExistException):
+            CourseRegCodeItem.add_to_order(self.cart, fake_course_id, 2)
+
+    def test_course_reg_item_already_in_cart(self):
+        CourseRegCodeItem.add_to_order(self.cart, self.course_key, 2)
+        with self.assertRaises(ItemAlreadyInCartException):
+            CourseRegCodeItem.add_to_order(self.cart, self.course_key, 2)
+
+    def test_course_reg_item_already_enrolled_in_course(self):
+        CourseEnrollment.enroll(self.user, self.course_key)
+        with self.assertRaises(AlreadyEnrolledInCourseException):
+            CourseRegCodeItem.add_to_order(self.cart, self.course_key, 2)
+
     def test_purchased_callback(self):
         reg1 = PaidCourseRegistration.add_to_order(self.cart, self.course_key)
         self.cart.purchase()
@@ -382,6 +418,12 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase):
             reg1.purchased_callback()
         self.assertFalse(CourseEnrollment.is_enrolled(self.user, self.course_key))
 
+        course_reg_code_item = CourseRegCodeItem.add_to_order(self.cart, self.course_key, 2)
+        course_reg_code_item.course_id = CourseLocator(org="changed1", course="forsome1", run="reason1")
+        course_reg_code_item.save()
+        with self.assertRaises(PurchasedCallbackException):
+            course_reg_code_item.purchased_callback()
+
     def test_user_cart_has_both_items(self):
         """
         This test exists b/c having both CertificateItem and PaidCourseRegistration in an order used to break
diff --git a/lms/djangoapps/shoppingcart/tests/test_reports.py b/lms/djangoapps/shoppingcart/tests/test_reports.py
index e3f69dee9cbd874d52fce014ea6612e6a51c22c5..80402d33004f1f09a085e08914c6bd4a4568c6db 100644
--- a/lms/djangoapps/shoppingcart/tests/test_reports.py
+++ b/lms/djangoapps/shoppingcart/tests/test_reports.py
@@ -13,7 +13,8 @@ from django.test.utils import override_settings
 
 from course_modes.models import CourseMode
 from courseware.tests.tests import TEST_DATA_MONGO_MODULESTORE
-from shoppingcart.models import (Order, CertificateItem, PaidCourseRegistration, PaidCourseRegistrationAnnotation)
+from shoppingcart.models import (Order, CertificateItem, PaidCourseRegistration, PaidCourseRegistrationAnnotation,
+                                 CourseRegCodeItemAnnotation)
 from shoppingcart.views import initialize_report
 from student.tests.factories import UserFactory
 from student.models import CourseEnrollment
@@ -203,6 +204,8 @@ class ItemizedPurchaseReportTest(ModuleStoreTestCase):
         course_mode2.save()
         self.annotation = PaidCourseRegistrationAnnotation(course_id=self.course_key, annotation=self.TEST_ANNOTATION)
         self.annotation.save()
+        self.course_reg_code_annotation = CourseRegCodeItemAnnotation(course_id=self.course_key, annotation=self.TEST_ANNOTATION)
+        self.course_reg_code_annotation.save()
         self.cart = Order.get_cart_for_user(self.user)
         self.reg = PaidCourseRegistration.add_to_order(self.cart, self.course_key)
         self.cert_item = CertificateItem.add_to_order(self.cart, self.course_key, self.cost, 'verified')
@@ -269,3 +272,9 @@ class ItemizedPurchaseReportTest(ModuleStoreTestCase):
         Fill in gap in test coverage.  __unicode__ method of PaidCourseRegistrationAnnotation
         """
         self.assertEqual(unicode(self.annotation), u'{} : {}'.format(self.course_key.to_deprecated_string(), self.TEST_ANNOTATION))
+
+    def test_courseregcodeitemannotationannotation_unicode(self):
+        """
+        Fill in gap in test coverage.  __unicode__ method of CourseRegCodeItemAnnotation
+        """
+        self.assertEqual(unicode(self.course_reg_code_annotation), u'{} : {}'.format(self.course_key.to_deprecated_string(), self.TEST_ANNOTATION))
diff --git a/lms/djangoapps/shoppingcart/tests/test_views.py b/lms/djangoapps/shoppingcart/tests/test_views.py
index fae0285673c556ab7cef5f58300bae04d1584201..5c1c16ddb9093a970c0fedddd90cc6704f986a9a 100644
--- a/lms/djangoapps/shoppingcart/tests/test_views.py
+++ b/lms/djangoapps/shoppingcart/tests/test_views.py
@@ -1,9 +1,7 @@
 """
 Tests for Shopping Cart views
 """
-import json
 from urlparse import urlparse
-from decimal import Decimal
 
 from django.http import HttpRequest
 from django.conf import settings
@@ -14,6 +12,7 @@ from django.utils.translation import ugettext as _
 from django.contrib.admin.sites import AdminSite
 from django.contrib.auth.models import Group, User
 from django.contrib.messages.storage.fallback import FallbackStorage
+from django.core import mail
 
 from django.core.cache import cache
 from pytz import UTC
@@ -28,7 +27,7 @@ from xmodule.modulestore.tests.django_utils import (
 from xmodule.modulestore.tests.factories import CourseFactory
 from shoppingcart.views import _can_download_report, _get_date_from_str
 from shoppingcart.models import (
-    Order, CertificateItem, PaidCourseRegistration,
+    Order, CertificateItem, PaidCourseRegistration, CourseRegCodeItem,
     Coupon, CourseRegistrationCode, RegistrationCodeRedemption,
     DonationConfiguration
 )
@@ -41,6 +40,8 @@ from shoppingcart.processors import render_purchase_form_html
 from shoppingcart.admin import SoftDeleteCouponAdmin
 from shoppingcart.views import initialize_report
 from shoppingcart.tests.payment_fake import PaymentFakeView
+from decimal import Decimal
+import json
 
 
 def mock_render_purchase_form_html(*args, **kwargs):
@@ -133,6 +134,30 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
         resp = self.client.post(reverse('shoppingcart.views.add_course_to_cart', args=[self.course_key.to_deprecated_string()]))
         self.assertEqual(resp.status_code, 403)
 
+    def test_billing_details(self):
+        billing_url = reverse('billing_details')
+        self.login_user()
+
+        # page not found error because order_type is not business
+        resp = self.client.get(billing_url)
+        self.assertEqual(resp.status_code, 404)
+
+        #chagne the order_type to business
+        self.cart.order_type = 'business'
+        self.cart.save()
+        resp = self.client.get(billing_url)
+        self.assertEqual(resp.status_code, 200)
+
+        data = {'company_name': 'Test Company', 'company_contact_name': 'JohnDoe',
+                'company_contact_email': 'john@est.com', 'recipient_name': 'Mocker',
+                'recipient_email': 'mock@germ.com', 'company_address_line_1': 'DC Street # 1',
+                'company_address_line_2': '',
+                'company_city': 'DC', 'company_state': 'NY', 'company_zip': '22003', 'company_country': 'US',
+                'customer_reference_number': 'PO#23'}
+
+        resp = self.client.post(billing_url, data)
+        self.assertEqual(resp.status_code, 200)
+
     def test_add_course_to_cart_already_in_cart(self):
         PaidCourseRegistration.add_to_order(self.cart, self.course_key)
         self.login_user()
@@ -148,6 +173,120 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
         self.assertEqual(resp.status_code, 404)
         self.assertIn("Discount does not exist against code '{0}'.".format(non_existing_code), resp.content)
 
+    def test_valid_qty_greater_then_one_and_purchase_type_should_business(self):
+        qty = 2
+        item = self.add_course_to_user_cart(self.course_key)
+        resp = self.client.post(reverse('shoppingcart.views.update_user_cart'), {'ItemId': item.id, 'qty': qty})
+        self.assertEqual(resp.status_code, 200)
+        data = json.loads(resp.content)
+        self.assertEqual(data['total_cost'], item.unit_cost * qty)
+        cart = Order.get_cart_for_user(self.user)
+        self.assertEqual(cart.order_type, 'business')
+
+    def test_in_valid_qty_case(self):
+        # invalid quantity, Quantity must be between 1 and 1000.
+        qty = 0
+        item = self.add_course_to_user_cart(self.course_key)
+        resp = self.client.post(reverse('shoppingcart.views.update_user_cart'), {'ItemId': item.id, 'qty': qty})
+        self.assertEqual(resp.status_code, 400)
+        self.assertIn("Quantity must be between 1 and 1000.", resp.content)
+
+        # invalid quantity, Quantity must be an integer.
+        qty = 'abcde'
+        resp = self.client.post(reverse('shoppingcart.views.update_user_cart'), {'ItemId': item.id, 'qty': qty})
+        self.assertEqual(resp.status_code, 400)
+        self.assertIn("Quantity must be an integer.", resp.content)
+
+        # invalid quantity, Quantity is not present in request
+        resp = self.client.post(reverse('shoppingcart.views.update_user_cart'), {'ItemId': item.id})
+        self.assertEqual(resp.status_code, 400)
+        self.assertIn("Quantity must be between 1 and 1000.", resp.content)
+
+    def test_valid_qty_but_item_not_found(self):
+        qty = 2
+        item_id = '-1'
+        self.login_user()
+        resp = self.client.post(reverse('shoppingcart.views.update_user_cart'), {'ItemId': item_id, 'qty': qty})
+        self.assertEqual(resp.status_code, 404)
+        self.assertEqual('Order item does not exist.', resp.content)
+
+        # now testing the case if item id not found in request,
+        resp = self.client.post(reverse('shoppingcart.views.update_user_cart'), {'qty': qty})
+        self.assertEqual(resp.status_code, 400)
+        self.assertEqual('Order item not found in request.', resp.content)
+
+    def test_purchase_type_should_be_personal_when_qty_is_one(self):
+        qty = 1
+        item = self.add_course_to_user_cart(self.course_key)
+        resp = self.client.post(reverse('shoppingcart.views.update_user_cart'), {'ItemId': item.id, 'qty': qty})
+        self.assertEqual(resp.status_code, 200)
+        data = json.loads(resp.content)
+        self.assertEqual(data['total_cost'], item.unit_cost * 1)
+        cart = Order.get_cart_for_user(self.user)
+        self.assertEqual(cart.order_type, 'personal')
+
+    def test_purchase_type_on_removing_item_and_cart_has_item_with_qty_one(self):
+        qty = 5
+        self.add_course_to_user_cart(self.course_key)
+        item2 = self.add_course_to_user_cart(self.testing_course.id)
+        resp = self.client.post(reverse('shoppingcart.views.update_user_cart'), {'ItemId': item2.id, 'qty': qty})
+        self.assertEqual(resp.status_code, 200)
+        cart = Order.get_cart_for_user(self.user)
+        cart_items = cart.orderitem_set.all()
+        test_flag = False
+        for cartitem in cart_items:
+            if cartitem.qty == 5:
+                test_flag = True
+                resp = self.client.post(reverse('shoppingcart.views.remove_item', args=[]), {'id': cartitem.id})
+                self.assertEqual(resp.status_code, 200)
+        self.assertTrue(test_flag)
+
+        cart = Order.get_cart_for_user(self.user)
+        self.assertEqual(cart.order_type, 'personal')
+
+    def test_billing_details_btn_in_cart_when_qty_is_greater_than_one(self):
+        qty = 5
+        item = self.add_course_to_user_cart(self.course_key)
+        resp = self.client.post(reverse('shoppingcart.views.update_user_cart'), {'ItemId': item.id, 'qty': qty})
+        self.assertEqual(resp.status_code, 200)
+        resp = self.client.get(reverse('shoppingcart.views.show_cart', args=[]))
+        self.assertIn("Billing Details", resp.content)
+
+    def test_purchase_type_should_be_personal_when_remove_all_items_from_cart(self):
+        item1 = self.add_course_to_user_cart(self.course_key)
+        resp = self.client.post(reverse('shoppingcart.views.update_user_cart'), {'ItemId': item1.id, 'qty': 2})
+        self.assertEqual(resp.status_code, 200)
+
+        item2 = self.add_course_to_user_cart(self.testing_course.id)
+        resp = self.client.post(reverse('shoppingcart.views.update_user_cart'), {'ItemId': item2.id, 'qty': 5})
+        self.assertEqual(resp.status_code, 200)
+
+        cart = Order.get_cart_for_user(self.user)
+        cart_items = cart.orderitem_set.all()
+        test_flag = False
+        for cartitem in cart_items:
+            test_flag = True
+            resp = self.client.post(reverse('shoppingcart.views.remove_item', args=[]), {'id': cartitem.id})
+            self.assertEqual(resp.status_code, 200)
+        self.assertTrue(test_flag)
+
+        cart = Order.get_cart_for_user(self.user)
+        self.assertEqual(cart.order_type, 'personal')
+
+    def test_use_valid_coupon_code_and_qty_is_greater_than_one(self):
+        qty = 5
+        item = self.add_course_to_user_cart(self.course_key)
+        resp = self.client.post(reverse('shoppingcart.views.update_user_cart'), {'ItemId': item.id, 'qty': qty})
+        self.assertEqual(resp.status_code, 200)
+        data = json.loads(resp.content)
+        self.assertEqual(data['total_cost'], item.unit_cost * qty)
+
+        # use coupon code
+        self.add_coupon(self.course_key, True, self.coupon_code)
+        resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': self.coupon_code})
+        item = self.cart.orderitem_set.all().select_subclasses()[0]
+        self.assertEquals(item.unit_cost * qty, 180)
+
     def test_course_discount_invalid_reg_code(self):
         self.add_reg_code(self.course_key)
         self.add_course_to_user_cart(self.course_key)
@@ -319,6 +458,36 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
         info_log.assert_called_with(
             'Coupon "{0}" redemption entry removed for user "{1}" for order item "{2}"'.format(self.coupon_code, self.user, reg_item.id))
 
+    @patch('shoppingcart.views.log.info')
+    def test_reset_redemption_for_coupon(self, info_log):
+
+        self.add_coupon(self.course_key, True, self.coupon_code)
+        reg_item = self.add_course_to_user_cart(self.course_key)
+
+        resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': self.coupon_code})
+        self.assertEqual(resp.status_code, 200)
+
+        resp = self.client.post(reverse('shoppingcart.views.reset_code_redemption', args=[]))
+
+        self.assertEqual(resp.status_code, 200)
+        info_log.assert_called_with(
+            'Coupon redemption entry removed for user {0} for order {1}'.format(self.user, reg_item.id))
+
+    @patch('shoppingcart.views.log.info')
+    def test_reset_redemption_for_registration_code(self, info_log):
+
+        self.add_reg_code(self.course_key)
+        reg_item = self.add_course_to_user_cart(self.course_key)
+
+        resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': self.reg_code})
+        self.assertEqual(resp.status_code, 200)
+
+        resp = self.client.post(reverse('shoppingcart.views.reset_code_redemption', args=[]))
+
+        self.assertEqual(resp.status_code, 200)
+        info_log.assert_called_with(
+            'Registration code redemption entry removed for user {0} for order {1}'.format(self.user, reg_item.id))
+
     @patch('shoppingcart.views.log.info')
     def test_existing_reg_code_redemption_on_removing_item(self, info_log):
 
@@ -474,14 +643,14 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
         resp = self.client.get(reverse('shoppingcart.views.show_cart', args=[]))
         self.assertEqual(resp.status_code, 200)
 
-        ((purchase_form_arg_cart,), _) = form_mock.call_args
+        ((purchase_form_arg_cart,), _) = form_mock.call_args  # pylint: disable=W0621
         purchase_form_arg_cart_items = purchase_form_arg_cart.orderitem_set.all().select_subclasses()
         self.assertIn(reg_item, purchase_form_arg_cart_items)
         self.assertIn(cert_item, purchase_form_arg_cart_items)
         self.assertEqual(len(purchase_form_arg_cart_items), 2)
 
         ((template, context), _) = render_mock.call_args
-        self.assertEqual(template, 'shoppingcart/list.html')
+        self.assertEqual(template, 'shoppingcart/shopping_cart.html')
         self.assertEqual(len(context['shoppingcart_items']), 2)
         self.assertEqual(context['amount'], 80)
         self.assertIn("80.00", context['form_html'])
@@ -626,7 +795,7 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
         self.assertEqual(resp.status_code, 200)
 
         resp = self.client.get(reverse('shoppingcart.views.show_cart', args=[]))
-        self.assertIn('Check Out', resp.content)
+        self.assertIn('Payment', resp.content)
         self.cart.purchase(first='FirstNameTesting123', street1='StreetTesting123')
 
         resp = self.client.get(reverse('shoppingcart.views.show_receipt', args=[self.cart.id]))
@@ -665,13 +834,58 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
         self.assertIn('FirstNameTesting123', resp.content)
         self.assertIn('80.00', resp.content)
 
-        ((template, context), _) = render_mock.call_args
+        ((template, context), _) = render_mock.call_args  # pylint: disable=W0621
         self.assertEqual(template, 'shoppingcart/receipt.html')
         self.assertEqual(context['order'], self.cart)
-        self.assertIn(reg_item, context['order_items'])
-        self.assertIn(cert_item, context['order_items'])
+        self.assertIn(reg_item, context['shoppingcart_items'][0])
+        self.assertIn(cert_item, context['shoppingcart_items'][1])
         self.assertFalse(context['any_refunds'])
 
+    @patch('shoppingcart.views.render_to_response', render_mock)
+    def test_courseregcode_item_total_price(self):
+        self.cart.order_type = 'business'
+        self.cart.save()
+        CourseRegCodeItem.add_to_order(self.cart, self.course_key, 2)
+        self.cart.purchase(first='FirstNameTesting123', street1='StreetTesting123')
+        self.assertEquals(CourseRegCodeItem.get_total_amount_of_purchased_item(self.course_key), 80)
+
+    @patch('shoppingcart.views.render_to_response', render_mock)
+    def test_show_receipt_success_with_order_type_business(self):
+        self.cart.order_type = 'business'
+        self.cart.save()
+        reg_item = CourseRegCodeItem.add_to_order(self.cart, self.course_key, 2)
+        self.cart.add_billing_details(company_name='T1Omega', company_contact_name='C1',
+                                      company_contact_email='test@t1.com', recipient_email='test@t2.com')
+        self.cart.purchase(first='FirstNameTesting123', street1='StreetTesting123')
+
+        # mail is sent to these emails recipient_email, company_contact_email, order.user.email
+        self.assertEquals(len(mail.outbox), 3)
+
+        self.login_user()
+        resp = self.client.get(reverse('shoppingcart.views.show_receipt', args=[self.cart.id]))
+        self.assertEqual(resp.status_code, 200)
+
+        # when order_type = 'business' the user is not enrolled in the
+        # course but presented with the enrollment links
+        self.assertFalse(CourseEnrollment.is_enrolled(self.cart.user, self.course_key))
+        self.assertIn('FirstNameTesting123', resp.content)
+        self.assertIn('80.00', resp.content)
+        # check for the enrollment codes content
+        self.assertIn('Please send each professional one of these unique registration codes to enroll into the course.', resp.content)
+
+        ((template, context), _) = render_mock.call_args  # pylint: disable=W0621
+        self.assertEqual(template, 'shoppingcart/receipt.html')
+        self.assertEqual(context['order'], self.cart)
+        self.assertIn(reg_item, context['shoppingcart_items'][0])
+        self.assertIn(self.cart.purchase_time.strftime("%B %d, %Y"), resp.content)
+        self.assertIn(self.cart.company_name, resp.content)
+        self.assertIn(self.cart.company_contact_name, resp.content)
+        self.assertIn(self.cart.company_contact_email, resp.content)
+        self.assertIn(self.cart.recipient_email, resp.content)
+        self.assertIn("Invoice #{order_id}".format(order_id=self.cart.id), resp.content)
+        self.assertIn('You have successfully purchased <b>{total_registration_codes} course registration codes'
+                      .format(total_registration_codes=context['total_registration_codes']), resp.content)
+
     @patch('shoppingcart.views.render_to_response', render_mock)
     def test_show_receipt_success_with_upgrade(self):
 
@@ -705,8 +919,8 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
 
         self.assertEqual(template, 'shoppingcart/receipt.html')
         self.assertEqual(context['order'], self.cart)
-        self.assertIn(reg_item, context['order_items'])
-        self.assertIn(cert_item, context['order_items'])
+        self.assertIn(reg_item, context['shoppingcart_items'][0])
+        self.assertIn(cert_item, context['shoppingcart_items'][1])
         self.assertFalse(context['any_refunds'])
 
         course_enrollment = CourseEnrollment.get_or_create_enrollment(self.user, self.course_key)
@@ -736,8 +950,8 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
         ((template, context), _tmp) = render_mock.call_args
         self.assertEqual(template, 'shoppingcart/receipt.html')
         self.assertEqual(context['order'], self.cart)
-        self.assertIn(reg_item, context['order_items'])
-        self.assertIn(cert_item, context['order_items'])
+        self.assertIn(reg_item, context['shoppingcart_items'][0])
+        self.assertIn(cert_item, context['shoppingcart_items'][1])
         self.assertTrue(context['any_refunds'])
 
     @patch('shoppingcart.views.render_to_response', render_mock)
@@ -869,6 +1083,12 @@ class RegistrationCodeRedemptionCourseEnrollment(ModuleStoreTestCase):
         response = self.client.post(redeem_url, **{'HTTP_HOST': 'localhost'})
         self.assertTrue("You've clicked a link for an enrollment code that has already been used." in response.content)
 
+        #now check the response of the dashboard page
+        dashboard_url = reverse('dashboard')
+        response = self.client.get(dashboard_url)
+        self.assertEquals(response.status_code, 200)
+        self.assertTrue(self.course.display_name, response.content)
+
 
 @override_settings(MODULESTORE=MODULESTORE_CONFIG)
 @ddt.ddt
diff --git a/lms/djangoapps/shoppingcart/urls.py b/lms/djangoapps/shoppingcart/urls.py
index 6d5865f93d5f2e275fedf8c6bf61af5ef72d4c77..02776da0a0f8ce8dfb5f777759d899b9ec454b4f 100644
--- a/lms/djangoapps/shoppingcart/urls.py
+++ b/lms/djangoapps/shoppingcart/urls.py
@@ -17,6 +17,9 @@ if settings.FEATURES['ENABLE_SHOPPING_CART']:
         url(r'^add/course/{}/$'.format(settings.COURSE_ID_PATTERN), 'add_course_to_cart', name='add_course_to_cart'),
         url(r'^register/redeem/(?P<registration_code>[0-9A-Za-z]+)/$', 'register_code_redemption', name='register_code_redemption'),
         url(r'^use_code/$', 'use_code'),
+        url(r'^update_user_cart/$', 'update_user_cart'),
+        url(r'^reset_code_redemption/$', 'reset_code_redemption'),
+        url(r'^billing_details/$', 'billing_details', name='billing_details'),
         url(r'^register_courses/$', 'register_courses'),
     )
 
diff --git a/lms/djangoapps/shoppingcart/views.py b/lms/djangoapps/shoppingcart/views.py
index 869ebea6a026dbd2189be2c1d53ca7aaf4788702..53c72219ab47c5c69f81f607c3b39c753a1c40dd 100644
--- a/lms/djangoapps/shoppingcart/views.py
+++ b/lms/djangoapps/shoppingcart/views.py
@@ -9,12 +9,13 @@ from django.http import (
     HttpResponseBadRequest, HttpResponseForbidden, Http404
 )
 from django.utils.translation import ugettext as _
+from util.json_request import JsonResponse
 from django.views.decorators.http import require_POST, require_http_methods
 from django.core.urlresolvers import reverse
 from django.views.decorators.csrf import csrf_exempt
-from microsite_configuration import microsite
 from util.bad_request_rate_limiter import BadRequestRateLimiter
 from django.contrib.auth.decorators import login_required
+from microsite_configuration import microsite
 from edxmako.shortcuts import render_to_response
 from opaque_keys.edx.locations import SlashSeparatedCourseKey
 from opaque_keys.edx.locator import CourseLocator
@@ -31,7 +32,8 @@ from .exceptions import (
     MultipleCouponsNotAllowedException, InvalidCartItem
 )
 from .models import (
-    Order, PaidCourseRegistration, OrderItem, Coupon,
+    Order, OrderTypes,
+    PaidCourseRegistration, OrderItem, Coupon, CourseRegCodeItem,
     CouponRedemption, CourseRegistrationCode, RegistrationCodeRedemption,
     Donation, DonationConfiguration
 )
@@ -39,6 +41,7 @@ from .processors import (
     process_postpay_callback, render_purchase_form_html,
     get_signed_purchase_params, get_purchase_endpoint
 )
+
 import json
 from xmodule_django.models import CourseKeyField
 
@@ -90,22 +93,68 @@ def add_course_to_cart(request, course_id):
     return HttpResponse(_("Course added to cart."))
 
 
+@login_required
+def update_user_cart(request):
+    """
+    when user change the number-of-students from the UI then
+    this method Update the corresponding qty field in OrderItem model and update the order_type in order model.
+    """
+    try:
+        qty = int(request.POST.get('qty', -1))
+    except ValueError:
+        log.exception('Quantity must be an integer.')
+        return HttpResponseBadRequest('Quantity must be an integer.')
+
+    if not 1 <= qty <= 1000:
+        log.warning('Quantity must be between 1 and 1000.')
+        return HttpResponseBadRequest('Quantity must be between 1 and 1000.')
+
+    item_id = request.POST.get('ItemId', None)
+    if item_id:
+        try:
+            item = OrderItem.objects.get(id=item_id, status='cart')
+        except OrderItem.DoesNotExist:
+            log.exception('Cart OrderItem id={0} DoesNotExist'.format(item_id))
+            return HttpResponseNotFound('Order item does not exist.')
+
+        item.qty = qty
+        item.save()
+        item.order.update_order_type()
+        total_cost = item.order.total_cost
+        return JsonResponse({"total_cost": total_cost}, 200)
+
+    return HttpResponseBadRequest('Order item not found in request.')
+
+
 @login_required
 def show_cart(request):
+    """
+    This view shows cart items.
+    """
     cart = Order.get_cart_for_user(request.user)
     total_cost = cart.total_cost
-    cart_items = cart.orderitem_set.all()
+    cart_items = cart.orderitem_set.all().select_subclasses()
+    shoppingcart_items = []
+    for cart_item in cart_items:
+        course_key = getattr(cart_item, 'course_id')
+        if course_key:
+            course = get_course_by_id(course_key, depth=0)
+            shoppingcart_items.append((cart_item, course))
+
+    site_name = microsite.get_value('SITE_NAME', settings.SITE_NAME)
 
     callback_url = request.build_absolute_uri(
         reverse("shoppingcart.views.postpay_callback")
     )
     form_html = render_purchase_form_html(cart, callback_url=callback_url)
     context = {
-        'shoppingcart_items': cart_items,
+        'order': cart,
+        'shoppingcart_items': shoppingcart_items,
         'amount': total_cost,
+        'site_name': site_name,
         'form_html': form_html,
     }
-    return render_to_response("shoppingcart/list.html", context)
+    return render_to_response("shoppingcart/shopping_cart.html", context)
 
 
 @login_required
@@ -127,22 +176,26 @@ def clear_cart(request):
 
 @login_required
 def remove_item(request):
+    """
+    This will remove an item from the user cart and also delete the corresponding coupon codes redemption.
+    """
     item_id = request.REQUEST.get('id', '-1')
-    try:
-        item = OrderItem.objects.get(id=item_id, status='cart')
+
+    items = OrderItem.objects.filter(id=item_id, status='cart').select_subclasses()
+
+    if not len(items):
+        log.exception('Cannot remove cart OrderItem id={0}. DoesNotExist or item is already purchased'.format(item_id))
+    else:
+        item = items[0]
         if item.user == request.user:
-            order_item_course_id = None
-            if hasattr(item, 'paidcourseregistration'):
-                order_item_course_id = item.paidcourseregistration.course_id
+            order_item_course_id = getattr(item, 'course_id')
             item.delete()
             log.info('order item {0} removed for user {1}'.format(item_id, request.user))
             remove_code_redemption(order_item_course_id, item_id, item, request.user)
+            item.order.update_order_type()
 
-    except OrderItem.DoesNotExist:
-        log.exception('Cannot remove cart OrderItem id={0}. DoesNotExist or item is already purchased'.format(item_id))
     return HttpResponse('OK')
 
-
 def remove_code_redemption(order_item_course_id, item_id, item, user):
     """
     If an item removed from shopping cart then we will remove
@@ -159,16 +212,30 @@ def remove_code_redemption(order_item_course_id, item_id, item, user):
         log.info('Coupon "{0}" redemption entry removed for user "{1}" for order item "{2}"'
                  .format(coupon_redemption.coupon.code, user, item_id))
     except CouponRedemption.DoesNotExist:
-        try:
-            # Try to remove redemption information of registration code, If exist.
-            reg_code_redemption = RegistrationCodeRedemption.objects.get(redeemed_by=user, order=item.order_id)
-        except RegistrationCodeRedemption.DoesNotExist:
-            log.debug('Code redemption does not exist for order item id={0}.'.format(item_id))
-        else:
-            if order_item_course_id == reg_code_redemption.registration_code.course_id:
-                reg_code_redemption.delete()
-                log.info('Registration code "{0}" redemption entry removed for user "{1}" for order item "{2}"'
-                         .format(reg_code_redemption.registration_code.code, user, item_id))
+        pass
+
+    try:
+        # Try to remove redemption information of registration code, If exist.
+        reg_code_redemption = RegistrationCodeRedemption.objects.get(redeemed_by=user, order=item.order_id)
+    except RegistrationCodeRedemption.DoesNotExist:
+        log.debug('Code redemption does not exist for order item id={0}.'.format(item_id))
+    else:
+        if order_item_course_id == reg_code_redemption.registration_code.course_id:
+            reg_code_redemption.delete()
+            log.info('Registration code "{0}" redemption entry removed for user "{1}" for order item "{2}"'
+                     .format(reg_code_redemption.registration_code.code, user, item_id))
+
+
+@login_required
+def reset_code_redemption(request):
+    """
+    This method reset the code redemption from user cart items.
+    """
+    cart = Order.get_cart_for_user(request.user)
+    cart.reset_cart_items_prices()
+    CouponRedemption.delete_coupon_redemption(request.user, cart)
+    RegistrationCodeRedemption.delete_registration_redemption(request.user, cart)
+    return HttpResponse('reset')
 
 
 @login_required
@@ -448,6 +515,49 @@ def postpay_callback(request):
         return render_to_response('shoppingcart/error.html', {'order': result['order'],
                                                               'error_html': result['error_html']})
 
+
+@require_http_methods(["GET", "POST"])
+@login_required
+def billing_details(request):
+    """
+    This is the view for capturing additional billing details
+    in case of the business purchase workflow.
+    """
+
+    cart = Order.get_cart_for_user(request.user)
+    cart_items = cart.orderitem_set.all()
+
+    if getattr(cart, 'order_type') != OrderTypes.BUSINESS:
+        raise Http404('Page not found!')
+
+    if request.method == "GET":
+        callback_url = request.build_absolute_uri(
+            reverse("shoppingcart.views.postpay_callback")
+        )
+        form_html = render_purchase_form_html(cart, callback_url=callback_url)
+        total_cost = cart.total_cost
+        context = {
+            'shoppingcart_items': cart_items,
+            'amount': total_cost,
+            'form_html': form_html,
+            'site_name': microsite.get_value('SITE_NAME', settings.SITE_NAME),
+        }
+        return render_to_response("shoppingcart/billing_details.html", context)
+    elif request.method == "POST":
+        company_name = request.POST.get("company_name", "")
+        company_contact_name = request.POST.get("company_contact_name", "")
+        company_contact_email = request.POST.get("company_contact_email", "")
+        recipient_name = request.POST.get("recipient_name", "")
+        recipient_email = request.POST.get("recipient_email", "")
+        customer_reference_number = request.POST.get("customer_reference_number", "")
+
+        cart.add_billing_details(company_name, company_contact_name, company_contact_email, recipient_name,
+                                 recipient_email, customer_reference_number)
+        return JsonResponse({
+            'response': _('success')
+        })  # status code 200: OK by default
+
+
 @login_required
 def show_receipt(request, ordernum):
     """
@@ -464,29 +574,61 @@ def show_receipt(request, ordernum):
         raise Http404('Order not found!')
 
     order_items = OrderItem.objects.filter(order=order).select_subclasses()
+    shoppingcart_items = []
+    course_names_list = []
+    for order_item in order_items:
+        course_key = getattr(order_item, 'course_id')
+        if course_key:
+            course = get_course_by_id(course_key, depth=0)
+            shoppingcart_items.append((order_item, course))
+            course_names_list.append(course.display_name)
+
+    appended_course_names = ", ".join(course_names_list)
     any_refunds = any(i.status == "refunded" for i in order_items)
     receipt_template = 'shoppingcart/receipt.html'
     __, instructions = order.generate_receipt_instructions()
-    # we want to have the ability to override the default receipt page when
-    # there is only one item in the order
+    order_type = getattr(order, 'order_type')
+
+    # Only orders where order_items.count() == 1 might be attempting to upgrade
+    attempting_upgrade = request.session.get('attempting_upgrade', False)
+    if attempting_upgrade:
+        course_enrollment = CourseEnrollment.get_or_create_enrollment(request.user, order_items[0].course_id)
+        course_enrollment.emit_event(EVENT_NAME_USER_UPGRADED)
+        request.session['attempting_upgrade'] = False
+
+    recipient_list = []
+    registration_codes = None
+    total_registration_codes = None
+    recipient_list.append(getattr(order.user, 'email'))
+    if order_type == OrderTypes.BUSINESS:
+        registration_codes = CourseRegistrationCode.objects.filter(order=order)
+        total_registration_codes = registration_codes.count()
+        if order.company_contact_email:
+            recipient_list.append(order.company_contact_email)
+        if order.recipient_email:
+            recipient_list.append(order.recipient_email)
+
+    appended_recipient_emails = ", ".join(recipient_list)
+
     context = {
         'order': order,
-        'order_items': order_items,
+        'shoppingcart_items': shoppingcart_items,
         'any_refunds': any_refunds,
         'instructions': instructions,
+        'site_name': microsite.get_value('SITE_NAME', settings.SITE_NAME),
+        'order_type': order_type,
+        'appended_course_names': appended_course_names,
+        'appended_recipient_emails': appended_recipient_emails,
+        'total_registration_codes': total_registration_codes,
+        'registration_codes': registration_codes,
+        'order_purchase_date': order.purchase_time.strftime("%B %d, %Y"),
     }
-
+    # we want to have the ability to override the default receipt page when
+    # there is only one item in the order
     if order_items.count() == 1:
         receipt_template = order_items[0].single_item_receipt_template
         context.update(order_items[0].single_item_receipt_context)
 
-    # Only orders where order_items.count() == 1 might be attempting to upgrade
-    attempting_upgrade = request.session.get('attempting_upgrade', False)
-    if attempting_upgrade:
-        course_enrollment = CourseEnrollment.get_or_create_enrollment(request.user, order_items[0].course_id)
-        course_enrollment.emit_event(EVENT_NAME_USER_UPGRADED)
-        request.session['attempting_upgrade'] = False
-
     return render_to_response(receipt_template, context)
 
 
diff --git a/lms/static/coffee/src/instructor_dashboard/e-commerce.coffee b/lms/static/coffee/src/instructor_dashboard/e-commerce.coffee
index 2f614e6cd4e10c390b93ed4141fd2924abb43b9d..026e321b5b804447571e48fe147621090cc70d46 100644
--- a/lms/static/coffee/src/instructor_dashboard/e-commerce.coffee
+++ b/lms/static/coffee/src/instructor_dashboard/e-commerce.coffee
@@ -11,6 +11,7 @@ class ECommerce
     # gather elements
     @$list_purchase_csv_btn = @$section.find("input[name='list-purchase-transaction-csv']'")
     @$list_sale_csv_btn = @$section.find("input[name='list-sale-csv']'")
+    @$list_order_sale_csv_btn = @$section.find("input[name='list-order-sale-csv']'")
     @$download_company_name = @$section.find("input[name='download_company_name']'")
     @$active_company_name = @$section.find("input[name='active_company_name']'")
     @$spent_company_name = @$section.find('input[name="spent_company_name"]')
@@ -35,6 +36,10 @@ class ECommerce
       url += '/csv'
       location.href = url
 
+    @$list_order_sale_csv_btn.click (e) =>
+      url = @$list_order_sale_csv_btn.data 'endpoint'
+      location.href = url
+
     @$download_coupon_codes.click (e) =>
       url = @$download_coupon_codes.data 'endpoint'
       location.href = url
diff --git a/lms/static/sass/base/_base.scss b/lms/static/sass/base/_base.scss
index 8f6cfe98a631bd6034819d243f69fef4dade33d5..4a9fbcc1fcfd7e699c0813fb4fbda35e1a5c95a4 100644
--- a/lms/static/sass/base/_base.scss
+++ b/lms/static/sass/base/_base.scss
@@ -55,6 +55,15 @@ span {
   font: inherit;
 }
 
+.text-center {
+  text-align: center;
+}
+
+.text-dark-grey {
+  color: $dark-gray1;
+  font-size: 24px;
+}
+
 p + p, ul + p, ol + p {
   margin-top: 20px;
 }
diff --git a/lms/static/sass/base/_variables.scss b/lms/static/sass/base/_variables.scss
index a54a4687c7973a7c8ba8aceb880c762539449a3f..91cb01dfdfc0865414edbccfc880711229e2f213 100644
--- a/lms/static/sass/base/_variables.scss
+++ b/lms/static/sass/base/_variables.scss
@@ -421,3 +421,14 @@ $header-sans-serif: 'Open Sans', Arial, Helvetica, sans-serif;
 // SPLINT: colors
 
 $msg-bg: $action-primary-bg;
+
+// New Shopping Cart
+
+$dark-gray1: #4a4a4a;
+$light-gray1: #f2f2f2;
+$light-gray2: #ababab;
+$dark-gray2: #979797;
+$blue1: #4A90E2;
+$blue2: #00A1E5;
+$green1: #61A12E;
+$red1: #D0021B;
diff --git a/lms/static/sass/course/instructor/_instructor_2.scss b/lms/static/sass/course/instructor/_instructor_2.scss
index 6bc0618bddd3274ef8cd373fb1ee0677668648dc..8aebd745be69985ea198eece842122944635b7ce 100644
--- a/lms/static/sass/course/instructor/_instructor_2.scss
+++ b/lms/static/sass/course/instructor/_instructor_2.scss
@@ -1144,6 +1144,9 @@ input[name="subject"] {
 
 }
 #e-commerce{
+  input[name='list-order-sale-csv'] {
+    margin-right: 14px;
+  }
   input {
     margin-bottom: 1em;
     line-height: 1.3em;
@@ -1292,22 +1295,20 @@ input[name="subject"] {
     width: 650px;
     margin-left: -325px;
     border-radius: 2px;
-    input[type="submit"]#update_coupon_button{
-      @include button(simple, $blue);
-      @extend .button-reset;
-    }
-    input[type="submit"]#add_coupon_button{
+    input[type="button"]#update_coupon_button, input[type="button"]#add_coupon_button,
+    input[type="button"]#set_course_button {
       @include button(simple, $blue);
       @extend .button-reset;
+      display: block;
+      height: auto;
+      margin: 0 auto;
+      width: 100%;
+      white-space: normal;
     }
     input[name="generate-registration-codes-csv"]{
       @include button(simple, $blue);
       @extend .button-reset;
     }
-    input[type="submit"]#set_course_button{
-      @include button(simple, $blue);
-      @extend .button-reset;
-    }
     .modal-form-error {
       box-shadow: inset 0 -1px 2px 0 #f3d9db;
       -webkit-box-sizing: border-box;
diff --git a/lms/static/sass/views/_shoppingcart.scss b/lms/static/sass/views/_shoppingcart.scss
index 1b5119c9a1d1c8a55e0ace3cfd62d3a6a7fce362..65dcd8c00d81677fe59bc3bf2cfd92ad195bedb3 100644
--- a/lms/static/sass/views/_shoppingcart.scss
+++ b/lms/static/sass/views/_shoppingcart.scss
@@ -30,7 +30,7 @@
     font-size: 1.5em;
     color: $base-font-color;
   }
-  
+
   .cart-table {
     width: 100%;
     tr:nth-child(even){
@@ -66,7 +66,7 @@
       th {
         text-align: left;
         border-bottom: 1px solid $border-color-1;
-        
+
         &.qty {
           width: 100px;
         }
@@ -87,7 +87,7 @@
         }
       }
     }
-    
+
     .cart-items {
       td {
         padding: 10px 0px;
@@ -115,7 +115,7 @@
          padding-right: 20px;
       }
     }
-    
+
     .cart-totals {
       td {
         &.cart-total-cost {
@@ -127,10 +127,10 @@
       }
     }
   }
-  
+
   table.order-receipt {
     width: 100%;
-    
+
     .order-number {
       font-weight: bold;
     }
@@ -147,7 +147,7 @@
     th {
       text-align: left;
       padding: 25px 0 15px 0;
-      
+
       &.qty {
         width: 50px;
       }
@@ -210,7 +210,7 @@
       }
     }
     .enrollment-text {
-      color: #4A4A46;
+      color: #9b9b93;
       font-family: 'Open Sans',Verdana,Geneva,sans;
       line-height: normal;
       a {
@@ -264,4 +264,655 @@
     text-shadow: 0 1px 0 #00A1E5;
     font-size: 24px;
   }
-}
\ No newline at end of file
+}
+
+.shopping-cart{
+  a.blue{
+      display: inline-block;
+      background: $blue2;
+      color: white;
+      padding: 20px 40px;
+      border-radius: 3px;
+      font-size: 24px;
+      font-weight: 400;
+      margin: 10px 0px 20px;
+      &:hover{
+        text-decoration: none;
+      }
+    }
+  .relative{
+    position: relative;
+  }
+  input[type="text"], input[type="email"] , select{
+        font-family: "Open Sans",Verdana,Geneva,sans-serif,sans-serif;
+        font-style: normal;
+        border: 2px solid $dark-gray2;
+        height: auto;
+        padding: 8px 12px;
+        font-weight: 600;
+        width: 260px;
+        font-size: 16px;
+        &:focus{
+          border-color: $dark-gray2;
+          box-shadow: none;
+          outline: none;
+        }
+         &.error{
+            border-color: $red1;
+          }
+      }
+  .hidden{display: none;}
+  .show{display: inline-block;}
+  h1{
+    font-size: 24px;
+    color: $dark-gray1;
+    text-align: left;
+    padding: 15px 0px;
+    margin: 10px 0 0 0;
+    letter-spacing: 0px;
+  }
+  ul.steps{
+    padding: 0px;
+    margin: 0;
+    list-style: none;
+    border-top: 3px solid $light-gray1;
+    border-bottom: 3px solid $light-gray1;
+    li{
+      display: inline-block;
+      padding: 26px 30px;
+      margin: 0px 30px;
+      font-size: 20px;
+      font-weight: 100;
+      position: relative;
+      color: $dark-gray1;
+      &.active{font-weight: 400; border-bottom: 3px solid $light-gray1;}
+      &:first-child {padding-left: 30px;margin-left: 0;}
+      &:last-child {
+        padding-right: 30px;margin-right: 0;
+        &:after{display: none;}
+      }
+      &:after{
+        content: "\f178";
+        position: absolute;
+        font-family: FontAwesome;
+        right: -40px;
+        color: #ddd;
+        font-weight: 100;
+      }
+    }
+  }
+  hr{border-top: 1px solid $dark-gray2;}
+  .user-data{
+    margin: 20px 0px;
+    .image{
+      width: 220px;
+      float: left;
+      img{
+        width: 100%;
+        height: auto;
+      }
+    }
+    .data-input{
+      width: calc(100% - 245px);
+      float: left;
+      margin-left: 25px;
+      h3, h3 span{
+        font-family: "Open Sans",Verdana,Geneva,sans-serif,sans-serif;
+        font-size: 16px;
+        text-transform: uppercase;
+        color: $light-gray2;
+        padding: 0;
+      }
+      h1, h1 span{
+        font-size: 24px;
+        color: $dark-gray1;
+        padding: 0 0 10px 0;
+        text-transform: capitalize;
+        span{font-size: 16px;}
+      }
+      hr{border-top: 1px solid $dark-gray2;}
+      .three-col{
+        .col-1{
+          width: 450px;
+          float: left;
+          font-size: 16px;
+          text-transform: uppercase;
+          color: $light-gray2;
+          .price{
+              span{
+                color: $dark-gray1;
+                font-size: 24px;
+                padding-left: 20px;
+              }
+            &.green{color: $green1;}
+            .line-through{text-decoration: line-through;}
+          }
+        }
+        .col-2{
+          width: 350px;
+          float: left;
+          line-height: 44px;
+          text-transform: uppercase;
+          color: $light-gray2;
+          .numbers-row{
+            position: relative;
+            label{
+              font-size: 16px;
+              text-transform: uppercase;
+              color: $light-gray2;
+              font-family: "Open Sans",Verdana,Geneva,sans-serif,sans-serif;
+              font-weight: 400;
+              font-style: normal;
+            }
+            .counter{
+              margin-left: 25px;
+              border-radius: 3px;
+              padding: 6px 30px 6px 10px;
+              display: inline-block;
+              border: 2px solid $dark-gray2;
+              input[type="text"]{
+                width: 75px;
+                border: none;
+                box-shadow: none;
+                color: #666;
+                font-size: 25px;
+                font-style: normal;
+                font-family: "Open Sans",Verdana,Geneva,sans-serif,sans-serif;
+                font-weight: 600;
+                padding: 8px 0;
+                height: auto;
+                text-align: center;
+                &:focus{
+                  outline: none;
+                }
+              }
+
+            }
+            .button{
+              position: absolute;
+              background: none;
+              margin-left: -30px;
+              padding: 0;
+              border: none;
+              box-shadow: none;
+              text-shadow: none;
+              height: 17px;
+              i{
+                color: $dark-gray2;
+                font-size: 24px;
+                span{display: none;}
+              }
+              &.inc{top: 9px;}
+              &.dec{top: 30px;height: 22px;}
+            }
+            &.disabled{
+              .counter{
+                border: 2px solid #CCCCCC;
+                &:hover{
+                  cursor: not-allowed;
+                }
+                input{
+                  color: #CCC;
+                }
+              }
+              .button{
+                i{
+                  color: #ccc;
+                }
+              }
+              }
+            .updateBtn{
+                display: inline-block;
+                float: right;
+                font-size: 15px;
+                padding: 25px 35px 25px 0;
+                &:focus{
+                  outline: none;
+                }
+            }
+            span.error-text{
+              display: block;
+              text-transform: lowercase;
+            }
+          }
+          .disable-numeric-counter{
+            pointer-events: none;
+          }
+        }
+        .col-3{
+          width: 100px;
+          float: right;
+          a.btn-remove{
+            float: right;
+            opacity: 0.8;
+            i{
+              color: $dark-gray2;
+              font-size: 24PX;
+              line-height: 40px;
+            }
+            &:hover{text-decoration: none;opacity: 1;}
+          }
+        }
+      }
+    }
+
+  }
+  .discount{
+      border-bottom: 2px solid $light-gray1;
+      border-top: 2px solid $light-gray1;
+      margin: 20px 0;
+      padding: 17px 20px 15px;
+      min-height: 45px;
+      .code-text{
+        a{
+        color: $blue1;
+        font-size: 18px;
+        text-transform: lowercase;
+        font-weight: 600;
+        display: inline-block;
+        padding: 10px 0px;
+        cursor: pointer;
+        }
+        span{
+          display: inline-block;
+          padding: 9px 0px;
+          b{
+            font-weight: 600;
+            font-size: 24px;
+            padding-left: 20px;
+            letter-spacing: 0;
+          }
+        }
+      }
+
+    .code-input{
+      display: inline-block;
+      input[type="text"]{
+        font-family: "Open Sans",Verdana,Geneva,sans-serif,sans-serif;
+        font-style: normal;
+        border: 2px solid $dark-gray2;
+        height: auto;
+        padding: 8px 12px;
+        font-weight: 600;
+        width: 260px;
+        &:focus{
+          border-color: $dark-gray2;
+          box-shadow: none;
+        }
+         &.error{
+            border-color: $red1;
+          }
+      }
+      .error-text{
+        color: $red1;
+        font-size: 12px;
+        display: block;
+        padding-bottom: 0;
+      }
+    input[type="submit"]{
+      padding: 9px 35px;
+    }
+    }
+    .code-applied{
+      display: inline-block;
+      .green{
+        color: $green1;
+        font-weight: 600;
+        margin-right: 20px;
+      }
+      input[type="submit"]{
+        padding: 9px 35px;
+        background: white;
+        border: 2px solid $dark-gray2;
+        color: $dark-gray2;
+        box-shadow: none;
+        text-shadow: none;
+        &:hover{
+          background: white;
+          color: $dark-gray1;
+          border: 2px solid $dark-gray2;
+        }
+      }
+    }
+    input[type="submit"]{
+      width: auto;
+      padding: 7px 20px;
+      height: auto;
+      float: none;
+      font-size: 16px;
+      letter-spacing: 0;
+      font-weight: 600;
+      &:hover{
+        background: #1F8FC2;
+        border: 1px solid transparent;
+        box-shadow: none;
+      }
+    }
+    }
+    .col-two{
+      overflow: hidden;
+      padding-bottom: 20px;
+      border-bottom: 2px solid #f2f2f2;
+      .row-inside {
+        float: left;
+        width: 50%;
+        padding: 10px 0;
+        b{
+          font-size: 14px;
+          width: 190px;
+          display: inline-block;
+          margin-right: 20px;
+          font-family: "Open Sans",Verdana,Geneva,sans-serif,sans-serif;
+          vertical-align: top;
+        }
+        label{
+          width: 300px;
+          margin: 0px;
+          display: inline-block;
+          font-family: "Open Sans",Verdana,Geneva,sans-serif,sans-serif;
+          font-style: normal;
+          font-size: 14px;
+          word-wrap: break-word;
+        }
+      }
+      .col-1{
+        width: 35%;
+        float: left;
+        span.radio-group{
+          display: inline-block;
+          border: 2px solid #979797;
+          border-radius: 3px;
+          margin: 10px 0;
+          margin-left: 5px;
+          &:first-child{
+            margin-left: 15px;
+          }
+          &.blue{
+            border-color: $blue2;
+            label{
+              color: $blue2;
+            }
+          }
+          label{
+            font-family: "Open Sans",Verdana,Geneva,sans-serif,sans-serif;
+            font-size: 16px;
+            font-style: normal;
+            color: $dark-gray2;
+            font-weight: 400;
+            padding: 8px 15px 8px 6px;
+            display: inline-block;
+            margin-bottom: 0;
+          }
+          }
+          input[type="radio"]{
+            margin-left: 10px;
+          }
+        }
+      .col-2{
+        width: 65%;
+        float: right;
+        input[type="submit"]{
+          width: auto;
+          padding: 18px 60px 22px 30px;
+          height: auto;
+          font-size: 24px;
+          letter-spacing: 0;
+          font-weight: 600;
+          margin-left: 15px;
+          &#register{
+            padding: 18px 30px;
+          }
+         }
+        p{
+          font-family: "Open Sans",Verdana,Geneva,sans-serif,sans-serif;
+          padding: 13px 0;
+          text-align: right;
+        }
+        form{
+          position: relative;
+        }
+          i.icon-caret-right{
+            position: absolute;
+            right: 30px;
+            top: 25px;
+            color: white;
+            font-size: 24px;
+          }
+
+        label.pull-right{
+          font-family: "Open Sans",Verdana,Geneva,sans-serif,sans-serif;
+          font-style: normal;
+          text-align: right;
+          padding: 10px 25px 10px;
+          display: inline-block;
+          float: right;
+          line-height: 20px;
+          color: $dark-gray1;
+        }
+      }
+    }
+  .disclaimer{
+    color: $light-gray2;
+    padding: 10px 0px;
+    text-align: right;
+    font-weight: 300;
+  }
+  h3{
+    font-family: "Open Sans",Verdana,Geneva,sans-serif,sans-serif;
+    font-size: 16px;
+    font-weight: 400;
+    padding: 30px 20px;
+    color: $dark-gray1;
+  }
+  .billing-data{
+    display: table;
+    width: 100%;
+    h3{
+      padding: 12px 0px;
+      color: $dark-gray1;
+      font-size: 17px;
+      margin-bottom: 5px;
+    }
+    .row{
+      display: table-row;
+    }
+    .col-half{
+      width: 45%;
+      float: left;
+      background: $light-gray1;
+      padding: 20px;
+      border-radius: 4px;
+      margin-bottom: 15px;
+      min-height: 240px;
+      &:nth-child(even){
+        margin-left: 30px;
+      }
+      .data-group{
+      margin-bottom: 15px;
+        label{
+        display: block;
+        font-family: "Open Sans",Verdana,Geneva,sans-serif,sans-serif;
+        font-size: 16px;
+        font-style: normal;
+        font-weight: 400;
+        color: $dark-gray2;
+      }
+      input{width: 100%;margin-bottom: 5px;}
+      &:nth-child(4n){
+        margin-right: 0px;
+      }
+    }
+    }
+  }
+  .error-text{
+    color: $red1;
+    font-size: 12px;
+    display: block;
+    padding-bottom: 0;
+  }
+  .gray-bg{
+    background: $light-gray1;
+    border-radius: 3px;
+    padding: 20px 20px 20px 30px;
+    margin: 20px 0;
+    overflow: hidden;
+    .message-left{
+      float: left;
+      line-height: 24px;
+      color: $dark-gray1;
+      b{
+        text-transform: capitalize;
+      }
+      a.blue{
+        margin:0 0 0 20px;
+        i{
+          margin-left: 10px;
+        }
+      }
+    }
+  }
+  .bordered-bar{
+    border-bottom: 2px solid $light-gray1;
+    border-top: 2px solid $light-gray1;
+    margin-bottom: 20px;
+    padding: 20px;
+    h2{
+      color: $dark-gray1;
+      font-family: "Open Sans",Verdana,Geneva,sans-serif,sans-serif;
+      font-weight: bold;
+      margin-bottom: 0;
+      font-size: 17px;
+      span{
+        padding-left: 60px;
+        text-transform: capitalize;
+        .blue-link{
+          color: $blue2;
+          font-size: 14px;
+          &:hover{
+            text-decoration: none;
+          }
+        }
+      }
+    }
+  }
+  .pattern{
+    margin-top: 10px;
+    margin-bottom: 20px;
+    padding:20px;
+    color: $dark-gray1;
+  }
+  hr.border{
+    border-top: 2px solid $light-gray1;
+  }
+  .no-border{border: none !important; }
+  table.course-receipt{
+    width: 94%;
+    margin: auto;
+    margin-bottom: 27px;
+    thead{
+      th{
+        color: $light-gray2;
+        font-weight: normal;
+        text-align: center;
+        text-transform: uppercase;
+        padding: 8px 0;
+        border-bottom: 1px solid $dark-gray2;
+        &:first-child{
+          text-align: left;
+        }
+        &:last-child{
+          text-align: right;
+        }
+      }
+    }
+    tr{
+      border-bottom: 1px solid $light-gray1;
+      &:last-child{
+        border-bottom: none;
+      }
+      td{
+        padding: 15px 0;
+        text-align: center;
+        color: $dark-gray1;
+        width: 33.33333%;
+
+        &:first-child{
+          text-align: left;
+          font-size: 18px;
+          text-transform: capitalize;
+        }
+        &:last-child{
+          text-align: right;
+        }
+      }
+    }
+  }
+}
+.empty-cart{
+  padding: 20px 0px;
+  background: $light-gray1;
+  text-align: center;
+  border-radius: 3px;
+  margin: 20px 0px;
+  h2{
+    font-size: 24PX;
+      font-family: "Open Sans",Verdana,Geneva,sans-serif,sans-serif;
+      font-weight: 600;
+      letter-spacing: 0;
+      color: #9b9b9b;
+      text-align: center;
+      margin-top: 20px;
+      text-transform: initial;
+  }
+  a.blue{
+    display: inline-block;
+    background: $blue2;
+    color: white;
+    padding: 20px 40px;
+    border-radius: 3px;
+    font-size: 24px;
+    font-weight: 400;
+    margin: 10px 0px 20px;
+    &:hover{
+      text-decoration: none;
+    }
+  }
+}
+
+// Print
+
+@media print{
+  a[href]:after {
+    content: none !important;
+  }
+  ul.steps, a.blue.pull-right, .bordered-bar span.pull-right, .left.nav-global.authenticated {
+    display: none;
+  }
+  .shopping-cart{
+    font-size:  14px;
+    padding-right: 40px;
+    .gray-bg{
+      margin: 0;
+      padding: 10px 0 20px 0;
+      background: none;
+      .message-left{
+        width: 100%;
+      }
+    }
+    .bordered-bar{
+      h2{
+        font-size: 14px;
+      }
+      span{
+        float: right;
+      }
+    }
+    .user-data{
+       .data-input{
+         h1{
+           font-size: 18px;
+         }
+       }
+    }
+  }
+}
diff --git a/lms/templates/emails/business_order_confirmation_email.txt b/lms/templates/emails/business_order_confirmation_email.txt
new file mode 100644
index 0000000000000000000000000000000000000000..870ca26c986edc5cee341dbd9bf2e1a783e78a46
--- /dev/null
+++ b/lms/templates/emails/business_order_confirmation_email.txt
@@ -0,0 +1,93 @@
+<%! from django.utils.translation import ugettext as _ %>
+<p>
+${_("Hi {name},").format(name=recipient_name)}
+</p>
+<p>
+${_("Thank you for your purchase of ")} <b> ${course_names} </b>
+</p>
+%if recipient_type == 'user':
+<p>${_("Your payment was successful.")}</p>
+% if marketing_link('FAQ'):
+<p>${_("If you have billing questions, please read the FAQ ({faq_url}) or contact {billing_email}.").format(billing_email=payment_support_email, faq_url=marketing_link('FAQ'))}</p>
+% else:
+<p>${_("If you have billing questions, please contact {billing_email}.").format(billing_email=payment_support_email)}</p>
+% endif
+
+%elif recipient_type == 'company_contact':
+
+<p>${_("{order_placed_by} placed an order and mentioned your name as the Organization contact.").format(order_placed_by=order_placed_by)}</p>
+
+%elif recipient_type == 'email_recipient':
+
+<p>${_("{order_placed_by} placed an order and mentioned your name as the additional receipt recipient.").format(order_placed_by=order_placed_by)}</p>
+
+%endif
+
+<p>${_("The items in your order are:")}</p>
+
+<p>${_("Quantity - Description - Price")}<br>
+%for order_item in order_items:
+    ${order_item.qty} - ${order_item.line_desc} - ${"$" if order_item.currency == 'usd' else ""}${order_item.line_cost}</p>
+%endfor
+
+<p>${_("Total billed to credit/debit card: {currency_symbol}{total_cost}").format(total_cost=order.total_cost, currency_symbol=("$" if order.currency == 'usd' else ""))}</p>
+
+<p>
+% if order.company_name:
+${_('Company Name:')} ${order.company_name}<br>
+%endif
+% if order.customer_reference_number:
+${_('Purchase Order Number:')} ${order.customer_reference_number}<br>
+%endif
+% if order.company_contact_name:
+${_('Company Contact Name:')} ${order.company_contact_name}<br>
+ %endif
+% if order.company_contact_email:
+${_('Company Contact Email:')} ${order.company_contact_email}<br>
+%endif
+% if order.recipient_name:
+${_('Recipient Name:')} ${order.recipient_name}<br>
+ %endif
+% if order.recipient_email:
+${_('Recipient Email:')} ${order.recipient_email}<br>
+ %endif
+
+% if has_billing_info:
+${order.bill_to_cardtype} ${_("#:")} ${order.bill_to_ccnum}<br>
+${order.bill_to_first} ${order.bill_to_last}<br>
+${order.bill_to_street1}<br>
+${order.bill_to_street2}<br>
+${order.bill_to_city}, ${order.bill_to_state} ${order.bill_to_postalcode}<br>
+${order.bill_to_country.upper()}
+% endif
+</p>
+<p>${_("Order Number: {order_number}").format(order_number=order.id)}</p>
+
+<p><b>${_("A CSV file of your registration URLs is attached. Please distribute registration URLs to each student planning to enroll using the email template below.")}</b></p>
+
+<p>${_("Warm regards,")}<br>
+% if payment_email_signature:
+${payment_email_signature}
+% else:
+${_("The {platform_name} Team").format(platform_name=platform_name)}
+%endif
+</p>
+
+
+———————————————————————————————————————————
+
+
+<p>Dear [[Name]]</p>
+
+<p>To enroll in ${course_names} we have provided a registration URL for you.  Please follow the instructions below to claim your access.</p>
+
+<p>Your redeem url is: [[Enter Redeem URL here from the attached CSV]]</p>
+
+<p>${_("(1) Register for an account at <a href='https://{site_name}' >https://{site_name}</a>.").format(site_name=site_name)}<br>
+${_("(2) Once registered, copy the redeem URL and paste it in your web browser.")}<br>
+${_("(3) On the enrollment confirmation page, Click the 'Activate Enrollment Code' button. This will show the enrollment confirmation.")}<br>
+${_("(4) You should be able to click on 'view course' button or see your course on your student dashboard at <a href='https://{dashboard_url}'>https://{dashboard_url}</a>").format(dashboard_url=dashboard_url)}<br>
+${_("(5) Course materials will not be available until the course start date.")}</p>
+
+<p>Sincerely,</p>
+<p>[[Your Signature]]</p>
diff --git a/lms/templates/emails/order_confirmation_email.txt b/lms/templates/emails/order_confirmation_email.txt
index 65c0e3a67e71400f71d3942061b5fcf2956d758c..87d4c26b8095e386176d9d7a8b79d5323598a535 100644
--- a/lms/templates/emails/order_confirmation_email.txt
+++ b/lms/templates/emails/order_confirmation_email.txt
@@ -4,11 +4,17 @@ ${_("Hi {name}").format(name=order.user.profile.name)}
 ${_("Your payment was successful. You will see the charge below on your next credit or debit card statement.")}
 ${_("The charge will show up on your statement under the company name {merchant_name}.").format(merchant_name=settings.CC_MERCHANT_NAME)}
 % if marketing_link('FAQ'):
-${_("If you have billing questions, please read the FAQ ({faq_url}) or contact {billing_email}.").format(billing_email=settings.PAYMENT_SUPPORT_EMAIL, faq_url=marketing_link('FAQ'))}
+${_("If you have billing questions, please read the FAQ ({faq_url}) or contact {billing_email}.").format(billing_email=payment_support_email, faq_url=marketing_link('FAQ'))}
 % else:
-${_("If you have billing questions, please contact {billing_email}.").format(billing_email=settings.PAYMENT_SUPPORT_EMAIL)}
+${_("If you have billing questions, please contact {billing_email}.").format(billing_email=payment_support_email)}
 % endif
-${_("-The {platform_name} Team").format(platform_name=settings.PLATFORM_NAME)}
+
+${_("Warm regards,")}
+% if payment_email_signature:
+${payment_email_signature}
+% else:
+${_("The {platform_name} Team").format(platform_name=platform_name)}
+%endif
 
 ${_("Your order number is: {order_number}").format(order_number=order.id)}
 
@@ -16,7 +22,7 @@ ${_("The items in your order are:")}
 
 ${_("Quantity - Description - Price")}
 %for order_item in order_items:
-    ${order_item.qty} - ${order_item.line_desc} - ${"$" if order_item.currency == 'usd' else ""}${order_item.line_cost} 
+    ${order_item.qty} - ${order_item.line_desc} - ${"$" if order_item.currency == 'usd' else ""}${order_item.line_cost}
 %endfor
 
 ${_("Total billed to credit/debit card: {currency_symbol}{total_cost}").format(total_cost=order.total_cost, currency_symbol=("$" if order.currency == 'usd' else ""))}
diff --git a/lms/templates/instructor/instructor_dashboard_2/add_coupon_modal.html b/lms/templates/instructor/instructor_dashboard_2/add_coupon_modal.html
index 82990bd8e5a8a8e22fd9fac595a78af11f7adbad..04b8c148069654c6093b350ef0f16517c2439f5e 100644
--- a/lms/templates/instructor/instructor_dashboard_2/add_coupon_modal.html
+++ b/lms/templates/instructor/instructor_dashboard_2/add_coupon_modal.html
@@ -1,7 +1,7 @@
 <%! from django.utils.translation import ugettext as _ %>
 <%! from django.core.urlresolvers import reverse %>
 <%page args="section_data"/>
-<section id="add-coupon-modal" class="modal" role="dialog" tabindex="-1" aria-label="${_('Password Reset')}">
+<section id="add-coupon-modal" class="modal" role="dialog" tabindex="-1" aria-label="${_('Add Coupon')}">
   <div class="inner-wrapper">
     <button class="close-modal">
       <i class="icon-remove"></i>
@@ -21,7 +21,7 @@
           ${_("Please enter Coupon detail below")}</p>
       </div>
 
-      <form id="add_coupon_form" action="${section_data['ajax_add_coupon']}" method="post" data-remote="true">
+      <form id="add_coupon_form">
         <div id="coupon_form_error" class="modal-form-error"></div>
         <fieldset class="group group-form group-form-requiredinformation">
           <legend class="is-hidden">${_("Required Information")}</legend>
@@ -54,7 +54,7 @@
         </fieldset>
 
         <div class="submit">
-          <input name="submit" type="submit" id="add_coupon_button" value="${_('Add Coupon')}"/>
+          <input name="submit" type="button" id="add_coupon_button" value="${_('Add Coupon')}"/>
         </div>
       </form>
     </div>
diff --git a/lms/templates/instructor/instructor_dashboard_2/e-commerce.html b/lms/templates/instructor/instructor_dashboard_2/e-commerce.html
index 37af5ad4b52e0a991eb419f9133910d3cdf81b5b..7a2dda941d5eea22dcadcde9933a017ab8467e08 100644
--- a/lms/templates/instructor/instructor_dashboard_2/e-commerce.html
+++ b/lms/templates/instructor/instructor_dashboard_2/e-commerce.html
@@ -68,8 +68,12 @@
       <div class="wrap">
          <h2>${_("Sales")}</h2>
          <div>
-            <span class="csv_tip">${_("Click to generate a CSV file for all sales records in this course")}
-                <input type="button" class="add blue-button" name="list-sale-csv" value="${_("Download All e-Commerce Sales")}" data-endpoint="${ section_data['get_sale_records_url'] }" data-csv="true"></p></td>
+            <span class="csv_tip">
+              <div >
+              ${_("Click to generate a CSV file for all sales records in this course")}
+                <input type="button" class="add blue-button" name="list-sale-csv" value="${_("Download All Invoice Sales")}" data-endpoint="${ section_data['get_sale_records_url'] }" data-csv="true">
+                <input type="button" class="add blue-button" name="list-order-sale-csv" value="${_("Download All Order Sales")}" data-endpoint="${ section_data['get_sale_order_records_url'] }" data-csv="true">
+              </div>
             </span>
              <hr>
              <p>${_("Enter the invoice number to invalidate or re-validate sale")}</p>
@@ -384,8 +388,28 @@
       modal_overLay.hide();
      });
 
-     $('#edit_coupon_form').submit(function () {
+     $('#update_coupon_button').click(function () {
        $("#update_coupon_button").attr('disabled', true);
+       var coupon_id = $.trim($('#coupon_id').val());
+       var description = $.trim($('#edit_coupon_description').val());
+
+       $.ajax({
+         type: "POST",
+         data: {
+           "coupon_id"  : coupon_id,
+           "description": description
+         },
+         url: "${section_data['ajax_update_coupon']}",
+         success: function (data) {
+             location.reload(true);
+           },
+         error: function(jqXHR, textStatus, errorThrown) {
+            var data = $.parseJSON(jqXHR.responseText);
+            $("#update_coupon_button").removeAttr('disabled');
+            $('#edit_coupon_form #coupon_form_error').attr('style', 'display: block !important');
+            $('#edit_coupon_form #coupon_form_error').text(data.message);
+         }
+       });
      });
      $('#course_price_link').click(function () {
        reset_input_fields();
@@ -397,7 +421,7 @@
         reset_input_fields();
         $('input[name="generate-registration-codes-csv"]').removeAttr('disabled');
      });
-     $('#set_price_form').submit(function () {
+     $('#set_course_button').click(function () {
        $("#set_course_button").attr('disabled', true);
        // Get the Code and Discount value and trim it
        var course_price = $.trim($('#mode_price').val());
@@ -422,12 +446,31 @@
          $("#set_course_button").removeAttr('disabled');
          return false;
        }
+       $.ajax({
+         type: "POST",
+         data: {
+           "course_price"  : course_price,
+           "currency": currency
+         },
+         url: "${section_data['set_course_mode_url']}",
+         success: function (data) {
+             location.reload(true);
+           },
+         error: function(jqXHR, textStatus, errorThrown) {
+            var data = $.parseJSON(jqXHR.responseText);
+            $("#set_course_button").removeAttr('disabled');
+            $('#set_price_form #course_form_error').attr('style', 'display: block !important');
+            $('#set_price_form #course_form_error').text(data.message);
+         }
+       });
      });
-     $('#add_coupon_form').submit(function () {
+     $('#add_coupon_button').click(function () {
        $("#add_coupon_button").attr('disabled', true);
        // Get the Code and Discount value and trim it
        var code = $.trim($('#coupon_code').val());
        var coupon_discount = $.trim($('#coupon_discount').val());
+       var course_id = $.trim($('#coupon_course_id').val());
+       var description = $.trim($('#coupon_description').val());
 
        // Check if empty of not
        if (code === '') {
@@ -448,36 +491,25 @@
          $('#add_coupon_form #coupon_form_error').text("${_('Please enter the numeric value for discount')}");
          return false;
        }
-     });
-
-     $('#set_price_form').on('ajax:complete', function (event, xhr) {
-       if (xhr.status == 200) {
-         location.reload(true);
-       } else {
-         $("#set_course_button").removeAttr('disabled');
-         $('#set_price_form #course_form_error').attr('style', 'display: block !important');
-         $('#set_price_form #course_form_error').text(xhr.responseText);
-       }
-     });
-
-     $('#add_coupon_form').on('ajax:complete', function (event, xhr) {
-       if (xhr.status == 200) {
-         location.reload(true);
-       } else {
-         $("#add_coupon_button").removeAttr('disabled');
-         $('#add_coupon_form #coupon_form_error').attr('style', 'display: block !important');
-         $('#add_coupon_form #coupon_form_error').text(xhr.responseText);
-       }
-     });
-
-     $('#edit_coupon_form').on('ajax:complete', function (event, xhr) {
-       if (xhr.status == 200) {
-         location.reload(true);
-       } else {
-         $("#update_coupon_button").removeAttr('disabled');
-         $('#edit_coupon_form #coupon_form_error').attr('style', 'display: block !important');
-         $('#edit_coupon_form #coupon_form_error').text(xhr.responseText);
-       }
+       $.ajax({
+         type: "POST",
+         data: {
+           "code"  : code,
+           "discount": coupon_discount,
+           "course_id": course_id,
+           "description": description
+         },
+         url: "${section_data['ajax_add_coupon']}",
+         success: function (data) {
+             location.reload(true);
+           },
+         error: function(jqXHR, textStatus, errorThrown) {
+            var data = $.parseJSON(jqXHR.responseText);
+            $('#add_coupon_form #coupon_form_error').attr('style', 'display: block !important');
+            $('#add_coupon_form #coupon_form_error').text(data.message);
+            $("#add_coupon_button").removeAttr('disabled');
+         }
+       });
      });
      // removing close link's default behavior
      $('.close-modal').click(function (e) {
diff --git a/lms/templates/instructor/instructor_dashboard_2/edit_coupon_modal.html b/lms/templates/instructor/instructor_dashboard_2/edit_coupon_modal.html
index 8052d7be710a4ecdaf690d5daf2fb0fcd2cd421e..b0345c917face8a5ddf9eee03916232eb87d6072 100644
--- a/lms/templates/instructor/instructor_dashboard_2/edit_coupon_modal.html
+++ b/lms/templates/instructor/instructor_dashboard_2/edit_coupon_modal.html
@@ -54,7 +54,7 @@
 
         <div class="submit">
           <input type="hidden" name="coupon_id" id="coupon_id"/>
-          <input name="submit" type="submit" id="update_coupon_button" value="${_('Update Coupon')}"/>
+          <input name="submit" type="button" id="update_coupon_button" value="${_('Update Coupon')}"/>
         </div>
       </form>
     </div>
diff --git a/lms/templates/instructor/instructor_dashboard_2/set_course_mode_price_modal.html b/lms/templates/instructor/instructor_dashboard_2/set_course_mode_price_modal.html
index f0c37f97cc0ebc60513e5699b19e5e2852eabbc0..5c4a52ab49396d030d6c97c6acc06d163087b95d 100644
--- a/lms/templates/instructor/instructor_dashboard_2/set_course_mode_price_modal.html
+++ b/lms/templates/instructor/instructor_dashboard_2/set_course_mode_price_modal.html
@@ -21,7 +21,7 @@
           ${_("Please enter Course Mode detail below")}</p>
       </div>
 
-      <form id="set_price_form" action="${section_data['set_course_mode_url']}" method="post" data-remote="true">
+      <form id="set_price_form">
         <div id="course_form_error" class="modal-form-error"></div>
         <fieldset class="group group-form group-form-requiredinformation">
           <legend class="is-hidden">${_("Required Information")}</legend>
@@ -40,7 +40,7 @@
           </ol>
         </fieldset>
         <div class="submit">
-          <input name="submit" type="submit" id="set_course_button" value="${_('Set Price')}"/>
+          <input name="submit" type="button" id="set_course_button" value="${_('Set Price')}"/>
         </div>
       </form>
     </div>
diff --git a/lms/templates/shoppingcart/billing_details.html b/lms/templates/shoppingcart/billing_details.html
new file mode 100644
index 0000000000000000000000000000000000000000..d1dbf4e54febd5283c19e8fb759154f6cbc89f17
--- /dev/null
+++ b/lms/templates/shoppingcart/billing_details.html
@@ -0,0 +1,114 @@
+<%inherit file="shopping_cart_flow.html" />
+<%! from django.utils.translation import ugettext as _ %>
+<%! from django.core.urlresolvers import reverse %>
+
+<%block name="billing_details_highlight"><li class="active" >${_('Billing Details')}</li></%block>
+<%block name="confirmation_highlight"></%block>
+
+<%block name="custom_content">
+<div class="container">
+  % if shoppingcart_items:
+  <section class="confirm-enrollment shopping-cart">
+  <h3>${_('You can proceed to payment at any point in time. Any additional information you provide will be included in your receipt.')}</h3>
+    <div class="billing-data">
+      <div class="col-half">
+        <h3>${_('Purchasing Organizational Details')}</h3>
+        <div class="data-group"><label for="id_company_name">${_('Purchasing organization')}</label><input type="text" id="id_company_name" name="company_name"></div>
+      <div class="data-group"><label for="id_customer_reference_number">${_('Purchase order number (if any)')}</label><input type="text" id="id_customer_reference_number" maxlength="63" name="customer_reference_number"></div>
+      </div>
+      <div class="col-half">
+        <h3>${_('Organization Contact')}</h3>
+         <div class="data-group"><label for="id_company_contact_name">${_('Name')}</label><input type="text"id="id_company_contact_name" name="company_contact_name"></div>
+      <div class="data-group"><label for="id_company_contact_email">${_('Email Address')}</label><input type="email" placeholder="${_('email@example.com')}" id="id_company_contact_email" name="company_contact_email"><span id="company_contact_email_error" class="error-text"></span></div>
+      </div>
+      <div class="col-half">
+        <h3>${_('Additional Receipt Recipient')}</h3>
+        <div class="data-group">
+          <label for="id_recipient_name">${_('Name')}</label>
+       <input type="text" id="id_recipient_name" name="recipient_name">
+       </div>
+       <div class="data-group">
+         <label for="id_recipient_email">${_('Email Address')}</label>
+       <input type="email" id="id_recipient_email" placeholder="${_('email@example.com')}" name="recipient_email">
+         <span id="recipient_email_error" class="error-text"></span>
+       </div>
+      </div>
+    </div>
+    <div class="discount">
+      <div class="code-text">
+          <span class="pull-right">${_('Total')}: <b>$${"{0:0.2f}".format(amount)} USD</b></span>
+      </div>
+      </div>
+      <div class="col-two">
+
+          <div class="col-2">
+               ${form_html}
+                <p>
+                  ${_('If no additional billing details are populated the payment confirmation will be sent to the user making the purchase')}
+               </p>
+          </div>
+      </div>
+      <div class="disclaimer">${_('Payment processing occurs on a separate secure site.')}</div>
+
+  </section>
+  %else:
+  <div class="empty-cart" >
+        <h2>${_('Your Shopping cart is currently empty.')}</h2>
+          <a href="${marketing_link('COURSES')}" class="blue">${_('View Courses')}</a>
+  </div>
+  %endif
+</div>
+</%block>
+
+<script>
+  $(function() {
+    function validateEmail(sEmail) {
+      filter = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/
+      return filter.test(sEmail)
+     }
+    $('form input[type="submit"]').click(function(event) {
+      var is_valid_email = true;
+      var payment_form = $(this).parent('form');
+      var recipient_email = $('input[name="recipient_email"]').val();
+      var company_contact_email =  $('input[name="company_contact_email"]').val();
+      if ( recipient_email != '' && !(validateEmail(recipient_email))) {
+         $('span#recipient_email_error').html('Please enter valid email address');
+         $('input[name="recipient_email"]').addClass('error');
+        is_valid_email = false;
+      }
+      else {
+        $('input[name="recipient_email"]').removeClass('error');
+        $('span#recipient_email_error').html('');
+      }
+      if ( company_contact_email != '' && !(validateEmail(company_contact_email))) {
+         $('span#company_contact_email_error').html('Please enter valid email address');
+        $('input[name="company_contact_email"]').addClass('error');
+        is_valid_email = false;
+      }
+      else {
+        $('input[name="company_contact_email"]').removeClass('error');
+        $('span#company_contact_email_error').html('');
+      }
+      if (!is_valid_email) {
+        return false;
+      }
+      event.preventDefault();
+      var post_url = "${reverse('billing_details')}";
+      var data = {
+               "company_name" : $('input[name="company_name"]').val(),
+               "company_contact_name" : $('input[name="company_contact_name"]').val(),
+               "company_contact_email" : company_contact_email,
+               "recipient_name" : $('input[name="recipient_name"]').val(),
+               "recipient_email" : recipient_email,
+               "customer_reference_number" : $('input[name="customer_reference_number"]').val()
+               };
+      $.post(post_url, data)
+      .success(function(data) {
+                 payment_form.submit();
+              })
+      .error(function(data,status) {
+
+             })
+    });
+  });
+</script>
diff --git a/lms/templates/shoppingcart/cybersource_form.html b/lms/templates/shoppingcart/cybersource_form.html
index b07af57ab7d24d6088926dd617962cd4638a0998..8a603baa72fb8076f4ec1f8df3eb412602b0a3c5 100644
--- a/lms/templates/shoppingcart/cybersource_form.html
+++ b/lms/templates/shoppingcart/cybersource_form.html
@@ -3,5 +3,5 @@
                 <input type="hidden" name="${pk}" value="${pv}" />
             % endfor
 
-                <input type="submit" value="Check Out" />
+                <i class="icon-caret-right"></i><input type="submit" value="Payment"/>
         </form> 
\ No newline at end of file
diff --git a/lms/templates/shoppingcart/list.html b/lms/templates/shoppingcart/list.html
deleted file mode 100644
index 632b75d534a237977ff79033f21067c38dd57d91..0000000000000000000000000000000000000000
--- a/lms/templates/shoppingcart/list.html
+++ /dev/null
@@ -1,129 +0,0 @@
-<%! from django.utils.translation import ugettext as _ %>
-
-<%! from django.core.urlresolvers import reverse %>
-
-<%inherit file="../main.html" />
-
-<%block name="pagetitle">${_("Your Shopping Cart")}</%block>
-
-<section class="container cart-list">
-  <h2>${_("Your selected items:")}</h2>
-    <h3 class="cart-errors" id="cart-error">Error goes here.</h3>
-  % if shoppingcart_items:
-    <table class="cart-table">
-      <thead>
-        <tr class="cart-headings">
-          <th class="dsc">${_("Description")}</th>
-          <th class="u-pr">${_("Price")}</th>
-          <th class="cur">${_("Currency")}</th>
-          <th>&nbsp;</th>
-        </tr>
-      </thead>
-      <tbody>
-        % for item in shoppingcart_items:
-        <tr class="cart-items">
-          <td>${item.line_desc}</td>
-          <td>
-              ${"{0:0.2f}".format(item.unit_cost)}
-              % if item.list_price != None:
-                <span class="old-price"> ${"{0:0.2f}".format(item.list_price)}</span>
-              % endif
-          </td>
-          <td>${item.currency.upper()}</td>
-          <td><a data-item-id="${item.id}" class='remove_line_item' href='#'>[x]</a></td>
-        </tr>
-        % endfor
-        <tr class="always-gray">
-            <td colspan="4" valign="middle" class="cart-total" align="right">
-                <b>${_("Total Amount")}: <span> ${"{0:0.2f}".format(amount)} </span> </b>
-            </td>
-        </tr>
-
-      </tbody>
-      <tfoot>
-        <tr class="always-white">
-            <td colspan="2">
-                 <input type="text" placeholder="Enter code here" name="cart_code" id="code">
-                 <input type="button" value="Apply Code" id="cart-code">
-            </td>
-            <td colspan="4" align="right">
-                % if amount == 0:
-                     <input type="button" value = "Register" id="register" >
-                % else:
-                   ${form_html}
-                %endif
-            </td>
-        </tr>
-
-      </tfoot>
-    </table>
-    <!-- <input id="back_input" type="submit" value="Return" /> -->
-  % else:
-    <p>${_("You have selected no items for purchase.")}</p>
-  % endif
-
-</section>
-
-
-<script>
-  $(function() {
-    $('a.remove_line_item').click(function(event) {
-      event.preventDefault();
-      var post_url = "${reverse('shoppingcart.views.remove_item')}";
-      $.post(post_url, {id:$(this).data('item-id')})
-        .always(function(data){
-        location.reload(true);
-      });
-    });
-
-    $('#cart-code').click(function(event){
-      event.preventDefault();
-      var post_url = "${reverse('shoppingcart.views.use_code')}";
-      $.post(post_url,{
-               "code" :  $('#code').val(),
-                beforeSend: function(xhr, options){
-                 if($('#code').val() == "") {
-                     showErrorMsgs('Must enter a valid code')
-                     xhr.abort();
-                    }
-                }
-               }
-      )
-      .success(function(data) {
-                 location.reload(true);
-              })
-      .error(function(data,status) {
-                  if(status=="parsererror"){
-                       location.reload(true);
-                  }else{
-                        showErrorMsgs(data.responseText)
-                      }
-             })
-    });
-
-    $('#register').click(function(event){
-      event.preventDefault();
-      var post_url = "${reverse('shoppingcart.views.register_courses')}";
-      $.post(post_url)
-      .success(function(data) {
-                  window.location.href = "${reverse('dashboard')}";
-              })
-      .error(function(data,status) {
-                  if(status=="parsererror"){
-                       location.reload(true);
-                  }else{
-                        showErrorMsgs(data.responseText)
-                      }
-             })
-    });
-
-    $('#back_input').click(function(){
-      history.back();
-    });
-
-    function showErrorMsgs(msg){
-        $(".cart-errors").css('display', 'block');
-        $("#cart-error").html(msg);
-    }
-  });
-</script>
\ No newline at end of file
diff --git a/lms/templates/shoppingcart/receipt.html b/lms/templates/shoppingcart/receipt.html
index 28c71de7d17fb5de95290bf065a3361bdc6a1584..fac1ef230d19796e4052e7cc7dc775ab11829593 100644
--- a/lms/templates/shoppingcart/receipt.html
+++ b/lms/templates/shoppingcart/receipt.html
@@ -1,108 +1,356 @@
+<%inherit file="shopping_cart_flow.html" />
 <%! from django.utils.translation import ugettext as _ %>
 <%! from django.core.urlresolvers import reverse %>
-<%! from django.conf import settings %>
-<%! from microsite_configuration import microsite %>
+<%!
+from courseware.courses import course_image_url, get_course_about_section, get_course_by_id
+%>
 
-<%inherit file="../main.html" />
-
-<%block name="bodyclass">purchase-receipt</%block>
-
-<%block name="pagetitle">${_("Register for [Course Name] | Receipt (Order")} ${order.id})</%block>
+<%block name="billing_details_highlight">
+% if order_type == 'business':
+  <li>${_('Billing Details')}</li>
+%endif
+</%block>
 
-<%block name="content">
+<%block name="confirmation_highlight">class="active"</%block>
 
+<%block name="custom_content">
 <div class="container">
   <section class="notification">
     <h2>${_("Thank you for your Purchase!")}</h2>
-    <p>${_("Please print this receipt page for your records. You should also have received a receipt in your email.")}</p>
-    % for inst in instructions:
-      <p>${inst}</p>
-    % endfor
+    % if (len(shoppingcart_items) == 1 and order_type == 'personal') or receipt_has_donation_item:
+      % for inst in instructions:
+        <p>${inst}</p>
+      % endfor
+    % endif
   </section>
+  <section class="wrapper confirm-enrollment shopping-cart print">
+    <div class="gray-bg">
+      <div class="message-left">
+        <% courses_url = reverse('courses') %>
+        % if order_type == 'personal':
+           ## in case of multiple courses in single self purchase scenario,
+           ## we will show the button View Dashboard
+          % if len(shoppingcart_items) > 1 :
+            <% dashboard_url = reverse('dashboard') %>
+            <a href="${dashboard_url}" class="blue pull-right">${_("View Dashboard")} <i class="icon-caret-right"></i></a>
+          % elif shoppingcart_items and shoppingcart_items[0][1]:
+            <% course = shoppingcart_items[0][1] %>
+            <% course_info_url = reverse('info', kwargs={'course_id': course.id.to_deprecated_string()}) %>
+            <a href="${course_info_url}" class="blue pull-right">${_("View Course")} <i class="icon-caret-right"></i></a>
+          %endif
+          ${_("You have successfully been enrolled for <b>{appended_course_names}</b>. The following receipt has been emailed to"
+          " <strong>{appended_recipient_emails}</strong>").format(appended_course_names=appended_course_names, appended_recipient_emails=appended_recipient_emails)}
+        % elif order_type == 'business':
+          % if total_registration_codes > 1 :
+            <% code_plural_form = 'codes' %>
+          % else:
+            <% code_plural_form = 'code' %>
+          % endif
+          ${_("You have successfully purchased <b>{total_registration_codes} course registration codes</b> "
+          "for <b>{appended_course_names}. </b>"
+           "The following receipt has been emailed to <strong>{appended_recipient_emails}</strong>"
+           ).format(total_registration_codes=total_registration_codes, appended_course_names=appended_course_names, appended_recipient_emails=appended_recipient_emails)}
+        % endif
 
-  <section class="wrapper cart-list">
-    <div class="wrapper-content-main">
-      <article class="content-main">
-        <h1>${_("{platform_name} ({site_name}) Electronic Receipt").format(platform_name=microsite.get_value('platform_name', settings.PLATFORM_NAME), site_name=microsite.get_value('SITE_NAME', settings.SITE_NAME))}</h1>
-        <hr />
-
-        <table class="order-receipt">
-          <tbody>
-          <tr>
-            <td colspan="2"><h3 class="order-number">${_("Order #")}${order.id}</h3></td>
-            <td></td>
-            <td colspan="2"><h3 class="order-date">${_("Date:")} ${order.purchase_time.date().isoformat()}</h3></td>
-          </tr>
-          <tr>
-            <td colspan="5"><h2 class="items-ordered">${_("Items ordered:")}</h2></td>
-          </tr>
+      </div>
+    </div>
+    % if order_type == 'business':
+      <h3 class="text-center">${_("Please send each professional one of these unique registration codes to enroll into the course. The confirmation/receipt email you will receive has an example email template with directions for the individuals enrolling.")}.</h3>
+      <table class="course-receipt">
+        <thead>
+        <th>${_("Course Name")}</th>
+        <th>${_("Enrollment Code")}</th>
+        <th>${_("Enrollment Link")}</th>
+        </thead>
+        <tbody>
+        % for registration_code in registration_codes:
+          <% course = get_course_by_id(registration_code.course_id, depth=0) %>
           <tr>
-            <th class="qty">${_("Qty")}</th>
-            <th class="desc">${_("Description")}</th>
-            <th class="url">${_("URL")}</th>
-            <th class="u-pr">${_("Unit Price")}</th>
-            <th class="pri">${_("Price")}</th>
-            <th class="curr">${_("Currency")}</th>
+            <td>${_("{course_name}").format(course_name=course.display_name)}</td>
+            <td>${registration_code.code}</td>
+
+            <% redemption_url = reverse('register_code_redemption', args = [registration_code.code] ) %>
+            <% enrollment_url = '{base_url}{redemption_url}'.format(base_url=site_name, redemption_url=redemption_url) %>
+            <td><a href="${redemption_url}">${enrollment_url}</a></td>
           </tr>
-          % for item in order_items:
+        % endfor
+        </tbody>
+      </table>
+    %endif
+    <div class="bordered-bar">
+      <h2>${_('Invoice')} #${order.id}<span>${_('Date of purchase')}: ${order_purchase_date} </span><span
+          class="pull-right"><a href="" onclick="window.print();" class="blue-link"><i class="icon-print"></i> ${_('Print Receipt')}</a></span>
+      </h2>
+    </div>
+    % if order.total_cost > 0:
+      <div class="pattern">
+        <h2> ${_("Billed To Details")}: </h2>
 
+        <div class="col-two no-border">
+          % if order_type == 'business':
+            <div class="row">
+              <div class="row-inside">
+                <p>
+                  <b>${_('Company Name')}:</b>
+                  <label>
+                    % if order.company_name:
+                      ${_("{company_name}").format(company_name=order.company_name)}
+                    % else:
+                      N/A
+                    % endif
+                  </label>
+                </p>
+              </div>
+              <div class="row-inside">
+                <p>
+                  <b>${_('Purchase Order Number')}:</b>
+                  <label>
+                    % if order.customer_reference_number:
+                      ${_("{customer_reference_number}").format(customer_reference_number=order.customer_reference_number)}
+                    % else:
+                      N/A
+                    % endif
+                  </label>
+                </p>
+              </div>
+              <div class="row-inside">
+                <p>
+                  <b>${_('Company Contact Name')}:</b>
+                  <label>
+                    % if order.company_contact_name:
+                      ${_("{company_contact_name}").format(company_contact_name=order.company_contact_name)}
+                    % else:
+                      N/A
+                    % endif
+                  </label>
+                </p>
+              </div>
+              <div class="row-inside">
+                <p>
+                  <b>${_('Company Contact Email')}:</b>
+                  <label>
+                    % if order.company_contact_email:
+                      ${ order.company_contact_email }
+                    % else:
+                      N/A
+                    % endif
+                  </label>
+                </p>
+              </div>
+              <div class="row-inside">
+                <p>
+                  <b>${_('Recipient Name')}:</b>
+                  <label>
+                    % if order.recipient_name:
+                      ${_("{recipient_name}").format(recipient_name=order.recipient_name)}
+                    % else:
+                      N/A
+                    % endif
+                  </label>
+                </p>
+              </div>
+              <div class="row-inside">
+                <p>
+                  <b>${_('Recipient Email')}:</b>
+                  <label>
+                    % if order.recipient_email:
+                      ${order.recipient_email}
+                    % else:
+                      N/A
+                    % endif
+                  </label>
+                </p>
+              </div>
+            </div>
+        %endif
+          <div class="row">
+            <div class="row-inside">
+              <p>
+                <b>${_('Card Type')}:</b>
+                <label>
+                  % if order.bill_to_cardtype:
+                    ${order.bill_to_cardtype}
+                  % else:
+                    N/A
+                  % endif
+                </label>
+              </p>
+            </div>
+            <div class="row-inside">
+              <p>
+                <b>${_('Credit Card Number')}:</b>
+                <label>
+                  % if order.bill_to_ccnum:
+                    ${order.bill_to_ccnum}
+                  % else:
+                    N/A
+                  % endif
+                </label>
+              </p>
+            </div>
+            <div class="row-inside">
+              <p>
+                <b>${_('Name')}:</b>
+                <label>
+                  % if order.bill_to_first or order.bill_to_last:
+                    ${order.bill_to_first} ${order.bill_to_last}
+                  % else:
+                    N/A
+                  % endif
+                </label>
+              </p>
+            </div>
+            <div class="row-inside">
+              <p>
+                <b>${_('Address 1')}:</b>
+                <label>
+                  % if order.bill_to_street1:
+                    ${order.bill_to_street1}
+                  % else:
+                    N/A
+                  % endif
+                </label>
+              </p>
+            </div>
+            <div class="row-inside">
+              <p>
+                <b>${_('Address 2')}:</b>
+                <label>
+                  % if order.bill_to_street2:
+                    ${order.bill_to_street2}
+                  % else:
+                    N/A
+                  % endif
+                </label>
+              </p>
+            </div>
+            <div class="row-inside">
+              <p>
+                <b>${_('City')}:</b>
+                <label>
+                  % if order.bill_to_city:
+                    ${order.bill_to_city}
+                  % else:
+                    N/A
+                  % endif
+                </label>
+              </p>
+            </div>
+            <div class="row-inside">
+              <p>
+                <b>${_('State')}:</b>
+                <label>
+                  % if order.bill_to_state:
+                    ${order.bill_to_state}
+                  % else:
+                    N/A
+                  % endif
+                </label>
+              </p>
+            </div>
+            <div class="row-inside">
+              <p>
+                <b>${_('Country')}:</b>
+                <label>
+                  % if order.bill_to_country:
+                    ${order.bill_to_country.upper()}
+                  % else:
+                    N/A
+                  % endif
+                </label>
+              </p>
+            </div>
+          </div>
+        </div>
+      </div>
+    % endif
+    <hr class="border"/>
+    % for item, course in shoppingcart_items:
+      % if loop.index > 0 :
+        <hr>
+      %endif
+      <div class="user-data">
+        <div class="clearfix">
+          <div class="image">
+            <img style="width: 100%; height: 100%;" src="${course_image_url(course)}"
+                 alt="${course.display_number_with_default | h} ${get_course_about_section(course, 'title')} Image"/>
+          </div>
+          <div class="data-input">
+            <h3>${_("Registration for")}:
+              <span class="pull-right">
+                % if course.start_date_text or course.end_date_text:
+                  ${_("Course Dates")}:
+                %endif
+              </span>
+            </h3>
 
-            <tr class="order-item">
+            <h1>${_(" {course_name} ").format(course_name=course.display_name)}
+              <span class="pull-right">
+                % if course.start_date_text:
+                  ${course.start_date_text}
+                %endif
+                -
+                % if course.end_date_text:
+                  ${course.end_date_text}
+                %endif
+              </span>
+            </h1>
+            <hr/>
+            <div class="three-col">
               % if item.status == "purchased":
-                <td>${item.qty}</td>
-                <td>${item.line_desc}</td>
-                <td>
-                % if item.course_id:
-                  <% course_id = reverse('info', args=[item.course_id.to_deprecated_string()]) %>
-                  <a href="${course_id | h}" class="enter-course">${_('View Course')}</a></td>
-                % endif
-                </td>
-                <td>${"{0:0.2f}".format(item.unit_cost)}
-                    % if item.list_price != None:
-                        <span class="old-price"> ${"{0:0.2f}".format(item.list_price)}</span>
-                    % endif
-                    </td>
-                <td>${"{0:0.2f}".format(item.line_cost)}</td>
-                <td>${item.currency.upper()}</td></tr>
+                <div class="col-1">
+                  % if item.list_price != None:
+                    <div class="price">${_('Price per student:')} <span class="line-through">  $${"{0:0.2f}".format(item.list_price)}</span>
+                    </div>
+                    <div class="price green">${_('Discount Applied:')} <span>  $${"{0:0.2f}".format(item.unit_cost)} </span></div>
+                  % else:
+                    <div class="price">${_('Price per student:')} <span>  $${"{0:0.2f}".format(item.unit_cost)}</span></div>
+                  % endif
+                </div>
+                <div class="col-2">
+                  <div class="numbers-row">
+                    <label>${_("Students")}:</label>
+                    <div class="counter no-border text-dark-grey">
+                      ${item.qty}
+                    </div>
+                  </div>
+                </div>
               % elif item.status == "refunded":
-                <td><del>${item.qty}</del></td>
-                <td><del>${item.line_desc}</del></td>
-                <td><del>${"{0:0.2f}".format(item.unit_cost)}</del></td>
-                <td><del>${"{0:0.2f}".format(item.line_cost)}</del></td>
-                <td><del>${item.currency.upper()}</del></td></tr>
-              % endif
-          % endfor
-          <tr>
-            <td colspan="3"></td>
-            <th>${_("Total Amount")}</th>
-            <td></td>
-          </tr>
-          <tr>
-            <td colspan="3"></td>
-            <td>${"{0:0.2f}".format(order.total_cost)}</td>
-            <td></td>
-          </tr>
-          </tbody>
-        </table>
-
+                <div class="col-1">
+                  % if item.list_price != None:
+                    <div class="price">${_('Price per student:')} <span class="line-through">  $${"{0:0.2f}".format(item.list_price)}</span>
+                    </div>
+                    <div class="price green">${_('Discount Applied:')} <span><del> $${"{0:0.2f}".format(item.unit_cost)}
+                    </del></span></div>
+                  % else:
+                    <div class="price">${_('Price per student:')} <span><del> $${"{0:0.2f}".format(item.unit_cost)}</del></span>
+                    </div>
+                  % endif
+                </div>
+                <div class="col-2">
+                  <div class="numbers-row">
+                    <label>${_("Students")}:</label>
+                    <div class="counter no-border">
+                      <del>${item.qty}</del>
+                    </div>
+                  </div>
+                </div>
+              %endif
+            </div>
+          </div>
+        </div>
+      </div>
+    % endfor
+    <div class="discount">
+      <div class="code-text">
         % if any_refunds:
-          <p>
-	    ## Translators: Please keep the "<del>" and "</del>" tags around your translation of the word "this" in your translation.
+          <span>
+          ## Translators: Please keep the "<del>" and "</del>" tags around your translation of the word "this" in your translation.
             ${_("Note: items with strikethough like <del>this</del> have been refunded.")}
-          </p>
+          </span>
         % endif
-        % if order.total_cost > 0:
-            <h2>${_("Billed To:")}</h2>
-            <p>
-              ${order.bill_to_cardtype} ${_("#:")} ${order.bill_to_ccnum}<br />
-              ${order.bill_to_first} ${order.bill_to_last}<br />
-              ${order.bill_to_street1}<br />
-              ${order.bill_to_street2}<br />
-              ${order.bill_to_city}, ${order.bill_to_state} ${order.bill_to_postalcode}<br />
-              ${order.bill_to_country.upper()}<br />
-            </p>
-         % endif
-      </article>
+        <span class="pull-right">${_("Total")}: <b>$${"{0:0.2f}".format(order.total_cost)} USD</b></span>
+      </div>
     </div>
   </section>
 </div>
diff --git a/lms/templates/shoppingcart/shopping_cart.html b/lms/templates/shoppingcart/shopping_cart.html
new file mode 100644
index 0000000000000000000000000000000000000000..0bd92f388296d4bfcd8a512e94c73ead166c64af
--- /dev/null
+++ b/lms/templates/shoppingcart/shopping_cart.html
@@ -0,0 +1,288 @@
+<%inherit file="shopping_cart_flow.html" />
+<%block name="review_highlight">class="active"</%block>
+
+<%!
+from courseware.courses import course_image_url, get_course_about_section
+from django.core.urlresolvers import reverse
+from edxmako.shortcuts import marketing_link
+from django.utils.translation import ugettext as _
+
+%>
+
+<%block name="custom_content">
+
+<div class="container">
+  % if shoppingcart_items:
+        <%block name="billing_details_highlight">
+         % if order.order_type == 'business':
+            <li>${_('Billing Details')}</li>
+         % endif
+        </%block>
+ <% discount_applied = False %>
+  <section class="wrapper confirm-enrollment shopping-cart">
+    % for item, course in shoppingcart_items:
+       % if loop.index > 0 :
+        <hr>
+      %endif
+     <div class="user-data">
+      <div class="clearfix">
+      <div class="image">
+
+           <img style="width: 100%; height: 100%;" src="${course_image_url(course)}"
+                alt="${course.display_number_with_default | h} ${get_course_about_section(course, 'title')} Cover Image" />
+
+      </div>
+      <div class="data-input">
+        <h3>${_('Registration for:')} <span class="pull-right">${_('Course Dates:')}</span></h3>
+        <h1>${ course.display_name }<span class="pull-right">${course.start_date_text} -  ${course.end_date_text}</span></h1>
+        <hr />
+        <div class="three-col">
+            <div class="col-1">
+                % if item.list_price != None:
+                <% discount_applied = True %>
+                <div class="price">${_('Price per student:')} <span class="line-through">  $${"{0:0.2f}".format(item.list_price)}</span></div>
+                <div class="price green">${_('Discount Applied:')} <span>  $${"{0:0.2f}".format(item.unit_cost)} </span></div>
+                % else:
+                <div class="price">${_('Price per student:')} <span>  $${"{0:0.2f}".format(item.unit_cost)}</span></div>
+                % endif
+            </div>
+            <div class="col-2">
+              <div class="numbers-row">
+                <label for="students">${_('Students:')}</label>
+                <div class="counter">
+                    <input maxlength="3" max="999" type="text" name="students" value="${item.qty}" id="${item.id}" >
+                </div>
+                <div class="inc button"><i class="icon-caret-up"><span>+</span></i></div><div class="dec button"><i class="icon-caret-down"></i></div>
+                    <a name="updateBtn" class="updateBtn hidden" id="updateBtn-${item.id}" href="#">update</a>
+                <span class="error-text hidden" id="students-${item.id}"></span>
+            </div>
+              </div>
+
+            <div class="col-3">
+               <a href="#" class="btn-remove" data-item-id="${item.id}"><i class="icon-remove-sign"></i></a>
+            </div>
+        </div>
+      </div>
+          </div>
+
+  </div>
+    % endfor
+      <div class="discount">
+
+          <div class="code-text">
+           % if not discount_applied:
+           <div class="code-input">
+              <input type="text" placeholder="discount or activation code" id="input_code">
+              <input type="submit" value="Apply" class="blue" id="submit-code">
+              <span class="error-text hidden" id="code" ></span>
+           </div>
+           % else:
+           <div class="code-applied">
+              <span class="green"><i class="icon-ok"></i>${_('code has been applied')}</span>
+              <input type="submit" value="Reset" class="blue-border" id="submit-reset-redemption">
+           </div>
+            %endif
+              <span class="pull-right">${_('Total:')} <b id="total-amount">$${"{0:0.2f}".format(amount)} USD</b></span>
+          </div>
+      </div>
+      <div class="col-two">
+          <div class="col-2 relative">
+             % if amount == 0:
+                <input type="submit" value = "Register" id="register" >
+             % elif item.order.order_type == 'business':
+                <input type="submit" value = "Billing Details" id="billing-details"><i class="icon-caret-right"></i>
+                <p>
+                    ${_('After this purchase is complete, a receipt is generated with relative billing details and registration codes for students.')}
+                </p>
+             % else:
+                ${form_html}
+                <p>
+                    ${_('After this purchase is complete,')}<br/><b>${order.user.username}</b>
+                    ${_('will be enrolled in this course.')}
+                </p>
+             %endif
+          </div>
+      </div>
+   </section>
+    % else:
+      <div class="empty-cart" >
+        <h2>${_('Your Shopping cart is currently empty.')}</h2>
+          <a href="${marketing_link('COURSES')}" class="blue">${_('View Courses')}</a>
+      </div>
+    % endif
+
+</div>
+</%block>
+<script>
+    $(function() {
+
+        $('a.btn-remove').click(function(event) {
+      event.preventDefault();
+      var post_url = "${reverse('shoppingcart.views.remove_item')}";
+      $.post(post_url, {id:$(this).data('item-id')})
+        .always(function(data){
+        location.reload(true);
+      });
+    });
+
+   $('#submit-code').click(function(event){
+      event.preventDefault();
+      var post_url = "${reverse('shoppingcart.views.use_code')}";
+      if($('#input_code').val() == "") {
+        showErrorMsgs('Must enter a valid code','code');
+        return;
+      }
+      $.post(post_url,{
+                  "code" :  $('#input_code').val()
+              }
+      )
+      .success(function(data) {
+                  location.reload(true);
+              })
+      .error(function(data,status) {
+                  if(status=="parsererror"){
+                       location.reload(true);
+                  }else{
+                        showErrorMsgs(data.responseText, 'code')
+                      }
+              })
+   });
+
+   $('#submit-reset-redemption').click(function(event){
+       event.preventDefault();
+       var post_url = "${reverse('shoppingcart.views.reset_code_redemption')}";
+       $.post(post_url)
+       .success(function(data) {
+                   location.reload(true);
+              })
+       .error(function(data,status) {
+                   if(status=="parsererror"){
+                       location.reload(true);
+                  }else{
+                        showErrorMsgs(data.responseText,'code')
+                      }
+               })
+   });
+
+   $('#register').click(function(event){
+       event.preventDefault();
+       var post_url = "${reverse('shoppingcart.views.register_courses')}";
+       $.post(post_url)
+       .success(function(data) {
+                   window.location.href = "${reverse('dashboard')}";
+               })
+       .error(function(data,status) {
+                   if(status=="parsererror"){
+                       location.reload(true);
+                   }else{
+                        showErrorMsgs(data.responseText)
+                      }
+               })
+   });
+
+   $('#billing-details').click(function(event){
+       event.preventDefault();
+       location.href = "${reverse('shoppingcart.views.billing_details')}";
+   });
+
+
+ $(".button").on("click", function() {
+     var studentField =  $(this).parent().find('input');
+     var ItemId = studentField.attr('id');
+     var $button = $(this);
+     var oldValue = $button.parent().find("input").val();
+     var newVal = 1; // initialize with 1.
+     hideErrorMsg('students-'+ItemId);
+     if ($.isNumeric(oldValue)){
+         if ($button.text() == "+") {
+             if(oldValue > 0){
+                 newVal = parseFloat(oldValue) + 1;
+                 if(newVal > 1000){
+                     newVal = 1000;
+                 }
+             }
+         } else {
+     // Don't allow decrementing below one
+     if (oldValue > 1) {
+         newVal = parseFloat(oldValue) - 1;
+     }
+         }
+     }
+     $button.parent().find("input").val(newVal);
+     $('#updateBtn-'+ItemId).removeClass('hidden');
+
+ });
+
+$('a[name="updateBtn"]').click(function(event) {
+    var studentField =  $(this).parent().find('input');
+    var number_of_students = studentField.val();
+    var ItemId = studentField.attr('id');
+
+    if($.isNumeric(number_of_students) && number_of_students > 0 ){
+        hideErrorMsg('students-'+ItemId);
+        update_user_cart(ItemId, number_of_students);
+    }else{
+        showErrorMsgs('quantity must be greater then 0.', 'students-'+ItemId);
+    }
+});
+
+  function showErrorMsgs(msg, msg_area){
+
+      $( "span.error-text#"+ msg_area +"" ).removeClass("hidden");
+      $( "span.error-text#"+ msg_area +"" ).html(msg).show();
+
+      if(msg_area=='code'){
+        $("#input_code").addClass('error');
+      }
+  }
+
+  function hideErrorMsg(msg_area){
+      $( "span.error-text#"+ msg_area +"" ).addClass("hidden");
+  }
+
+  function update_user_cart(ItemId, number_of_students){
+      var post_url = "${reverse('shoppingcart.views.update_user_cart')}";
+      $.post(post_url, {
+          ItemId:ItemId,
+          qty:number_of_students
+          }
+      )
+      .success(function(data) {
+                    location.reload(true);
+            })
+      .error(function(data,status) {
+                  location.reload(true);
+              })
+  }
+
+$('input[name="students"]').on("click", function() {
+    $('#updateBtn-'+this.id).removeClass('hidden');
+});
+
+// allowing user to enter numeric qty only.
+  $("input[name=students]").keydown(function(event) {
+      var eventDelete       = 46;
+      var eventBackSpace    = 8;
+      var eventLeftKey      = 37;
+      var eventRightKey     = 39;
+      var allowedEventCodes = [eventDelete, eventBackSpace, eventLeftKey, eventRightKey ];
+      // Allow only backspace and delete
+	  if (allowedEventCodes.indexOf(event.keyCode) > -1) {
+          // let it happen, don't do anything
+		}
+      else {
+	     /*
+          Ensure that it is a number.
+          KeyCode range 48 - 57 represents [0-9]
+          KeyCode range 96 - 105 represents [numpad 0 - numpad 9]
+         */
+		if ((event.keyCode >= 48 && event.keyCode <= 57) || (event.keyCode >= 96 && event.keyCode <= 105) ) {
+            $('#updateBtn-'+this.id).removeClass('hidden');
+        }else{
+            event.preventDefault();
+        }
+	  }
+
+	});
+});
+</script>
diff --git a/lms/templates/shoppingcart/shopping_cart_flow.html b/lms/templates/shoppingcart/shopping_cart_flow.html
new file mode 100644
index 0000000000000000000000000000000000000000..bc7fa4731714a4978ed560eecf06bd0398f6c3a5
--- /dev/null
+++ b/lms/templates/shoppingcart/shopping_cart_flow.html
@@ -0,0 +1,27 @@
+<%!
+from django.utils.translation import ugettext as _
+%>
+<%inherit file="../main.html" />
+<%namespace name='static' file='/static_content.html'/>
+<%block name="pagetitle">${_("Shopping cart")}</%block>
+
+
+
+<%block name="bodyextra">
+
+<div class="container">
+  <section class="wrapper confirm-enrollment shopping-cart">
+  <h1> ${_("{site_name} -  Shopping Cart").format(site_name=site_name)}</h1>
+      % if shoppingcart_items:
+      <ul class="steps">
+          <li <%block name="review_highlight"/>>${_('Review')}</li>
+          <%block name="billing_details_highlight"/>
+          <li <%block name="payment_highlight"/>>${_('Payment')}</li>
+          <li <%block name="confirmation_highlight"/>>${_('Confirmation')}</li>
+      </ul>
+      %endif
+  </section>
+</div>
+<%block name="custom_content"/>
+
+</%block>
diff --git a/lms/templates/shoppingcart/verified_cert_receipt.html b/lms/templates/shoppingcart/verified_cert_receipt.html
index 85b36aa231ccb12ad63abebccf2483a4503b4fcf..885694c241934d5b0fa35ce08a99b2da68cf1973 100644
--- a/lms/templates/shoppingcart/verified_cert_receipt.html
+++ b/lms/templates/shoppingcart/verified_cert_receipt.html
@@ -103,7 +103,7 @@
                 </thead>
 
                 <tbody>
-                  % for item in order_items:
+                  % for item, course in shoppingcart_items:
                   <tr>
                     <td>${item.line_desc}</td>
                     <td>
@@ -158,7 +158,7 @@
                 </thead>
 
                 <tbody>
-                  % for item in order_items:
+                  % for item, course in shoppingcart_items:
                   <tr>
                     % if item.status == "purchased":
                     <td>${order.id}</td>