Commits

Bruce Kroeze  committed 6cffdfe

preparing the remaining gateways

  • Participants
  • Parent commits 803420c

Comments (0)

Files changed (21)

File bursar/gateway/cybersource_gateway/config.py

-from livesettings import *
-from django.utils.translation import ugettext_lazy as _
-
-# this is so that the translation utility will pick up the string
-gettext = lambda s: s
-_strings = (gettext('CreditCard'), gettext('Credit Card'))
-
-PAYMENT_GROUP = ConfigurationGroup('PAYMENT_CYBERSOURCE', 
-    _('Cybersource.net Payment Settings'), 
-    ordering=102)
-
-config_register_list(
-
-    StringValue(PAYMENT_GROUP, 
-        'CONNECTION',
-        description=_("WSDL URL"),
-        help_text=_("""This is the address to submit live transactions."""),
-        default='https://ics2ws.ic3.com/commerce/1.x/transactionProcessor/CyberSourceTransaction_1.26.wsdl'),
-
-    StringValue(PAYMENT_GROUP, 
-        'CONNECTION_TEST',
-        description=_("Submit to Test WSDL URL"),
-        help_text=("""This is the address to submit test transactions"""),
-        default='https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor/CyberSourceTransaction_1.26.wsdl'),
-
-    BooleanValue(PAYMENT_GROUP, 
-        'SSL', 
-        description=_("Use SSL for the checkout pages?"), 
-        default=False),
-    
-    BooleanValue(PAYMENT_GROUP, 
-        'LIVE', 
-        description=_("Accept real payments"),
-        help_text=_("False if you want to be in test mode"),
-        default=False),
-    
-    ModuleValue(PAYMENT_GROUP,
-        'MODULE',
-        description=_('Implementation module'),
-        hidden=True,
-        default = 'payment.modules.cybersource'),
-    
-    StringValue(PAYMENT_GROUP,
-        'KEY',
-        description=_("Module key"),
-        hidden=True,
-        default = 'CYBERSOURCE'),
-
-    StringValue(PAYMENT_GROUP,
-        'LABEL',
-        description=_('English name for this group on the checkout screens'),
-        default = 'Credit Cards',
-        help_text = _('This will be passed to the translation utility')),
-        
-    StringValue(PAYMENT_GROUP,
-        'CURRENCY_CODE',
-        description=_('Currency Code'),
-        help_text=_('Currency code for Cybersource transactions.'),
-        default = 'USD'),
-        
-    StringValue(PAYMENT_GROUP,
-        'URL_BASE',
-        description=_('The url base used for constructing urlpatterns which will use this module'),
-        default = r'^credit/'),
-
-    MultipleStringValue(PAYMENT_GROUP,
-        'CREDITCHOICES',
-        description=_('Available credit cards'),
-        choices = (
-            (('American Express', 'American Express')),
-            (('Visa','Visa')),
-            (('Mastercard','Mastercard')),
-            (('Discover','Discover'))),
-        default = ('Visa', 'Mastercard', 'Discover')),
-    
-    StringValue(PAYMENT_GROUP, 
-        'MERCHANT_ID', 
-        description=_('Your Cybersource merchant ID'),
-        default=""),
-    
-    LongStringValue(PAYMENT_GROUP, 
-        'TRANKEY', 
-        description=_('Your Cybersource transaction key'),
-        default=""),
-        
-    BooleanValue(PAYMENT_GROUP,
-        'EXTRA_LOGGING',
-        description=_("Verbose logs"),
-        help_text=_("Add extensive logs during post."),
-        default=False)
-)

File bursar/gateway/cybersource_gateway/tests.py

Empty file added.

File bursar/gateway/cybersource_gateway/urls.py

-from django.conf.urls.defaults import *
-from livesettings import config_value, config_get_group
-
-config = config_get_group('PAYMENT_CYBERSOURCE')
-
-urlpatterns = patterns('',
-     (r'^$', 'payment.modules.cybersource.views.pay_ship_info', {'SSL':config.SSL.value}, 'CYBERSOURCE_satchmo_checkout-step2'),
-     (r'^confirm/$', 'payment.modules.cybersource.views.confirm_info', {'SSL':config.SSL.value}, 'CYBERSOURCE_satchmo_checkout-step3'),
-     (r'^success/$', 'payment.views.checkout.success', {'SSL':config.SSL.value}, 'CYBERSOURCE_satchmo_checkout-success'),
-)

File bursar/gateway/google_gateway/config.py

