Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
cf9d4277
Commit
cf9d4277
authored
Aug 09, 2013
by
Jason Bau
Committed by
Diana Huang
Aug 21, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
factor out cybersource processor from cart
parent
ab1452cb
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
141 additions
and
82 deletions
+141
-82
lms/djangoapps/shoppingcart/models.py
+2
-1
lms/djangoapps/shoppingcart/processors/CyberSource.py
+82
-0
lms/djangoapps/shoppingcart/processors/__init__.py
+34
-0
lms/djangoapps/shoppingcart/views.py
+5
-68
lms/envs/aws.py
+1
-1
lms/envs/common.py
+10
-6
lms/templates/shoppingcart/cybersource_form.html
+6
-0
lms/templates/shoppingcart/list.html
+1
-6
No files found.
lms/djangoapps/shoppingcart/models.py
View file @
cf9d4277
...
...
@@ -4,6 +4,7 @@ from datetime import datetime
from
django.db
import
models
from
django.core.exceptions
import
ObjectDoesNotExist
from
django.contrib.auth.models
import
User
from
courseware.courses
import
course_image_url
,
get_course_about_section
from
student.views
import
course_from_id
from
student.models
import
CourseEnrollmentAllowed
,
CourseEnrollment
from
statsd
import
statsd
...
...
@@ -152,7 +153,7 @@ class PaidCourseRegistration(OrderItem):
item
.
qty
=
1
item
.
unit_cost
=
cost
item
.
line_cost
=
cost
item
.
line_desc
=
"Registration for Course {0}"
.
format
(
course_id
)
item
.
line_desc
=
'Registration for Course: {0}'
.
format
(
get_course_about_section
(
course
,
"title"
)
)
item
.
currency
=
currency
item
.
save
()
return
item
...
...
lms/djangoapps/shoppingcart/processors/CyberSource.py
0 → 100644
View file @
cf9d4277
### Implementation of support for the Cybersource Credit card processor
### The name of this file should be used as the key of the dict in the CC_PROCESSOR setting
import
time
import
hmac
import
binascii
from
collections
import
OrderedDict
from
hashlib
import
sha1
from
django.conf
import
settings
from
mitxmako.shortcuts
import
render_to_string
shared_secret
=
settings
.
CC_PROCESSOR
[
'CyberSource'
]
.
get
(
'SHARED_SECRET'
,
''
)
merchant_id
=
settings
.
CC_PROCESSOR
[
'CyberSource'
]
.
get
(
'MERCHANT_ID'
,
''
)
serial_number
=
settings
.
CC_PROCESSOR
[
'CyberSource'
]
.
get
(
'SERIAL_NUMBER'
,
''
)
orderPage_version
=
settings
.
CC_PROCESSOR
[
'CyberSource'
]
.
get
(
'ORDERPAGE_VERSION'
,
'7'
)
purchase_endpoint
=
settings
.
CC_PROCESSOR
[
'CyberSource'
]
.
get
(
'PURCHASE_ENDPOINT'
,
''
)
def
hash
(
value
):
"""
Performs the base64(HMAC_SHA1(key, value)) used by CyberSource Hosted Order Page
"""
hash_obj
=
hmac
.
new
(
shared_secret
,
value
,
sha1
)
return
binascii
.
b2a_base64
(
hash_obj
.
digest
())[:
-
1
]
# last character is a '\n', which we don't want
def
sign
(
params
):
"""
params needs to be an ordered dict, b/c cybersource documentation states that order is important.
Reverse engineered from PHP version provided by cybersource
"""
params
[
'merchantID'
]
=
merchant_id
params
[
'orderPage_timestamp'
]
=
int
(
time
.
time
()
*
1000
)
params
[
'orderPage_version'
]
=
orderPage_version
params
[
'orderPage_serialNumber'
]
=
serial_number
fields
=
","
.
join
(
params
.
keys
())
values
=
","
.
join
([
"{0}={1}"
.
format
(
i
,
params
[
i
])
for
i
in
params
.
keys
()])
fields_sig
=
hash
(
fields
)
values
+=
",signedFieldsPublicSignature="
+
fields_sig
params
[
'orderPage_signaturePublic'
]
=
hash
(
values
)
params
[
'orderPage_signedFields'
]
=
fields
return
params
def
verify
(
params
):
"""
Verify the signatures accompanying the POST back from Cybersource Hosted Order Page
"""
signed_fields
=
params
.
get
(
'signedFields'
,
''
)
.
split
(
','
)
data
=
","
.
join
([
"{0}={1}"
.
format
(
k
,
params
.
get
(
k
,
''
))
for
k
in
signed_fields
])
signed_fields_sig
=
hash
(
params
.
get
(
'signedFields'
,
''
))
data
+=
",signedFieldsPublicSignature="
+
signed_fields_sig
returned_sig
=
params
.
get
(
'signedDataPublicSignature'
,
''
)
if
not
returned_sig
:
return
False
return
hash
(
data
)
==
returned_sig
def
render_purchase_form_html
(
cart
,
user
):
total_cost
=
cart
.
total_cost
amount
=
"{0:0.2f}"
.
format
(
total_cost
)
cart_items
=
cart
.
orderitem_set
.
all
()
params
=
OrderedDict
()
params
[
'comment'
]
=
'Stanford OpenEdX Purchase'
params
[
'amount'
]
=
amount
params
[
'currency'
]
=
cart
.
currency
params
[
'orderPage_transactionType'
]
=
'sale'
params
[
'orderNumber'
]
=
"{0:d}"
.
format
(
cart
.
id
)
params
[
'billTo_email'
]
=
user
.
email
idx
=
1
for
item
in
cart_items
:
prefix
=
"item_{0:d}_"
.
format
(
idx
)
params
[
prefix
+
'productSKU'
]
=
"{0:d}"
.
format
(
item
.
id
)
params
[
prefix
+
'quantity'
]
=
item
.
qty
params
[
prefix
+
'productName'
]
=
item
.
line_desc
params
[
prefix
+
'unitPrice'
]
=
item
.
unit_cost
params
[
prefix
+
'taxAmount'
]
=
"0.00"
signed_param_dict
=
sign
(
params
)
return
render_to_string
(
'shoppingcart/cybersource_form.html'
,
{
'action'
:
purchase_endpoint
,
'params'
:
signed_param_dict
,
})
\ No newline at end of file
lms/djangoapps/shoppingcart/processors/__init__.py
0 → 100644
View file @
cf9d4277
from
django.conf
import
settings
### Now code that determines, using settings, which actual processor implementation we're using.
processor_name
=
settings
.
CC_PROCESSOR
.
keys
()[
0
]
module
=
__import__
(
'shoppingcart.processors.'
+
processor_name
,
fromlist
=
[
'sign'
,
'verify'
,
'render_purchase_form_html'
])
def
sign
(
*
args
,
**
kwargs
):
"""
Given a dict (or OrderedDict) of parameters to send to the
credit card processor, signs them in the manner expected by
the processor
Returns a dict containing the signature
"""
return
module
.
sign
(
*
args
,
**
kwargs
)
def
verify
(
*
args
,
**
kwargs
):
"""
Given a dict (or OrderedDict) of parameters to returned by the
credit card processor, verifies them in the manner specified by
the processor
Returns a boolean
"""
return
module
.
sign
(
*
args
,
**
kwargs
)
def
render_purchase_form_html
(
*
args
,
**
kwargs
):
"""
Given a shopping cart,
Renders the HTML form for display on user's browser, which POSTS to Hosted Processors
Returns the HTML as a string
"""
return
module
.
render_purchase_form_html
(
*
args
,
**
kwargs
)
lms/djangoapps/shoppingcart/views.py
View file @
cf9d4277
import
logging
import
random
import
time
import
hmac
import
binascii
from
hashlib
import
sha1
from
collections
import
OrderedDict
from
django.conf
import
settings
from
django.http
import
HttpResponse
,
HttpResponseRedirect
from
django.views.decorators.csrf
import
csrf_exempt
from
django.contrib.auth.decorators
import
login_required
from
mitxmako.shortcuts
import
render_to_response
from
.models
import
*
from
.processors
import
verify
,
render_purchase_form_html
log
=
logging
.
getLogger
(
"shoppingcart"
)
shared_secret
=
settings
.
CYBERSOURCE
.
get
(
'SHARED_SECRET'
,
''
)
merchant_id
=
settings
.
CYBERSOURCE
.
get
(
'MERCHANT_ID'
,
''
)
serial_number
=
settings
.
CYBERSOURCE
.
get
(
'SERIAL_NUMBER'
,
''
)
orderPage_version
=
settings
.
CYBERSOURCE
.
get
(
'ORDERPAGE_VERSION'
,
'7'
)
def
test
(
request
,
course_id
):
item1
=
PaidCourseRegistration
(
course_id
,
200
)
item1
.
purchased_callback
(
request
.
user
.
id
)
...
...
@@ -47,26 +35,11 @@ def show_cart(request):
total_cost
=
cart
.
total_cost
amount
=
"{0:0.2f}"
.
format
(
total_cost
)
cart_items
=
cart
.
orderitem_set
.
all
()
params
=
OrderedDict
()
params
[
'comment'
]
=
'Stanford OpenEdX Purchase'
params
[
'amount'
]
=
amount
params
[
'currency'
]
=
cart
.
currency
params
[
'orderPage_transactionType'
]
=
'sale'
params
[
'orderNumber'
]
=
"{0:d}"
.
format
(
cart
.
id
)
params
[
'billTo_email'
]
=
request
.
user
.
email
idx
=
1
for
item
in
cart_items
:
prefix
=
"item_{0:d}_"
.
format
(
idx
)
params
[
prefix
+
'productSKU'
]
=
"{0:d}"
.
format
(
item
.
id
)
params
[
prefix
+
'quantity'
]
=
item
.
qty
params
[
prefix
+
'productName'
]
=
item
.
line_desc
params
[
prefix
+
'unitPrice'
]
=
item
.
unit_cost
params
[
prefix
+
'taxAmount'
]
=
"0.00"
signed_param_dict
=
cybersource_sign
(
params
)
form_html
=
render_purchase_form_html
(
cart
,
request
.
user
)
return
render_to_response
(
"shoppingcart/list.html"
,
{
'shoppingcart_items'
:
cart_items
,
'amount'
:
amount
,
'
params'
:
signed_param_dict
,
'
form_html'
:
form_html
,
})
@login_required
...
...
@@ -89,47 +62,11 @@ def remove_item(request):
@csrf_exempt
def
receipt
(
request
):
"""
Receives the POST-back from
Cybersource
and performs the validation and displays a receipt
Receives the POST-back from
processor
and performs the validation and displays a receipt
and does some other stuff
"""
if
cybersource_verify
(
request
.
POST
):
if
verify
(
request
.
POST
.
dict
()
):
return
HttpResponse
(
"Validated"
)
else
:
return
HttpResponse
(
"Not Validated"
)
def
cybersource_hash
(
value
):
"""
Performs the base64(HMAC_SHA1(key, value)) used by CyberSource Hosted Order Page
"""
hash_obj
=
hmac
.
new
(
shared_secret
,
value
,
sha1
)
return
binascii
.
b2a_base64
(
hash_obj
.
digest
())[:
-
1
]
# last character is a '\n', which we don't want
def
cybersource_sign
(
params
):
"""
params needs to be an ordered dict, b/c cybersource documentation states that order is important.
Reverse engineered from PHP version provided by cybersource
"""
params
[
'merchantID'
]
=
merchant_id
params
[
'orderPage_timestamp'
]
=
int
(
time
.
time
()
*
1000
)
params
[
'orderPage_version'
]
=
orderPage_version
params
[
'orderPage_serialNumber'
]
=
serial_number
fields
=
","
.
join
(
params
.
keys
())
values
=
","
.
join
([
"{0}={1}"
.
format
(
i
,
params
[
i
])
for
i
in
params
.
keys
()])
fields_sig
=
cybersource_hash
(
fields
)
values
+=
",signedFieldsPublicSignature="
+
fields_sig
params
[
'orderPage_signaturePublic'
]
=
cybersource_hash
(
values
)
params
[
'orderPage_signedFields'
]
=
fields
return
params
def
cybersource_verify
(
params
):
signed_fields
=
params
.
get
(
'signedFields'
,
''
)
.
split
(
','
)
data
=
","
.
join
([
"{0}={1}"
.
format
(
k
,
params
.
get
(
k
,
''
))
for
k
in
signed_fields
])
signed_fields_sig
=
cybersource_hash
(
params
.
get
(
'signedFields'
,
''
))
data
+=
",signedFieldsPublicSignature="
+
signed_fields_sig
returned_sig
=
params
.
get
(
'signedDataPublicSignature'
,
''
)
if
not
returned_sig
:
return
False
return
cybersource_hash
(
data
)
==
returned_sig
lms/envs/aws.py
View file @
cf9d4277
...
...
@@ -191,7 +191,7 @@ if SEGMENT_IO_LMS_KEY:
MITX_FEATURES
[
'SEGMENT_IO_LMS'
]
=
ENV_TOKENS
.
get
(
'SEGMENT_IO_LMS'
,
False
)
C
YBERSOURCE
=
AUTH_TOKENS
.
get
(
'CYBERSOURCE'
,
CYBERSOURCE
)
C
C_PROCESSOR
=
AUTH_TOKENS
.
get
(
'CC_PROCESSOR'
,
CC_PROCESSOR
)
SECRET_KEY
=
AUTH_TOKENS
[
'SECRET_KEY'
]
...
...
lms/envs/common.py
View file @
cf9d4277
...
...
@@ -431,12 +431,16 @@ ZENDESK_URL = None
ZENDESK_USER
=
None
ZENDESK_API_KEY
=
None
##### CyberSource Payment parameters #####
CYBERSOURCE
=
{
'SHARED_SECRET'
:
''
,
'MERCHANT_ID'
:
''
,
'SERIAL_NUMBER'
:
''
,
'ORDERPAGE_VERSION'
:
'7'
,
##### shoppingcart Payment #####
##### Using cybersource by default #####
CC_PROCESSOR
=
{
'CyberSource'
:
{
'SHARED_SECRET'
:
''
,
'MERCHANT_ID'
:
''
,
'SERIAL_NUMBER'
:
''
,
'ORDERPAGE_VERSION'
:
'7'
,
'PURCHASE_ENDPOINT'
:
''
,
}
}
################################# open ended grading config #####################
...
...
lms/templates/shoppingcart/cybersource_form.html
0 → 100644
View file @
cf9d4277
<form
action=
"${action}"
method=
"post"
>
% for pk, pv in params.iteritems():
<input
type=
"hidden"
name=
"${pk}"
value=
"${pv}"
/>
% endfor
<input
type=
"submit"
value=
"Check Out"
/>
</form>
lms/templates/shoppingcart/list.html
View file @
cf9d4277
...
...
@@ -25,12 +25,7 @@
</tbody>
</table>
<form
action=
"https://orderpagetest.ic3.com/hop/orderform.jsp"
method=
"post"
>
% for pk, pv in params.iteritems():
<input
type=
"hidden"
name=
"${pk}"
value=
"${pv}"
/>
% endfor
<input
type=
"submit"
value=
"Check Out"
/>
</form>
${form_html}
% else:
<p>
You have selected no items for purchase.
</p>
% endif
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment