### Navigation

- index
- modules |
- next |
- previous |
- TurboGears 2.1.5 documentation »
- Search:
- Extended Table of Contents »
- Tips and Recipes »

# Using Authorize.net in a TurboGears Form

Table of Contents

- Using Authorize.net in a TurboGears Form
  - The Authorize Package
  - Defining The Validator
  - Defining The Form
  - Using It In A Controller

The goal of this tutorial is to get a tw.forms form to go through two layers of validation before passing:

> 1. Use the validation packages provided by tw.forms and formencode
> 2. If the first layer of validation passes, try to run the authorize.net charge using the authorize package. If this returns a response code of 1 (approved) then all validation has passed. Otherwise, invalidate the form and flash the authorize.net error.

## The Authorize Package

The authorize package handles authorize.net requests, and can be found here or by typing: `easy_install authorize`

## Defining The Validator

First we will need to define our ProcessCard() class which will be the chained FancyValidator for processing the card:

    import tw.forms as twf
    from authorize import aim as aim_api

    # FancyValidator to process the Credit Card using the authorize package
    class ProcessCard(twf.validators.FancyValidator):
        def _to_python(self, value, state):
            # Setup the aim Api object.
            aim = aim_api.Api(AUTHNET_LOGIN, AUTHNET_KEY, is_test=False)

            # Create a transaction against a credit card
            result_dict = aim.transaction(
                amount=u"16.00",
                card_num=unicode(value['card_number']),
                exp_date=unicode(value['card_expiry']),
                # ...and others...
                )

            if result_dict['code'] == '1':
                # success
                return value
            else:
                # failure
                raise twf.validators.Invalid(result_dict['reason_text'], value, state)

## Defining The Form

Next we’ll define our form class that will end up being passed to the view:

    from tw.api import WidgetsList

    class AuthnetForm(twf.TableForm):
        submit_text='Process Card'

        # specify chained validators
        validator = twf.validators.Schema(
            chained_validators = [
                twf.validators.CreditCardValidator('card_type','card_number'),
                twf.validators.CreditCardSecurityCode('card_type','card_cvv'),
                # you could also add an expiry validator, but authnet will handle this for you
                ProcessCard()
            ]
        )

        # specify form fields
        class fields(WidgetsList):
            name = twf.TextField(validator=twf.validators.String(not_empty=True))
            # ...and others like address, city, state, zip...
            spacer = twf.Spacer(suppress_label=True)
            card_type = twf.SingleSelectField(options=[('visa', 'Visa'),
                                                       ('mastercard', 'Master Card'),
                                                       ('discover', 'Discover'),
                                                       ('amex', 'American Express')], validator=twf.validators.NotEmpty)
            card_expiry = twf.CalendarDatePicker(date_format="%m/%Y", validator=twf.validators.NotEmpty)
            card_number = twf.TextField(label_text='Card #', validator=twf.validators.NotEmpty)
            card_cvv = twf.TextField(label_text='CVV Code', validator=twf.validators.NotEmpty)

## Using It In A Controller

Now all you have to do is set up your controller class methods to use the form:

    # Assign a name to the form
    authnet_form = AuthnetForm('authnet_form', action='/authnet/process/')

    class AuthnetController(BaseController):
        @expose('authnet.templates.index')
        def index(self, **kw):
            if '_the_form' in tmpl_context.form_errors:
                # if we have top-level form errors, use flash() to display them
                flash(tmpl_context.form_errors['_the_form'], 'error')
            # Use ${form()} to print the form in your template
            return dict(form=authnet_form)

        @validate(authnet_form, error_handler=index)
        @expose()
        def process(self, **kw):
            # if validation passes, this method will run (specified by form action)
            return 'Card was successfully charged!'