-from livesettings import *
-from django.utils.translation import ugettext_lazy as _
-
-# this is so that the translation utility will pick up the string
-gettext = lambda s: s
-
-PAYMENT_GROUP = ConfigurationGroup('PAYMENT_GOOGLE', 
-    _('Google Checkout Module Settings'), 
-    ordering = 101)
-
-config_register_list(
-
-    StringValue(PAYMENT_GROUP,
-        'CART_XML_TEMPLATE',
-        description=_("XML Template"),
-        help_text=_("The XML template to use when submitting to Google. Probably you should not change this."),
-        default = "payment/google/cart.xml"),
-    
-    StringValue(PAYMENT_GROUP,
-        'CURRENCY_CODE',
-        description=_('Currency Code'),
-        help_text=_('Currency code for Google Checkout transactions.'),
-        default = 'USD'),
-    
-    StringValue(PAYMENT_GROUP,
-        'CHECKOUT_BUTTON_URL',
-        description=_('Checkout Button URL'),
-        default="http://checkout.google.com/buttons/checkout.gif"),
-        
-    StringValue(PAYMENT_GROUP,
-        'CHECKOUT_BUTTON_SIZE',
-        description=_('Checkout Button Size'),
-        choices=(
-            ('SMALL', _('Small')), 
-            ('MEDIUM', _('Medium')), 
-            ('LARGE', _('Large'))),
-        default='MEDIUM'),
-    
-    StringValue(PAYMENT_GROUP,
-        'POST_URL',
-        description=_('Post URL'),
-        help_text=_('The Google URL for real transaction posting.'),
-        default="https://checkout.google.com/cws/v2/Merchant/%(MERCHANT_ID)s/checkout"),
-
-    StringValue(PAYMENT_GROUP,
-        'POST_TEST_URL',
-        description=_('Post URL'),
-        help_text=_('The Google URL for test transaction posting.'),
-        default="https://sandbox.google.com/payment/cws/v2/Merchant/%(MERCHANT_ID)s/checkout"),
-
-    StringValue(PAYMENT_GROUP,
-        'MERCHANT_ID',
-        description=_('Merchant ID'),
-        default=""),
-
-    StringValue(PAYMENT_GROUP,
-        'MERCHANT_KEY',
-        description=_('Merchant Key'),
-        default=""),
-
-    StringValue(PAYMENT_GROUP,
-        'MERCHANT_TEST_ID',
-        description=_('Merchant Test ID'),
-        default=""),
-
-    StringValue(PAYMENT_GROUP,
-        'MERCHANT_TEST_KEY',
-        description=_('Merchant Test Key'),
-        default=""),
-    
-    BooleanValue(PAYMENT_GROUP, 
-        'SSL', 
-        description=_("Use SSL for the module checkout pages?"), 
-        default=False),
-        
-    BooleanValue(PAYMENT_GROUP, 
-        'LIVE', 
-        description=_("Accept real payments"),
-        help_text=_("False if you want to be in test mode"),
-        default=False),
-        
-    ModuleValue(PAYMENT_GROUP,
-        'MODULE',
-        description=_('Implementation module'),
-        hidden=True,
-        default = 'payment.modules.google'),
-        
-    StringValue(PAYMENT_GROUP,
-        'KEY',
-        description=_("Module key"),
-        hidden=True,
-        default = 'GOOGLE'),
-
-    StringValue(PAYMENT_GROUP,
-        'LABEL',
-        description=_('English name for this group on the checkout screens'),
-        default = 'Google Checkout',
-        help_text = _('This will be passed to the translation utility')),
-
-    StringValue(PAYMENT_GROUP,
-        'URL_BASE',
-        description=_('The url base used for constructing urlpatterns which will use this module'),
-        default = '^google/'),
-        
-    BooleanValue(PAYMENT_GROUP,
-        'EXTRA_LOGGING',
-        description=_("Verbose logs"),
-        help_text=_("Add extensive logs during post."),
-        default=False)
-
-)
-
-PAYMENT_GROUP['TEMPLATE_OVERRIDES'] = {
-    'payment/confirm.html' : 'payment/google/confirm.html',
-}

File bursar/gateway/google_gateway/readme.txt

-To enable the Google checkout module, at the google checkout dashboard put in your the notification url, which by default is https://www.example.com/checkout/google/notification/
-
-Google checkout calls back this url with notifications on the order and payment status.
-
-After a user submits their cart it calls back the notification url with new order received message.
-
-Then after payment google calls back with a payment charged and a seperate payment amount method. This will update the order status and mark how much was paid in satchmo.
-
-Then to post off the item, from the google checkout console mark it as shipped and another call back into the notification url will change the status in satchmo to delivered.

File bursar/gateway/google_gateway/tests.py

Empty file added.

File bursar/gateway/google_gateway/urls.py

-from django.conf.urls.defaults import *
-from livesettings import config_get_group
-
-config = config_get_group('PAYMENT_GOOGLE')
-
-urlpatterns = patterns('',
-     (r'^$', 'payment.modules.google.views.pay_ship_info', {'SSL': config.SSL.value}, 'GOOGLE_satchmo_checkout-step2'),
-     (r'^confirm/$', 'payment.modules.google.views.confirm_info', {'SSL': config.SSL.value}, 'GOOGLE_satchmo_checkout-step3'),
-     (r'^success/$', 'payment.modules.google.views.success', {'SSL': config.SSL.value}, 'GOOGLE_satchmo_checkout-success'),
-     (r'^notification/$', 'payment.modules.google.views.notification', {'SSL': config.SSL.value},
-        'GOOGLE_satchmo_checkout-notification'),
-     (r'^confirmorder/$', 'payment.views.confirm.confirm_free_order', 
-        {'SSL' : config.SSL.value, 'key' : 'GOOGLE'}, 'GOOGLE_satchmo_checkout_free-confirm')
-)

File bursar/gateway/google_gateway/views.py

