def testSimpleRequiresChoices(self): v = config_value('BASE', 'rc1') self.assertEqual(v, ['c1']) g = config_get_group('req2') keys = [cfg.key for cfg in g] self.assertEqual(keys, ['c1', 'c3']) c = config_get('BASE', 'rc1') c.update(['c1', 'c2']) g = config_get_group('req2') keys = [cfg.key for cfg in g] self.assertEqual(keys, ['c1', 'c2', 'c3'])
def testRequiresValue(self): v = config_value('BASE', 'valchoices') self.assertEquals(v, ['foo']) g = config_get_group('reqval') keys = [cfg.key for cfg in g] self.assertEqual(keys, ['c1', 'c3']) c = config_get('BASE', 'valchoices') c.update(['foo', 'bar']) g = config_get_group('reqval') keys = [cfg.key for cfg in g] self.assertEqual(keys, ['c1', 'c2', 'c3'])
def testRequiresValue(self): v = config_value('BASE', 'valchoices') self.assertEqual(v, ['foo']) g = config_get_group('reqval') keys = [cfg.key for cfg in g] self.assertEqual(keys, ['c1', 'c3']) c = config_get('BASE', 'valchoices') c.update(['foo', 'bar']) g = config_get_group('reqval') keys = [cfg.key for cfg in g] self.assertEqual(keys, ['c1', 'c2', 'c3'])
def payment_label(group): """convert a payment key into its translated text""" if not group.startswith('PAYMENT_'): group = "PAYMENT_" + group.upper() config = config_get_group(group) label = translation.ugettext(config.LABEL.value) return label.capitalize()
def new_shipper(self, single_box=True): """ Creates a new Shipper instance, make sure that you set-up your livesettings.functions for this module. """ service_type = ('FEDEX_GROUND', 'Fedex Ground Shipping') settings = config_get_group('shipping.modules.fedex_web_services') CONFIG_OBJ = get_config_obj(settings) packaging = settings.PACKAGING.value or "YOUR_PACKAGING" default_weight = settings.DEFAULT_ITEM_WEIGHT.value or 0.5 default_weight_units = settings.DEFAULT_WEIGHT_UNITS.value single_box = single_box verbose_log = settings.VERBOSE_LOG.value dropoff_type = settings.DROPOFF_TYPE.value shipper = Shipper( service_type=service_type, config=CONFIG_OBJ, packaging=packaging, default_weight=default_weight, default_weight_units=default_weight_units, single_box=single_box, verbose_log=verbose_log, dropoff_type=dropoff_type) return shipper
def google_checkout_image_url(parser, token): """ Render the url for a google checkout image. Sample usage:: {% google_checkout_image_url [imagesize] ['transparent'] ['disabled'] %} """ args = token.split_contents() payment_module = config_get_group('PAYMENT_GOOGLE') merchid = payment_module.MERCHANT_ID sizes = CHECKOUT_BUTTON_SIZES.keys() imgsize = "MEDIUM" transparent = False disabled = False locale = None for arg in args[1:]: k = arg.upper() if k == 'TRANSPARENT': transparent = True elif k == 'DISABLED': disabled = True else: if k in sizes: imgsize = k else: raise template.TemplateSyntaxError("%r tag got an unexpected argument. Perhaps a bad size? Didn't know: %s" % (args[0], arg)) return GoogleCheckoutImageUrlNode(merchid, imgsize, transparent, disabled)
def google_checkout_image_url(parser, token): """ Render the url for a google checkout image. Sample usage:: {% google_checkout_image_url [imagesize] ['transparent'] ['disabled'] %} """ args = token.split_contents() payment_module = config_get_group('PAYMENT_GOOGLE') merchid = payment_module.MERCHANT_ID sizes = CHECKOUT_BUTTON_SIZES.keys() imgsize = "MEDIUM" transparent = False disabled = False locale = None for arg in args[1:]: k = arg.upper() if k == 'TRANSPARENT': transparent = True elif k == 'DISABLED': disabled = True else: if k in sizes: imgsize = k else: raise template.TemplateSyntaxError( "%r tag got an unexpected argument. Perhaps a bad size? Didn't know: %s" % (args[0], arg)) return GoogleCheckoutImageUrlNode(merchid, imgsize, transparent, disabled)
def one_step(request): payment_module = config_get_group('PAYMENT_AUTOSUCCESS') #First verify that the customer exists try: contact = Contact.objects.from_request(request, create=False) except Contact.DoesNotExist: url = lookup_url(payment_module, 'satchmo_checkout-step1') return HttpResponseRedirect(url) #Verify we still have items in the cart tempCart = Cart.objects.from_request(request) if tempCart.numItems == 0: template = lookup_template(payment_module, 'shop/checkout/empty_cart.html') return render_to_response(template, context_instance=RequestContext(request)) # Create a new order newOrder = Order(contact=contact) pay_ship_save(newOrder, tempCart, contact, shipping="", discount="", notes="") request.session['orderID'] = newOrder.id processor = get_processor_by_key('PAYMENT_AUTOSUCCESS') processor.prepare_data(newOrder) payment = processor.process(newOrder) tempCart.empty() success = lookup_url(payment_module, 'satchmo_checkout-success') return HttpResponseRedirect(success)
def one_step(request): payment_module = config_get_group('PAYMENT_AUTOSUCCESS') #First verify that the customer exists try: contact = Contact.objects.from_request(request, create=False) except Contact.DoesNotExist: url = lookup_url(payment_module, 'satchmo_checkout-step1') return HttpResponseRedirect(url) #Verify we still have items in the cart tempCart = Cart.objects.from_request(request) if tempCart.numItems == 0: template = lookup_template(payment_module, 'shop/checkout/empty_cart.html') return render(request, template) # Create a new order newOrder = Order(contact=contact) pay_ship_save(newOrder, tempCart, contact, shipping="", discount="", notes="") request.session['orderID'] = newOrder.id processor = get_processor_by_key('PAYMENT_AUTOSUCCESS') processor.prepare_data(newOrder) payment = processor.process(newOrder) tempCart.empty() success = lookup_url(payment_module, 'satchmo_checkout-success') return HttpResponseRedirect(success)
def register(request, redirect=None, template='registration/registration_form.html'): """ Allows a new user to register an account. """ ret = register_handle_form(request, redirect) success = ret[0] todo = ret[1] if len(ret) > 2: extra_context = ret[2] else: extra_context = {} if success: return todo else: if config_get_group('NEWSLETTER'): show_newsletter = True else: show_newsletter = False ctx = { 'form': todo, 'title': _('Registration Form'), 'show_newsletter': show_newsletter, 'allow_nickname': config_value('SHOP', 'ALLOW_NICKNAME_USERNAME') } if extra_context: ctx.update(extra_context) return render(request, template, ctx)
def register(request, redirect=None, template='registration/registration_form.html'): """ Allows a new user to register an account. """ ret = register_handle_form(request, redirect) success = ret[0] todo = ret[1] if len(ret) > 2: extra_context = ret[2] else: extra_context = {} if success: return todo else: if config_get_group('NEWSLETTER'): show_newsletter = True else: show_newsletter = False ctx = { 'form': todo, 'title' : _('Registration Form'), 'show_newsletter' : show_newsletter, 'allow_nickname' : config_value('SHOP', 'ALLOW_NICKNAME_USERNAME') } if extra_context: ctx.update(extra_context) context = RequestContext(request, ctx) return render_to_response(template, context_instance=context)
def new_shipper(self, single_box=True): """ Creates a new Shipper instance, make sure that you set-up your livesettings for this module. """ service_type = ('FEDEX_GROUND', 'Fedex Ground Shipping') settings = config_get_group('shipping.modules.fedex_web_services') CONFIG_OBJ = get_config_obj(settings) packaging = settings.PACKAGING.value or "YOUR_PACKAGING" default_weight = settings.DEFAULT_ITEM_WEIGHT.value or 0.5 default_weight_units = settings.DEFAULT_WEIGHT_UNITS.value single_box = single_box verbose_log = settings.VERBOSE_LOG.value dropoff_type = settings.DROPOFF_TYPE.value shipper = Shipper( service_type=service_type, config=CONFIG_OBJ, packaging=packaging, default_weight=default_weight, default_weight_units=default_weight_units, single_box=single_box, verbose_log=verbose_log, dropoff_type=dropoff_type) return shipper
def notify_callback(request): payment_module = config_get_group('PAYMENT_SERMEPA') if payment_module.LIVE.value: log.debug("Live IPN on %s", payment_module.KEY.value) signature_code = payment_module.MERCHANT_SIGNATURE_CODE.value terminal = payment_module.MERCHANT_TERMINAL.value else: log.debug("Test IPN on %s", payment_module.KEY.value) signature_code = payment_module.MERCHANT_TEST_SIGNATURE_CODE.value terminal = payment_module.MERCHANT_TEST_TERMINAL.value data = request.POST log.debug("Transaction data: " + repr(data)) try: sig_data = "%s%s%s%s%s%s" % ( data['Ds_Amount'], data['Ds_Order'], data['Ds_MerchantCode'], data['Ds_Currency'], data['Ds_Response'], signature_code) sig_calc = sha1(sig_data).hexdigest() if sig_calc != data['Ds_Signature'].lower(): log.error("Invalid signature. Received '%s', calculated '%s'." % (data['Ds_Signature'], sig_calc)) return HttpResponseBadRequest("Checksum error") if data['Ds_MerchantCode'] != payment_module.MERCHANT_FUC.value: log.error("Invalid FUC code: %s" % data['Ds_MerchantCode']) return HttpResponseNotFound("Unknown FUC code") if int(data['Ds_Terminal']) != int(terminal): log.error("Invalid terminal number: %s" % data['Ds_Terminal']) return HttpResponseNotFound("Unknown terminal number") # TODO: fields Ds_Currency, Ds_SecurePayment may be worth checking xchg_order_id = data['Ds_Order'] try: order_id = xchg_order_id[:xchg_order_id.index('T')] except ValueError: log.error("Incompatible order ID: '%s'" % xchg_order_id) return HttpResponseNotFound("Order not found") try: order = Order.objects.get(id=order_id) except Order.DoesNotExist: log.error("Received data for nonexistent Order #%s" % order_id) return HttpResponseNotFound("Order not found") amount = Decimal(data['Ds_Amount']) / Decimal( '100') # is in cents, divide it if int(data['Ds_Response']) > 100: log.info("Response code is %s. Payment not accepted." % data['Ds_Response']) return HttpResponse() except KeyError: log.error("Received incomplete SERMEPA transaction data") return HttpResponseBadRequest("Incomplete data") # success order.add_status(status='New', notes=u"Paid through SERMEPA.") processor = get_processor_by_key('PAYMENT_SERMEPA') payment = processor.record_payment( order=order, amount=amount, transaction_id=data['Ds_AuthorisationCode']) # empty customer's carts for cart in Cart.objects.filter(customer=order.contact): cart.empty() return HttpResponse()
def notify_neworder(request, data): """ Called when google reports a new order. Looks up the order from the private data and sets the status. Empties the cart. """ # get params from data private_data = data['shopping-cart.merchant-private-data'] order_id = re.search('satchmo-order id="(\d+)"', private_data).group(1) order = Order.objects.get(pk=order_id) payment_module = config_get_group('PAYMENT_GOOGLE') processor = get_processor_by_key('PAYMENT_GOOGLE') # record pending payment amount = data['order-total'] pending_payment = processor.create_pending_payment(order) # save transaction id so we can find this order later pending_payment.capture.transaction_id = data['google-order-number'] pending_payment.capture.save() # delete cart for cart in Cart.objects.filter(customer=order.contact): cart.empty() cart.delete() # set status order.add_status(status='New', notes=_("Received through Google Checkout."))
def get_methods(): settings = config_get_group('shipping.modules.fedex_web_services') if not settings.ACCOUNT.value: log.warn("No fedex account found in settings") return if not settings.METER_NUMBER.value: log.warn("No fedex meter number found in settings") return if not settings.AUTHENTICATION_KEY.value: log.warn("No fedex authentication key found in settings") return if not settings.AUTHENTICATION_PASSWORD.value: log.warn("No fedex authentication password found in settings") return CONFIG_OBJ = get_config_obj(settings) packaging = settings.PACKAGING.value or "YOUR_PACKAGING" default_weight = settings.DEFAULT_ITEM_WEIGHT.value or 0.5 default_weight_units = settings.DEFAULT_WEIGHT_UNITS.value single_box = settings.SINGLE_BOX.value verbose_log = settings.VERBOSE_LOG.value dropoff_type = settings.DROPOFF_TYPE.value return [ shipper.Shipper( service_type=value, config=CONFIG_OBJ, packaging=packaging, default_weight=default_weight, default_weight_units=default_weight_units, single_box=single_box, verbose_log=verbose_log, dropoff_type=dropoff_type) for value in config_choice_values( 'shipping.modules.fedex_web_services', 'SHIPPING_CHOICES') ]
def confirm_info(request, template='shop/checkout/sagepay/confirm.html', extra_context={}): payment_module = config_get_group('PAYMENT_SAGEPAY') controller = confirm.ConfirmController(request, payment_module) controller.templates['CONFIRM'] = template controller.extra_context = extra_context controller.onForm = secure3d_form_handler controller.confirm() return controller.response
def get_processor_by_key(key): """ Returns an instance of a payment processor, referred to by *key*. :param key: A string of the form 'PAYMENT_<PROCESSOR_NAME>'. """ payment_module = config_get_group(key) processor_module = payment_module.MODULE.load_module('processor') return processor_module.PaymentProcessor(payment_module)
def cost(self): """ Complex calculations can be done here as long as the return value is a decimal figure """ assert(self._calculated) settings = config_get_group('shipping.modules.ups') if settings.HANDLING_FEE and Decimal(str(settings.HANDLING_FEE)) > Decimal(0): self.charges = Decimal(self.charges) + Decimal(str(settings.HANDLING_FEE)) return(Decimal(self.charges))
def order_payment_methods(order): """ Returns a list of payment method labels for an order. Usage:: {{ order|order_payment_methods|join:", " }} """ return (config_get_group('PAYMENT_%s' % p.payment).LABEL.value for p in order.payments.all())
def checkout_image_url(merchid, imgsize, locale, transparent=False, disabled=False): payment_module = config_get_group('PAYMENT_GOOGLE') dimensions = CHECKOUT_BUTTON_SIZES[imgsize] return ("%s?%s" % ( payment_module.CHECKOUT_BUTTON_URL, urlencode((('merchant_id', merchid), ('w', dimensions[0]), ('h', dimensions[1]), ('style', _truefalse(transparent, t="trans", f="white")), ('variant', _truefalse(disabled, t="disabled", f="text")), ('loc', locale)))))
def gateway_live(settings): if is_string_like(settings): settings = config_get_group(settings) try: if config_value('PAYMENT', 'LIVE'): return settings['LIVE'].value except SettingNotSet: pass return False
def render_template(self, template, cart=None, contact=None): from satchmo_store.shop.models import Config shop_details = Config.objects.get_current() settings = config_get_group('shipping.modules.usps') if not self.is_intl: mail_type = CODES[self.service_type_code] if mail_type == 'INTL': return '' if mail_type == 'FIRST CLASS': self.api = None else: self.api = APIS[mail_type] else: mail_type = None self.api = None # calculate the weight of the entire order weight = Decimal('0.0') for item in cart.cartitem_set.all(): if item.product.smart_attr('weight'): weight += item.product.smart_attr('weight') * item.quantity self.verbose_log('WEIGHT: %s' % weight) # I don't know why USPS made this one API different this way... if self.api == 'ExpressMailCommitment': zip_ending = 'ZIP' else: zip_ending = 'zip' # get the shipping country (for the international orders) ship_country = contact.shipping_address.country.printable_name configuration = { 'userid': settings.USER_ID.value, 'password': settings.USER_PASSWORD.value, 'container': settings.SHIPPING_CONTAINER.value, 'ship_type': mail_type, 'shop_details': shop_details } c = Context({ 'config': configuration, 'cart': cart, 'contact': contact, 'is_international': self.is_intl, 'api': self.api, 'weight': weight, 'zip': zip_ending, 'country': ship_country, 'first_class_types': ['LETTER', 'FLAT', 'PARCEL'] }) t = loader.get_template(template) return t.render(c)
def __init__(self, cart=None, contact=None, service_type=None): """ Initialize a Shipper for a given service type """ if service_type: self.service_code, self.service_text = service_type else: self.service_code = "BAD.CODE" self.service_text = "Uninitialized" self.id = "canadapost-dev-prog-{}".format(self.service_code) self.settings = config_get_group('canada_post_dp_shipping') super(Shipper, self).__init__(cart=cart, contact=contact)
def get_cred(): payment_module = config_get_group('PAYMENT_GOOGLE') live = gateway_live(payment_module) # get key and value if live: merchant_id = payment_module.MERCHANT_ID.value merchant_key = payment_module.MERCHANT_KEY.value else: merchant_id = payment_module.MERCHANT_TEST_ID.value merchant_key = payment_module.MERCHANT_TEST_KEY.value return (merchant_id, merchant_key)
def get_url(): """ Returns the urls needed """ (merchant_id, merchant_key) = get_cred() payment_module = config_get_group('PAYMENT_GOOGLE') live = gateway_live(payment_module) if live: url_template = payment_module.POST_URL.value else: url_template = payment_module.POST_TEST_URL.value post_url = url_template % {'MERCHANT_ID': merchant_id} return post_url
def get_url(): """ Returns the urls needed """ (merchant_id, merchant_key) = get_cred() payment_module = config_get_group('PAYMENT_GOOGLE') live = gateway_live(payment_module) if live: url_template = payment_module.POST_URL.value else: url_template = payment_module.POST_TEST_URL.value post_url = url_template % {'MERCHANT_ID' : merchant_id} return post_url
def confirm_secure3d( request, secure3d_template='shop/checkout/sagepay/secure3d_form.html', confirm_template='shop/checkout/confirm.html', extra_context={}): """Handles confirming an order and processing the charges when secured by secure3d. """ payment_module = config_get_group('PAYMENT_SAGEPAY') controller = confirm.ConfirmController(request, payment_module, extra_context=extra_context) controller.template['CONFIRM'] = confirm_template if not controller.sanity_check(): return controller.response auth3d = request.session.get('3D', None) if not auth3d: controller.processorMessage = _( '3D Secure transaction expired. Please try again.') else: if request.method == "POST": returnMD = request.POST.get('MD', None) if not returnMD: template = lookup_template(payment_module, secure3d_template) return render(request, template, { 'order': controller.order, 'auth': auth3d }) elif returnMD == auth3d['MD']: pares = request.POST.get('PaRes', None) controller.processor.prepare_data(controller.order) controller.processor.prepare_data3d(returnMD, pares) if controller.process(): return controller.onSuccess(controller) else: controller.processorMessage = _( '3D Secure transaction was not approved by payment gateway. Please contact us.' ) else: template = lookup_template(payment_module, secure3d_template) return render(request, template, { 'order': controller.order, 'auth': auth3d }) return secure3d_form_handler(controller)
def checkout_image_url(merchid, imgsize, locale, transparent=False, disabled=False): payment_module = config_get_group('PAYMENT_GOOGLE') dimensions = CHECKOUT_BUTTON_SIZES[imgsize] return ("%s?%s" % (payment_module.CHECKOUT_BUTTON_URL, urlencode( (('merchant_id', merchid), ('w', dimensions[0]), ('h', dimensions[1]), ('style', _truefalse(transparent, t="trans", f="white")), ('variant', _truefalse(disabled, t="disabled", f="text")), ('loc', locale)))))
def form_valid(self, form): contact = self.get_contact() new_data = self.request.POST.copy() tempCart = self.get_cart() if contact is None and self.request.user \ and self.request.user.is_authenticated: contact = Contact(user=self.request.user) custID = form.save(self.request, cart=tempCart, contact=contact) self.request.session[CUSTOMER_ID] = custID modulename = new_data['paymentmethod'] if not modulename.startswith('PAYMENT_'): modulename = 'PAYMENT_' + modulename paymentmodule = config_get_group(modulename) url = lookup_url(paymentmodule, 'satchmo_checkout-step2') self._success_url = url return super(CheckoutForm, self).form_valid(form)
def form_valid(self, form): contact = self.get_contact() new_data = self.request.POST.copy() tempCart = self.get_cart() if contact is None and self.request.user \ and self.request.user.is_authenticated(): contact = Contact(user=self.request.user) custID = form.save(self.request, cart=tempCart, contact=contact) self.request.session[CUSTOMER_ID] = custID modulename = new_data['paymentmethod'] if not modulename.startswith('PAYMENT_'): modulename = 'PAYMENT_' + modulename paymentmodule = config_get_group(modulename) url = lookup_url(paymentmodule, 'satchmo_checkout-step2') self._success_url = url return super(CheckoutForm, self).form_valid(form)
def confirm_secure3d(request, secure3d_template='shop/checkout/sagepay/secure3d_form.html', confirm_template='shop/checkout/confirm.html', extra_context={}): """Handles confirming an order and processing the charges when secured by secure3d. """ payment_module = config_get_group('PAYMENT_SAGEPAY') controller = confirm.ConfirmController(request, payment_module, extra_context=extra_context) controller.template['CONFIRM'] = confirm_template if not controller.sanity_check(): return controller.response auth3d = request.session.get('3D', None) if not auth3d: controller.processorMessage = _('3D Secure transaction expired. Please try again.') else: if request.method == "POST": returnMD = request.POST.get('MD', None) if not returnMD: template = lookup_template(payment_module, secure3d_template) ctx = RequestContext(request, {'order': controller.order, 'auth': auth3d }) return render_to_response(template, context_instance=ctx) elif returnMD == auth3d['MD']: pares = request.POST.get('PaRes', None) controller.processor.prepare_data(controller.order) controller.processor.prepare_data3d(returnMD, pares) if controller.process(): return controller.onSuccess(controller) else: controller.processorMessage = _('3D Secure transaction was not approved by payment gateway. Please contact us.') else: template = lookup_template(payment_module, secure3d_template) ctx =RequestContext(request, { 'order': controller.order, 'auth': auth3d }) return render_to_response(template, context_instance=ctx) return secure3d_form_handler(controller)
def get_methods(): settings = config_get_group('shipping.modules.fedex_web_services') if not settings.ACCOUNT.value: log.warn("No fedex account found in settings") return if not settings.METER_NUMBER.value: log.warn("No fedex meter number found in settings") return if not settings.AUTHENTICATION_KEY.value: log.warn("No fedex authentication key found in settings") return if not settings.AUTHENTICATION_PASSWORD.value: log.warn("No fedex authentication password found in settings") return CONFIG_OBJ = get_config_obj(settings) packaging = settings.PACKAGING.value or "YOUR_PACKAGING" default_weight = settings.DEFAULT_ITEM_WEIGHT.value or 0.5 default_weight_units = settings.DEFAULT_WEIGHT_UNITS.value single_box = settings.SINGLE_BOX.value verbose_log = settings.VERBOSE_LOG.value dropoff_type = settings.DROPOFF_TYPE.value return [ shipper.Shipper(service_type=value, config=CONFIG_OBJ, packaging=packaging, default_weight=default_weight, default_weight_units=default_weight_units, single_box=single_box, verbose_log=verbose_log, dropoff_type=dropoff_type) for value in config_choice_values( 'shipping.modules.fedex_web_services', 'SHIPPING_CHOICES') ]
def balance_remaining(request): """Allow the user to pay the remaining balance.""" order = None orderid = request.session.get('orderID') if orderid: try: order = Order.objects.get(pk=orderid) except Order.DoesNotExist: # TODO: verify user against current user pass if not order: url = urlresolvers.reverse('satchmo_checkout-step1') return HttpResponseRedirect(url) if request.method == "POST": new_data = request.POST.copy() form = PaymentMethodForm(data=new_data, order=order) if form.is_valid(): data = form.cleaned_data modulename = data['paymentmethod'] if not modulename.startswith('PAYMENT_'): modulename = 'PAYMENT_' + modulename paymentmodule = config_get_group(modulename) url = lookup_url(paymentmodule, 'satchmo_checkout-step2') return HttpResponseRedirect(url) else: form = PaymentMethodForm(order=order) ctx = RequestContext(request, {'form' : form, 'order' : order, 'paymentmethod_ct': len(active_gateways()) }) return render_to_response('shop/checkout/balance_remaining.html', context_instance=ctx)
def confirm_info(request): payment_module = config_get_group('PAYMENT_GOOGLE') controller = confirm.ConfirmController(request, payment_module) if not controller.sanity_check(): return controller.response live = gateway_live(payment_module) gcart = GoogleCart(controller.order, payment_module, live) log.debug("CART:\n%s", gcart.cart_xml) post_url = auth.get_url() default_view_tax = config_value('TAX', 'DEFAULT_VIEW_TAX') ctx = { 'post_url': post_url, 'google_cart' : gcart.encoded_cart(), 'google_signature' : gcart.encoded_signature(), 'PAYMENT_LIVE' : live } controller.extra_context = ctx controller.confirm() return controller.response
def confirm_info(request): payment_module = config_get_group('PAYMENT_GOOGLE') controller = confirm.ConfirmController(request, payment_module) if not controller.sanity_check(): return controller.response live = gateway_live(payment_module) gcart = GoogleCart(controller.order, payment_module, live) log.debug("CART:\n%s", gcart.cart_xml) post_url = auth.get_url() default_view_tax = config_value('TAX', 'DEFAULT_VIEW_TAX') ctx = { 'post_url': post_url, 'google_cart': gcart.encoded_cart(), 'google_signature': gcart.encoded_signature(), 'PAYMENT_LIVE': live } controller.extra_context = ctx controller.confirm() return controller.response
def balance_remaining(request): """Allow the user to pay the remaining balance.""" order = None orderid = request.session.get('orderID') if orderid: try: order = Order.objects.get(pk=orderid) except Order.DoesNotExist: # TODO: verify user against current user pass if not order: url = urlresolvers.reverse('satchmo_checkout-step1') return HttpResponseRedirect(url) if request.method == "POST": new_data = request.POST.copy() form = PaymentMethodForm(data=new_data, order=order) if form.is_valid(): data = form.cleaned_data modulename = data['paymentmethod'] if not modulename.startswith('PAYMENT_'): modulename = 'PAYMENT_' + modulename paymentmodule = config_get_group(modulename) url = lookup_url(paymentmodule, 'satchmo_checkout-step2') return HttpResponseRedirect(url) else: form = PaymentMethodForm(order=order) ctx = {'form' : form, 'order' : order, 'paymentmethod_ct': len(active_gateways()) } return render(request, 'shop/checkout/balance_remaining.html', ctx)
def login_signup(request, template_name="contact/login_signup.html", registration_handler=register_handle_form, handler_kwargs = {}): """Display/handle a combined login and create account form""" redirect_to = request.REQUEST.get(REDIRECT_FIELD_NAME, '') handler_kwargs['redirect'] = redirect_to loginform = None createform = None extra_context = {} if request.POST: action = request.POST.get('action', 'login') if action == 'create': #log.debug('Signup form') ret = registration_handler(request, **handler_kwargs) success = ret[0] todo = ret[1] if len(ret) > 2: extra_context = ret[2] if success: #log.debug('Successful %s form submit, sending to reg complete page') if redirect_to: return HttpResponseRedirect(redirect_to) else: ctx = RequestContext(request, { REDIRECT_FIELD_NAME: redirect_to, }) return render_to_response('registration/registration_complete.html', context_instance=ctx) else: createform = todo else: #log.debug('Login form') success, todo = _login(request, redirect_to) if success: return todo else: loginform = todo request.POST = QueryDict("") else: request.session.set_test_cookie() if not loginform: success, loginform = _login(request, redirect_to) if not createform: ret = registration_handler(request, **handler_kwargs) success = ret[0] createform = ret[1] if len(ret) > 2: extra_context = ret[2] site = Site.objects.get_current() if config_get_group('NEWSLETTER'): show_newsletter = True else: show_newsletter = False ctx = { 'loginform': loginform, 'createform' : createform, REDIRECT_FIELD_NAME: redirect_to, 'site_name': site.name, 'show_newsletter' : show_newsletter, } if extra_context: ctx.update(extra_context) context = RequestContext(request, ctx) return render_to_response(template_name, context_instance=context)
def _verify_feedback(request, order, params): ''' Extract the payment feedback parameters from the request and update the order accordingly Returns a string in case of error, None otherwise ''' # Calculate the sha1 digest to make sure the parameters haven't been # tempered with payment_module = config_get_group('PAYMENT_CONCARDIS') passphrase = payment_module.SHA_OUT_PASSPHRASE.value digest = sha1_sign(params, passphrase) if digest and (digest != request.GET.get('SHASIGN')): log.info('Invalid SHASIGN for order %s, got "%s", expected: "%s"', order, digest, request.GET.get('SHASIGN')) return _('Unexpected parameters when processing request, please ' 'contact [email protected].') pay_id = params['PAYID'] amount = params['AMOUNT'] # If the payment hasn't already been processed: if not OrderPayment.objects.filter(transaction_id=pay_id).count(): processor = get_processor_by_key('PAYMENT_CONCARDIS') status, status_verbose = get_payment_status(params) kwargs = { 'order': order, 'amount': amount, 'transaction_id': pay_id, 'reason_code': status_verbose, } if status.startswith('9'): order.add_status(status='New', notes=_('Paid through Concardis')) processor.record_payment(**kwargs) elif status.startswith('5'): processor.record_authorization(**kwargs) else: processor.record_failure(**kwargs) # Save the payment parameters if order.notes: notes = order.notes + '\n' else: notes = '' notes += '--- Concardis payment parameters ---\n' for key, val in params.items(): notes += '{}: {}\n'.format(key, val) order.notes = notes order.save() # Added to track total sold for each product for item in order.orderitem_set.all(): product = item.product product.total_sold += item.quantity if config_value('PRODUCT', 'TRACK_INVENTORY'): product.items_in_stock -= item.quantity product.save() # Clean up cart now, the rest of the order will be cleaned on paypal IPN for cart in Cart.objects.filter(customer=order.contact): cart.empty()
def confirm_info(request): return confirm.credit_confirm_info(request, config_get_group('PAYMENT_PAYFLOWPRO'))
"""Simple wrapper for standard checkout as implemented in payment.views""" from django import http from forms import PurchaseorderPayShipForm from livesettings.functions import config_get_group from payment.views import confirm, payship from satchmo_utils.dynamic import lookup_url import logging log = logging.getLogger('purchaseorder.views') settings = config_get_group('PAYMENT_PURCHASEORDER') def pay_ship_info(request): return payship.base_pay_ship_info( request, settings, purchaseorder_process_form, 'shop/checkout/purchaseorder/pay_ship.html') def confirm_info(request): return confirm.credit_confirm_info( request, settings, template='shop/checkout/purchaseorder/confirm.html') def purchaseorder_process_form(request, contact, working_cart, payment_module, allow_skip): log.debug('purchaseorder_process_form') if request.method == "POST": log.debug('handling POST') new_data = request.POST.copy()
def pay_ship_info(request): return payship.credit_pay_ship_info(request, config_get_group('PAYMENT_PAYFLOWPRO'))
def calculate(self, cart, contact): """ Based on the chosen UPS method, we will do our call to UPS and see how much it will cost. We will also need to store the results for further parsing and return via the methods above """ from satchmo_store.shop.models import Config settings = config_get_group('shipping.modules.ups') self.delivery_days = _("3 - 4") #Default setting for ground delivery shop_details = Config.objects.get_current() # Get the code and description for the packaging container = settings.SHIPPING_CONTAINER.value container_description = settings.SHIPPING_CONTAINER.choices[int( container)][1] configuration = { 'xml_key': settings.XML_KEY.value, 'account': settings.ACCOUNT.value, 'userid': settings.USER_ID.value, 'password': settings.USER_PASSWORD.value, 'container': container, 'container_description': container_description, 'pickup': settings.PICKUP_TYPE.value, 'ship_type': self.service_type_code, 'shop_details': shop_details, } shippingdata = { 'single_box': False, 'config': configuration, 'contact': contact, 'cart': cart, 'shipping_address': shop_details, 'shipping_phone': shop_details.phone, 'shipping_country_code': shop_details.country.iso2_code } if settings.SINGLE_BOX.value: log.debug("Using single-box method for ups calculations.") box_weight = Decimal("0.00") for product in cart.get_shipment_list(): if product.smart_attr('weight') is None: log.warn( "No weight on product (skipping for ship calculations): %s", product) else: box_weight += product.smart_attr('weight') if product.smart_attr('weight_units') and product.smart_attr( 'weight_units') != "": box_weight_units = product.smart_attr('weight_units') else: log.warn("No weight units for product") if box_weight < Decimal("0.1"): log.debug("Total box weight too small, defaulting to 0.1") box_weight = Decimal("0.1") shippingdata['single_box'] = True shippingdata['box_weight'] = '%.1f' % box_weight shippingdata['box_weight_units'] = box_weight_units.upper() total_weight = 0 for product in cart.get_shipment_list(): try: total_weight += product.smart_attr('weight') except TypeError: pass signals.shipping_data_query.send(Shipper, shipper=self, cart=cart, shippingdata=shippingdata) c = Context(shippingdata) t = loader.get_template('shipping/ups/request.xml') request = t.render(c) self.is_valid = False if settings.LIVE.value: connection = settings.CONNECTION.value else: connection = settings.CONNECTION_TEST.value cachekey = cache_key( 'UPS_SHIP', #service_type = self.service_type_code, weight=str(total_weight), country=shop_details.country.iso2_code, zipcode=contact.shipping_address.postal_code) try: tree = cache_get(cachekey) except NotCachedError: tree = None if tree is not None: self.verbose_log('Got UPS info from cache [%s]', cachekey) else: self.verbose_log("Requesting from UPS [%s]\n%s", cachekey, request) cache_set(cachekey, value=request, length=600) tree = self._process_request(connection, request) self.verbose_log("Got from UPS [%s]:\n%s", cachekey, self.raw) cache_set(cachekey, value=tree) try: status_code = tree.getiterator('ResponseStatusCode') status_val = status_code[0].text self.verbose_log("UPS Status Code for cart #%s = %s", int(cart.id), status_val) except AttributeError: status_val = "-1" if status_val == '1': self.is_valid = False self._calculated = False all_rates = tree.getiterator('RatedShipment') for response in all_rates: if self.service_type_code == response.find( './/Service/Code').text: self.charges = response.find( './/TotalCharges/MonetaryValue').text if response.find('.//GuaranteedDaysToDelivery').text: self.delivery_days = response.find( './/GuaranteedDaysToDelivery').text self.is_valid = True self._calculated = True if not self.is_valid: self.verbose_log("UPS Cannot find rate for code: %s [%s]", self.service_type_code, self.service_type_text) else: self.is_valid = False self._calculated = False try: errors = tree.find('.//Error') log.info("UPS %s Error: Code %s - %s" % (errors[0].text, errors[1].text, errors[2].text)) except AttributeError: log.info("UPS error - cannot parse response:\n %s", self.raw) if self.is_valid and settings.TIME_IN_TRANSIT.value: self.verbose_log('Now getting time in transit for cart') self.time_in_transit(contact, cart)
def pay_ship_info(request): return payship.credit_pay_ship_info(request, config_get_group('PAYMENT_SAGEPAY'), template="shop/checkout/sagepay/pay_ship.html")
def __init__(self, *args, **kwargs): super(OrderShippingAdmin, self).__init__(*args, **kwargs) self.settings = config_get_group('canada_post_dp_shipping')
def ups_time_in_transit(self, contact, pickup_date=None, price=None, test=False): """Calculate est delivery days for a zipcode, from Store Zipcode""" from satchmo_store.shop.models import Config delivery_days = None if pickup_date is None: pickup_date = timezone.now() + timezone.timedelta(days=1) # UPS doesn't pick up on weekends if pickup_date.day == 5: pickup_date += timezone.timedelta(days=2) if pickup_date.day == 6: pickup_date += timezone.timedelta(days=1) if price is None: price = Decimal('10.0') shipaddr = contact.shipping_address shop_details = Config.objects.get_current() settings = config_get_group('shipping.modules.ups') configuration = { 'xml_key': settings.XML_KEY.value, 'account': settings.ACCOUNT.value, 'userid': settings.USER_ID.value, 'password': settings.USER_PASSWORD.value, 'container': settings.SHIPPING_CONTAINER.value, 'pickup': settings.PICKUP_TYPE.value, 'shop_details': shop_details, } shippingdata = { 'config': configuration, 'zipcode': shipaddr.postal_code, 'contact': contact, 'shipping_address': shop_details, 'shipping_phone': shop_details.phone, 'shipping_country_code': shop_details.country.iso2_code, 'pickup_date': pickup_date.strftime('%Y%m%d'), 'price': "%.2f" % price } c = Context(shippingdata) t = loader.get_template('shipping/ups/transit_request.xml') request = t.render(c) if settings.LIVE.value and not test: connection = 'https://wwwcie.ups.com/ups.app/xml/TimeInTransit' else: connection = 'https://onlinetools.ups.com/ups.app/xml/TimeInTransit' cachekey = cache_key("UPS-TIT", shipaddr.postal_code, pickup_date.strftime('%Y%m%d'), "%.2f" % price) try: ups = cache_get(cachekey) except NotCachedError: ups = None if ups is None: log.debug('Requesting from UPS: %s\n%s', connection, request) conn = urllib.request.Request(url=connection, data=request.encode("utf-8")) f = urllib.request.urlopen(conn) all_results = f.read() self.verbose_log("Received from UPS:\n%s", all_results) ups = fromstring(all_results) needs_cache = True else: needs_cache = False ok = False try: ok = ups.find('Response/ResponseStatusCode').text == '1' except AttributeError: log.warning('Bad response from UPS TimeInTransit') pass if not ok: try: response = ups.find('Response/ResponseStatusDescription').text log.warning('Bad response from UPS TimeInTransit: %s', response) except AttributeError: log.warning('Unknown UPS TimeInTransit response') if ok: services = ups.findall('TransitResponse/ServiceSummary') for service in services: transit_code = service.find('Service/Code').text if self.service_type_code == TRANSIT_CODE_MAP.get( transit_code, ''): try: delivery_days = service.find( 'EstimatedArrival/BusinessTransitDays').text self.verbose_log('Found delivery days %s for %s', delivery_days, self.service_type_code) except AttributeError: log.warning( 'Could not find BusinessTransitDays in UPS response' ) try: delivery_days = int(delivery_days) except ValueError: pass break if delivery_days is not None and needs_cache: cache_set(cachekey, value=ups, length=600) return delivery_days
settingsl = settings_module.split('.') settings = __import__(settings_module, {}, {}, settingsl[-1]) sampleOrder = testOrder() sampleOrder.id = '1234' sampleOrder.contact.first_name = 'Chris' sampleOrder.contact.last_name = 'Smith' sampleOrder.contact.primary_phone = '801-555-9242' sampleOrder.contact.email = '*****@*****.**' sampleOrder.full_bill_street = '123 Main Street' sampleOrder.bill_postal_code = '12345' sampleOrder.bill_state = 'TN' sampleOrder.bill_city = 'Some City' sampleOrder.bill_country = 'US' sampleOrder.total = "27.00" sampleOrder.balance = "27.00" sampleOrder.credit_card.decryptedCC = '6011000000000012' sampleOrder.credit_card.expirationDate = "10/09" sampleOrder.credit_card.ccv = "144" cybersource_settings = config_get_group('PAYMENT_CYBERSOURCE') if cybersource_settings.LIVE.value: print "Warning. You are submitting a live order. CYBERSOURCE system is set LIVE." processor = PaymentProcessor(cybersource_settings) processor.prepare_data(sampleOrder) results = processor.process(testing=True) print results
from django.utils.translation import ugettext_lazy as _ from livesettings.values import StringValue,DecimalValue from livesettings.functions import config_register_list,config_get,config_get_group SHIP_MODULES = config_get('SHIPPING', 'MODULES') SHIP_MODULES.add_choice(('shipping.modules.flat', _('Flat rate'))) SHIPPING_GROUP = config_get_group('SHIPPING') config_register_list( DecimalValue(SHIPPING_GROUP, 'FLAT_RATE', description=_("Flat shipping"), requires=SHIP_MODULES, requiresvalue='shipping.modules.flat', default="4.00"), StringValue(SHIPPING_GROUP, 'FLAT_SERVICE', description=_("Flat Shipping Service"), help_text=_("Shipping service used with Flat rate shipping"), requires=SHIP_MODULES, requiresvalue='shipping.modules.flat', default=u"U.S. Mail"), StringValue(SHIPPING_GROUP, 'FLAT_DAYS', description=_("Flat Delivery Days"), requires=SHIP_MODULES, requiresvalue='shipping.modules.flat', default="3 - 4 business days")
# of its contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY ESO ``AS IS'' AND ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO # EVENT SHALL ESO BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER # IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE from django.conf.urls import url from livesettings.functions import config_get_group from payment.views.checkout import success from djangoplicity.coposweb.views import confirm_info, pay_ship_info config = config_get_group('PAYMENT_COPOSWEB') urlpatterns = [ url(r'^$', pay_ship_info, {'SSL': config.SSL.value}, 'COPOSWEB_satchmo_checkout-step2'), url(r'^confirm/$', confirm_info, {'SSL': config.SSL.value}, 'COPOSWEB_satchmo_checkout-step3'), url(r'^success/$', success, {'SSL': config.SSL.value}, 'COPOSWEB_satchmo_checkout-success'), ]
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE """ Simple wrapper for standard checkout as implemented in payment.views """ from django.http import HttpResponseRedirect from django.views.decorators.cache import never_cache from livesettings.functions import config_get_group from payment.views import confirm, payship from satchmo_store.shop.models import Order from satchmo_utils.dynamic import lookup_url coposweb = config_get_group( 'PAYMENT_COPOSWEB' ) def pay_ship_info( request ): payment_module = coposweb # Copied from payship.base_pay_ship_info results = payship.pay_ship_info_verify( request, payment_module ) if not results[0]: return results[1] contact = results[1] working_cart = results[2] # Check if there's anything to pay
"""Simple wrapper for standard checkout as implemented in payment.views""" from django.views.decorators.cache import never_cache from livesettings.functions import config_get_group from payment.views import confirm, payship dummy = config_get_group('PAYMENT_DUMMY') def pay_ship_info(request): return payship.credit_pay_ship_info(request, dummy) pay_ship_info = never_cache(pay_ship_info) def confirm_info(request): return confirm.credit_confirm_info(request, dummy) confirm_info = never_cache(confirm_info)
def pay_ship_info(request): return payship.simple_pay_ship_info(request, config_get_group('PAYMENT_GOOGLE'), 'shop/checkout/google/pay_ship.html')
"""Simple wrapper for standard checkout as implemented in payment.views""" from django import http from livesettings.functions import config_get_group from payment.views import confirm, payship from satchmo_utils.dynamic import lookup_url from .forms import PurchaseorderPayShipForm import logging log = logging.getLogger('purchaseorder.views') settings = config_get_group('PAYMENT_PURCHASEORDER') def pay_ship_info(request): return payship.base_pay_ship_info( request, settings, purchaseorder_process_form, 'shop/checkout/purchaseorder/pay_ship.html') def confirm_info(request): return confirm.credit_confirm_info( request, settings, template='shop/checkout/purchaseorder/confirm.html') def purchaseorder_process_form(request, contact, working_cart, payment_module, allow_skip): log.debug('purchaseorder_process_form') if request.method == "POST": log.debug('handling POST') new_data = request.POST.copy()