Commit 4ee7e494 authored by drastik's avatar drastik

Major changes to the buildForm and other Stripe-activation logic.

Fix in civicrm_stripe.js that was causing "Stripe.js Not passed" because token was empty.
Fix error message about accessing static variable.
Large cleanup to code structure in stripe.php.
parent 011843bd
...@@ -19,9 +19,8 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment { ...@@ -19,9 +19,8 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
* Mode of operation: live or test. * Mode of operation: live or test.
* *
* @var object * @var object
* @static
*/ */
static protected $_mode = NULL; protected $_mode = NULL;
/** /**
* Constructor * Constructor
...@@ -32,31 +31,12 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment { ...@@ -32,31 +31,12 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
* @return void * @return void
*/ */
function __construct($mode, &$paymentProcessor) { function __construct($mode, &$paymentProcessor) {
self::$_mode = $mode; $this->_mode = $mode;
$this->_islive = ($mode == 'live' ? 1 : 0);
$this->_paymentProcessor = $paymentProcessor; $this->_paymentProcessor = $paymentProcessor;
$this->_processorName = ts('Stripe'); $this->_processorName = ts('Stripe');
} }
/**
* Singleton function used to manage this object.
*
* @param string $mode the mode of operation: live or test
* @param object $paymentProcessor the details of the payment processor being invoked
* @param object $paymentForm reference to the form object if available
* @param boolean $force should we force a reload of this payment object
*
* @return object
* @static
*
*/
static function &singleton($mode = 'test', &$paymentProcessor, &$paymentForm = NULL, $force = FALSE) {
$processorName = $paymentProcessor['name'];
if (self::$_singleton[$processorName] === NULL || $force) {
self::$_singleton[$processorName] = new self($mode, $paymentProcessor);
}
return self::$_singleton[$processorName];
}
/** /**
* This function checks to see if we have the right config values. * This function checks to see if we have the right config values.
* *
...@@ -256,16 +236,6 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment { ...@@ -256,16 +236,6 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
return $params; return $params;
} }
// Get live/test mode.
switch ($this->_mode) {
case 'test':
$params['transaction_mode'] = $transaction_mode = 0;
break;
case 'live':
$params['transaction_mode'] = $transaction_mode = 1;
break;
}
// Get proper entry URL for returning on error. // Get proper entry URL for returning on error.
if (!(array_key_exists('qfKey', $params))) { if (!(array_key_exists('qfKey', $params))) {
// Probably not called from a civicrm form (e.g. webform) - // Probably not called from a civicrm form (e.g. webform) -
...@@ -344,7 +314,7 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment { ...@@ -344,7 +314,7 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
$customer_query = CRM_Core_DAO::singleValueQuery("SELECT id $customer_query = CRM_Core_DAO::singleValueQuery("SELECT id
FROM civicrm_stripe_customers FROM civicrm_stripe_customers
WHERE email = %1 AND is_live = '$transaction_mode'", $query_params); WHERE email = %1 AND is_live = '{$this->_islive}'", $query_params);
/**** /****
* If for some reason you cannot use Stripe.js and you are aware of PCI Compliance issues, * If for some reason you cannot use Stripe.js and you are aware of PCI Compliance issues,
...@@ -401,7 +371,7 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment { ...@@ -401,7 +371,7 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
); );
CRM_Core_DAO::executeQuery("INSERT INTO civicrm_stripe_customers CRM_Core_DAO::executeQuery("INSERT INTO civicrm_stripe_customers
(email, id, is_live) VALUES (%1, %2, '$transaction_mode')", $query_params); (email, id, is_live) VALUES (%1, %2, '{$this->_islive}')", $query_params);
} }
else { else {
CRM_Core_Error::fatal(ts('There was an error saving new customer within Stripe. Is Stripe down?')); CRM_Core_Error::fatal(ts('There was an error saving new customer within Stripe. Is Stripe down?'));
...@@ -453,7 +423,7 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment { ...@@ -453,7 +423,7 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
1 => array($email, 'String'), 1 => array($email, 'String'),
); );
CRM_Core_DAO::executeQuery("DELETE FROM civicrm_stripe_customers CRM_Core_DAO::executeQuery("DELETE FROM civicrm_stripe_customers
WHERE email = %1 AND is_live = '$transaction_mode'", $query_params); WHERE email = %1 AND is_live = '{$this->_islive}'", $query_params);
// Create new record for this customer. // Create new record for this customer.
$query_params = array( $query_params = array(
...@@ -461,7 +431,7 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment { ...@@ -461,7 +431,7 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
2 => array($stripe_customer->id, 'String'), 2 => array($stripe_customer->id, 'String'),
); );
CRM_Core_DAO::executeQuery("INSERT INTO civicrm_stripe_customers (email, id, is_live) CRM_Core_DAO::executeQuery("INSERT INTO civicrm_stripe_customers (email, id, is_live)
VALUES (%1, %2, '$transaction_mode')", $query_params); VALUES (%1, %2, '{$this->_islive}')", $query_params);
} }
else { else {
// Customer was found in civicrm_stripe database, but unable to be // Customer was found in civicrm_stripe database, but unable to be
...@@ -551,8 +521,6 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment { ...@@ -551,8 +521,6 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
* @public * @public
*/ */
function doRecurPayment(&$params, $amount, $stripe_customer) { function doRecurPayment(&$params, $amount, $stripe_customer) {
$transaction_mode = $params['transaction_mode'];
// Get recurring contrib properties. // Get recurring contrib properties.
$frequency = $params['frequency_unit']; $frequency = $params['frequency_unit'];
$installments = $params['installments']; $installments = $params['installments'];
...@@ -567,7 +535,7 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment { ...@@ -567,7 +535,7 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
$stripe_plan_query = CRM_Core_DAO::singleValueQuery("SELECT plan_id $stripe_plan_query = CRM_Core_DAO::singleValueQuery("SELECT plan_id
FROM civicrm_stripe_plans FROM civicrm_stripe_plans
WHERE plan_id = %1 AND is_live = '$transaction_mode'", $query_params); WHERE plan_id = %1 AND is_live = '{$this->_islive}'", $query_params);
if (!isset($stripe_plan_query)) { if (!isset($stripe_plan_query)) {
$formatted_amount = '$' . number_format(($amount / 100), 2); $formatted_amount = '$' . number_format(($amount / 100), 2);
...@@ -594,7 +562,7 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment { ...@@ -594,7 +562,7 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
1 => array($plan_id, 'String'), 1 => array($plan_id, 'String'),
); );
CRM_Core_DAO::executeQuery("INSERT INTO civicrm_stripe_plans (plan_id, is_live) CRM_Core_DAO::executeQuery("INSERT INTO civicrm_stripe_plans (plan_id, is_live)
VALUES (%1, '$transaction_mode')", $query_params); VALUES (%1, '{$this->_islive}')", $query_params);
} }
// If a contact/customer has an existing active recurring // If a contact/customer has an existing active recurring
...@@ -623,7 +591,7 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment { ...@@ -623,7 +591,7 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
$existing_subscription_query = CRM_Core_DAO::singleValueQuery("SELECT invoice_id $existing_subscription_query = CRM_Core_DAO::singleValueQuery("SELECT invoice_id
FROM civicrm_stripe_subscriptions FROM civicrm_stripe_subscriptions
WHERE customer_id = %1 AND is_live = '$transaction_mode'", $query_params); WHERE customer_id = %1 AND is_live = '{$this->_islive}'", $query_params);
if (!empty($existing_subscription_query)) { if (!empty($existing_subscription_query)) {
// Cancel existing Recurring Contribution in CiviCRM. // Cancel existing Recurring Contribution in CiviCRM.
...@@ -658,14 +626,14 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment { ...@@ -658,14 +626,14 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
if (empty($installments)) { if (empty($installments)) {
CRM_Core_DAO::executeQuery("INSERT INTO civicrm_stripe_subscriptions CRM_Core_DAO::executeQuery("INSERT INTO civicrm_stripe_subscriptions
(customer_id, invoice_id, is_live) (customer_id, invoice_id, is_live)
VALUES (%1, %2, '$transaction_mode')", $query_params); VALUES (%1, %2, '{$this->_islive}')", $query_params);
} }
else { else {
// Add the end time to the query params. // Add the end time to the query params.
$query_params[3] = array($end_time, 'Integer'); $query_params[3] = array($end_time, 'Integer');
CRM_Core_DAO::executeQuery("INSERT INTO civicrm_stripe_subscriptions CRM_Core_DAO::executeQuery("INSERT INTO civicrm_stripe_subscriptions
(customer_id, invoice_id, end_time, is_live) (customer_id, invoice_id, end_time, is_live)
VALUES (%1, %2, %3, '$transaction_mode')", $query_params); VALUES (%1, %2, %3, '{$this->_islive}')", $query_params);
} }
$params['trxn_id'] = $stripe_response->id; $params['trxn_id'] = $stripe_response->id;
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
<author>Joshua Walker (drastik) - Drastik by Design</author> <author>Joshua Walker (drastik) - Drastik by Design</author>
<email>admin@drastikbydesign.com</email> <email>admin@drastikbydesign.com</email>
</maintainer> </maintainer>
<releaseDate>2015-09-09</releaseDate> <releaseDate>2015-10-09</releaseDate>
<version>1.9.2</version> <version>1.9.2</version>
<compatibility> <compatibility>
<ver>4.4</ver> <ver>4.4</ver>
......
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
} }
else { else {
if (!($('.stripe-payment-form').length)) { if (!($('.stripe-payment-form').length)) {
$('#crm-container>form').addClass('stripe-payment-form'); $('#crm-container > form').addClass('stripe-payment-form');
} }
} }
$form = $('form.stripe-payment-form'); $form = $('form.stripe-payment-form');
...@@ -59,8 +59,8 @@ ...@@ -59,8 +59,8 @@
} }
else { else {
$submit = $form.find('input[type="submit"][formnovalidate!="1"]'); $submit = $form.find('input[type="submit"][formnovalidate!="1"]');
// If CiviDiscount button or field is submitted, flag the form // If CiviDiscount button or field is submitted, flag the form.
$form.data('cividiscount-dont-handle', '0'); $form.data('cividiscount-dont-handle', '0');
$form.find('input[type="submit"][formnovalidate="1"]').click( function() { $form.find('input[type="submit"][formnovalidate="1"]').click( function() {
$form.data('cividiscount-dont-handle', 1); $form.data('cividiscount-dont-handle', 1);
...@@ -73,6 +73,7 @@ ...@@ -73,6 +73,7 @@
$submit; $submit;
} }
// For CiviCRM Webforms.
if (isWebform) { if (isWebform) {
if (!($('#action').length)) { if (!($('#action').length)) {
$form.append('<input type="hidden" name="op" id="action" />'); $form.append('<input type="hidden" name="op" id="action" />');
...@@ -92,7 +93,7 @@ ...@@ -92,7 +93,7 @@
var webformPrevious = $('input.webform-previous').first().val(); var webformPrevious = $('input.webform-previous').first().val();
} }
else { else {
// This is native civicrm form - check for existing token // This is native civicrm form - check for existing token.
if ($form.find("input#stripe-token").val()) { if ($form.find("input#stripe-token").val()) {
$('.credit_card_info-group').hide(); $('.credit_card_info-group').hide();
$('#billing-payment-block').append('<input type="button" value="Edit CC details" id="ccButton" />'); $('#billing-payment-block').append('<input type="button" value="Edit CC details" id="ccButton" />');
...@@ -110,8 +111,8 @@ ...@@ -110,8 +111,8 @@
// Intercept form submission. // Intercept form submission.
$form.submit(function (event) { $form.submit(function (event) {
// Don't handle submits generated by the CiviDiscount button // Don't handle submits generated by the CiviDiscount button.
if ($form.data('cividiscount-dont-handle') == 1) { if ($form.data('cividiscount-dont-handle') == 1) {
return true; return true;
} }
if (isWebform) { if (isWebform) {
...@@ -138,11 +139,12 @@ ...@@ -138,11 +139,12 @@
buttonText = $submit.attr('value'); buttonText = $submit.attr('value');
$submit.prop('disabled', true).attr('value', 'Processing'); $submit.prop('disabled', true).attr('value', 'Processing');
// Hide payment if total is 0 and no more participants // Hide payment if total is 0 and no more participants.
if ($('#priceset').length) { if ($('#priceset').length) {
currentTotal = cj('#pricevalue').text().replace(/[^\/\d]/g,'');
additionalParticipants = cj("#additional_participants").val(); additionalParticipants = cj("#additional_participants").val();
// The currentTotal is already being calculated in Form/Contribution/Main.tpl.
if (currentTotal == 0 && !additionalParticipants) { if (currentTotal == 0 && !additionalParticipants) {
// This is also hit when "Going back", but we already have stripe_token.
return true; return true;
} }
} }
...@@ -161,7 +163,7 @@ ...@@ -161,7 +163,7 @@
} }
} }
// Handle pay later (option value '0' in payment_processor radio group) // Handle pay later (option value '0' in payment_processor radio group).
if ($form.find('input[name="payment_processor"]:checked').length && !parseInt($form.find('input[name="payment_processor"]:checked').val())) { if ($form.find('input[name="payment_processor"]:checked').length && !parseInt($form.find('input[name="payment_processor"]:checked').val())) {
return true; return true;
} }
......
...@@ -32,7 +32,7 @@ function stripe_civicrm_install() { ...@@ -32,7 +32,7 @@ function stripe_civicrm_install() {
`email` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL, `email` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`id` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `id` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`is_live` tinyint(4) NOT NULL COMMENT 'Whether this is a live or test transaction', `is_live` tinyint(4) NOT NULL COMMENT 'Whether this is a live or test transaction',
UNIQUE KEY `email` (`email`) UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
"); ");
...@@ -125,14 +125,17 @@ function stripe_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) { ...@@ -125,14 +125,17 @@ function stripe_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) {
* @param $errors - Reference to the errors array. * @param $errors - Reference to the errors array.
*/ */
function stripe_civicrm_validateForm($formName, &$fields, &$files, &$form, &$errors) { function stripe_civicrm_validateForm($formName, &$fields, &$files, &$form, &$errors) {
if ((isset($form->_paymentProcessor['payment_processor_type']) &&$form->_paymentProcessor['payment_processor_type'] == 'Stripe') if (empty($form->_paymentProcessor['payment_processor_type'])) {
|| (!isset($form->_paymentProcessor['payment_processor_type']) && isset($form->_elementIndex['stripe_token']))) { return;
if($form->elementExists('credit_card_number')){ }
// If Stripe is active here.
if (isset($form->_elementIndex['stripe_token'])) {
if ($form->elementExists('credit_card_number')) {
$cc_field = $form->getElement('credit_card_number'); $cc_field = $form->getElement('credit_card_number');
$form->removeElement('credit_card_number', true); $form->removeElement('credit_card_number', true);
$form->addElement($cc_field); $form->addElement($cc_field);
} }
if($form->elementExists('cvv2')){ if ($form->elementExists('cvv2')) {
$cvv2_field = $form->getElement('cvv2'); $cvv2_field = $form->getElement('cvv2');
$form->removeElement('cvv2', true); $form->removeElement('cvv2', true);
$form->addElement($cvv2_field); $form->addElement($cvv2_field);
...@@ -148,79 +151,66 @@ function stripe_civicrm_validateForm($formName, &$fields, &$files, &$form, &$err ...@@ -148,79 +151,66 @@ function stripe_civicrm_validateForm($formName, &$fields, &$files, &$form, &$err
*/ */
function stripe_civicrm_buildForm($formName, &$form) { function stripe_civicrm_buildForm($formName, &$form) {
$stripe_key = stripe_get_key($form); $stripe_key = stripe_get_key($form);
if (!empty($stripe_key)) { // If this is not a form Stripe is involved in, do nothing.
if (!stristr($formName, '_Confirm') && !stristr($formName, '_ThankYou')) { if (empty($stripe_key)) {
// This is the 'Main', or first step of the form that collects CC data. return;
if (!$form->elementExists('stripe_token')) {
$form->setAttribute('class', $form->getAttribute('class') . ' stripe-payment-form');
$form->addElement('hidden', 'stripe_token', NULL, array('id' => 'stripe-token'));
}
stripe_add_stripe_js($stripe_key, $form);
}
else {
// This is a Confirm or Thank You (completed) form.
$params = $form->get('params');
// Contrib forms store this in $params, Event forms in $params[0].
if (!empty($params[0]['stripe_token'])) {
$params = $params[0];
}
if (!empty($params['stripe_token'])) {
// Stash the token (including its value) in Confirm, in case they go backwards.
$form->addElement('hidden', 'stripe_token', $params['stripe_token'], array('id' => 'stripe-token'));
}
}
} }
$params = $form->get('params');
// Contrib forms store this in $params, Event forms in $params[0].
if (!empty($params[0]['stripe_token'])) {
$params = $params[0];
}
$stripe_token = (empty($params['stripe_token']) ? NULL : $params['stripe_token']);
// For the 'Record Contribution' backend page. // Add some hidden fields for Stripe.
$backendForms = array( if (!$form->elementExists('stripe_token')) {
'CRM_Contribute_Form_Contribution', $form->setAttribute('class', $form->getAttribute('class') . ' stripe-payment-form');
'CRM_Event_Form_Participant', $form->addElement('hidden', 'stripe_token', $stripe_token, array('id' => 'stripe-token'));
'CRM_Member_Form_Membership', }
'CRM_Member_Form_MembershipRenewal' stripe_add_stripe_js($stripe_key, $form);
);
if (in_array($formName, $backendForms) && !empty($stripe_key)) { // Add email field as it would usually be found on donation forms.
if (!isset($form->_elementIndex['stripe_token'])) { if (!isset($form->_elementIndex['email']) && !empty($form->userEmail)) {
if (empty($form->_attributes['class'])) { $form->addElement('hidden', 'email', $form->userEmail, array('id' => 'user-email'));
$form->_attributes['class'] = '';
}
$form->_attributes['class'] .= ' stripe-payment-form';
$form->addElement('hidden', 'stripe_token', NULL, array('id' => 'stripe-token'));
stripe_add_stripe_js($stripe_key, $form);
}
// Add email field as it would usually be found on donation forms.
if (!isset($form->_elementIndex['email']) && !empty($form->userEmail)) {
$form->addElement('hidden', 'email', $form->userEmail, array('id' => 'user-email'));
}
} }
} }
/** /**
* Return the stripe api public key (aka password) * Return the stripe api public key (aka password)
* *
* If this form could conceiveably now or at any time in the future * If this form could conceiveably now or at any time in the future
* contain a Stripe payment processor, return the api public key for * contain a Stripe payment processor, return the api public key for
* that processor. * that processor.
*/ */
function stripe_get_key($form) { function stripe_get_key($form) {
// Backend contribution pages have the password embedded in them. // Only return first value if Stripe is the only/default.
if(isset($form->_paymentProcessor['password'])) { if ($form->_paymentProcessor['payment_processor_type'] == 'Stripe') {
return $form->_paymentProcessor['password']; if (isset($form->_paymentProcessor['password'])) {
return $form->_paymentProcessor['password'];
}
} }
// Otherwise we need to look through all active payprocs and find Stripe.
$is_test = 0; $is_test = 0;
if(isset($form->_mode)) { if (isset($form->_mode)) {
$is_test = $form->_mode == 'live' ? 0 : 1; $is_test = $form->_mode == 'live' ? 0 : 1;
} }
// _paymentProcessors array seems to be the most reliable way to find // The _paymentProcessors array seems to be the most reliable way to find
// at least payment processor on the form that is a stripe pp. // if the form is using Stripe.
if(isset($form->_paymentProcessors)) { if (!empty($form->_paymentProcessors)) {
foreach($form->_paymentProcessors as $k => $pp) { foreach ($form->_paymentProcessors as $pp) {
if($pp['payment_processor_type'] == 'Stripe') { if ($pp['payment_processor_type'] == 'Stripe') {
if (!empty($pp['password'])) {
return $pp['password'];
}
// We have a match. // We have a match.
return stripe_get_key_for_name($pp['name'], $is_test); return stripe_get_key_for_name($pp['name'], $is_test);
} }
} }
} }
// Return NULL if this is not a form with Stripe involved.
return NULL;
} }
/** /**
...@@ -230,13 +220,13 @@ function stripe_get_key_for_name($name, $is_test) { ...@@ -230,13 +220,13 @@ function stripe_get_key_for_name($name, $is_test) {
try { try {
$params = array('name' => $name, 'is_test' => $is_test); $params = array('name' => $name, 'is_test' => $is_test);
$results = civicrm_api3('PaymentProcessor', 'get', $params); $results = civicrm_api3('PaymentProcessor', 'get', $params);
if($results['count'] == 1) { if ($results['count'] == 1) {
$result = array_pop($results['values']); $result = array_pop($results['values']);
return $result['password']; return $result['password'];
} }
} }
catch (CiviCRM_API3_Exception $e) { catch (CiviCRM_API3_Exception $e) {
return NULL; return NULL;
} }
} }
...@@ -245,8 +235,7 @@ function stripe_get_key_for_name($name, $is_test) { ...@@ -245,8 +235,7 @@ function stripe_get_key_for_name($name, $is_test) {
*/ */
function stripe_add_stripe_js($stripe_key, $form) { function stripe_add_stripe_js($stripe_key, $form) {
$form->addElement('hidden', 'stripe_pub_key', $stripe_key, array('id' => 'stripe-pub-key')); $form->addElement('hidden', 'stripe_pub_key', $stripe_key, array('id' => 'stripe-pub-key'));
CRM_Core_Resources::singleton() CRM_Core_Resources::singleton()->addScriptFile('com.drastikbydesign.stripe', 'js/civicrm_stripe.js', 0);
->addScriptFile('com.drastikbydesign.stripe', 'js/civicrm_stripe.js', 0);
} }
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment