Single click donations with CiviCRM

From Creative Commons
Revision as of 23:00, 13 May 2010 by Nkinkade (talk | contribs) (Summary)
Jump to: navigation, search

Summary

Creative Commons has developed a modified donation process using CiviCRM which can potentially send a contributor off to the payment processor with as little as a single click. All of the donation buttons on CC's donation page utilize this process.

There are a number of possible benefits to using this method as opposed to regular contribution pages in CiviCRM:

  • The contributor (potentially) makes a single click to donate on your site. The less clicks/keystrokes the better chance someone will complete a contribution. I believe this has been empirically tested and demonstrated (??).
  • You are no longer limited to designing your contribution pages within the confines/scope of Drupal and CiviCRM. You can create pages the way you want, wherever you want. This is especially nice for widgets, or anyone else wanting to help your campaign. Potentially, people can create their own donate links on their own sites ... it doesn't matter. And if you run multiple sites, you can place Donate links wherever you want on any of those sites, and it makes no difference whether it's run by Drupal, Wordpress, Joomla, or even made with static HTML.
  • Tired of Pending (Incomplete Transaction) contribution statuses and bogus contacts for people who never completed a transaction? This method virtually eliminates those because a contact/contribution is not created in the CiviCRM database until an IPN/notification is received from the payment processor.
  • As long as the "one-click" scripts are in place, the state of your CiviCRM install doesn't really matter from a user perspective, at least as it relates to contributions. This has been useful for CC when upgrading -- not having to worry about disrupting live contributions should an upgrade encounter problems.

The system is currently comprised of 2 custom scripts: a class file which contains all the code, and a simple router/wrapper script which receives and routes incoming requests:

Special Considerations

This method is known to work with CiviCRM versions 2.2.7, 3.1.1 and 3.1.3. It should work fine with any version in the 2.2.x or 3.1.x line.

It currently works with PayPal and Google Checkout.

The "one-click" method will not work without modifications to a couple other core CiviCRM files: CRM/Contribute/BAO/Contribution/Utils.php and bin/ContributionProcessor.php. The necessary patches for those files are here:

A couple of the modifications in the above patches are specific to CC and will probably need to be changed for other installations.

Once the scripts are in place and modified to suit your unique set up and needs, then there are two ways to make this process work.

  1. Using IPN/notifications from the payment processor.
  2. Running ContributionProcessor via a cron job periodically.

If using IPN/noticiations, then you will need to make two configurations. For PayPal you must set the variable $pp_config['paypal_notify_url'] in OneClickConfig.php to something like http://yoursite.org/sites/default/modules/civicrm/bin/OneClickIPN.php. For Google Checkout you must login to your merchant account and enter the same type of URL as for PayPal under Settings -> Integration.

If you choose to run bin/ContributionProcessor.php periodically to pull new contributions into CiviCRM, your crontab entry will probably look something like:

*/15 * * * * wget -O - -q -t 1 "https://support.creativecommons.org/sites \
/default/modules/civicrm/bin/ContributionProcessor.php?name=my_user& \
pass=my_pass&key=XXXXXXXXXXXXXXXXXXXXXXXX&ppID=5&ppMode=live&type=paypal" &> \
/dev/null; wget -O - -q -t 1 "https://support.creativecommons.org/sites/default \
/modules/civicrm/bin/ContributionProcessor.php?name=my_user&pass=my_pass& \
key=XXXXXXXXXXXXXXXXXXXXXXXXX&ppID=7&ppMode=live&type=google" &> /dev/null

Variables

All of the following are found and set in the file bin/OneClickConfig.php.

// Valid groups that users can join.  This is just a safeguard to prevent users
// from joining arbitrary groups
$pp_config['valid_groups'] = array(
    "CC Newsletter",
    "CC Events"
);

// PayPal processor name in CiviCRM db.  Unfortunately, at the moment this '''must''' be exactly "PayPal API Access".
$pp_config['paypal_pp_name'] = "PayPal API Access";

// Google Checkout processor name in CiviCRM db.  Unfortunately, at the moment this '''must''' be exactly "Google Checkout API Access".
$pp_config['gc_pp_name'] = "Google Checkout API Access";

// IPN callback URL for PayPal.  If you are not going to be using IPN, but instead ContributionProcessor.php run from a cron job, then set this to be an empty string.
$pp_config['paypal_notify_url'] = "https://support.creativecommons.org/sites/default/modules/civicrm/bin/OneClickIPN.php";

// Base URL for PayPal request (minus the query string).  This probably doesn't need to be changed.
$pp_config['paypal_base_url'] = "https://www.paypal.com/cgi-bin/webscr";

