Commits

Bruce Kroeze committed 225200f

adding paypal gateway, and templates

Comments (0)

Files changed (23)

 *.egg-info
 satchmo
 local_bursar_*py
+.DS_Store

bursar/gateway/authorizenet_gateway/processor.py

         """Post one subscription request."""
         self.log_extra('Processing subscription: %s', data['product'].slug)
         
-        t = loader.get_template('shop/checkout/authorizenet/arb_create_subscription.xml')
+        t = loader.get_template('bursar/gateway/authorizenet_gateway/arb_create_subscription.xml')
         ctx = Context(data)
         request = t.render(ctx)
         

bursar/gateway/authorizenet_gateway/templates/bursar/gateway/authorizenet_gateway/arb_create_subscription.xml

+<?xml version="1.0" encoding="utf-8"?>
+<ARBCreateSubscriptionRequest xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">
+	<merchantAuthentication>
+		<name>{{ config.merchantID }}</name>
+		<transactionKey>{{ config.transactionKey }}</transactionKey>
+	</merchantAuthentication>
+	<refId>{{ subscription.id }}</refId>
+	<subscription>
+		<name>{{ product.translated_name }}</name>
+		<paymentSchedule>
+			<interval>
+				<length>{{ product.subscriptionproduct.expire_length }}</length>
+				<unit>{% ifequal product.subscriptionproduct.expire_unit "DAY" %}days{% else %}months{% endifequal %}</unit>
+			</interval>
+			<startDate>{% now "Y-m-d" %}</startDate>
+			<totalOccurrences>{{ occurrences }}</totalOccurrences>{% if trial %}
+			<trialOccurrences>{{ trial_occurrences }}</trialOccurrences>{% endif %}
+		</paymentSchedule>
+		<amount>{{ amount }}</amount>{% if trial %}
+		<trialAmount>{{ trial_amount }}</trialAmount>{% endif %}
+		<payment>
+			<creditCard>
+				<cardNumber>{% if redact %}REDACTED{% else %}{{ order.credit_card.decryptedCC }}{% endif %}</cardNumber>
+				<expirationDate>{{ card_expiration }}</expirationDate>
+			</creditCard>
+		</payment>
+		<order>
+			<invoiceNumber>{{ order.id }}</invoiceNumber>
+			<description>{{ config.shop_name }} subscription for {{ subscription.product.translated_name }}</description>
+		</order>
+		<customer>
+			<id>{{ order.contact.id }}</id>
+			<email>{{ order.contact.email }}</email>
+			<phoneNumber>{{ order.contact.primary_phone.phone }}</phoneNumber>
+		</customer>
+		<billTo>
+			<firstName>{{ order.contact.first_name }}</firstName>
+			<lastName>{{ order.contact.last_name }}</lastName>
+		</billTo>
+	</subscription>
+</ARBCreateSubscriptionRequest>

bursar/gateway/authorizenet_gateway/tests.py

 # -*- coding: UTF-8 -*-
-"""Bursar Dummy Gateway Tests."""
+"""Bursar Authorizenet Gateway Tests."""
 from bursar.gateway.authorizenet_gateway import processor
 from bursar.errors import GatewayError
 from bursar.models import Authorization, Payment

bursar/gateway/autosuccess_gateway/tests.py

 # -*- coding: UTF-8 -*-
+"""Bursar Autosucess Gateway Tests."""
 from bursar.gateway.autosuccess_gateway import processor
 from bursar.models import Authorization, Payment
 from bursar.tests import make_test_purchase

bursar/gateway/cod_gateway/tests.py

 # -*- coding: UTF-8 -*-
+"""Bursar COD Gateway Tests."""
 from bursar.gateway.cod_gateway import processor
 from bursar.models import Authorization, Payment
 from bursar.tests import make_test_purchase

bursar/gateway/cybersource_gateway/processor.py

             invoice = "%s_%i" % (invoice, failct)
         
         # XML format is very simple, using ElementTree for generation would be overkill