-from django import http
-from django.shortcuts import render_to_response
-from django.template import Context, RequestContext
-from django.template.loader import get_template
-from django.utils.translation import ugettext as _
-from django.views.decorators.cache import never_cache
-from livesettings import config_get_group, config_value
-from payment.config import gateway_live
-from payment.views import confirm, payship
-from satchmo_store.shop.models import Order
-from satchmo_utils.dynamic import lookup_url
-from satchmo_utils.views import bad_or_missing
-import auth
-import base64
-import hmac
-import logging
-import notifications
-import sha
-
-# TODO: This module doesn't seem to actually record any payments.
-
-log = logging.getLogger("payment.modules.google.processor")
-
-class GoogleCart(object):
-    def __init__(self, order, gateway_settings, live):
-        self.settings = gateway_settings
-        self.cart_xml = self._cart_xml(order)
-        self.signature = self._signature(live)
-
-    def _cart_xml(self, order):
-        template = get_template(self.settings["CART_XML_TEMPLATE"].value)
-
-        shopping_url = lookup_url(self.settings, 'satchmo_checkout-success', True, self.settings.SSL.value)
-        edit_url = lookup_url(self.settings, 'satchmo_cart', True, self.settings.SSL.value)
-        ctx = Context({"order" : order,
-                       "continue_shopping_url" : shopping_url,
-                       "edit_cart_url" : edit_url,
-                       "currency" : self.settings.CURRENCY_CODE.value,
-                       })
-        return template.render(ctx)
-
-    def _signature(self, live):
-        if live:
-            merchkey = self.settings.MERCHANT_KEY.value
-        else:
-            merchkey = self.settings.MERCHANT_TEST_KEY.value
-
-        s = hmac.new(merchkey, self.cart_xml, sha)
-        rawsig = s.digest()
-        return rawsig
-
-    def encoded_cart(self):
-        return base64.encodestring(self.cart_xml)[:-1]
-
-    def encoded_signature(self):
-        sig = base64.encodestring(self.signature)[:-1]
-        log.debug("Sig is: %s", sig)
-        return sig
-
-@never_cache
-def pay_ship_info(request):
-    return payship.simple_pay_ship_info(request, config_get_group('PAYMENT_GOOGLE'), 'payment/google/pay_ship.html')
-
-@never_cache
-def confirm_info(request):
-    gateway_settings = config_get_group('PAYMENT_GOOGLE')
-
-    controller = confirm.ConfirmController(request, gateway_settings)
-    if not controller.sanity_check():
-        return controller.response
-
-    live = gateway_live(gateway_settings)
-    gcart = GoogleCart(controller.order, gateway_settings, 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(),
-        'gateway_live' : live
-    }
-
-    controller.extra_context = ctx
-    controller.confirm()
-    return controller.response
-
-@never_cache
-def notification(request):
-    """
-    View to receive notifications from google about order status
-    """
-    data = request.POST
-    log.debug(data)
-    
-    # check the given merchant id
-    log.debug("Google Checkout Notification")
-    response = auth.do_auth(request)
-    if response:
-        return response
-    
-    # ok its authed, get the type and serial
-    type = data['_type']
-    serial_number = data['serial-number'].strip()
-    
-    log.debug("type: %s" % type)
-    log.debug("serial-number: %s" % serial_number)
-    
-    # check type
-    if type == 'new-order-notification':
-        notifications.notify_neworder(request, data)
-    elif type == 'order-state-change-notification':
-        notifications.notify_statechanged(request, data)
-    elif type == 'charge-amount-notification':
-        notifications.notify_chargeamount(request, data)
-
-    # return ack so google knows we handled the message
-    ack = '<notification-acknowledgment xmlns="http://checkout.google.com/schema/2" serial-number="%s"/>' % serial_number 
-    response = http.HttpResponse(content=ack, content_type="text/xml; charset=UTF-8")
-    log.debug(response)
-    return response
-
-@never_cache
-def success(request):
-    """
-    The order has been succesfully processed.  This can be used to generate a receipt or some other confirmation
-    """
-    try:
-        order = Order.objects.from_request(request)
-    except Order.DoesNotExist:
-        return bad_or_missing(request, _('Your order has already been processed.'))
-        
-    del request.session['orderID']
-    context = RequestContext(request, {'order': order})
-    return render_to_response('payment/success.html', context)
-

File bursar/gateway/protx_gateway/config.py

-from livesettings import *
-from django.utils.translation import ugettext_lazy as _
-
-# this is so that the translation utility will pick up the string
-gettext = lambda s: s
-_strings = (gettext('CreditCard'), gettext('Credit Card'), gettext('Prot/X Secure Payments'))
-
-# These cards require the issue number and start date fields filled in.
-REQUIRES_ISSUE_NUMBER = ('MAESTRO', 'SOLO')
-
-PAYMENT_GROUP = ConfigurationGroup('PAYMENT_PROTX', 
-    _('Prot/X Payment Settings'), 
-    ordering=101)
-
-config_register_list(
-
-    BooleanValue(PAYMENT_GROUP, 
-        'LIVE', 
-        description=_("Accept real payments"),
-        help_text=_("False if you want to be in test mode"),
-        default=False),
-        
-    BooleanValue(PAYMENT_GROUP, 
-        'SIMULATOR', 
-        description=_("Simulated Transactions?"),
-        help_text=_("Must be false to accept real payments"),
-        default=False),
-
-    BooleanValue(PAYMENT_GROUP, 
-        'SKIP_POST', 
-        description=_("Skip post?"),
-        help_text=_("For testing only, this will skip actually posting to Prot/x servers.  This is because their servers restrict IPs of posting servers, even for tests.  If you are developing on a desktop, you'll have to enable this."),
-        default=False),
-        
-    StringValue(PAYMENT_GROUP, 
-        'CAPTURE',
-        description=_('Payment Capture'),
-        help_text=_('This can be "Payment" which captures immediately, or "Deferred".  Note that you can only use the latter if you set option on your Prot/X account first.'),
-        choices = (
-            (('PAYMENT', 'Payment')),
-            (('DEFERRED', 'Deferred')),
-        ),
-        default = 'PAYMENT'),
-    
-    
-    BooleanValue(PAYMENT_GROUP, 
-        'SSL', 
-        description=_("Use SSL for the checkout pages?"), 
-        default=False),
-
-    ModuleValue(PAYMENT_GROUP,
-        'MODULE',
-        description=_('Implementation module'),
-        hidden=True,
-        default = 'payment.modules.protx'),
-    
-    StringValue(PAYMENT_GROUP,
-        'KEY',
-        description=_("Module key"),
-        hidden=True,
-        default = 'PROTX'),
-
-    StringValue(PAYMENT_GROUP,
-        'LABEL',
-        description=_('English name for this group on the checkout screens'),
-        default = 'Prot/X Secure Payments',
-        help_text = _('This will be passed to the translation utility')),
-
-    MultipleStringValue(PAYMENT_GROUP,
-        'CREDITCHOICES',
-        description=_('Available credit cards'),
-        choices = (
-                (('VISA','Visa Credit/Debit')),
-                (('UKE','Visa Electron')),
-                (('DELTA','Delta')),
-                #(('AMEX','American Express')),  # not always available
-                #(('DC','Diners Club')), # not always available
-                (('MC','Mastercard')),
-                (('MAESTRO','UK Maestro')),
-                (('SOLO','Solo')),
-                (('JCB','JCB')),
-            ),
-        default = ('VISA', 'MC')),
-    
-    StringValue(PAYMENT_GROUP, 
-        'VENDOR', 
-        description=_('Your Vendor Name'),
-        default="",
-        help_text= _("This is used for Live and Test transactions.  Make sure to add your server IP address to VSP, or it won't work.")),
-
-    StringValue(PAYMENT_GROUP, 
-        'VENDOR_SIMULATOR', 
-        description=_('Simulator Vendor Name'),
-        default="",
-        help_text= _("This is used for Live and Test transactions.  Make sure to activate the VSP Simulator (you have to directly request it) and add your server IP address to the VSP Simulator, or it won't work.")),
-            
-    StringValue(PAYMENT_GROUP, 
-        'CURRENCY_CODE',
-        description=_('Currency Code'),
-        help_text=_('Currency code for Prot/X transactions.'),
-        default = 'GBP'),
-        
-    StringValue(PAYMENT_GROUP,
-        'URL_BASE',
-        description=_('The url base used for constructing urlpatterns which will use this module'),
-        default = r'^protx/'),
-        
-    BooleanValue(PAYMENT_GROUP,
-        'EXTRA_LOGGING',
-        description=_("Verbose logs"),
-        help_text=_("Add extensive logs during post."),
-        default=False)
-)

File bursar/gateway/protx_gateway/forms.py

-"""Protx Form"""
-from django import forms
-from django.utils.translation import ugettext as _
-from bursar.forms import CreditPayShipForm, MONTHS
-from bursar.gateway.protx.config import REQUIRES_ISSUE_NUMBER
-import logging
-
-log = logging.getLogger('payment.protx.forms')
-
-class ProtxPayShipForm(CreditPayShipForm):
-    """Adds fields required by Prot/X to the Credit form."""
-    
-    card_holder = forms.CharField(max_length=75, required=False)
-    month_start = forms.ChoiceField(choices=[(1, '--')]+MONTHS, required=False)
-    year_start = forms.ChoiceField(required=False)
-    issue_num = forms.CharField(max_length=2, required=False)
-    
-    def __init__(self, request, paymentmodule, *args, **kwargs):
-        super(ProtxPayShipForm, self).__init__(request, paymentmodule, *args, **kwargs)
-        cf = self.fields['card_holder']
-        if (not cf.initial) or cf.initial == "":
-            user = request.user
-            if user and user.is_authenticated() and user.contact_set.count() > 0:
-                cf.initial = self.tempContact.full_name
-        self.requires_issue_number = REQUIRES_ISSUE_NUMBER
-        self.fields['year_start'].choices = self.fields['year_expires'].choices
-
-    def save(self, request, cart, contact, gateway_settings):
-        """Save the order and the credit card details."""
-        super(ProtxPayShipForm, self).save(request, cart, contact, gateway_settings)
-        data = self.cleaned_data 
-        log.debug("data: %s", data)                       
-        card_holder=data.get('card_holder', '')
-        if not card_holder:
-            card_holder = contact.full_name
-        self.cc.card_holder = card_holder
-        month_start = data.get('month_start', None)
-        year_start = data.get('year_start', None)
-        if month_start:
-            try:
-                month_start = int(month_start)
-            except ValueError:
-                log.warn("Could not parse month_start int from %s on order for order: %s", month_start, self.order)
-                month_start = 1
-                # TODO: raise some error to be caught by processor
-        else:
-            month_start=None
-            
-        if year_start:
-            try:
-                year_start = int(year_start)
-            except ValueError:
-                log.warn("Could not parse year_start int from %s on order for order: %s", year_start, self.order)
-                year_start = 1
-        else:
-            year_start=None
-        
-        issue_num = data.get('issue_num', "")
-        
-        self.cc.start_month=month_start
-        self.cc.start_year=year_start
-        self.cc.issue_num=issue_num
-        self.cc.save()
-
-    def clean_card_holder(self):
-        ch = self.cleaned_data['card_holder']
-        if (not ch) or ch == "":
-            fn = self.tempContact.full_name
-            self.cleaned_data['card_holder'] = fn
-            log.debug('Setting card_holder to contact full name: %s', fn)
-        else:
-            log.debug('Card holder OK')
-
-    def clean_month_start(self):
-        data = self.cleaned_data
-        
-        self._maybe_require(data, 'month_start', _('You must provide a starting month when using this type of card.'))
-
-        if data['month_start']:
-            try:
-                v = int(self.cleaned_data['month_start'])
-            except ValueError:
-                raise forms.ValidationError(_("This must be a number"))
-            
-            if not v>0 and v<13:
-                raise forms.ValidationError(_("Out of range, must be 1-12"))
-            
-    def clean_year_start(self):
-        data = self.cleaned_data
-        self._maybe_require(data, 'credit_type', _('You must provide a starting year when using this type of card.'))
-        
-        if data['year_start']:
-            try:
-                v = int(self.cleaned_data['year_start'])
-            except ValueError:
-                raise forms.ValidationError(_("This must be a number"))
-
-            if not v>0 and v<13:
-                raise forms.ValidationError(_("Out of range, must be 1-12"))
-
-    def clean_issue_num(self):
-        data = self.cleaned_data
-        self._maybe_require(data, 'issue_num', _('You must provide an issue number when using this type of card.'))
-
-    def _maybe_require(self, data, field, message):
-        if data['credit_type'] in REQUIRES_ISSUE_NUMBER and not (data[field]):
-            raise forms.ValidationError(message)

File bursar/gateway/protx_gateway/tests.py

Empty file added.

File bursar/gateway/protx_gateway/urls.py

-from django.conf.urls.defaults import *
-from livesettings import config_get_group
-
-config = config_get_group('PAYMENT_PROTX')
-
-urlpatterns = patterns('',
-     (r'^$', 'payment.modules.protx.views.pay_ship_info', 
-        {'SSL':config.SSL.value}, 'PROTX_satchmo_checkout-step2'),
-
-     (r'^confirm/$', 'payment.modules.protx.views.confirm_info', 
-        {'SSL':config.SSL.value}, 'PROTX_satchmo_checkout-step3'),
-
-    (r'^secure3d/$', 'payment.modules.protx.views.confirm_secure3d', 
-       {'SSL':config.SSL.value}, 'PROTX_satchmo_checkout-secure3d'),
-
-     (r'^success/$', 'payment.views.checkout.success', 
-        {'SSL':config.SSL.value}, 'PROTX_satchmo_checkout-success'),
-)

File bursar/gateway/protx_gateway/views.py

-"""Protx checkout custom views"""
-
-from django import http
-from django.shortcuts import render_to_response
-from django.template import RequestContext
-from django.utils.translation import ugettext as _
-from livesettings import config_get_group
-from payment.views import payship, confirm
-import logging
-from satchmo_utils.dynamic import lookup_template
-
-log = logging.getLogger('protx.views')
-    
-def pay_ship_info(request):
-    return payship.credit_pay_ship_info(request, 
-            config_get_group('PAYMENT_PROTX'),
-            template="payment/protx/pay_ship.html")
-    
-def confirm_info(request, template='payment/protx/confirm.html', extra_context={}):
-    gateway_settings = config_get_group('PAYMENT_PROTX')
-    controller = confirm.ConfirmController(request, gateway_settings)
-    controller.templates['CONFIRM'] = template
-    controller.extra_context = extra_context
-    controller.onForm = secure3d_form_handler
-    controller.confirm()
-    return controller.response
-            
-def confirm_secure3d(request, secure3d_template='payment/secure3d_form.html', 
-    confirm_template='payment/confirm.html', extra_context={}):
-    """Handles confirming an order and processing the charges when secured by secure3d.
- 
-    """
-    gateway_settings = config_get_group('PAYMENT_PROTX')
-    controller = confirm.ConfirmController(request, gateway_settings, 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(gateway_settings, secure3d_template)
-                ctx = RequestContext(request, {'order': controller.order, 'auth': auth3d })
-                return render_to_response(template, 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(gateway_settings, secure3d_template)
-            ctx =RequestContext(request, {
-                'order': controller.order, 'auth': auth3d 
-                })
-            return render_to_response(template, ctx)                
-                    
-    return secure3d_form_handler(controller)
-
-def secure3d_form_handler(controller):
-    """At the confirmation step, protx may ask for a secure3d authentication.  This method
-    catches that, and if so, sends to that step, otherwise the form as normal"""
-    
-    if controller.processorReasonCode == '3DAUTH':
-        log.debug('caught secure 3D request for order #%i, putting 3D into session as %s', 
-            controller.order.id, controller.processorReasonCode)
-            
-        redirectUrl = controller.lookup_url('satchmo_checkout-secure3d')
-        controller.processor.response['TermUrl'] = redirectUrl
-        controller.request.session['3D'] = controller.processorReasonCode
-        return http.HttpResponseRedirect(redirectUrl)
-    
-    return controller.onForm(controller)

File bursar/gateway/sermepa_gateway/config.py

-#
-#   SERMEPA / ServiRed payments module for Satchmo
-#
-#   Author: Michal Salaban <michal (at) salaban.info>
-#   with a great help of Fluendo S.A., Barcelona
-#
-#   Based on "Guia de comercios TPV Virtual SIS" ver. 5.18, 15/11/2008, SERMEPA
-#   For more information about integration look at http://www.sermepa.es/
-#
-#   TODO: SERMEPA interface provides possibility of recurring payments, which
-#   could be probably used for SubscriptionProducts. This module doesn't support it.
-#
-from livesettings import *
-from django.utils.translation import ugettext_lazy as _
-
-PAYMENT_GROUP = ConfigurationGroup('PAYMENT_SERMEPA', 
-    _('SERMEPA (ServiRed) Payment Module Settings'), 
-    ordering = 101)
-
-config_register_list(
-    ModuleValue(PAYMENT_GROUP,
-        'MODULE',
-        description=_('Implementation module'),
-        hidden=True,
-        default = 'payment.modules.sermepa'
-        ),
-    StringValue(PAYMENT_GROUP,
-        'KEY',
-        description=_("Module key"),
-        hidden=True,
-        default = 'SERMEPA'
-        ),
-    StringValue(PAYMENT_GROUP,
-        'LABEL',
-        description=_('English name for this group on the checkout screens'),
-        default = 'Credit Card (via SERMEPA)',
-        help_text = _('This will be passed to the translation utility'),
-        ordering=10
-        ),
-    StringValue(PAYMENT_GROUP,
-        'URL_BASE',
-        description=_('The url base used for constructing urlpatterns which will use this module'),
-        default = '^sermepa/',
-        ordering=20
-        ),
-    BooleanValue(
-        PAYMENT_GROUP,
-        'LIVE',
-        description=_("Accept real payments"),
-        help_text=_("False if you want to be in test mode"),
-        default=False,
-        ordering=30
-        ),
-    StringValue(
-        PAYMENT_GROUP,
-        'MERCHANT_CURRENCY',
-        description=_('Currency'),
-        default='978',
-        choices=[
-            ('978', _("EUR (Euro)")),
-            ('840', _("USD (US Dollar)")),
-            ('826', _("GBP (British Pound)")),
-            ('392', _("JPY (Japanese Yen)")),
-            ],
-        ordering=40
-        ),
-    StringValue(
-        PAYMENT_GROUP,
-        'MERCHANT_FUC',
-        description=_('Merchant FUC'),
-        help_text=_('Your FUC code'),
-        ordering=50
-        ),
-    StringValue(
-        PAYMENT_GROUP,
-        'MERCHANT_TITULAR',
-        description=_('Merchant title'),
-        help_text=_('Description of your shop which will be visible on payment confirmation screen'),
-        ordering=60,
-        ),
-
-    # signature
-    StringValue(
-        PAYMENT_GROUP,
-        'MERCHANT_SIGNATURE_CODE',
-        description=_('Signature code'),
-        help_text=_('Your secret code used to sign transaction data'),
-        ordering=100,
-        ),
-    StringValue(
-        PAYMENT_GROUP,
-        'MERCHANT_TEST_SIGNATURE_CODE',
-        description=_('Test signature code'),
-        help_text=_('Your secret code used to sign transaction data in test payments'),
-        ordering=200,
-        ),
-    # terminal
-    IntegerValue(
-        PAYMENT_GROUP,
-        'MERCHANT_TERMINAL',
-        description=_('Terminal number'),
-        default=1,
-        ordering=110
-        ),
-    IntegerValue(
-        PAYMENT_GROUP,
-        'MERCHANT_TEST_TERMINAL',
-        description=_('Test terminal number'),
-        default=1,
-        help_text=_('Terminal number used for test payments'),
-        ordering=210
-        ),
-    # post url
-    StringValue(
-        PAYMENT_GROUP,
-        'POST_URL',
-        description=_('Post URL'),
-        help_text=_('The SERMEPA URL for real transaction posting.'),
-        default="https://sis.sermepa.es/sis/realizarPago",
-        ordering=120
-        ),
-    StringValue(
-        PAYMENT_GROUP,
-        'POST_TEST_URL',
-        description=_('Test Post URL'),
-        help_text=_('The SERMEPA URL for test transaction posting.'),
-        default="https://sis-t.sermepa.es:25443/sis/realizarPago",
-        ordering=220
-        ),
-
-    StringValue(
-        PAYMENT_GROUP,
-        'MERCHANT_URL_CALLBACK',
-        description=_('Callback URL'),
-        help_text=_('Callback URL for on-line notifications about payment progress'),
-        default='SERMEPA_satchmo_checkout-notify_callback',
-        ordering=300
-        ),
-    StringValue(
-        PAYMENT_GROUP,
-        'MERCHANT_URL_OK',
-        description=_('OK URL'),
-        help_text=_('URL for customer to return after successful payment'),
-        default='SERMEPA_satchmo_checkout-success',
-        ordering=310
-        ),
-    StringValue(
-        PAYMENT_GROUP,
-        'MERCHANT_URL_KO',
-        description=_('Failure URL'),
-        help_text=_('URL for customer to return after payment failure'),
-        default='SERMEPA_satchmo_checkout-failure',
-        ordering=320
-        ),
-    BooleanValue(
-        PAYMENT_GROUP,
-        'SSL',
-        description=_("Use SSL for the module checkout pages?"),
-        default=False,
-        ordering=330
-        ),
-        
-    BooleanValue(PAYMENT_GROUP,
-        'EXTRA_LOGGING',
-        description=_("Verbose logs"),
-        help_text=_("Add extensive logs during post."),
-        default=False)
-    )

File bursar/gateway/sermepa_gateway/tests.py

Empty file added.

File bursar/gateway/sermepa_gateway/urls.py

-#
-#   SERMEPA / ServiRed payments module for Satchmo
-#
-#   Author: Michal Salaban <michal (at) salaban.info>
-#   with a great help of Fluendo S.A., Barcelona
-#
-#   Based on "Guia de comercios TPV Virtual SIS" ver. 5.18, 15/11/2008, SERMEPA
-#   For more information about integration look at http://www.sermepa.es/
-#
-#   TODO: SERMEPA interface provides possibility of recurring payments, which
-#   could be probably used for SubscriptionProducts. This module doesn't support it.
-#
-from django.conf.urls.defaults import *
-from livesettings import config_get_group
-
-config = config_get_group('PAYMENT_SERMEPA')
-
-urlpatterns = patterns('',
-    (r'^$', 'payment.modules.sermepa.views.pay_ship_info', {'SSL': config.SSL.value}, 'SERMEPA_satchmo_checkout-step2'),
-    (r'^confirm/$', 'payment.modules.sermepa.views.confirm_info', {'SSL': config.SSL.value}, 'SERMEPA_satchmo_checkout-step3'),
-    (r'^success/$', 'payment.views.checkout.success', {'SSL': config.SSL.value}, 'SERMEPA_satchmo_checkout-success'),
-    (r'^failure/$', 'payment.views.checkout.failure', {'SSL': config.SSL.value}, 'SERMEPA_satchmo_checkout-failure'),
-    (
-        r'^notify/$',
-        'payment.modules.sermepa.views.notify_callback',
-        {'SSL': config.SSL.value},
-        'SERMEPA_satchmo_checkout-notify_callback'
-        ),
-    (r'^confirmorder/$', 'payment.views.confirm.confirm_free_order', 
-       {'SSL' : config.SSL.value, 'key' : 'SERMEPA'}, 'SERMEPA_satchmo_checkout_free-confirm')
-)

File bursar/gateway/sermepa_gateway/views.py

-#
-#   SERMEPA / ServiRed payments module for Satchmo
-#
-#   Author: Michal Salaban <michal (at) salaban.info>
-#   with a great help of Fluendo S.A., Barcelona
-#
-#   Based on "Guia de comercios TPV Virtual SIS" ver. 5.18, 15/11/2008, SERMEPA
-#   For more information about integration look at http://www.sermepa.es/
-#
-#   TODO: SERMEPA interface provides possibility of recurring payments, which
-#   could be probably used for SubscriptionProducts. This module doesn't support it.
-#
-from django.core import urlresolvers
-from django.http import HttpResponse, HttpResponseRedirect, HttpResponseNotFound, HttpResponseBadRequest
-from django.shortcuts import render_to_response
-from django.views.decorators.cache import never_cache
-from django.template import RequestContext
-from livesettings import config_get_group, config_value 
-from payment.utils import get_gateway_by_key
-from payment.views import payship
-from satchmo_store.shop.models import Order, Cart
-from satchmo_utils.dynamic import lookup_url, lookup_template
-from django.utils.translation import ugettext_lazy as _
-
-from datetime import datetime
-from decimal import Decimal
-import logging
-try:
-    from hashlib import sha1
-except ImportError:
-    # python < 2.5
-    from sha import sha as sha1
-
-log = logging.getLogger()
-
-def pay_ship_info(request):
-    return payship.base_pay_ship_info(
-            request,
-            config_get_group('PAYMENT_SERMEPA'), payship.simple_pay_ship_process_form,
-            'payment/sermepa/pay_ship.html'
-            )
-pay_ship_info = never_cache(pay_ship_info)
-
-
-def _resolve_local_url(gateway_settings, cfgval, ssl=False):
-    try:
-        return lookup_url(gateway_settings, cfgval.value, include_server=True, ssl=ssl)
-    except urlresolvers.NoReverseMatch:
-        return cfgval.value
-
-
-def confirm_info(request):
-    gateway_settings = config_get_group('PAYMENT_SERMEPA')
-
-    try:
-        order = Order.objects.from_request(request)
-    except Order.DoesNotExist:
-        url = lookup_url(gateway_settings, 'satchmo_checkout-step1')
-        return HttpResponseRedirect(url)
-
-    tempCart = Cart.objects.from_request(request)
-    if tempCart.numItems == 0:
-        template = lookup_template(gateway_settings, 'payment/empty_cart.html')
-        return render_to_response(template, RequestContext(request))
-
-    # Check if the order is still valid
-    if not order.validate(request):
-        context = RequestContext(request,
-            {'message': _('Your order is no longer valid.')})
-        return render_to_response('shop/404.html', context)
-
-    # Check if we are in test or real mode
-    live = gateway_settings.LIVE.value
-    if live:
-        post_url = gateway_settings.POST_URL.value
-        signature_code = gateway_settings.MERCHANT_SIGNATURE_CODE.value
-        terminal = gateway_settings.MERCHANT_TERMINAL.value
-    else:
-        post_url = gateway_settings.POST_TEST_URL.value
-        signature_code = gateway_settings.MERCHANT_TEST_SIGNATURE_CODE.value
-        terminal = gateway_settings.MERCHANT_TEST_TERMINAL.value
-
-    # SERMEPA system does not accept multiple payment attempts with the same ID, even
-    # if the previous one has never been finished. The worse is that it does not display
-    # any message which could be understood by an end user.
-    #
-    # If user goes to SERMEPA page and clicks 'back' button (e.g. to correct contact data),
-    # the next payment attempt will be rejected.
-    #
-    # To provide higher probability of ID uniqueness, we add mm:ss timestamp part
-    # to the order id, separated by 'T' character in the following way:
-    #
-    #   ID: oooooooTmmss
-    #   c:  123456789012
-    #
-    # The Satchmo's Order number is therefore limited to 10 million - 1.
-    now = datetime.now()
-    xchg_order_id = "%07dT%02d%02d" % (order.id, now.minute, now.second)
-
-    amount = "%d" % (order.balance * 100,)    # in cents
-    signature_data = ''.join(
-            map(str, (
-                    amount,
-                    xchg_order_id,
-                    gateway_settings.MERCHANT_FUC.value,
-                    gateway_settings.MERCHANT_CURRENCY.value,
-                    signature_code,
-                    )
-               )
-            )
-
-    signature = sha1(signature_data).hexdigest()
-
-    template = lookup_template(gateway_settings, 'payment/sermepa/confirm.html')
-
-    url_callback = _resolve_local_url(gateway_settings, gateway_settings.MERCHANT_URL_CALLBACK, ssl=gateway_settings.SSL.value)
-    url_ok = _resolve_local_url(gateway_settings, gateway_settings.MERCHANT_URL_OK)
-    url_ko = _resolve_local_url(gateway_settings, gateway_settings.MERCHANT_URL_KO)
-
-    ctx = {
-        'live': live,
-        'post_url': post_url,
-        'MERCHANT_CURRENCY': gateway_settings.MERCHANT_CURRENCY.value,
-        'MERCHANT_FUC': gateway_settings.MERCHANT_FUC.value,
-        'terminal': terminal,
-        'MERCHANT_TITULAR': gateway_settings.MERCHANT_TITULAR.value,
-        'url_callback': url_callback,
-        'url_ok': url_ok,
-        'url_ko': url_ko,
-        'order': order,
-        'xchg_order_id' : xchg_order_id,
-        'amount': amount,
-        'signature': signature,
-        'default_view_tax': config_value('TAX', 'DEFAULT_VIEW_TAX'),
-    }
-    return render_to_response(template, ctx, context_instance=RequestContext(request))
-confirm_info = never_cache(confirm_info)
-
-def notify_callback(request):
-    gateway_settings = config_get_group('PAYMENT_SERMEPA')
-    if gateway_settings.LIVE.value:
-        log.debug("Live IPN on %s", gateway_settings.KEY.value)
-        signature_code = gateway_settings.MERCHANT_SIGNATURE_CODE.value
-        terminal = gateway_settings.MERCHANT_TERMINAL.value
-    else:
-        log.debug("Test IPN on %s", gateway_settings.KEY.value)
-        signature_code = gateway_settings.MERCHANT_TEST_SIGNATURE_CODE.value
-        terminal = gateway_settings.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'] != gateway_settings.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_gateway_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()

File bursar/gateway/trustcommerce_gateway/config.py

-from livesettings import *
-from django.utils.translation import ugettext_lazy as _
-
-gettext = lambda s:s
-_strings = (gettext('CreditCard'), gettext('Credit Card'))
-
-PAYMENT_GROUP = ConfigurationGroup('PAYMENT_TRUSTCOMMERCE', 
-    _('TrustCommerce Payment Settings'), 
-    ordering=102)
-
-config_register_list(
-
-    StringValue(PAYMENT_GROUP,
-        'KEY',
-        description=_("Module key"),
-        hidden=True,
-        default = 'TRUSTCOMMERCE'),
-
-    ModuleValue(PAYMENT_GROUP,
-        'MODULE',
-        description=_('Implementation module'),
-        hidden=True,
-        default = 'payment.modules.trustcommerce'),
-        
-    BooleanValue(PAYMENT_GROUP, 
-        'SSL', 
-        description=_("Use SSL for the checkout pages?"), 
-        default=False),
-    
-    BooleanValue(PAYMENT_GROUP, 
-        'AVS', 
-        description=_("Use Address Verification System (AVS)?"), 
-        default=False),
-    
-    BooleanValue(PAYMENT_GROUP, 
-        'LIVE', 
-        description=_("Accept real payments"),
-        help_text=_("False if you want to be in test mode"),
-        default=False),
-    
-    StringValue(PAYMENT_GROUP,
-        'AUTH_TYPE',
-        description=_("Type of authorization to perform."),
-        help_text = _("Refer to manual for details on the different types."),
-        default = 'sale',
-        choices = [('sale', _('Sale')),
-                    ('preauth', _('Preauth'))]
-        ),
-        
-    StringValue(PAYMENT_GROUP,
-        'LABEL',
-        description=_('English name for this group on the checkout screens'),
-        default = 'Credit Cards',
-        help_text = _('This will be passed to the translation utility')),
-
-    StringValue(PAYMENT_GROUP,
-        'URL_BASE',
-        description=_('The url base used for constructing urlpatterns which will use this module'),
-        default = r'^credit/'),
-
-    MultipleStringValue(PAYMENT_GROUP,
-        'CREDITCHOICES',
-        description=_('Available credit cards'),
-        choices = (
-            (('American Express', 'American Express')),
-            (('Visa','Visa')),
-            (('Mastercard','Mastercard')),
-            (('Discover','Discover'))),
-        default = ('Visa', 'Mastercard', 'Discover')),
-    
-    StringValue(PAYMENT_GROUP, 
-        'LOGIN', 
-        description=_('Your TrustCommerce login'),
-        default=""),
-    
-    StringValue(PAYMENT_GROUP, 
-        'PASSWORD', 
-        description=_('Your TrustCommerce password'),
-        default=""),
-        
-    BooleanValue(PAYMENT_GROUP,
-        'EXTRA_LOGGING',
-        description=_("Verbose logs"),
-        help_text=_("Add extensive logs during post."),
-        default=False)
-)

File bursar/gateway/trustcommerce_gateway/tests.py

Empty file added.

File bursar/gateway/trustcommerce_gateway/urls.py

-from django.conf.urls.defaults import *
-from livesettings import config_value, config_get_group
-
-
-config = config_get_group('PAYMENT_TRUSTCOMMERCE')
-
-urlpatterns = patterns('',
-     (r'^$', 'payment.modules.trustcommerce.views.pay_ship_info', {'SSL':config.SSL.value}, 'TRUSTCOMMERCE_satchmo_checkout-step2'),
-     (r'^confirm/$', 'payment.modules.trustcommerce.views.confirm_info', {'SSL':config.SSL.value}, 'TRUSTCOMMERCE_satchmo_checkout-step3'),
-     (r'^success/$', 'payment.views.checkout.success', {'SSL':config.SSL.value}, 'TRUSTCOMMERCE_satchmo_checkout-success'),
-)

File bursar/gateway/trustcommerce_gateway/views.py

-from livesettings import config_get_group
-from payment.views import confirm, payship
-    
-def pay_ship_info(request):
-    return payship.credit_pay_ship_info(request, config_get_group('PAYMENT_TRUSTCOMMERCE'))
-    
-def confirm_info(request):
-    return confirm.payment_confirm_info(request, config_get_group('PAYMENT_TRUSTCOMMERCE'))