$this->_paymentProcessor = $paymentProcessor;
}
+ /**
+ * @var GuzzleHttp\Client
+ */
+ protected $guzzleClient;
+
+ /**
+ * @return \GuzzleHttp\Client
+ */
+ public function getGuzzleClient(): \GuzzleHttp\Client {
+ return $this->guzzleClient ?? new \GuzzleHttp\Client();
+ }
+
+ /**
+ * @param \GuzzleHttp\Client $guzzleClient
+ */
+ public function setGuzzleClient(\GuzzleHttp\Client $guzzleClient) {
+ $this->guzzleClient = $guzzleClient;
+ }
+
/**
* Helper function to check which payment processor type is being used.
*
}
/**
- * @return null|string
- * @throws \Civi\Payment\Exception\PaymentProcessorException
+ * Get url for users to manage this recurring contribution for this processor.
+ *
+ * @param int $entityID
+ * @param null $entity
+ * @param string $action
+ *
+ * @return string|null
+ * @throws \CRM_Core_Exception
*/
- public function cancelSubscriptionURL() {
+ public function subscriptionURL($entityID = NULL, $entity = NULL, $action = 'cancel') {
if ($this->isPayPalType($this::PAYPAL_STANDARD)) {
+ if ($action !== 'cancel') {
+ return NULL;
+ }
return "{$this->_paymentProcessor['url_site']}cgi-bin/webscr?cmd=_subscr-find&alias=" . urlencode($this->_paymentProcessor['user_name']);
}
- else {
- return NULL;
- }
+ return parent::subscriptionURL($entityID, $entity, $action);
}
/**
$sub = empty($params['is_recur']) ? 'cgi-bin/webscr' : 'subscriptions';
$paypalURL = "{$url}{$sub}?$uri";
+ // Allow each CMS to do a pre-flight check before redirecting to PayPal.
+ CRM_Core_Config::singleton()->userSystem->prePostRedirect();
+
CRM_Utils_System::redirect($paypalURL);
}
throw new PaymentProcessorException('curl functions NOT available.');
}
- //setting the curl parameters.
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_URL, $url);
- curl_setopt($ch, CURLOPT_VERBOSE, 0);
+ $response = (string) $this->getGuzzleClient()->post($url, [
+ 'body' => $nvpreq,
+ 'curl' => [
+ CURLOPT_RETURNTRANSFER => TRUE,
+ CURLOPT_SSL_VERIFYPEER => Civi::settings()->get('verifySSL'),
+ ],
+ ])->getBody();
- //turning off the server and peer verification(TrustManager Concept).
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, Civi::settings()->get('verifySSL'));
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, Civi::settings()->get('verifySSL') ? 2 : 0);
-
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
- curl_setopt($ch, CURLOPT_POST, 1);
-
- //setting the nvpreq as POST FIELD to curl
- curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);
-
- //getting response from server
- $response = curl_exec($ch);
-
- //converting NVPResponse to an Associative Array
$result = self::deformat($response);
- if (curl_errno($ch)) {
- throw new PaymentProcessorException(ts('Network error') . ' ' . curl_error($ch) . curl_errno($ch), curl_errno($ch));
- }
- curl_close($ch);
-
- $outcome = strtolower(CRM_Utils_Array::value('ack', $result));
+ $outcome = strtolower($result['ack'] ?? '');
- if ($outcome != 'success' && $outcome != 'successwithwarning') {
+ if ($outcome !== 'success' && $outcome !== 'successwithwarning') {
throw new PaymentProcessorException("{$result['l_shortmessage0']} {$result['l_longmessage0']}");
}
// The contribution form passes a 'button' but the event form might still set one of these fields.
// @todo more standardisation & get paypal fully out of the form layer.
$possibleExpressFields = [
+ // @todo - we think these top 2 are likely not required & it's still here
+ // on a precautionary basis.
+ // see https://github.com/civicrm/civicrm-core/pull/18680
'_qf_Register_upload_express_x',
'_qf_Payment_upload_express_x',
+ '_qf_Register_upload_express',
+ '_qf_Payment_upload_express',
'_qf_Main_upload_express',
];
if (array_intersect_key($params, array_fill_keys($possibleExpressFields, 1))) {