// Email address of site's PayPal merchant account
$pp_config['paypal_business'] = "paypal@creativecommons.org";

// Base URL for Google Checkout request.  This probably doesn't need to be changed.
$pp_config['gc_base_url'] = "https://checkout.google.com/api/checkout/v2/merchantCheckout/Merchant/";

// Default name of item as contributor sees it and as recorded in CiviCRM.
if ( ! empty($_REQUEST['source']) ) {
    $pp_config['item_name'] = $_REQUEST['source'];
} else {
    $pp_config['item_name'] = "Online Contribution: Support Creative Commons";
}

// Where contributor goes if they cancel contribution at payment processor
if ( ! empty($_REQUEST['cancel_return']) ) {
    $pp_config['cancel_return'] = $_REQUEST['cancel_return'];
} else {
    $pp_config['cancel_return'] = "https://support.creativecommons.org/donate";
}

// Where user goes when they click "Return to Merchant Site"
if ( ! empty($_REQUEST['return']) ) {
        $pp_config['return'] = $_REQUEST['return'];
} else {
        $pp_config['return'] = "https://support.creativecommons.org/thanks";
}

// Minimum contribution amount, anything lower will be kicked back.
$pp_config['min_amount'] = '5';

Usage

Anyone can make use of the script from anywhere, but the script expects certain variables to be passed to it. The only variables which are absolutely necessary are pp and amount. Here is a summary of the possible variables, which can be sent by either a GET or POST request:

  • pp (required): The payment processor to use. Presently it can be one of paypal and gc (for Google Checkout). Example: ?pp=paypal
  • amount (required): The amount of the contribution, with no currency symbol. It can be a floating number, but will get rounded to two decimal places if for some reason it has more. Example: ?amount=150
  • cancel_return (optional): This is the URL the contributor will be directed to should they for some reason click a Cancel link on the payment processor's site without having completed the transaction. Will always have a predefined default value should it not be passed. Example (urlencoded): ?cancel_return=http%3A%2F%2Flolz.biz%2Fthanks
  • groups (optional): A colon separated list of groups that the user should be subscribed to. The group names are the exact names as they are found in the CiviCRM database, spaces and all. The script will not let users join arbitrary groups. Passed groups that are not in the predefined groups list in OneClickDonate.php will be ignored. Example (urlencoded): ?groups=CC+Newsletter:CC+Events
  • pcpid (optional): If this contribution originated from a Personal Campaign Page (PCP), this is the CiviCRM database ID of the PCP page. Example: ?pcpid=8
  • premium (optional): If the user has opted for a gift/premium, this is the CiviCRM database ID of the premium they will get. Example: ?premium=12
    • size (optional): If the premium includes a t-shirt, this is a free-text description of the size. This option is ignored if premium is not set. Example (urlencoded): ?size=Adult+Large
  • receipt (optional): This is the database ID of the message template to use when generating a receipt email to the contributor. These are the message templates found in CiviCRM at CiviCRM -> Administer CiviCRM -> Configure -> Message Templates. This functionality allow you to send a different receipt message based on various criteria, whatever they may be. You can use any, all or none of a few variable tokens in the templates. They are pretty much self-explanatory and they are these:
    • %{amount}
    • %{date}
    • %{trxn_id}
    • %{first_name}
    • %{last_name}
  • return (optional): This is the URL the contributor will be directed to if/when they click on some link directing them back to your site after having completed the transaction. Will always have a predefined default value should it not be passed. Example (urlencoded): ?return=http%3A%2F%2Froflcon.org%2Fthanks
  • recur (optional): Defines whether this is to be a recurring contribution, and if so of what type. A passed value of 1 means that the amount will charged to the contributor's account every month for 12 months. A passed value of 2 means that the amount will be charged to the contributor's account every month indefinitely. Example: ?recur=1
  • sloptout (optional): If this variable is present in the request the contributor's name will not be included in the public supporter list on the CC support site. If the contribution originated from a PCP, the contributor will not show up in the "honor roll" list on the PCP page. The value doesn't matter. If this variable is not passed, the contributor's name will by default be displayed in public supporter listings. Example: ?slopout=LOL
  • source (optional): When the contributor is sent to the payment processor there is a description displayed letting them know what the payment is for. If this value is passed it will be the text that is displayed to the contributor. It is also the text that will be stored in the CiviCRM contribution field "Source," so it can used to identify where the contribution originated such as from the CC Network, a regular donation, a donation widget, etc. A default value is set in the script which will be used if this variable isn't passed. Will always have a predefined default value should it not be passed. Example (urlencoded): ?source=CC+Network+Annual+Membership