Commit 7601d5f9 authored by mattwire's avatar mattwire

Merge branch 'leavepagealert' into 'master'

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

See merge request !14
parents 6330e54d c4fe693c
......@@ -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