-        t = loader.get_template('shop/checkout/cybersource/request.xml')
+        t = loader.get_template('payment/cybersource/request.xml')
         c = Context({
             'config' : self.configuration,
             'merchantReferenceCode' : invoice,

bursar/gateway/cybersource_gateway/templates/bursar/gateway/cybersource/request.xml

+<?xml version="1.0" encoding="UTF-8"?>
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:schemas-cybersource-com:transaction-data-1.26">
+  <SOAP-ENV:Header xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
+    <wsse:Security SOAP-ENV:mustUnderstand="1">
+      <wsse:UsernameToken>
+        <wsse:Username>{{ config.merchantID }}</wsse:Username>
+        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">{{ config.password }}</wsse:Password>
+      </wsse:UsernameToken>
+    </wsse:Security>
+  </SOAP-ENV:Header>
+  <SOAP-ENV:Body>
+    <ns1:requestMessage>
+      <ns1:merchantID>{{ config.merchantID }}</ns1:merchantID>
+      <ns1:merchantReferenceCode>{{ merchantReferenceCode }}</ns1:merchantReferenceCode>
+      <ns1:billTo>
+        <ns1:firstName>{{ billTo.firstName }}</ns1:firstName>
+        <ns1:lastName>{{ billTo.lastName }}</ns1:lastName>
+        <ns1:street1>{{ billTo.street1 }}</ns1:street1>
+        <ns1:city>{{ billTo.city }}</ns1:city>
+        <ns1:state>{{ billTo.state }}</ns1:state>
+        <ns1:postalCode>{{ billTo.postalCode }}</ns1:postalCode>
+        <ns1:country>{{ billTo.country }}</ns1:country>
+        <ns1:email>{{ billTo.email }}</ns1:email>
+      </ns1:billTo>
+      <ns1:purchaseTotals>
+        <ns1:currency>{{ purchaseTotals.currency }}</ns1:currency>
+        <ns1:grandTotalAmount>{{ purchaseTotals.grandTotalAmount }}</ns1:grandTotalAmount>
+      </ns1:purchaseTotals>
+      <ns1:card>
+        <ns1:accountNumber>{{ card.accountNumber }}</ns1:accountNumber>
+        <ns1:expirationMonth>{{ card.expirationMonth }}</ns1:expirationMonth>
+        <ns1:expirationYear>{{ card.expirationYear }}</ns1:expirationYear>
+      </ns1:card>
+      <ns1:ccAuthService run="true"/>
+    </ns1:requestMessage>
+  </SOAP-ENV:Body>
+</SOAP-ENV:Envelope>

bursar/gateway/giftcertificate_gateway/templates/shop/checkout/confirm.html

-{% extends "shop/checkout/base_confirm.html" %}
+{% extends "payment/base_confirm.html" %}
 {% load i18n %}
 {% load satchmo_currency satchmo_order %}
 {# this is the gift certificate confirmation template #}

bursar/gateway/giftcertificate_gateway/templates/shop/checkout/giftcertificate/confirm.html

-{% extends "shop/checkout/base_confirm.html" %}
+{% extends "payment/base_confirm.html" %}
 {% load i18n %}
 {% load satchmo_currency %}
 {# this is the credit-card confirm template #}

bursar/gateway/giftcertificate_gateway/templates/shop/checkout/giftcertificate/pay_ship.html

-{% extends "shop/checkout/base_pay_ship.html" %}
+{% extends "payment/base_pay_ship.html" %}
 {% load i18n %}
 {# gift cert pay_ship version #}
 

bursar/gateway/giftcertificate_gateway/views.py

     return payship.base_pay_ship_info(request, 
         gc, 
         giftcert_pay_ship_process_form,
-        template="shop/checkout/giftcertificate/pay_ship.html")
+        template="payment/giftcertificate/pay_ship.html")
     
-def confirm_info(request, template="shop/checkout/giftcertificate/confirm.html"):
+def confirm_info(request, template="payment/giftcertificate/confirm.html"):
     try:
         order = Order.objects.get(id=request.session['orderID'])
         giftcert = GiftCertificate.objects.from_order(order)

bursar/gateway/google_gateway/config.py

         'CART_XML_TEMPLATE',
         description=_("XML Template"),
         help_text=_("The XML template to use when submitting to Google. Probably you should not change this."),
-        default = "shop/checkout/google/cart.xml"),
+        default = "payment/google/cart.xml"),
     
     StringValue(PAYMENT_GROUP,
         'CURRENCY_CODE',
         'POST_TEST_URL',
         description=_('Post URL'),
         help_text=_('The Google URL for test transaction posting.'),
-        default="https://sandbox.google.com/shop/checkout/cws/v2/Merchant/%(MERCHANT_ID)s/checkout"),
+        default="https://sandbox.google.com/payment/cws/v2/Merchant/%(MERCHANT_ID)s/checkout"),
 
     StringValue(PAYMENT_GROUP,
         'MERCHANT_ID',
 )
 
 PAYMENT_GROUP['TEMPLATE_OVERRIDES'] = {
-    'shop/checkout/confirm.html' : 'shop/checkout/google/confirm.html',
+    'payment/confirm.html' : 'payment/google/confirm.html',
 }

bursar/gateway/google_gateway/views.py

 
 @never_cache
 def pay_ship_info(request):
-    return payship.simple_pay_ship_info(request, config_get_group('PAYMENT_GOOGLE'), 'shop/checkout/google/pay_ship.html')
+    return payship.simple_pay_ship_info(request, config_get_group('PAYMENT_GOOGLE'), 'payment/google/pay_ship.html')
 
 @never_cache
 def confirm_info(request):
         
     del request.session['orderID']
     context = RequestContext(request, {'order': order})
-    return render_to_response('shop/checkout/success.html', context)
+    return render_to_response('payment/success.html', context)
 

bursar/gateway/paypal_gateway/config.py

-from livesettings import *
-from django.utils.translation import ugettext_lazy as _
-
-PAYMENT_GROUP = ConfigurationGroup('PAYMENT_PAYPAL', 
-    _('Paypal Payment Module Settings'), 
-    ordering = 101)
-
-config_register_list(
-
-StringValue(PAYMENT_GROUP,
-    'CURRENCY_CODE',
-    description=_('Currency Code'),
-    help_text=_('Currency code for Paypal transactions.'),
-    default = 'USD'),
-    
-StringValue(PAYMENT_GROUP,
-    'POST_URL',
-    description=_('Post URL'),
-    help_text=_('The Paypal URL for real transaction posting.'),
-    default="https://www.paypal.com/cgi-bin/webscr"),
-
-StringValue(PAYMENT_GROUP,
-    'POST_TEST_URL',
-    description=_('Post URL'),
-    help_text=_('The Paypal URL for test transaction posting.'),
-    default="https://www.sandbox.paypal.com/cgi-bin/webscr"),
-
-StringValue(PAYMENT_GROUP,
-    'BUSINESS',
-    description=_('Paypal account email'),
-    help_text=_('The email address for your paypal account'),
-    default=""),
-
-StringValue(PAYMENT_GROUP,
-    'BUSINESS_TEST',
-    description=_('Paypal test account email'),
-    help_text=_('The email address for testing your paypal account'),
-    default=""),
-
-StringValue(PAYMENT_GROUP,
-    'RETURN_ADDRESS',
-    description=_('Return URL'),
-    help_text=_('Where Paypal will return the customer after the purchase is complete.  This can be a named url and defaults to the standard checkout success.'),
-    default="satchmo_checkout-success"),
-    
-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.paypal'),
-    
-StringValue(PAYMENT_GROUP,
-    'KEY',
-    description=_("Module key"),
-    hidden=True,
-    default = 'PAYPAL'),
-
-StringValue(PAYMENT_GROUP,
-    'LABEL',
-    description=_('English name for this group on the checkout screens'),
-    default = 'PayPal',
-    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 = '^paypal/'),
-    
-BooleanValue(PAYMENT_GROUP,
-    'EXTRA_LOGGING',
-    description=_("Verbose logs"),
-    help_text=_("Add extensive logs during post."),
-    default=False)
-)
-
-PAYMENT_GROUP['TEMPLATE_OVERRIDES'] = {
-    'shop/checkout/confirm.html' : 'shop/checkout/paypal/confirm.html',
-}

bursar/gateway/paypal_gateway/tests.py

+# -*- coding: UTF-8 -*-
+"""Bursar Dummy Gateway Tests."""
+from bursar.gateway.paypal_gateway import processor
+from bursar.errors import GatewayError
+from bursar.models import Authorization, Payment
+from bursar.tests import make_test_purchase
+from bursar.bursar_settings import get_bursar_setting
+from decimal import Decimal
+from django.conf import settings
+from django.contrib.sites.models import Site
+from django.core import urlresolvers
+from django.core.urlresolvers import reverse as url
+from django.test import TestCase
+from django.test.client import Client
+
+SKIP_TESTS = False
+NEED_SETTINGS = """Tests for paypal_gateway module require an
+PAYPAL_TEST section in settings.BURSAR_SETTINGS.  At a 
+minimum, you must specify the LOGIN, TRANKEY, and STORE_NAME."""
+
+class TestGateway(TestCase):
+    def setUp(self):
+        global SKIP_TESTS
+        self.client = Client()
+        if not SKIP_TESTS:
+            settings = get_bursar_setting('PAYPAL_TEST', default_value=None)
+            settings['EXTRA_LOGGING'] = True
+            if not settings:
+                SKIP_TESTS = True
+                raise GatewayError(NEED_SETTINGS)
+            self.gateway = processor.PaymentProcessor(settings=settings)
+            self.default_payment = {
+                'ccv' : '111',
+                'card_number' : '4111111111111111',
+                'expire_month' : 12,
+                'expire_year' : 2012,
+                'card_type' : 'visa'
+            }
+
+    def tearDown(self):
+        pass
+
+    def test_capture(self):
+        """Test making a direct payment using PAYPAL."""
+        if SKIP_TESTS: return
+        purchase = make_test_purchase(sub_total=Decimal('10.00'), payment=self.default_payment)
+        self.assertEqual(purchase.total, Decimal('10.00'))
+        result = self.gateway.capture_payment(purchase=purchase)
+        self.assert_(result.success)
+        payment = result.payment
+        self.assertEqual(payment.amount, Decimal('10.00'))
+        self.assertEqual(purchase.total_payments, Decimal('10.00'))
+        self.assertEqual(purchase.authorized_remaining, Decimal('0.00'))
+

bursar/gateway/paypal_gateway/urls.py

-from django.conf.urls.defaults import *
-from livesettings import config_get_group
-
-config = config_get_group('PAYMENT_PAYPAL')
-
-urlpatterns = patterns('',
-     (r'^$', 'payment.modules.paypal.views.pay_ship_info', {'SSL': config.SSL.value}, 'PAYPAL_satchmo_checkout-step2'),
-     (r'^confirm/$', 'payment.modules.paypal.views.confirm_info', {'SSL': config.SSL.value}, 'PAYPAL_satchmo_checkout-step3'),
-     (r'^success/$', 'payment.views.checkout.success', {'SSL': config.SSL.value}, 'PAYPAL_satchmo_checkout-success'),
-     (r'^ipn/$', 'payment.modules.paypal.views.ipn', {'SSL': config.SSL.value}, 'PAYPAL_satchmo_checkout-ipn'),
-     (r'^confirmorder/$', 'payment.views.confirm.confirm_free_order', 
-        {'SSL' : config.SSL.value, 'key' : 'PAYPAL'}, 'PAYPAL_satchmo_checkout_free-confirm')
-)

bursar/gateway/paypal_gateway/views.py

-from decimal import Decimal
-from django.core import urlresolvers
-from django.http import HttpResponse, HttpResponseRedirect
-from django.shortcuts import render_to_response
-from django.template import RequestContext
-from django.utils.http import urlencode
-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.utils import get_processor_by_key, get_processor_by_module
-from payment.views import payship
-from satchmo_store.shop.models import Cart
-from satchmo_store.shop.models import Order, Payment
-from satchmo_utils.dynamic import lookup_url, lookup_template
-from sys import exc_info
-from traceback import format_exception
-import logging
-import urllib2
-
-log = logging.getLogger()
-
-def pay_ship_info(request):
-    return payship.base_pay_ship_info(request,
-        config_get_group('PAYMENT_PAYPAL'), payship.simple_pay_ship_process_form,
-        'shop/checkout/paypal/pay_ship.html')
-pay_ship_info = never_cache(pay_ship_info)
-
-
-def confirm_info(request):
-    payment_module = config_get_group('PAYMENT_PAYPAL')
-
-    try:
-        order = Order.objects.from_request(request)
-    except Order.DoesNotExist:
-        url = lookup_url(payment_module, 'satchmo_checkout-step1')
-        return HttpResponseRedirect(url)
-
-    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, 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)
-
-    template = lookup_template(payment_module, 'shop/checkout/paypal/confirm.html')
-    if payment_module.LIVE.value:
-        log.debug("live order on %s", payment_module.KEY.value)
-        url = payment_module.POST_URL.value
-        account = payment_module.BUSINESS.value
-    else:
-        url = payment_module.POST_TEST_URL.value
-        account = payment_module.BUSINESS_TEST.value
-
-    try:
-        address = lookup_url(payment_module,
-            payment_module.RETURN_ADDRESS.value, include_server=True)
-    except urlresolvers.NoReverseMatch:
-        address = payment_module.RETURN_ADDRESS.value
-
-    processor = get_processor_by_module(payment_module)
-    processor.create_pending_payment(order=order)
-    default_view_tax = config_value('TAX', 'DEFAULT_VIEW_TAX') 
-  
-    recurring = None
-    order_items = order.orderitems.all()
-    for item in order_items:
-        if item.product.is_subscription:
-            recurring = {'product':item.product, 'price':item.product.price_set.all()[0].price.quantize(Decimal('.01')),}
-            trial0 = recurring['product'].subscriptionproduct.get_trial_terms(0)
-            if len(order_items) > 1 or trial0 is not None or recurring['price'] < order.balance:
-                recurring['trial1'] = {'price': order.balance,}
-                if trial0 is not None:
-                    recurring['trial1']['expire_length'] = trial0.expire_length
-                    recurring['trial1']['expire_unit'] = trial0.expire_unit[0]
-                # else:
-                #     recurring['trial1']['expire_length'] = recurring['product'].subscriptionproduct.get_trial_terms(0).expire_length
-                trial1 = recurring['product'].subscriptionproduct.get_trial_terms(1)
-                if trial1 is not None:
-                    recurring['trial2']['expire_length'] = trial1.expire_length
-                    recurring['trial2']['expire_unit'] = trial1.expire_unit[0]
-                    recurring['trial2']['price'] = trial1.price
- 
-    ctx = RequestContext(request, {'order': order,
-     'post_url': url,
-     'default_view_tax': default_view_tax, 
-     'business': account,
-     'currency_code': payment_module.CURRENCY_CODE.value,
-     'return_address': address,
-     'invoice': order.id,
-     'subscription': recurring,
-     'gateway_live' : gateway_live(payment_module)
-    })
-
-    return render_to_response(template, ctx)
-confirm_info = never_cache(confirm_info)
-
-def ipn(request):
-    """PayPal IPN (Instant Payment Notification)
-    Cornfirms that payment has been completed and marks invoice as paid.
-    Adapted from IPN cgi script provided at http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/456361"""
-    payment_module = config_get_group('PAYMENT_PAYPAL')
-    if payment_module.LIVE.value:
-        log.debug("Live IPN on %s", payment_module.KEY.value)
-        url = payment_module.POST_URL.value
-        account = payment_module.BUSINESS.value
-    else:
-        log.debug("Test IPN on %s", payment_module.KEY.value)
-        url = payment_module.POST_TEST_URL.value
-        account = payment_module.BUSINESS_TEST.value
-    PP_URL = url
-
-    try:
-        data = request.POST
-        log.debug("PayPal IPN data: " + repr(data))
-        if not confirm_ipn_data(data, PP_URL):
-            return HttpResponse()
-
-        if not 'payment_status' in data or not data['payment_status'] == "Completed":
-            # We want to respond to anything that isn't a payment - but we won't insert into our database.
-             log.info("Ignoring IPN data for non-completed payment.")
-             return HttpResponse()
-
-        try:
-            invoice = data['invoice']
-        except:
-            invoice = data['item_number']
-
-        gross = data['mc_gross']
-        txn_id = data['txn_id']
-
-        if not Payment.objects.filter(transaction_id=txn_id).count():
-            # If the payment hasn't already been processed:
-            order = Order.objects.get(pk=invoice)
-            
-            order.add_status(status='New', notes=_("Paid through PayPal."))
-            processor = get_processor_by_key('PAYMENT_PAYPAL')
-            payment = processor.record_payment(order=order, amount=gross, transaction_id=txn_id)
-            
-            if 'memo' in data:
-                if order.notes:
-                    notes = order.notes + "\n"
-                else:
-                    notes = ""
-                
-                order.notes = notes + _('---Comment via Paypal IPN---') + u'\n' + data['memo']
-                order.save()
-                log.debug("Saved order notes from Paypal")
-            
-            for item in order.orderitems.filter(product__subscriptionproduct__recurring=True, completed=False):
-                item.completed = True
-                item.save()
-            for cart in Cart.objects.filter(customer=order.contact):
-                cart.empty()
-                
-    except:
-        log.exception(''.join(format_exception(*exc_info())))
-
-    return HttpResponse()
-
-def confirm_ipn_data(data, PP_URL):
-    # data is the form data that was submitted to the IPN URL.
-
-    newparams = {}
-    for key in data.keys():
-        newparams[key] = data[key]
-
-    newparams['cmd'] = "_notify-validate"
-    params = urlencode(newparams)
-
-    req = urllib2.Request(PP_URL)
-    req.add_header("Content-type", "application/x-www-form-urlencoded")
-    fo = urllib2.urlopen(req, params)
-
-    ret = fo.read()
-    if ret == "VERIFIED":
-        log.info("PayPal IPN data verification was successful.")
-    else:
-        log.info("PayPal IPN data verification failed.")
-        log.debug("HTTP code %s, response text: '%s'" % (fo.code, ret))
-        return False
-
-    return True

