diff --git a/CRM/Core/Payment/Redsys.php b/CRM/Core/Payment/Redsys.php index 2706844d273732d792b2683ae9569c5577f999c6..4b5737c64001b74387239eccf78c66f892f9ea23 100644 --- a/CRM/Core/Payment/Redsys.php +++ b/CRM/Core/Payment/Redsys.php @@ -168,8 +168,15 @@ class CRM_Core_Payment_Redsys extends CRM_Core_Payment { } } + if (!empty($params["is_token"])) { + $processorName = "Redsys_Tokenization"; + } + else { + $processorName = "Redsys"; + } + $merchantUrl = CRM_Utils_System::url('civicrm/payment/ipn', - 'processor_name=Redsys&mode=' . $this->_mode . '&md=' . $component . '&qfKey=' . $params["qfKey"] . '&' . $merchantUrlParams, + "processor_name={$processorName}&mode={$this->_mode}&md={$component}&qfKey={$params['qfKey']}&{$merchantUrlParams}", TRUE, NULL, FALSE, TRUE ); @@ -235,10 +242,12 @@ class CRM_Core_Payment_Redsys extends CRM_Core_Payment { $miObj->setParameter("Ds_Merchant_ProductDescription", $description); $miObj->setParameter("Ds_Merchant_Titular", $params["first_name"] . " " . $params["last_name"]); $miObj->setParameter("Ds_Merchant_ConsumerLanguage", self::REDSYS_LANGUAGE_SPANISH); - if (!empty($params["is_bizum"])) { $miObj->setParameter("Ds_Merchant_PayMethods", 'z'); } + if (!empty($params["is_token"])) { + $miObj->setParameter("Ds_Merchant_Identifier", 'REQUIRED'); + } $version = "HMAC_SHA256_V1"; diff --git a/CRM/Core/Payment/RedsysIPN.php b/CRM/Core/Payment/RedsysIPN.php index 189eb8a928b6450ddb8da086ef372fcbc201f456..3f662ae4c107fbb2b6dc6de7c7a899d53286d1e8 100644 --- a/CRM/Core/Payment/RedsysIPN.php +++ b/CRM/Core/Payment/RedsysIPN.php @@ -91,6 +91,7 @@ class CRM_Core_Payment_RedsysIPN extends CRM_Core_Payment_BaseIPN { Civi::log()->debug("Redsys IPN Error Updating contribution: " . $e->getMessage()); } } + return TRUE; } @@ -115,6 +116,13 @@ class CRM_Core_Payment_RedsysIPN extends CRM_Core_Payment_BaseIPN { ]; $decodecResponseJson = $this->_redsysAPI->decodeMerchantParameters($input["Ds_MerchantParameters"]); $decodecResponse = json_decode($decodecResponseJson); + + // Capture if is incoming a Ds_Merchant_Identifier, a token + if (!empty($decodecResponse->Ds_Merchant_Identifier)) { + $input['Ds_Merchant_Identifier'] = $decodecResponse->Ds_Merchant_Identifier; + CRM_Utils_Hooks_Redsys::redsystoken($input['contactID'], $input['contributionID'], $input['Ds_Merchant_Identifier'], number_format(($decodecResponse->Ds_Amount / 100), 2)); + } + $input['Ds_MerchantCode'] = $decodecResponse->Ds_MerchantCode; $input['Ds_Response'] = $decodecResponse->Ds_Response; $input['Ds_AuthorisationCode'] = $decodecResponse->Ds_AuthorisationCode; diff --git a/CRM/Core/Payment/RedsysToken.php b/CRM/Core/Payment/RedsysToken.php new file mode 100644 index 0000000000000000000000000000000000000000..26e36b84010dcb32eacb17511b4be1f0a36e0d0d --- /dev/null +++ b/CRM/Core/Payment/RedsysToken.php @@ -0,0 +1,15 @@ + ['IN' => ["Redsys", "Bizum"]]]); + $paymentProcessorTypes = civicrm_api3('PaymentProcessorType', 'get', ['name' => ['IN' => ["Redsys", "Bizum", "Redsys_Tokenization"]]]); $paymentProcessorTypesIds = []; foreach ($paymentProcessorTypes["values"] as $paymentProcessorType) { $paymentProcessorTypesIds[] = $paymentProcessorType["id"]; diff --git a/CRM/Redsys/Upgrader.php b/CRM/Redsys/Upgrader.php index 13ec8bb707caa4752d2b097f13994ece0be7e9d9..fee504691f132abf9adce87a109eef95b70a8980 100644 --- a/CRM/Redsys/Upgrader.php +++ b/CRM/Redsys/Upgrader.php @@ -20,6 +20,9 @@ class CRM_Redsys_Upgrader extends CRM_Redsys_Upgrader_Base { // Add Bizum. $this->addBizumPayment(); + // Add token + $this->addTokenPayment(); + return TRUE; } @@ -79,6 +82,16 @@ class CRM_Redsys_Upgrader extends CRM_Redsys_Upgrader_Base { return TRUE; } + /** + * Add Tokenization/Recurring. + * + * @return void + */ + public function upgrade_4017() { + $this->addTokenPayment(); + return TRUE; + } + /** * Add build menu * @@ -171,4 +184,37 @@ class CRM_Redsys_Upgrader extends CRM_Redsys_Upgrader_Base { } } } + + /** + * Add Tokenization/Recurring Payment + * + * @return void + */ + private static function addTokenPayment() { + $resultPaymentMethod = civicrm_api3('PaymentProcessorType', 'get', [ + 'sequential' => 1, + 'name' => "Redsys_Tokenization", + ]); + if ($resultPaymentMethod["count"] == 0) { + $params = [ + 'name' => 'Redsys_Tokenization', + 'title' => 'Recurring Redsys Payment Processor', + 'description' => 'Works with Servired (Sermepa) and 4B (Pasat).', + 'class_name' => 'Payment_RedsysToken', + 'billing_mode' => 'notify', + 'user_name_label' => 'Número de comercio', + 'password_label' => 'Clave secreta de encriptación', + 'url_site_default' => 'https://sis.redsys.es/sis/realizarPago', + 'url_site_test_default' => 'https://sis-t.redsys.es:25443/sis/realizarPago', + 'is_recur' => 0, + 'payment_type' => 1, + ]; + civicrm_api3('PaymentProcessorType', 'create', $params); + } + else { + foreach ($resultPaymentMethod["values"] as $resultPaymentMethodValue) { + civicrm_api3('PaymentProcessorType', 'create', ["id" => $resultPaymentMethodValue["id"], 'is_active' => 1]); + } + } + } } diff --git a/CRM/Utils/Hooks/Redsys.php b/CRM/Utils/Hooks/Redsys.php new file mode 100644 index 0000000000000000000000000000000000000000..390930140387d96a0de7c2cab72d489c5856030e --- /dev/null +++ b/CRM/Utils/Hooks/Redsys.php @@ -0,0 +1,32 @@ +invoke($names, $args[0], $args[1], $args[2], $args[3], $args[4], $args[5], $fnSuffix); + + // Invoke Symfony Dispatch (new convention) + $event = \Civi\Core\Event\GenericHookEvent::createOrdered( + $names, + [&$args[0], &$args[1], &$args[2], &$args[3], &$args[4], &$args[5]] + ); + $fnSuffix = str_replace("civicrm_", "", $fnSuffix); + + \Civi::dispatcher()->dispatch('redsys.' . $fnSuffix, $event); + return $event->getReturnValues(); + } +} \ No newline at end of file diff --git a/templates/CRM/Redsys/Form/Settings.tpl b/templates/CRM/Redsys/Form/Settings.tpl index 588c5e64cc54544b8e22002e4dfc9dde8e27b79d..0ec51df9b698c675caf16c88fb51f4d0b8f80146 100644 --- a/templates/CRM/Redsys/Form/Settings.tpl +++ b/templates/CRM/Redsys/Form/Settings.tpl @@ -7,7 +7,7 @@ {$form.ipn_http.html}
- Redsys doesn't support ipn callbacks using SSL shared certificate in multiples websites with a single IP. In that case you must force to use http protocol in ipn callback url + Redsys doesn't support ipn callbacks using SSL shared certificate in multiples websites with a single IP. In that case you must force to use http protocol in ipn callback url @@ -24,7 +24,7 @@ {foreach key=property item=terminal from=$form name=terminals} {if $smarty.foreach.terminals.first} - Merchant terminal numbers for specific payment prcessors + Merchant terminal numbers for specific payment processors {/if}