Commit c4fe693c authored by mattwire's avatar mattwire

Fix "Leave Page Alert" triggered on some browsers when submitting payment

parent 6330e54d
......@@ -279,6 +279,7 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
'is_required' => TRUE,
'month_field' => 'credit_card_exp_date_M',
'year_field' => 'credit_card_exp_date_Y',
'extra' => ['class' => 'crm-form-select'],
),
'credit_card_type' => array(
......@@ -617,6 +618,9 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
$recurParams = [
'id' => $params['contributionRecurID'],
'trxn_id' => $stripeSubscription->id,
// FIXME processor_id is deprecated as it is not guaranteed to be unique, but currently (CiviCRM 5.9)
// it is required by cancelSubscription (where it is called subscription_id)
'processor_id' => $stripeSubscription->id,
'auto_renew' => 1,
'cycle_day' => date('d'),
'next_sched_contribution_date' => $this->calculateNextScheduledDate($params),
......@@ -631,11 +635,6 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
}
}
// FIXME: Is this required?
// Add subscription_id so tests can properly work with recurring
// contributions.
$params['subscription_id'] = $stripeSubscription->id;
// Hook to allow modifying recurring contribution params
CRM_Stripe_Hook::updateRecurringContribution($recurParams);
// Update the recurring payment
......@@ -829,7 +828,7 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
public function cancelSubscription(&$message = '', $params = []) {
$this->setAPIParams();
$contributionRecurId = CRM_Utils_Array::value('crid', $_GET);
$contributionRecurId = $this->getRecurringContributionId($params);
try {
$contributionRecur = civicrm_api3('ContributionRecur', 'getsingle', array(
'id' => $contributionRecurId,
......@@ -938,6 +937,7 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
/**
* Get url for users to manage this recurring contribution for this processor.
* FIXME: Remove and increment min version once https://github.com/civicrm/civicrm-core/pull/13215 is merged.
*
* @param int $entityID
* @param null $entity
......@@ -1019,5 +1019,39 @@ INNER JOIN civicrm_contribution con ON ( con.contribution_recur_id = rec.id )
return isset($this->_paymentProcessor['url_recur']) ? $this->_paymentProcessor['url_recur'] : '';
}
/**
* Get the recurring contribution ID from parameters passed in to cancelSubscription
* Historical the data passed to cancelSubscription is pretty poor and doesn't include much!
*
* @param array $params
*
* @return int|null
*/
protected function getRecurringContributionId($params) {
// Not yet passed, but could be added via core PR
$contributionRecurId = CRM_Utils_Array::value('contribution_recur_id', $params);
if (!empty($contributionRecurId)) {
return $contributionRecurId;
}
// Not yet passed, but could be added via core PR
$contributionId = CRM_Utils_Array::value('contribution_id', $params);
try {
return civicrm_api3('Contribution', 'getvalue', ['id' => $contributionId, 'return' => 'contribution_recur_id']);
}
catch (Exception $e) {
$subscriptionId = CRM_Utils_Array::value('subscriptionId', $params);
if (!empty($subscriptionId)) {
try {
return civicrm_api3('ContributionRecur', 'getvalue', ['processor_id' => $subscriptionId, 'return' => 'id']);
}
catch (Exception $e) {
return NULL;
}
}
return NULL;
}
}
}
......@@ -389,4 +389,12 @@ class CRM_Stripe_Upgrader extends CRM_Stripe_Upgrader_Base {
return TRUE;
}
public function upgrade_5021() {
$this->ctx->log->info('Applying Stripe update 5021. Copy trxn_id to processor_id so we can cancel recurring contributions.');
civicrm_api3('StripeSubscription', 'copytrxnidtoprocessorid', []);
return TRUE;
}
}
......@@ -112,3 +112,31 @@ function civicrm_api3_stripe_subscription_updatetransactionids() {
}
return civicrm_api3_create_success($counts);
}
/**
* API function (used in 5021 upgrader) to copy trxn_id to processor_id in civicrm_contribution_recur table
* processor_id (named subscriptionId) is the only value available to cancelSubscription in 5.9 (and earlier).
* It is not ideal as processor_id is not guaranteed to be unique in the CiviCRM database (trxn_id is unique).
*
* @return array
*/
function civicrm_api3_stripe_subscription_copytrxnidtoprocessorid() {
$sql = "SELECT cr.trxn_id, cr.processor_id, cr.payment_processor_id, cpp.class_name FROM civicrm_contribution_recur cr
LEFT JOIN civicrm_payment_processor AS cpp ON cr.payment_processor_id = cpp.id
WHERE cpp.class_name = 'Payment_Stripe'";
$dao = CRM_Core_DAO::executeQuery($sql);
$counts = [
'updated' => 0,
];
while ($dao->fetch()) {
if (!empty($dao->trxn_id) && empty($dao->processor_id)) {
$updateSQL = "UPDATE civicrm_contribution_recur
SET processor_id=%1
WHERE trxn_id=%1;";
$updateParams = [1 => [$dao->trxn_id, 'String']];
CRM_Core_DAO::executeQuery($updateSQL, $updateParams);
$counts['updated']++;
}
}
return civicrm_api3_create_success($counts);
}
......@@ -20,4 +20,5 @@ The api commands are:
### Additionally for upgrading:
* `StripeCustomer.updatecontactids` - Used to migrate civicrm_stripe_customer table to match on contact_id instead of email address.
* `StripeSubscription.updatetransactionids` - Used to migrate civicrm_stripe_subscriptions to use recurring contributions directly.
\ No newline at end of file
* `StripeSubscription.updatetransactionids` - Used to migrate civicrm_stripe_subscriptions to use recurring contributions directly.
* `StripeSubscription.copytrxnidtoprocessorid` - Used to copy trxn_id to processor_id in civicrm_contribution_recur table so we can use cancelSubscription. Hopefully this won't be needed in future versions of CiviCRM if we can pass more sensible values to the cancelSubscription function.
\ No newline at end of file
......@@ -12,8 +12,8 @@
<author>Matthew Wire (MJW Consulting)</author>
<email>mjw@mjwconsult.co.uk</email>
</maintainer>
<releaseDate>2018-11-21</releaseDate>
<version>5.2beta1</version>
<releaseDate>2018-12-13</releaseDate>
<version>5.2beta2</version>
<develStage>beta</develStage>
<compatibility>
<ver>5.3</ver>
......
......@@ -47,6 +47,9 @@ CRM.$(function($) {
// Prepare the form.
var onclickAction = null;
$(document).ready(function() {
// Disable the browser "Leave Page Alert" which is triggered because we mess with the form submit function.
window.onbeforeunload = null;
// Load Stripe onto the form.
loadStripeBillingBlock();
$submit = getBillingSubmit();
......
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