bursar/gateway/protx_gateway/views.py

 def pay_ship_info(request):
     return payship.credit_pay_ship_info(request, 
             config_get_group('PAYMENT_PROTX'),
-            template="shop/checkout/protx/pay_ship.html")
+            template="payment/protx/pay_ship.html")
     
-def confirm_info(request, template='shop/checkout/protx/confirm.html', extra_context={}):
+def confirm_info(request, template='payment/protx/confirm.html', extra_context={}):
     payment_module = config_get_group('PAYMENT_PROTX')
     controller = confirm.ConfirmController(request, payment_module)
     controller.templates['CONFIRM'] = template
     controller.confirm()
     return controller.response
             
-def confirm_secure3d(request, secure3d_template='shop/checkout/secure3d_form.html', 
-    confirm_template='shop/checkout/confirm.html', extra_context={}):
+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.
  
     """

bursar/gateway/purchaseorder_gateway/tests.py

 # -*- coding: UTF-8 -*-
+"""Bursar Purchase Order Gateway Tests."""
 from bursar.gateway.purchaseorder_gateway import processor
 from bursar.models import Authorization, Payment
 from bursar.tests import make_test_purchase

bursar/gateway/sermepa_gateway/views.py

     return payship.base_pay_ship_info(
             request,
             config_get_group('PAYMENT_SERMEPA'), payship.simple_pay_ship_process_form,
-            'shop/checkout/sermepa/pay_ship.html'
+            'payment/sermepa/pay_ship.html'
             )
 pay_ship_info = never_cache(pay_ship_info)
 
 
     tempCart = Cart.objects.from_request(request)
     if tempCart.numItems == 0:
-        template = lookup_template(payment_module, 'shop/checkout/empty_cart.html')
+        template = lookup_template(payment_module, 'payment/empty_cart.html')
         return render_to_response(template, RequestContext(request))
 
     # Check if the order is still valid
 
     signature = sha1(signature_data).hexdigest()
 
-    template = lookup_template(payment_module, 'shop/checkout/sermepa/confirm.html')
+    template = lookup_template(payment_module, 'payment/sermepa/confirm.html')
 
     url_callback = _resolve_local_url(payment_module, payment_module.MERCHANT_URL_CALLBACK, ssl=payment_module.SSL.value)
     url_ok = _resolve_local_url(payment_module, payment_module.MERCHANT_URL_OK)
 * Fix the OrderStatus stuff in bursar.models - should go in the adapter?
+* Gateways Complete:
+	authorizenet
+	autosuccess
+	cod
+	dummy
+	purchase order
 
+
+Satchmo Changes
+---------------
+
+template moves:
+payment/paypal -> payment/paypal

tests/settings.py

     'bursar.gateway.cod_gateway',
     'bursar.gateway.dummy_gateway',
     'bursar.gateway.purchaseorder_gateway',
+    'bursar.gateway.paypal_gateway',
     'payment.modules.authorizenet',
     'payment.modules.autosuccess',
     'payment.modules.cod',