StarterCart 1.0 Beta Documentation: Donation

Donation

Sometimes a site needs to collect payment without standard products and prices. Fortunately, StarterCart doesn't need to know anything about the products themselves in order to do a checkout. In fact, there not need even be a product.

This example shows how StarterCart can be used to take donations. The .cfm checkout pages provided with StarterCart assume the existence of more standard products (even if from multiple different sources) and so won't be useful for collecting donations.

Instead, we will create a donation.cfm page to collect the payment. The first thing to remember is that, like any other page taking payments, it must be secure (SSL) - which is not shown in this example.

Here is the code for the page:

<cfimport prefix="cart" taglib="/admin/cart/tags">
<cf_PageController>

<cf_layout title="Donation">
<cf_layout>

<cf_sebForm>
	<cf_sebField name="Amount" type="money">
	<cf_sebGroup label="Address" id="group-address">
		<cf_sebField name="FirstName">
		<cf_sebField name="LastName">
		<cf_sebField name="Address1">
		<cf_sebField name="Address2">
		<cf_sebField name="City">
		<cf_sebField name="StateProvinceID">
		<cf_sebField name="PostalCode">
	</cf_sebGroup>
	<cf_sebGroup label="Payment">
		<cart:payment>
	</cf_sebGroup>
	<cf_sebField type="Submit" label="Donate!">
</cf_sebForm>

<cf_layout>

This is based on the included cart.cfm page, which is used for single-page order processing. The title of the page has been changed to "Donation". Since no proper products are in use and no shipping address is needed, <cart:items> and <cart:addresses> are removed in favor of more manual code. The payment processing, however, remains the same so <cart:payment> stays. The label for the submit button is also changed. On a real page, more visual changes would likely be made as well, but this is sufficient for an example.

The processing of this page also needs to change, so we will create a page controller for this page:

<cfcomponent extends="checkout.cart" output="no">

<cffunction name="loadData" access="public" returntype="struct" output="no">
	
	<cfset var vars = super.loadData()>
	
	<cfset vars.SebFormAttributes.forward = "donation-thanks.cfm">
	
	<cfreturn vars>
</cffunction>

<cffunction name="placeOrder" access="public" returntype="void" output="no">

	<cfset var sProduct = StructNew()>
	
	<cfscript>
	sProduct["ProductIdentifier"] = "donation:#arguments.Amount#";
	sProduct["Price"] = arguments.Amount;
	sProduct["ProductName"] = "Donation";
	</cfscript>
	
	<cfset variables.oCart.addItem(argumentCollection=sProduct)>
	<cfset variables.oCart.setBuyer(argumentCollection=arguments)>
	
	<cfset processPayment(argumentCollection=arguments)>
	
	<cfset closeOrder()>
	
</cffunction>

</cfcomponent>

The page controller inherits cart.cfc, as it is a single page cart (otherwise it would inherit _cart.cfc). The "loadData" method that returns data for the page remains the same except that we want the user to go to a donation-specific thank you page after the successful completion of the process.

The main cart page submits to a method named "placeOrder" (this could be changed by changing the "CFC_Method" attribute of <cf_sebForm>) so we will use that method here. Instead of the default actions, however, we will manually add in a "Donation" item to the cart and then set the buyer and process the payment. The "closeOrder" method must be called after payment is processed so that if the user goes back to the donation page they will have the ability to enter a second donation without messing up the data on the original one.