E-Commerce Service Documentation: Release 0.1
E-Commerce Service Documentation: Release 0.1
Release 0.1
edX
2 Comprehensive Theming 9
2.1 Theme Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2 Templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.3 Static Assets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.4 Sass . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.5 Enabling a Theme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.6 Disabling a Theme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.7 Creating or Updating Site and SiteTheme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.8 Compiling Theme Sass . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.9 Troubleshooting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
5 Manage Orders 29
5.1 Place an Order . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
5.2 Fulfill Orders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
5.3 About Fulfillment Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
5.4 Recover from a Fulfillment Error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
6 Test Features 31
6.1 Tests for the Open edX Platform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
i
7 Test Your E-Commerce Application 33
7.1 Tests for E-Commerce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
ii
E-Commerce Service Documentation, Release 0.1
EdX uses a Django application called ecommerce to provide the platform with ecommerce functionality. This E-
Commerce service extends Oscar, an open source Django ecommerce framework, to manage the edX product catalog
and handle orders for those products. The following sections describe how to install and use the E-Commerce service
with the Open edX platform.
Contents 1
E-Commerce Service Documentation, Release 0.1
2 Contents
CHAPTER 1
To install and start the edX E-Commerce service, you must complete the following steps.
Note: These steps assume that you are running Open edX devstack. If you prefer to run the E-Commerce ser-
vice locally on your computer instead of on the virtual machine (VM) that devstack uses, see :Development Outside
Devstack.
1. Create or activate a Python virtual environment. You execute all of the commands described in this section
within the virtualenv (unless otherwise noted).
For more information, see Virtual Environments.
2. Run the following command to install dependencies.
$ make requirements
3
E-Commerce Service Documentation, Release 0.1
3. (Optional) Create settings overrides that you do not commit to the repository. To do this, create a file named
ecommerce/settings/private.py. The ecommerce/settings/local.py file reads the values
in this file, but Git ignores the file.
Note: Local installations use SQLite by default. If you use another database backend, make sure you update your
settings and create the database, if necessary, before you run migrations.
$ make migrate
When you run migrations, the E-Commerce service adds a default site to your installation.
The E-Commerce service relies on the LMS, which serves as the OAuth 2.0 authentication provider.
To configure the E-Commerce service to work with OAuth, complete the following procedures.
To finish creating and configuring your OAuth client, you must configure a partner, site, and site configuration for the
E-Commerce service to use. The site that you configure is the default site that the E-Commerce service adds when
you run migrations. You must update this default site to match the domain that you will use to access the E-Commerce
service. You must also set up a site configuration that contains an oauth_settings JSON field that stores your
OAuth client’s settings, as follows.
Setting Description Value
OAuth 2.0 client
BACKEND_SERVICE_EDX_OAUTH2_KEY The Client ID field in the Create and Register a Client
key section for backend server-to-server calls.
OAuth 2.0 client
BACKEND_SERVICE_EDX_OAUTH2_SECRET The Client Secret field in the Create and Register a Client
secret ection for backend server-to-server calls.
OAuth 2.0 client
SOCIAL_AUTH_EDX_OAUTH2_KEY The Client ID field in the Create and Register a Client
key section.
OAuth 2.0 client
SOCIAL_AUTH_EDX_OAUTH2_SECRET The Client Secret field in the Create and Register a Client
secret section.
OAuth 2.0
SOCIAL_AUTH_EDX_OAUTH2_URL_ROOT For example, http://127.0.0.1:8000.
authentication
URL
OAuth token
SOCIAL_AUTH_EDX_OAUTH2_ISSUER For example, http://127.0.0.1:8000.
issuer
User logout URL
SOCIAL_AUTH_EDX_OAUTH2_LOGOUT_URL For example, http://127.0.0.1:8000/logout.
To configure your default site, partner, and site configuration, use the appropriate settings module for your environment
(ecommerce.settings.devstack for Devstack, ecommerce.settings.production for Fullstack) to
run the following Django management command. This command updates the default site and creates a new partner
and site configuration with the specified options.
$ sudo su ecommerce
$ python manage.py create_or_update_site --site-id=1 --site-
˓→domain=localhost:8002 --partner-code=edX --partner-name='Open edX' --lms-
If you want to add more sites, partners, and site configurations, you can use the create_or_update_site com-
mand. The following options are available for this command.
˓→email=[from email]
To complete the installation and start the E-Commerce service, follow these steps.
Note: Local installations use SQLite by default. If you use another database backend, make sure you update your
settings and create the database, if necessary, before you run migrations.
1. (Devstack only) If you are using devstack, switch to the ecommerce user and use the ecommerce.
settings.devstack settings module to run the following commands.
$ sudo su ecommerce
$ make serve
Note: If you use a different port, make sure you update the OAuth client by using the Django administration
panel in the LMS. For more information about configuring the OAuth client, see Configure OAuth.
By default, the ShoppingCart service is enabled when you install an Open edX instance. To use the E-Commerce
service to handle ecommerce-related tasks instead of ShoppingCart, follow these steps.
1. Sign in to the Django administration console for your base URL. For example, http://{your_URL}/
admin.
2. In the Commerce section, next to Commerce configuration, select Add.
3. Select Enabled.
4. Select Checkout on ecommerce service.
5. (Optional) In the Single course checkout page field, override the default path value of /basket/
single-item/ with your own path value.
Important: If you override the default path value, you must also change all of the code that relies on that path.
If you are running the LMS in devstack but would prefer to run the E-Commerce service on your host, set up a reverse
port-forward. This reverse port-forward allows the LMS process inside your devstack to use 127.0.0.1:8002 to
make calls to the E-Commerce service running on your host. This simplifies LMS URL configuration.
To set up a reverse port-forward, execute the following command when you SSH into your devstack. Make sure that
you run this command on the VM host, not the guest.
Comprehensive Theming
Any application, including Otto, can be loosely divided into two parts:
• the user interface (“how it looks”),
• and the application logic (“how it works”).
For example, when considering a product in Otto, the user interface consists of how the products are laid out on the
page, how the selectors look, how the checkout button is labelled, what sort of fonts and colors are used to display the
text, and so on. The application logic consists of how Otto adjusts product price based on the discount coupons, and
how it records that information to be displayed in the future.
Theming consists of changing the user interface without changing the application logic. When setting up an E-
Commerce website, the website operator often wants to use their own logo, modify the color scheme, change links in
the header and footer for SEO (search engine optimization) purposes, and so on. However, although the user interface
may look different, the application logic must remain the same so that Otto continues to work properly. A well-
designed theme preserves the general layout and structure of the user interface, so that users of the website still find it
familiar and easy to use. Be careful about making sweeping changes to the user interface without warning: your users
will be very confused!
ENABLE_COMPREHENSIVE_THEMING = False
9
E-Commerce Service Documentation, Release 0.1
with themed versions of those resources. Every theme must conform to a directory structure. This structure mirrors
the Otto directory structure and looks like this
my-theme
- README.rst
- static
| - images
| | - logo.png
| |
| - sass
| - partials
| - utilities
| - _variables.scss
|
- templates
- oscar
| - dashboard
| - index.html
- 404.html
2.2 Templates
Any template included in ecommerce/templates directory is themable. However, make sure not to override class
names or id values of html elements inside a template, as these are used by javascript and/or css and overriding these
could cause unwanted behavior.
Any static asset included in ecommerce/static can be overridden except css files present in ecommerce/
static/css. Css styles can be overridden via sass overrides explained below.
Caution: Theme names should be unique and no static asset and/or directory name should be same as theme’s
name. Otherwise static assets would not work correctly.
2.4 Sass
Sass overrides are a little different from static asset or template overrides. There are two types of styles included in
ecommerce/static/sass:
• base
• partials
Any styles included in ecommerce/static/sass/partials can be overridden. Styles included in this direc-
tory contain variable definitions that are used by main sass files. This is the best place if you want to update things like
header/footer background, fonts etc.
To enable a theme, you must first install your theme onto the same server that is running Otto. If you are using devstack
or fullstack to run Otto, you must be sure that the theme is present on the Vagrant virtual machine. It is up to you where
to install the theme on the server, but a good default location is /edx/app/ecommerce/ecommerce/themes.
In order for Otto to use the installed themes, you must specify the location of the theme directory in Django settings
by setting COMPREHENSIVE_THEME_DIRS in your settings file:
COMPREHENSIVE_THEME_DIRS = ["/edx/app/ecommerce/ecommerce/themes", ]
Where /edx/app/ecommerce/ecommerce/themes is the path to where you have installed the themes on your
server. You can list any/all theme directories through this setting.
After installing a theme, it is associated with sites by adding appropriate entries to the following tables
• Site
• Site Themes
for local devstack, if Otto server is running at localhost:8002 you can enable a my-theme by
• Adding a new site with domain localhost:8002 and name “Otto My Theme”
• and a site theme with Theme dir name my-theme and selecting localhost:8002 from site dropdown.
Otto server can now be started, and my-theme should be applied now. If you have overridden sass styles and you are
not seeing those overrides then you need to compile sass files as discussed in Compiling Theme Sass.
Theme can be disabled by removing its corresponding Site Theme entry using django admin.
If you have already setup COMPREHENSIVE_THEME_DIRS then you can use management command for adding
Site and SiteTheme directly from the terminal.
python manage.py create_or_update_site_theme --site-domain=localhost:8002 --site-
˓→name=localhost:8002 --site-theme=my-theme
# update domain of the site with id 1 and add a new theme ``my-
˓→theme`` for this site
˓→localhost:8002 --site-theme=my-theme
˓→theme=my-theme
˓→theme=my-theme
Management command update_assets can be used for compiling and collecting themed sass.
–themes Space separated list of themes to compile sass for. ‘all’ for all themes, ‘no’ to skip
sass compilation for themes, default: 'all'
–output-style Coding style for compiled css files. Possible options are nested, expanded,
compact and compressed. default: 'nested'
# useful in cases where you have updated theme sass and system
˓→sass is unchanged.
–skip-collect This flag can be used to skip collectstatic call after sass compilation
2.9 Troubleshooting
If you have gone through the above procedure and you are not seeing theme overrides, you need to make sure
• COMPREHENSIVE_THEME_DIRS must contain path for the directory containing themes e.g. if
your theme is /edx/app/ecommerce/ecommerce/themes/my-theme then correct value for
COMPREHENSIVE_THEME_DIRS is ['/edx/app/ecommerce/ecommerce/themes'].
• domain name for site is the name users will put in the browser to access the site, it also includes port number
e.g. if Otto is running on localhost:8002 then domain should be localhost:8002
• Theme dir name is the name of the directory of you theme, for our ongoing example my-theme is the correct
theme dir name.
2.9. Troubleshooting 13
E-Commerce Service Documentation, Release 0.1
After you configure a partner and at least one site for the E-Commerce system to use, you must compile all static
assets and move them to the correct location to be served. The edX E-Commerce service uses django-compressor and
RequireJS to manage static assets.
• django-compressor compiles and minifies CSS and JavaScript files, and names files to facilitate cache busting
after new file deployment.
• RequireJS manages JavaScript dependencies.
Note: The static file directories are set up so that make static reads the build output directory of r.js before it
checks for assets in the ecommerce/static/ directory. EdX does not recommend that you run make static
locally. If you run make static or r.js locally, make sure you delete the ecommerce/static/build folder
or that you run make static before you continue with development. If you do not run make static again,
django-compressor ignores all changes that you make to static files.
To compile and move your static assets and deploy your E-Commerce service, execute the following command locally
or on another server.
$ make static
If you create new pages that have RequireJS dependencies, remember to add your new JavaScript modules to the
RequireJS build file for the project. This is the build.js file.
15
E-Commerce Service Documentation, Release 0.1
After you configure a partner and at least one site for the E-Commerce service to use, and you have compiled and
moved your static assests, you can create products. For more information, see the following topics.
The edX platform offers several types of products. You create these products in E-Commerce web pages.
• Course seats represent an enrollment track. Each course seat has an associated set of attributes, such as price and
certificate availability. The edX code uses course seats to determine how a given enrollment should be handled.
For more information, see Create Course Seats.
• Coupons allow users to offer learners a discount, either percentage or fixed amount, off a course enrollment. For
more information, see Create and Manage Coupons.
• Enrollment codes allow users to purchase bulk enrollments for a course.
Before you create a product, complete the following steps to start the E-Commerce service on your site.
1. In the ecommerce and LMS configuration files (/edx/etc/ecommerce.yml and /edx/app/edxapp/
lms.auth.json, respectively), verify the following settings.
Note: If you are using devstack, these values are set correctly for you. However, edX recommends that you
verify these values.
• The EDX_API_KEY value in the LMS file must be the same as the EDX_API_KEY value in the ecom-
merce file. If the values differ, change the value in the LMS file to match the ecommerce file.
17
E-Commerce Service Documentation, Release 0.1
• The ECOMMERCE_API_SIGNING_KEY value in the LMS file must be the same as the
JWT_SECRET_KEY value in the ecommerce file. If the values differ, change the value in the LMS file to
match the ecommerce file.
2. On devstack, start the E-Commerce server on port 8002, and start the LMS on port 8000.
A course seat represents an enrollment track, sometimes called an enrollment mode. For information about the enroll-
ment tracks that edX offers, see enrollment track.
You create course seats by creating a course on the Create New Course page in the course administration tool, which
is located at http://localhost:8002/courses/. After you create a course, the E-Commerce service creates
the course seats that are associated with that course.
To create a course seat, follow these steps.
1. Follow the steps in Creating Products Overview to start your E-Commerce server.
2. In a browser on your E-Commerce server, go to http://localhost:8002/courses to access the
Courses page.
3. On the Courses page, select Add New Course.
4. On the Add New Course page, enter the information for your course in the following fields.
• Course ID
• Course Name
5. For Course Type, select a course type and the options for that course type.
• If you select Free (Audit), you must specify whether you want to allow honor code learners to earn an
honor code certificate. To do this, select Yes under Include Honor Seat.
• If you select Verified, you must add the following information.
– Price (in USD)
– Upgrade Deadline
– Verification Deadline
– Include Honor Seat: This option grants honor code certificates to learners who successfully complete
the course.
• If you select Professional Education, you must add the following information.
– Price (in USD)
– ID Verification Required?
– Upgrade Deadline
• If you select Credit, you must add the following information.
– Price (in USD): The price for a verified certificate.
– Upgrade Deadline
– Credit Provider
– Price (USD): The price for course credit.
– Credit Hours
– Upgrade Deadline
– Verification Deadline
– Include Honor Seat: This option grants honor code certificates to learners who successfully complete
the course.
6. Select Create Course.
This topic covers how to create and distribute coupons and their associated coupon codes. You can use coupons to
provide discounted or free course enrollments, also called “course seats”, to your learners.
• Create a Coupon
• Download Coupon Information
• Edit a Coupon
• Deactivate a Coupon
• Distribute Coupon Codes to Learners
• View the Invoice for a Coupon
To create a coupon, you create one or more coupon codes that learners use to receive their discounts. You then use
your email system to distribute the discount or enrollment codes for that coupon.
Creating a coupon code has several steps.
You create coupons and their associated discount or enrollment codes on the Create New Coupon page in the coupon
administration tool, which is located at http://localhost:8002/coupons/. In the tool, you enter basic
information and select the options for your coupon.
Each coupon requires some basic information. To enter basic information for your coupon, follow these steps.
1. Follow the steps in Creating Products Overview to start your E-Commerce server.
In addition to entering basic information, you must specify a coupon code type. The coupon code type is either
“enrollment code” or “discount code”.
• An enrollment code covers the entire fee for a course seat.
• A discount code offers between 1% and 99% or a fixed dollar amount off the fee for a course seat.
A “course seat” is a single course enrollment in a specific course track.
To specify the coupon code type, follow these steps.
1. For Code Type, select Enrollment Code if you want the coupon code to cover the entire course fee, or select
Discount Code if you want to provide a discount for the course.
2. If you selected Enrollment Code, locate the Number of Codes field, and then enter the number of enrollment
codes that you want to create.
If you selected Discount Code, the following fields are visible.
• Discount per Code (required): Enter the percent or U.S. dollar amount of the discount that you want to
offer, then select Percent or Fixed. Do not add a percent sign or a dollar sign.
• Code (optional): If you want to specify your own discount code, such as SCHOLAR15, enter the code that
you want in this field. This code can have 1 to 16 characters.
If you want the system to generate a discount code for you, leave this field empty, and then enter the
number of discount codes that you want to create in the Number of Codes field.
After you complete this step, you must specify the courses that you want your coupon to apply to.
Specify Courses
In addition to specifying your coupon’s code type, you must specify the courses for your coupon. Your coupon can
apply to a single course or to multiple courses.
Note: If you want your coupon to apply to multiple courses, you must use the edX Course Catalog API. The Course
Catalog API is in beta and is not documented or fully supported.
Note: To create a query, you must use the edX Course Catalog API. The Course Catalog API is in beta and is not
documented or fully supported.
The coupon administration tool uses queries to return a catalog of courses. The coupons that you create apply to each
course in that catalog.
These queries use the following syntax.
field_name:search_terms
Your query can contain operators such as quotation marks (”), asterisks (*), and hyphens (-).
For example, your query might resemble one of the following queries.
org:(Company OR University)
org:(-Company OR -University)
start:[2016-01-01 TO 2016-12-31]
number:6.002x*
For more information about queries, including syntax and operators, see Query string syntax.
The following table lists the field names that you can use in your query, along with a description for each field name.
Field Name Description
announcement The date the course is announced to the public, in YYYY-MM-DD format.
end The course run end date, in YYYY-MM-DD format.
enrollment_end The enrollment end date, in YYYY-MM-DD format.
enrollment_start The enrollment start date, in YYYY-MM-DD format.
key The course run key, sometimes also called the course ID.
language The language in which the course is administered.
max_effort The estimated maximum number of hours necessary to complete the course.
min_effort The estimated minimum number of hours necessary to complete the course.
number The course number (for example, 6.002x).
org The organization associated with the course (for example, MITx).
pacing_type The pacing for the course run. Options are instructor_paced or self_paced.
start The course run start date, in YYYY-MM-DD format.
title The course title.
In addition to specifying courses for your coupon, you must specify usage limitations. Usage limitations control
whether one or more customers can use the coupon, as well as the number of times each customer can use the coupon.
To specify usage limitations, follow these steps.
1. On the Create New Coupon page, locate Usage Limitations.
2. Select one of the following options.
• Can be used once by one customer
If you select this option, the Number of Codes field is visible. In this field, specify the number of individ-
ual discount or enrollment codes you want to create. The value must be between 1 and 1000. Make sure
that you create enough discount or enrollment codes so that each person receives one code.
• Can be used once by multiple customers or Can be used multiple times by multiple customers
If you select one of these options, the Maximum Number of Usages field is visible. In this field, specify
the number of times customers can use the coupon code.
For example, if you want to create a coupon code that is available for 10 different customers, and each
customer can use the code only one time, enter 10 for Can be used once by multiple customers.
If you want to create a coupon code that is available for 10 uses, whether by one customer or multiple
customers, enter 10 for Can be used multiple times by multiple customers.
After you specify usage limitations, you must specify invoicing options for your coupon.
In addition to setting usage limitations for your coupon, you must specify invoicing options. You can send an invoice
when you create the coupon or after one or more customers have redeemed the coupon. The invoice can be for the
total amount or for part of the total amount.
To specify the way you want to invoice your client, follow these steps.
1. On the Create New Coupon page, locate Invoice Type.
2. Select one of the following options.
• Already invoiced: Select this option if you have already sent an invoice to your client.
If you select this option, you must also enter information in the following fields.
– Invoice Number: Your internal invoice number.
– Invoice Amount: The amount that you have already invoiced the client.
– Payment Date: The date when payment is due from the client.
• Invoice after redemption: Select this option if you will send an invoice to your client after one or more
coupon codes have been redeemed.
• N/A: Select this option if neither of the other options applies to your situation.
• After you have entered all the basic coupon information and specified the options that you want, select Create
Coupon.
When you select Create Coupon, the system generates one or more discount or enrollment codes as well as the URLs
where users can redeem these codes.
When the system has finished generating the coupon, a page for the coupon opens. This page lists the information for
your coupon, including all discount or enrollment codes for the coupon, the coupon’s status, URLs where users can
redeem the codes, dates the coupon is valid, and the course that the coupon applies to. You can also download a .csv
file with the coupon information from this page.
After you create a coupon, you can download a .csv file that lists the information that you entered when you created the
coupon. The .csv file also includes additional information, such as the discount or enrollment codes that are associated
with your coupon and the system-generated URL where a user can redeem each code.
1. In your browser, go to http://localhost:8002/coupons/ to open the coupon administration tool.
2. On the Coupon Codes page, locate the coupon that you want in the table, and then select the name of the
coupon. The page for the coupon opens.
3. On the page for the coupon, select Download. Your .csv file begins downloading automatically.
The .csv file for your coupon lists the following information.
• Code Type
• Course ID
• Single course or Multiple courses
• Seat Type
• Usage Limitations
• Number of Codes or Maximum Number of Usages
To deactivate a coupon, change the Valid from and Valid until date fields so that both dates are in the past. For more
information, see Edit a Coupon.
You can distribute both discount codes and enrollment codes to learners in two ways.
• You provide a coupon code that learners enter on the Checkout page for the verified or professional certificate
track. If you do this, edX recommends that you also provide the URL for the course About page to make signing
up for the course easier.
• You provide a URL for an offer landing page. This automatically generated page presents information about the
course, lets the learner know that the coupon code has been applied, and provides the opportunity for the learner
to enroll. Learners can access this URL if they do not have an edX account or they are not signed in. However,
learners must sign in or create an edX account to redeem the coupon and enroll in the course.
A URL for an offer landing page has the following format.
http://localhost:8002/coupons/offer/?code=################
Note: If the coupon code is a discount code, the learner must pay any balance due before enrolling in the course for
a verified or professional certificate.
To distribute the coupon code or URL to learners, you determine the coupon code or the URL for the learner to use,
and then you create and send an email that includes the coupon code or the URL. For suggestions for email message
text, see Example Email Messages.
You can find coupon codes, whether discount codes or enrollment codes, and their associated URLs in two places: on
the page for the coupon in the coupon administration tool, and in a downloadable .csv file. You can use either option
to find the coupon code or URL for your learners.
To find a coupon code or URL on the page for the coupon in the coupon administration tool, follow these steps.
1. In your browser, go to http://localhost:8002/coupons/ to open the coupon administration tool.
2. On the Coupon Codes page, locate the coupon that you want in the table, and then select the name of the
coupon. The page for the coupon opens.
3. On the page for the coupon, locate the table under Codes.
4. In the table, locate the information that you want.
• For a coupon code that the learner will enter on the Checkout page, use the value in the Code column.
• For an offer landing page, use the URL in the Redemption URL column.
To find a coupon code or URL in the .csv file for a coupon, follow these steps.
1. Download a .csv file that lists the information for your coupon, and then open the .csv file.
2. In the .csv file, locate the information that you want.
• For a coupon code that the learner will enter on the Checkout page, use the value in the Code column.
• For an offer landing page, use the URL in the URL column.
After you locate the coupon code or URL that you want to use, you use your email system to provide that information
in a message to potential learners.
Note: When you send a coupon code for a learner to use on the Checkout page, edX recommends that you include
the About page URL for the course as well as the coupon code to help the learner enroll more easily.
You can use the following email messages as examples of the communication that you send to your learners.
Dear learner,
This message includes a discount <or an enrollment> code for edX101: Overview
of Creating an edX Course. For more information about the course, see
https://www.edx.org/course/overview-creating-edx-course-edx-edx101.
To redeem this code, sign up for a verified <or professional> certificate, and
then enter the following coupon code in the **Coupon Code** field on the
**Checkout** page:
ZDPC3AQV3732RQT5
Dear learner,
This message includes a discount <or an enrollment> code for edX101: Overview
of Creating an edX Course. To redeem this code and enroll in the course, visit
the following URL:
http://localhost:8002/coupons/offer/?code=ZDPC3AQV3732RQT5
When you create a coupon, the E-Commerce service generates and fulfills an order. The Invoice Payment Processor
module in the service then records the fulfilled order. Because the Invoice Payment Processor module assumes that
you have sent or will send an invoice to the client who purchased the coupon, the module also records the order in the
Invoice table in the Django administration panel so that you can view and reconcile the order.
To view your coupon invoices in the Invoice table, go to http://localhost:8002/admin/invoice/
invoice/. The table lists all of the invoices for your coupons, along with information such as the client name
and the invoice status.
For more information about the way that the E-Commerce service manages orders, see Manage Orders.
Note: The enrollment codes in this topic are not related to the enrollment codes in the Create and Manage Coupons
topic.
You must enable enrollment codes in the E-Commerce service and in individual courses.
1. To enable enrollment codes in the E-Commerce service, run the site configuration command together with the
following option.
``--enable-enrollment-codes=True``
For more information, see Add Another Site, Partner, and Site Configuration.
Manage Orders
EdX has created a framework that manages order placement and fulfillment for digital products. Most of the products
that edX supports involve modifications to enrollments.
The edX framework allows modules that fulfill enrollment-related products to interact with the edX Enrollment API,
which is a part of the LMS. This process can be either synchronous or asynchronous.
To fulfill orders, emit a post_checkout signal. An internal fulfillment API then delegates fulfillment of individual
order items to the appropriate fulfillment modules.
29
E-Commerce Service Documentation, Release 0.1
fulfill_product(product)
revoke_line(line)
Every ProductType has a corresponding module that extends this interface and fulfills order items of that particular
ProductType. To fulfill an order, the system gives each fulfillment module configured in settings (_oscar.py)
an opportunity to fulfill order lines.
• The fulfill_product method fulfills the order. For example, fulfill_product might enroll a learner
in a course or upgrade the learner to a verified certificate).
• The revoke_line method revokes a specific order line. For example, revoke_line might unenroll learn-
ers from courses or downgrade a learner from a verified seat.
If a fulfillment operation fails, the E-Commerce service assigns the order a status indicating the reason for the failure.
If you have enabled asynchronous order fulfillment, the service tries again to fulfill the order. You can also manually
retry fulfillment of a failed order from the Oscar order dashboard.
Test Features
When you create a new feature for the Open edX platform, you must write two kinds of tests for that feature: general
tests that evaluate the feature on the Open edX platform, and tests that are specific to the type of feature that you
create. For example, if you create a coupon codes feature for use with the edX Ecommerce service, you must write
both Open edX tests and Ecommerce tests. This section describes the general tests that you must write for the Open
edX platform.
You must write the following types of tests for all new features that you create for the Open edX platform.
• Django tests. To learn how to test Django code, see the Testing in Django documentation provided by the Django
Software Foundation.
• Acceptance tests. These tests verify behavior that relies on external systems, such as the LMS or payment
processors. At a minimum, you must run these tests against a staging environment before you deploy code to
production to verify that critical user workflows are functioning as expected. With the right configuration, you
can also run the tests locally.
31
E-Commerce Service Documentation, Release 0.1
To test new applications that you develop for the E-Commerce service, you create and run tests for the Open edX
platform first, and then you run a set of tests that are specific to E-Commerce.
For more information about tests for the Open edX platform, see Test Features.
When you develop E-Commerce applications, you must run a pre-packaged set of unit tests, Python tests, and E-
Commerce acceptance tests.
The E-Commerce unit tests include migrations, the unit test suite, and quality checks. You can run the full unit test, or
save time for a local test by disabling the migrations. (You can also run the quality checks independent of the unit test
suite.)
• To run the full unit test, including migrations and quality checks, use the following command.
$ make validate
Note: If numerous unit tests fail with an OfflineGenerationError message, run the following com-
mand, then try to run unit tests again.
• To run unit tests with quality checks but without migrations, run the following command.
33
E-Commerce Service Documentation, Release 0.1
Note: We recommend that you only run tests without migrations when you run the tests locally.
When you create E-Commerce tests, use the TestCase class in ecommerce/tests/testcases.py to ensure
every test has Site and Partner objects configured. This will help you test any code that relies on these models,
which are used for multi-tenancy.
• To run a test really fast, use pytest.
$ pytest path/to/file.py::TestSuiteClass::test_name
– Note: You must update requirements and migrations before running with pytest.
– Some tests involving the database may be flaky. If this doesn’t work, use the manage.py method below.
• To run all Python unit tests and quality checks, run the following command.
$ make validate_python
• To run all Python unit tests and quality checks in parallel, run the following command.
$ make fast_validate_python
• To run the Python unit tests in a specific file and a specific test, such as ecommerce/courses/tests/
test_utils.py, run the following command and substitute the desired file path.
$ tox -e py35-tests -- ecommerce.courses.tests.test_utils:UtilsTests.test_get_
˓→course_info_from_catalog_cached
To debug when running tests using manage.py, you may need to use the following instead of pdb directly, or
nosetests may hang while creating the database:
import nose.tools as nosepdb; nosepdb.set_trace()
The E-Commerce project uses Jasmine for JavaScript unit testing. To create these tests, place your tests in the
ecommerce/static/js/test/specs directory, and add a _spec suffix. For example, your test name may
be ecommerce/static/js/test/specs/course_list_view_spec.js.
All JavaScript code must adhere to the edX JavaScript standards. These standards are enforced using ESLint.
• To run all JavaScript unit tests and linting checks, run the following command.
$ make validate_js
To run specific acceptance tests for the E-Commerce service, you must complete the following procedures.
"ECOMMERCE_API_URL": "http://localhost:8002/api/v2/"
"ECOMMERCE_PUBLIC_URL_ROOT": "http://localhost:8002/"
"JWT_ISSUER": "http://127.0.0.1:8000/oauth2" // Must match the E-Commerce JWT_
˓→ISSUER setting
"OAUTH_ENFORCE_SECURE": false
3. Verify that an LMS account with staff and superuser permissions exists.
By default, most devstack and fullstack LMS instances include a user account that has staff permissions. This
account has the username staff, the email address [email protected], and the password edx. Run the
following commands to grant the account superuser permissions.
4. In the Django administration panel, verify that an OAuth2 client with the following attributes exists. If one
does not already exist, create a new one. The client ID and secret must match the values of the E-Commerce
SOCIAL_AUTH_EDX_OAUTH2_KEY and SOCIAL_AUTH_EDX_OAUTH2_SECRET settings, respectively.
URL: http://localhost:8002/
Redirect uris: http://localhost:8002/complete/edx-oauth2/
Client id: 'replace-me'
Client secret: 'replace-me'
Client type: Confidentials
Authorization grant type: Authorization code
5. In the Django administration panel, verify that the OAuth2 client referred to above is designated as a trusted
client. If this isn’t already the case, add the client created above as a new trusted client.
6. In the Django administration panel, create a new access token for the superuser account. Set the client to the
OAuth2 client referred to above. Make note of this token; it is required to run the acceptance tests.
7. Make sure that the LMS instance that you will use for testing has at least two courses that learners could enroll
in. By default, most LMS instances include the edX demonstration course. Use Studio to create a second course.
Configure E-Commerce
You use the CAT to finish configuring the two courses in your LMS instance.
1. In your browser, go to http://localhost:8002/courses/ to access the CAT.
2. In the CAT, add both of the courses present on your LMS instance to E-Commerce. Configure one as a “Free
(Audit)” course, and the second as a “Verified” course.
3. So that you can test integration with external payment processors, update the contents of the
PAYMENT_PROCESSOR_CONFIG dictionary found in the settings with valid credentials. To over-
ride the default values for development, create a private settings module, private.py, and set
PAYMENT_PROCESSOR_CONFIG inside the module.
Note: If you created a private.py file to create settings overrides when you set up your virtual environment,
you can use that same private.py file.
Run all acceptance tests by executing make e2e. To run a specific test, execute the following command.
$ nosetests -v <path/to/the/test/module>
The acceptance tests rely on the environment variables that you have configured. For example, when you run the
acceptance tests against local instances of E-Commerce and the LMS, you might run the following command, replacing
values between angle brackets (<>) with your own values.
$ ECOMMERCE_URL_ROOT="http://localhost:8002" LMS_URL_ROOT="http://127.0.0.1:8000" LMS_
˓→USERNAME="<username>" LMS_EMAIL="<email address>" LMS_PASSWORD="<password>" ACCESS_
When you run the acceptance tests against a production-like staging environment, you might run the following com-
mand.
$ ECOMMERCE_URL_ROOT="https://ecommerce.stage.edx.org" LMS_URL_ROOT="https://courses.
˓→stage.edx.org" LMS_USERNAME="<username>" LMS_EMAIL="<email address>" LMS_PASSWORD="
After you install the basic features of the E-Commerce service on your instance of the Open edX platform, you can
enable or install additional features. You can set up E-Commerce to send email, switch payment processors, or track
event data if one of your usual processors is unavailable.
The edX E-Commerce service uses the Communications API that is part of Oscar to create and send notifications in
the form of email messages. To send notifications, you must set up notifications, create one or more email messages,
and then send the email messages.
1. Enable the E-Commerce service to send notifications. To do this, change the value of the
ENABLE_NOTIFICATIONS feature flag to True.
2. Define communication type codes to refer to particular types of notification. For example, you might define a
communication type code named COURSE_SEAT_PURCHASED to correspond to the purchase of a course seat.
The E-Commerce service can send both HTML and plain text email messages. To create an email message, create the
following three files in the ecommerce/ecommerce/templates/customer/emails/ folder.
• An HTML template that extends email_base.html and includes the body of the email.
• A plain text file that contains the email’s subject line.
• A plain text file that contains the body of the email.
Use the following convention to name these files.
commtype_{communication type code}_body.html
39
E-Commerce Service Documentation, Release 0.1
For example, if the communication type code is course_seat_purchased, the three files would have the follow-
ing names.
• commtype_course_seat_purchased_body.html
• commtype_course_seat_purchased_body.txt
• commtype_course_seat_purchased_subject.txt
Note: To add a custom email body, override block body in the email_base.html file. To add a custom footer,
override block footer in the email_base.html file.
To send email messages, use the send_notification(user, commtype_code, context) method. This
method is implemented in ecommerce/ecommerce/notifications/notifications.py.
Warning: As of 8/2019, with the introduction of the Payment microfrontend (MFE), the payment processors can
no longer be enabled or disabled for the frontend as documented below. At this time, CyberSource, Paypal, and
Apple Pay processing is baked into the Payment MFE.
Payment processors/gateways handle the acceptance/validation of payment data–credit cards, wallet payments, etc.–
and transfer of funds from learners to merchants. At edx.org, we use CyberSource to accept credit card payments,
and PayPal to accept PayPal payments (made from either the learner’s PayPal account, bank account, or credit card).
The codebase also contains an integration for Stripe, which supports credit card payments amongst other payment
methods.
If you are interested in supporting another payment processor, reach out to the open source community to determine if
someone has already developed an integration. Otherwise, you may refer to existing integrations as reference points.
All processor secrets are configured via the PAYMENT_PROCESSOR_CONFIG setting. This is a dict that maps partner
short codes to another dict that maps processor names to configuration. These settings are for each site/tenant. In order
to make use of a processor, the processor needs to be activated via the Site Configuration Django admin form. Finally,
there are Waffle flags that can be used to disable payment processors for all tenants in the event of an outage.
Note: The payment processor settings below will be displayed as if they were defined in a Python settings file. Ideally,
you should use the Ansible plays in edx/configuration to generate the settings, however that may not feasible for those
using pre-built systems such as the EC2 images from Bitnami and other providers.
Payment processors must be enabled globally and individually for each site/tenant hosted by your installation. At the
global level, you must specify the Python classes that will be used to process transactions for your processors. Each
of these classes should inherit from xxx.
PAYMENT_PROCESSORS = (
'ecommerce.extensions.payment.processors.cybersource.Cybersource',
'ecommerce.extensions.payment.processors.paypal.Paypal',
)
The secret keys and additional configuration must be specified for each site. The keys of the
PAYMENT_PROCESSOR_CONFIG dict correspond to the short_code field value on the Partner model linked
to each site.
PAYMENT_PROCESSOR_CONFIG = {
'edx': {
'cybersource': {
...
},
'paypal': {
...
},
},
'mitxpro': {
'cybersource': {
...
},
'paypal': {
...
},
},
}
Finally, the payment processors must be activated for each site via Django admin. The Payment processors field
should contain a comma-separated list of payment processor names. These names correspond to the NAME property
of the Python classes.
If you are using the checkout page hosted in the E-Commerce Service (e.g. client-side checkout), you must also
specify the name of the processor to be used for processing credit card transactions. Note that PayPal cannot be used
for these types of payments.
Payment processors sometimes experience temporary outages. When these outages occur, you can use Waffle switches
to disable the faulty payment processor or processors, then re-enable them after the outage is over.
The names of these switches use prefixes that are the value of the PAYMENT_PROCESSOR_SWITCH_PREFIX set-
ting. By default, this value is payment_processor_active_. The following table lists valid switches and the
payment processors they control.
Payment Processor Switch Name Default Value
PayPal payment_processor_active_paypal True
CyberSource payment_processor_active_cybersource True
Stripe payment_processor_active_stripe True
In the unlikely event that all payment processors are disabled, the LMS will display an informative error message
explaining why payment is not currently possible.
Apple Pay allows learners to checkout quickly without having to manually fill out the payment form. If you are
not familiar with Apple Pay, please take a moment to read the following documents to understand the user flow
and necessary configuration. Apple Pay support is only available when using either the CyberSource or Stripe
processors.
• Apple Pay JS
• CyberSource: Apple Pay Using the Simple Order API
• Stripe: Apple Pay on web
Apple Pay is only available to learners using Safari on the following platforms:
Note: The Apple Pay button is not displayed to users with incompatible hardware and software.
Testing
Apple Pay is only available over HTTPS (SSL). If you do not have SSL configured for your local development system,
use a tunnel/proxy application like ngrok to expose your system via publicly-accessible URL with HTTPS. Addition-
ally, when testing with CyberSource, you will need to validate your ngrok domain at Apple.
8.2.4 CyberSource
Our CyberSource integration supports accepting payments via both Silent Order POST and Secure Acceptance
Web/Mobile. (Note that both fall under the product name of “Secure Acceptance”.) We highly recommend using
the Silent Order POST integration as it allows for greater control over the checkout experience via the use of the
custom checkout page in this codebase. Web/Mobile, on the other hand, redirects learners to a checkout page hosted
by CyberSource.
In addition to Secure Acceptance, this processor plugin also makes use of the Simple Order API to facilitate payments
made via Apple Pay and refunds (for all payment methods).
When testing payments with your test profiles, use test card numbers from https://www.cybersource.com/developers/
other_resources/quick_references/test_cc_numbers/.
Settings
Note that “EBC” below refers to the Business Center accessible at one of the two URLs below, depending on the
environment in which you are operating.
• Test: https://ebctest.cybersource.com/ebctest/login/Login.do
• Production: https://ebc.cybersource.com/ebc/login/Login.do
# PAYMENT_PROCESSOR_CANCEL_PATH and PAYMENT_PROCESSOR_ERROR_PATH should come from here
from ecommerce.settings.production import *
PAYMENT_PROCESSOR_CONFIG = {
'edx': {
'cybersource': {
# This is the merchant ID assigned by CyberSource
'merchant_id': '',
# Generate this at EBC: Account Management > Transaction Security Keys >
˓→ SOAP Toolkit API
'transaction_key': '',
# Production: https://ics2wsa.ic3.com/commerce/1.x/transactionProcessor/
˓→CyberSourceTransaction_1.115.wsdl
'soap_api_url': 'https://ics2wstest.ic3.com/commerce/1.x/
˓→transactionProcessor/CyberSourceTransaction_1.115.wsdl',
# Production: https://secureacceptance.cybersource.com/silent/pay
'sop_payment_page_url': 'https://testsecureacceptance.cybersource.com/
˓→silent/pay',
8.2.5 PayPal
The PayPal integration redirects learners to a PayPal checkout page where they can pay with a PayPal balance, bank
transfer, or credit card. Regardless of how the learner pays, the work done by the E-Commerce Service is the same. In
fact, the service doesn’t even know the payment method.
Settings
PAYMENT_PROCESSOR_CONFIG = {
'edx': {
'paypal': {
# Change this to 'live' in production
'mode': 'sandbox',
'client_id': '',
'client_secret': '',
8.2.6 Stripe
The Stripe integration supports payments via credit cards, Apple Pay, Pay with Google, and the Payment Request API
which is a W3C browser standard that provides Apple Pay-like behavior across different browsers. Both payment
methods take advantage of tokenization. Sensitive data–credit card number, card expiration date, CVC–never touches
your servers. Instead this information is relayed directly to Stripe in exchange for a token. This token is sent to the
E-Commerce Service and used to make a final call to Stripe, charging the learner and completing the checkout process.
For additional details regarding Stripe payments, check out the Stripe quickstart guide.
If you wish to use Apple Pay, you must use SSL and verify your domain on your Stripe Dashboard.
Settings
PAYMENT_PROCESSOR_CONFIG = {
'edx': {
'stripe': {
# Get your keys from https://dashboard.stripe.com/account/apikeys.
# Remember to toggle test data to see keys for use with test mode
'publishable_key': '',
'secret_key': '',
Testing
Stripe provides both live and test API keys. Remember to use your test keys when testing. The publishable and secret
keys should be prefixed with pk_test_ and sk_test, respectively.
When in testing mode, you must use test credit card numbers. Test card numbers can be obtained from https://stripe.
com/docs/testing#cards. When testing Apple Pay, Stripe does allow for testing with real cards, so there is no need to
setup a sandbox iCloud account. You will not be charged provided you are using test API keys.
Apple Pay and the Payment Request API require HTTPS. If you do not have SSL configured for your local devel-
opment system, use a tunnel/proxy application like ngrok to expose your system via publicly-accessible URL with
HTTPS. You will also need to register your domain on your Stripe dashboard. Remember to remove the domain after
your testing is complete.
You can release new E-Commerce service features and functionality behind a feature gate. This project uses the Waffle
library for feature gating.
If you want to make a feature permanent, remove its feature gate from relevant code and tests, and delete the gate from
the database.
Most of the time, you do not have to perform maintenance on the E-Commerce service. However, E-Commerce creates
basket objects to track products that users want to purchase before users place an order. As more baskets and orders
are created, the baskets table can grow large. Depending on your database backend, a large table can become difficult
to manage and migrate. After an order is placed, you can delete the corresponding basket from the baskets table.
To delete one or more baskets, follow these steps.
Note: Baskets that contain products but that are not used to create orders, such as when a user adds a product to a
basket but does not complete the order process, are not deleted. These baskets provide records that users intended to
purchase a product.
1. To display the number of baskets that you can delete, run the following command.
$ ./manage.py delete_ordered_baskets
2. To delete all the baskets that appear after you run the command in step 1, use the –commit option.
To complete the procedures that this section describes, you use both the Django administration site and the Course
Administration Tool (CAT). The CAT is a web app that is included with the E-Commerce service. The CAT enables
you to configure and manage products that are associated with the courses on your instance of the Open edX learning
management system (LMS).
In addition to these required steps, you can add optional features to the E-Commerce service for your instance of the
Open edX platform. For more information, see Additional E-Commerce Features.