Skip to content
Snippets Groups Projects
Commit ab887e3a authored by Richard Burton's avatar Richard Burton
Browse files

Make civicrm stripe extension work with webform

parent 7e609013
Branches
Tags
No related merge requests found
......@@ -98,6 +98,22 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
CRM_Core_Error::debug_log_message("Stripe_Error {$op}: <pre> {$body} </pre>");
}
/**
* Check if return from stripeCatchErrors was an error object
* that should be passed back to original api caller.
*
* @param $stripeReturn
* The return from a call to stripeCatchErrors
* @return bool
*
*/
function isErrorReturn($stripeReturn) {
if (is_object($stripeReturn) && get_class($stripeReturn) == 'CRM_Core_Error') {
return true;
}
return false;
}
/**
* Run Stripe calls through this to catch exceptions gracefully.
*
......@@ -157,9 +173,22 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
$error_message .= 'Code: ' . $err['code'] . '<br />';
$error_message .= 'Message: ' . $err['message'] . '<br />';
if (isset($error_url)) {
// Redirect to first page of form and present error.
CRM_Core_Error::statusBounce("Oops! Looks like there was an error. Payment Response:
<br /> {$error_message}", $error_url);
}
else {
// Don't have return url - return error object to api
$core_err = CRM_Core_Error::singleton();
if ($err['code']) {
$core_err->push($err['code'], 0, NULL, $err['message']);
}
else {
$core_err->push(9000, 0, NULL, 'Unknown Error');
}
return $core_err;
}
}
catch (Exception $e) {
if (is_a($e, 'Stripe_Error')) {
......@@ -186,9 +215,22 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
$error_message .= 'Code: ' . $err['code'] . "<br />";
$error_message .= 'Message: ' . $err['message'] . "<br />";
if (isset($error_url)) {
// Redirect to first page of form and present error.
CRM_Core_Error::statusBounce("Oops! Looks like there was an error. Payment Response:
<br /> {$error_message}", $error_url);
}
else {
// Don't have return url - return error object to api
$core_err = CRM_Core_Error::singleton();
if ($err['code']) {
$core_err->push($err['code'], 0, NULL, $err['message']);
}
else {
$core_err->push(9000, 0, NULL, 'Unknown Error');
}
return $core_err;
}
}
return $return;
......@@ -213,11 +255,18 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
}
// Get proper entry URL for returning on error.
$qfKey = $params['qfKey'];
$parsed_url = parse_url($params['entryURL']);
$url_path = substr($parsed_url['path'], 1);
$params['stripe_error_url'] = $error_url = CRM_Utils_System::url($url_path,
if (!(array_key_exists('qfKey', $params))) {
// Probably not called from a civicrm form (e.g. webform) -
// will return error object to original api caller.
$params['stripe_error_url'] = $error_url = null;
}
else {
$qfKey = $params['qfKey'];
$parsed_url = parse_url($params['entryURL']);
$url_path = substr($parsed_url['path'], 1);
$params['stripe_error_url'] = $error_url = CRM_Utils_System::url($url_path,
$parsed_url['query'] . "&_qf_Main_display=1&qfKey={$qfKey}", FALSE, NULL, FALSE);
}
// Include Stripe library & Set API credentials.
require_once('stripe-php/lib/Stripe.php');
......@@ -330,6 +379,9 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
// Store the relationship between CiviCRM's email address for the Contact & Stripe's Customer ID.
if (isset($stripe_customer)) {
if ($this->isErrorReturn($stripe_customer)) {
return $stripe_customer;
}
// Prepare escaped query params.
$query_params = array(
1 => array($email, 'String'),
......@@ -347,6 +399,9 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
// Customer was found in civicrm_stripe database, fetch from Stripe.
$stripe_customer = $this->stripeCatchErrors('retrieve_customer', $customer_query, $params);
if (!empty($stripe_customer)) {
if ($this->isErrorReturn($stripe_customer)) {
return $stripe_customer;
}
// Avoid the 'use same token twice' issue while still using latest card.
if (!empty($params['selectMembership'])
&& $params['selectMembership']
......@@ -357,7 +412,10 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
}
else {
$stripe_customer->card = $card_details;
$this->stripeCatchErrors('save', $stripe_customer, $params);
$response = $this->stripeCatchErrors('save', $stripe_customer, $params);
if (isset($response) && $this->isErrorReturn($response)) {
return $response;
}
}
}
else {
......@@ -375,6 +433,9 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
// with a Customer within Stripe. (Perhaps deleted using Stripe interface?).
// Store the relationship between CiviCRM's email address for the Contact & Stripe's Customer ID.
if (isset($stripe_customer)) {
if ($this->isErrorReturn($stripe_customer)) {
return $stripe_customer;
}
// Delete whatever we have for this customer.
$query_params = array(
1 => array($email, 'String'),
......@@ -429,19 +490,33 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
// Fire away! Check for errors before trying to submit.
$stripe_response = $this->stripeCatchErrors('charge', $stripe_charge, $params);
if (!empty($stripe_response)) {
if ($this->isErrorReturn($stripe_response)) {
return $stripe_response;
}
// Success! Return some values for CiviCRM.
$params['trxn_id'] = $stripe_response->id;
// Return fees & net amount for Civi reporting.
// Uses new Balance Trasaction object.
$balance_transaction = $this->stripeCatchErrors('retrieve_balance_transaction', $stripe_response->balance_transaction, $params);
if (!empty($balance_transaction)) {
if ($this->isErrorReturn($balance_transaction)) {
return $balance_transaction;
}
$params['fee_amount'] = $balance_transaction->fee / 100;
$params['net_amount'] = $balance_transaction->net / 100;
}
}
else {
// There was no response from Stripe on the create charge command.
CRM_Core_Error::statusBounce('Stripe transaction response not recieved! Check the Logs section of your stripe.com account.', $error_url);
if (isset($error_url)) {
CRM_Core_Error::statusBounce('Stripe transaction response not recieved! Check the Logs section of your stripe.com account.', $error_url);
}
else {
// Don't have return url - return error object to api
$core_err = CRM_Core_Error::singleton();
$core_err->push(9000, 0, NULL, 'Stripe transaction response not recieved! Check the Logs section of your stripe.com account.');
return $core_err;
}
}
return $params;
......
......@@ -5,6 +5,7 @@
(function($, CRM) {
var $form, $submit, buttonText;
var isWebform = false;
// Response from Stripe.createToken.
function stripeResponseHandler(status, response) {
......@@ -29,6 +30,10 @@
var token = response['id'];
// Update form with the token & submit.
$form.find("input#stripe-token").val(token);
if (isWebform) {
$form.find("input#credit_card_number").removeAttr('name');
$form.find("input#cvv2").removeAttr('name');
}
$submit.prop('disabled', false);
window.onbeforeunload = null;
$form.get(0).submit();
......@@ -41,8 +46,32 @@
Stripe.setPublishableKey($('#stripe-pub-key').val());
});
if ($('.webform-client-form').length) {
isWebform = true;
$('form.webform-client-form').addClass('stripe-payment-form');
}
else {
$('#crm-container>form').addClass('stripe-payment-form');
}
$form = $('form.stripe-payment-form');
$submit = $form.find('[type="submit"]');
if (isWebform) {
$submit = $form.find('.button-primary');
}
else {
$submit = $form.find('input[type="submit"]');
}
if (isWebform) {
if (!($('#action').length)) {
$form.append($('<input type="hidden" name="op" id="action" />'));
}
var $actions = $form.find('input[type=submit]');
$(":submit").click(function() {
$('#action').val(this.value);
});
$('#billingcheckbox:input').hide();
$('label[for="billingcheckbox"]').hide();
}
$submit.removeAttr('onclick');
......@@ -50,13 +79,36 @@
// Intercept form submission.
$form.submit(function (event) {
if (isWebform) {
var $processorFields = $('.civicrm-enabled[name$="civicrm_1_contribution_1_contribution_payment_processor_id]"]');
var plabel = $('input[name$="civicrm_1_contribution_1_contribution_payment_processor_id]"]:checked').next().text();
if ($('#action').attr('value') == "< Previous Page") {
return true;
}
if ($('#wf-crm-billing-total').length) {
if ($('#wf-crm-billing-total').data('data-amount') == '0') {
return true;
}
}
if ($processorFields.length) {
if ($processorFields.filter(':checked').val() == '0') {
return true;
}
if (!(plabel.indexOf('stripe') >= 0)) {
return true;
}
}
}
// Disable the submit button to prevent repeated clicks, cache button text, restore if Stripe returns error
buttonText = $submit.attr('value');
$submit.prop('disabled', true).attr('value', 'Processing');
if ($('#priceset').length) {
if ($form.find("#priceset input[type='radio']:checked").data('amount') == 0) {
return true;
}
}
// Handle multiple payment options and Stripe not being chosen.
if ($form.find(".crm-section.payment_processor-section").length > 0) {
......
......@@ -122,10 +122,13 @@ function stripe_civicrm_buildForm($formName, &$form) {
if (!stristr($formName, '_Confirm') && !stristr($formName, '_ThankYou')) {
// This is the 'Main', or first step of the form that collects CC data.
if (!isset($form->_elementIndex['stripe_token'])) {
if (empty($form->_attributes['class'])) {
$form->_attributes['class'] = '';
}
$form->_attributes['class'] .= ' stripe-payment-form';
/*
* Moved this to civicrm_stripe.js for webform patch
* if (empty($form->_attributes['class'])) {
* $form->_attributes['class'] = '';
* }
* $form->_attributes['class'] .= ' stripe-payment-form';
*/
$form->addElement('hidden', 'stripe_token', NULL, array('id' => 'stripe-token'));
stripe_add_stripe_js($form);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment