Listing 1 CreditCard.cfc


<!--- The Credit Card CFC is the Base Class for Credit Card CFCs. --->
<cfcomponent displayname="CreditCard" hint="Base Class for Credit Card CFCs">
<!--- The Template Method for CreditCard.cfc is RunTransaction(). RunTransaction() calls the two hook methods VerifyAddress() and ProcessCCTrans() which must be implemented in any derived CFC's. --->
<cffunction name="RunTransaction" access="public" output="false" return type="string">
<!--- The AddresData argument is a structure that is passed through to the VerifyAddress() method. 

Using a structure allows us to vary the number and name of arguments dependent upon their derived implementation. --->
<cfargument name="addressData" required="true" type="struct">
<cfargument name="transactionData" required="true" type="struct">
<cfif VerifyAddress(arguments.addressData)>
<cfreturn processCCtrans(arguments.transactionData)>
<cfelse>
<cfreturn "Cannot Verify Address">
</cfif>
</cffunction>
<cffunction name="ProcessCCTrans" access="public" output="false" returntype="string">
<!--- Abstract Method - Must be overridden or will abort --->
<cfabort showerror="This Method is Abstract and needs to be overridden">
</cffunction>
<cffunction name="VerifyAddress" access="public" output="false" return type="boolean">
<!--- Abstract Method - Must be overridden or will abort --->
<cfabort showerror="This Method is Abstract and needs to be overridden">
</cffunction>
</cfcomponent>



Listing 2 VisaCC.cfc


<cfcomponent displayname="VisaCC" extends="CreditCard" hint="Base Class for Credit Card CFCs">

<cffunction name="VerifyAddress" access="public" output="false" return type="boolean">
<cfargument name="addressData" type="string" required="true" />
<cfparam name="arguments.addressdata.name" type="string" />
<cfparam name="arguments.addressdata.street1" type="string" />
<cfparam name="arguments.addressdata.street2" default="" type="string" />
<cfparam name="arguments.addressdata.city" type="string" />
<cfparam name="arguments.addressdata.state" type="string" />
<cfparam name="arguments.addressdata.zip" type="string" />
<!--- In the real world you would actually do something here --->
<cfreturn true>
</cffunction>
<cffunction name="processCCtrans" access="public" output="false" returntype="string">
<cfargument name="transactionData" type="string" required="true" />
<cfparam name="arguments.transactionData.name" type="string" />
<cfparam name="arguments.transactionData.ccnumber" type="string" />
<cfparam name="arguments.transactionData.amount" type="numeric">
<cfparam name="arguments.transactionData.securitycode" type="string" />
<cfparam name="arguments.transactionData.expiration" type="date">
<!--- In the real world you would actually do something here --->
<!--- Instead a random determination of approval ---> 
<cfif len(arguments.transactionData.amount) GT 100>
<cfreturn "Decline"> 
<cfelse>
<cfreturn "98765432"> 
</cfif>
</cffunction>
</cfcomponent>




Listing 3 AmexCC.cfc


<cfcomponent displayname="AmexCC" extends="CreditCard" hint="Base Class for Credit Card CFCs">

<cffunction name="VerifyAddress" access="public" output="false" returntype="boolean">
<cfargument name="addressData" type="string" required="true" />
<cfparam name="arguments.addressdata.name" type="string" />
<cfparam name="arguments.addressdata.street1" type="string" />
<cfparam name="arguments.addressdata.street2" default="" type="string" />
<cfparam name="arguments.addressdata.city" type="string" />
<cfparam name="arguments.addressdata.state" type="string" />
<cfparam name="arguments.addressdata.zip" type="string" />
<!--- In the real world you would actually do something here --->
<cfreturn true>
</cffunction>
<cffunction name="processCCtrans" access="public" output="false" returntype="string">
<cfargument name="transactionData" type="string" required="true" />
<cfparam name="arguments.transactionData.name" type="string" />
<cfparam name="arguments.transactionData.ccnumber" type="string" />
<cfparam name="arguments.transactionData.amount" type="numeric">
<cfparam name="arguments.transactionData.expiration" type="date">
<!--- In the real world you would actually do something here --->
<!--- Instead a random determination of approval ---> 
<cfif len(arguments.addressdata.amount) GT 100>
<cfreturn "Decline"> 
<cfelse>
<cfreturn "98765432"> 
</cfif>
</cffunction>
</cfcomponent>



Listing 4 ProcessCreditCard.cfm


<!--- Determine if this is a Submit event --->
<cfif IsDefined("form.CreditCard")>
<!--- Instantiate a CFC for the credit Card being processed --->
<cfif Not ListFindNoCase("AmexCC,VisaCC,DiscoverCC,MasterCardCC", form.CreditCard)>
<cfabort showerror="The Component ""#form.CreditCard#"" does not exist or is not authorized!">
</cfif>
<cfobject component="#form.CreditCard#" name="myCreditCard" />
<!--- Create a data structure to pass in to the processTransaction() 
method that will be passed through to the verifyAddress() method --- >
<cfset addressStructure = structNew()>
<cfset addressStructure.name = form.name>
<cfset addressStructure.street1 = form.street1>
<cfset addressStructure.street2 = form.street2>
<cfset addressStructure.city = form.city>
<cfset addressStructure.state = form.state>
<cfset addressStructure.zip = form.zip>
<!--- Create a --->
<cfset creditCardStructure = structNew()>
<cfset creditCardStructure.name = form.name>
<cfset creditCardStructure.ccnumber = form.ccnumber>
<cfset creditCardStructure.expiration = form.expiration>
<cfset creditCardStructure.amount = form.amount>
<!--- If a Security Code has been passed in via the form then add it to

the data structure to be passed through to the processCreditCard()method --->
<cfif form.securityCode neq "">
<cfset creditCardStructure.securityCode = form.securityCode>
</cfif>
<!--- Invoke the processTransaction() method passing in the two structures --->
<cfinvoke component="#myCreditCard#"
method="processTransaction"
returnvariable="approvalCode">
<cfinvokeargument name="addressData" value="#addressStructure#"> 
<cfinvokeargument name="creditCardData" value="#creditCardStructure#"> 
</cfinvoke>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Credit Card Transaction</title>
</head>
<body>
<cfif approvalCode eq "Declined">
We are unable to process your credit card transaction.
<br><br>
Your credit card has been declined.
<cfelseif approvalCode eq "Cannot verify address">
We are unable to process your credit card transaction.
<br><br>
We cannot verify your address.
<cfelse>
Your approval code is: <strong><cfoutput>#approvalCode#</cfoutput></strong>
<br><br>
Please print this page for your records.
</cfif>
</body>
</html>
</cfif>