This PR addresses an issue where we have insufficient nuance on processor capabilities for cancel.
There are 2 behaviours that we are trying to support with one capability
1) can this processor cope with us cancelling a recurring donation within CiviCRM
2) should we present the option of whether to or not to a user. This option is appropriate
when the processor manages the schedule (e.g Paypal) as the user may just be updating Civi to
match reality. However, for token driven processors it generally doesnt' apply.
This PR adds a new overridable capability - 'supportsOptionalCancelRecurring' which is the same as
supportsCancelRecurring by default. For the manual processor it is FALSE.
Call cancelRecurring for all cancels.
In almost all cases this will be no change as processors would have to implement the new-ish
doCancelRecurring themselves to have any change
public function buildQuickForm() {
$this->buildQuickEntityForm();
// Determine if we can cancel recurring contribution via API with this processor
- $cancelSupported = $this->_paymentProcessorObj->supports('CancelRecurring');
- if ($cancelSupported) {
+ if ($this->_paymentProcessorObj->supports('CancelRecurringNotifyOptional')) {
$searchRange = [];
$searchRange[] = $this->createElement('radio', NULL, NULL, ts('Yes'), '1');
$searchRange[] = $this->createElement('radio', NULL, NULL, ts('No'), '0');
else {
$this->assign('cancelRecurNotSupportedText', $this->_paymentProcessorObj->getText('cancelRecurNotSupportedText', []));
}
- $this->assign('cancelSupported', $cancelSupported);
if (!empty($this->_donorEmail)) {
$this->add('checkbox', 'is_notify', ts('Notify Contributor?') . " ({$this->_donorEmail})");
/**
* Process the form submission.
+ *
+ * @throws \CRM_Core_Exception
*/
public function postProcess() {
$message = NULL;
}
}
- if (CRM_Utils_Array::value('send_cancel_request', $params) == 1) {
- try {
- $propertyBag = new PropertyBag();
- $propertyBag->setContributionRecurID($this->getSubscriptionDetails()->recur_id);
- $propertyBag->setRecurProcessorID($this->getSubscriptionDetails()->subscription_id);
- $message = $this->_paymentProcessorObj->doCancelRecurring($propertyBag)['message'];
- }
- catch (\Civi\Payment\Exception\PaymentProcessorException $e) {
- CRM_Core_Error::statusBounce($e->getMessage());
- }
+ try {
+ $propertyBag = new PropertyBag();
+ $propertyBag->setIsNotifyProcessorOnCancelRecur(!empty($params['send_cancel_request']));
+ $propertyBag->setContributionRecurID($this->getSubscriptionDetails()->recur_id);
+ $propertyBag->setRecurProcessorID($this->getSubscriptionDetails()->subscription_id);
+ $message = $this->_paymentProcessorObj->doCancelRecurring($propertyBag)['message'];
+ }
+ catch (\Civi\Payment\Exception\PaymentProcessorException $e) {
+ CRM_Core_Error::statusBounce($e->getMessage());
}
if ($cancelSubscription) {
return method_exists(CRM_Utils_System::getClassName($this), 'cancelSubscription');
}
+ /**
+ * Does the processor support the user having a choice as to whether to cancel the recurring with the processor?
+ *
+ * If this returns TRUE then there will be an option to send a cancellation request in the cancellation form.
+ *
+ * This would normally be false for processors where CiviCRM maintains the schedule.
+ *
+ * @return bool
+ */
+ protected function supportsCancelRecurringNotifyOptional() {
+ return $this->supportsCancelRecurring();
+ }
+
/**
* Does this processor support pre-approval.
*
}
case 'cancelRecurNotSupportedText':
- return ts('Automatic cancellation is not supported for this payment processor. You or the contributor will need to manually cancel this recurring contribution using the payment processor website.');
+ if (!$this->supportsCancelRecurring()) {
+ return ts('Automatic cancellation is not supported for this payment processor. You or the contributor will need to manually cancel this recurring contribution using the payment processor website.');
+ }
+ return '';
}
CRM_Core_Error::deprecatedFunctionWarning('Calls to getText must use a supported method');
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
public function doCancelRecurring(PropertyBag $propertyBag) {
- if (method_exists($this, 'cancelSubscription')) {
+ if (method_exists($this, 'cancelSubscription')
+ && $propertyBag->getIsNotifyProcessorOnCancelRecur()) {
$message = NULL;
if ($this->cancelSubscription($message, $propertyBag)) {
return ['message' => $message];
return TRUE;
}
+ /**
+ * Does the processor support the user having a choice as to whether to cancel the recurring with the processor?
+ *
+ * If this returns TRUE then there will be an option to send a cancellation request in the cancellation form.
+ *
+ * This would normally be false for processors where CiviCRM maintains the schedule.
+ *
+ * @return bool
+ */
+ protected function supportsCancelRecurringNotifyOptional() {
+ return FALSE;
+ }
+
/**
* Are back office payments supported.
*
'transactionID' => TRUE,
'transaction_id' => 'transactionID',
'trxnResultCode' => TRUE,
+ 'isNotifyProcessorOnCancelRecur' => TRUE,
];
/**
*
* @param string $input
* @param string $label e.g. 'default'
+ *
+ * @return \Civi\Payment\PropertyBag
*/
public function setBillingCity($input, $label = 'default') {
return $this->set('billingCity', $label, (string) $input);
return $this->set('isRecur', $label, (bool) $isRecur);
}
+ /**
+ * Set whether the user has selected to notify the processor of a cancellation request.
+ *
+ * When cancelling the user may be presented with an option to notify the processor. The payment
+ * processor can take their response, if present, into account.
+ *
+ * @param bool $value
+ * @param string $label e.g. 'default'
+ *
+ * @return \Civi\Payment\PropertyBag
+ */
+ public function setIsNotifyProcessorOnCancelRecur($value, $label = 'default') {
+ return $this->set('isNotifyProcessorOnCancelRecur', $label, (bool) $value);
+ }
+
+ /**
+ * Get whether the user has selected to notify the processor of a cancellation request.
+ *
+ * When cancelling the user may be presented with an option to notify the processor. The payment
+ * processor can take their response, if present, into account.
+ *
+ * @param string $label e.g. 'default'
+ *
+ * @return \Civi\Payment\PropertyBag
+ */
+ public function getIsNotifyProcessorOnCancelRecur($label = 'default') {
+ return $this->get('isNotifyProcessorOnCancelRecur', $label);
+ }
+
/**
* Last name
*
<div class="help">
<div class="icon inform-icon"></div>
{$cancelRecurDetailText}
- {if !$cancelSupported}
+ {if $cancelRecurNotSupportedText}
<div class="status-warning">{$cancelRecurNotSupportedText}</div>
{/if}
</div>