def get_purchase_params(cart, callback_url=None, extra_data=None): """ This method will build out a dictionary of parameters needed by CyberSource to complete the transaction Args: cart (Order): The order model representing items in the user's cart. Keyword Args: callback_url (unicode): The URL that CyberSource should POST to when the user completes a purchase. If not provided, then CyberSource will use the URL provided by the administrator of the account (CyberSource config, not LMS config). extra_data (list): Additional data to include as merchant-defined data fields. Returns: dict """ total_cost = cart.total_cost amount = "{0:0.2f}".format(total_cost) params = OrderedDict() params["amount"] = amount params["currency"] = cart.currency params["orderNumber"] = "OrderId: {0:d}".format(cart.id) params["access_key"] = get_processor_config().get("ACCESS_KEY", "") params["profile_id"] = get_processor_config().get("PROFILE_ID", "") params["reference_number"] = cart.id params["transaction_type"] = "sale" params["locale"] = "en" params["signed_date_time"] = datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ") params[ "signed_field_names" ] = "access_key,profile_id,amount,currency,transaction_type,reference_number,signed_date_time,locale,transaction_uuid,signed_field_names,unsigned_field_names,orderNumber" params["unsigned_field_names"] = "" params["transaction_uuid"] = uuid.uuid4().hex params["payment_method"] = "card" if callback_url is not None: params["override_custom_receipt_page"] = callback_url params["override_custom_cancel_page"] = callback_url if extra_data is not None: # CyberSource allows us to send additional data in "merchant defined data" fields for num, item in enumerate(extra_data, start=1): key = u"merchant_defined_data{num}".format(num=num) params[key] = item return params
def get_purchase_endpoint(): """ Return the URL of the payment end-point for LiqPay. Returns: unicode """ return get_processor_config().get('PURCHASE_ENDPOINT', '')
def processor_hash(value): """ Performs the base64(HMAC_SHA1(key, value)) used by CyberSource Hosted Order Page """ shared_secret = get_processor_config().get('SHARED_SECRET', '') hash_obj = hmac.new(shared_secret.encode('utf-8'), value.encode('utf-8'), sha1) return binascii.b2a_base64(hash_obj.digest())[:-1] # last character is a '\n', which we don't want
def get_purchase_endpoint(): """ Return the URL of the payment end-point for CyberSource. Returns: unicode """ return get_processor_config().get("PURCHASE_ENDPOINT", "")
def get_purchase_params(cart, callback_url=None): """ This method will build out a dictionary of parameters needed by CyberSource to complete the transaction Args: cart (Order): The order model representing items in the user's cart. Keyword Args: callback_url (unicode): The URL that CyberSource should POST to when the user completes a purchase. If not provided, then CyberSource will use the URL provided by the administrator of the account (CyberSource config, not LMS config). Returns: dict """ total_cost = cart.total_cost amount = "{0:0.2f}".format(total_cost) params = OrderedDict() params['amount'] = amount params['currency'] = cart.currency params['orderNumber'] = "OrderId: {0:d}".format(cart.id) params['access_key'] = get_processor_config().get('ACCESS_KEY', '') params['profile_id'] = get_processor_config().get('PROFILE_ID', '') params['reference_number'] = cart.id params['transaction_type'] = 'sale' params['locale'] = 'en' params['signed_date_time'] = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ') params['signed_field_names'] = 'access_key,profile_id,amount,currency,transaction_type,reference_number,signed_date_time,locale,transaction_uuid,signed_field_names,unsigned_field_names,orderNumber' params['unsigned_field_names'] = '' params['transaction_uuid'] = uuid.uuid4().hex params['payment_method'] = 'card' if callback_url is not None: params['override_custom_receipt_page'] = callback_url params['override_custom_cancel_page'] = callback_url return params
def sign(params, signed_fields_key='orderPage_signedFields', full_sig_key='orderPage_signaturePublic'): """ params needs to be an ordered dict, b/c cybersource documentation states that order is important. Reverse engineered from PHP version provided by cybersource """ merchant_id = get_processor_config().get('MERCHANT_ID', '') order_page_version = get_processor_config().get('ORDERPAGE_VERSION', '7') serial_number = get_processor_config().get('SERIAL_NUMBER', '') params['merchantID'] = merchant_id params['orderPage_timestamp'] = int(time.time() * 1000) params['orderPage_version'] = order_page_version params['orderPage_serialNumber'] = serial_number fields = u",".join(params.keys()) values = u",".join([u"{0}={1}".format(i, params[i]) for i in params.keys()]) fields_sig = processor_hash(fields) values += u",signedFieldsPublicSignature=" + fields_sig params[full_sig_key] = processor_hash(values) params[signed_fields_key] = fields return params
def processor_hash(value): """ Calculate the base64-encoded, SHA-1 hash used by LiqPay. Args: value (string): The value to encode. Returns: string """ secret_key = get_processor_config().get('SECRET_KEY', '') return base64.b64encode(sha1(secret_key + value + secret_key).digest())
def processor_hash(value): """ Calculate the base64-encoded, SHA-256 hash used by CyberSource. Args: value (string): The value to encode. Returns: string """ secret_key = get_processor_config().get("SECRET_KEY", "") hash_obj = hmac.new(secret_key.encode("utf-8"), value.encode("utf-8"), sha256) return binascii.b2a_base64(hash_obj.digest())[:-1] # last character is a '\n', which we don't want
def processor_hash(value): """ Calculate the base64-encoded, SHA-256 hash used by CyberSource. Args: value (string): The value to encode. Returns: string """ private_key = get_processor_config().get('PRIVATE_KEY', None) if not private_key: raise CCProcessorPrivateKeyAbsenceException() return base64.b64encode(sha.new(private_key + value + private_key).digest())
def get_purchase_params(cart, callback_url=None, extra_data=None): """ Just stub for now """ total_cost = cart.total_cost amount = "{0:0.2f}".format(total_cost) params = OrderedDict() params['amount'] = amount params['currency'] = cart.currency params['orderNumber'] = "OrderId: {0:d}".format(cart.id) params['access_key'] = get_processor_config().get('ACCESS_KEY', '') params['profile_id'] = get_processor_config().get('PROFILE_ID', '') params['reference_number'] = cart.id params['transaction_type'] = 'sale' params['locale'] = 'en' params['signed_date_time'] = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ') params['signed_field_names'] = 'access_key,profile_id,amount,currency,transaction_type,reference_number,signed_date_time,locale,transaction_uuid,signed_field_names,unsigned_field_names,orderNumber' params['unsigned_field_names'] = '' params['transaction_uuid'] = uuid.uuid4().hex params['payment_method'] = 'card' params['success'] = True if callback_url is not None: params['override_custom_receipt_page'] = callback_url params['override_custom_cancel_page'] = callback_url if extra_data is not None: # CyberSource allows us to send additional data in "merchant defined data" fields for num, item in enumerate(extra_data, start=1): key = u"merchant_defined_data{num}".format(num=num) params[key] = item return params
def test_site_override_settings(self): self.assertEqual(get_processor_config()['MERCHANT_ID'], 'edx_test_override') self.assertEqual(get_processor_config()['SHARED_SECRET'], 'secret_override')
def get_purchase_endpoint(): return get_processor_config().get('PURCHASE_ENDPOINT', '')
def get_purchase_params(cart, callback_url=None, extra_data=None): """ This method will build out a dictionary of parameters needed by CyberSource to complete the transaction Args: cart (Order): The order model representing items in the user's cart. Keyword Args: callback_url (unicode): The URL that CyberSource should POST to when the user completes a purchase. If not provided, then CyberSource will use the URL provided by the administrator of the account (CyberSource config, not LMS config). extra_data (list): Additional data to include as merchant-defined data fields. Returns: dict """ site_name = microsite.get_value('SITE_NAME', settings.SITE_NAME) total_cost = cart.total_cost amount = "{0:0.2f}".format(total_cost) params = OrderedDict() params['version'] = 3 course = get_course_by_id(SlashSeparatedCourseKey.from_deprecated_string(extra_data[0])) course_name = course.display_name_with_default '{base_url}{dashboard}'.format( base_url=site_name, dashboard=reverse('dashboard')) params['description'] = u'Запис на курс "{course_name}" ({course_num}) | Номер заказу [{course_id}]'.format( course_name=course_name, course_num=extra_data[0], course_id=cart.id ) params['amount'] = amount params['currency'] = "uah" params['orderNumber'] = "OrderId: {0:d}".format(cart.id) params['signed_date_time'] = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ') params['course_id'] = extra_data[0] params['course_name'] = course_name params['public_key'] = get_processor_config().get('PUBLIC_KEY', '') params['type'] = 'buy' params['language'] = 'ru' # params['signed_date_time'] = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ') if callback_url is not None: params['server_url'] = callback_url params['server_url'] = get_processor_config().get('SERVER_URL', 'https://59065b71.ngrok.com/shoppingcart/postpay_callback/') params['result_url'] = '{base_url}{dashboard}'.format( base_url=site_name, dashboard=reverse('dashboard')) if get_processor_config().get('SANDBOX') or course_name == "sandbox": params['sandbox'] = 1 if callback_url is not None: params['override_custom_receipt_page'] = callback_url params['override_custom_cancel_page'] = callback_url if extra_data is not None: # LiqPay allows us to send additional data in "merchant defined data" fields for num, item in enumerate(extra_data, start=1): key = u"merchant_defined_data{num}".format(num=num) params[key] = item return params
def test_site_no_override_settings(self): self.assertEqual(get_processor_config()['MERCHANT_ID'], 'edx_test') self.assertEqual(get_processor_config()['SHARED_SECRET'], 'secret')
def get_purchase_endpoint(): return get_processor_config().get('PURCHASE_ENDPOINT', '')