eileenmcnaughton / nz.co.fuzion.omnipaymultiprocessor

Omnipay Multi Processor Payment Processor For CiviCRM
Other
14 stars 44 forks source link

Missing success, error and refused URL parameters #234

Closed bastienho closed 1 year ago

bastienho commented 2 years ago

Hi

After implementing support for Systempay #230, I figured that successURL, errorURL and refusedURL are not passed to the service. It seems to be nearly the same as #228 and #153.

At this time, I found that the cancelURL is correctly managed, but not the other ones and I can't figure why.

My current (dirty) workaround is the following:

1. Adding 3 custom pages, accessible or anyone

in xml/Menu/_customextension.xml

  <item>
    <path>civicrm/customextension/confirm/success</path>
    <page_callback>CRM_CustomExtension_Page_Confirm</page_callback>
    <title>Confirmation</title>
    <access_arguments>Any</access_arguments>
  </item>
  <item>
    <path>civicrm/customextension/confirm/error</path>
    <page_callback>CRM_CustomExtension_Page_Confirm</page_callback>
    <title>Confirmation</title>
    <access_arguments>Any</access_arguments>
  </item>
  <item>
    <path>civicrm/customextension/confirm/refused</path>
    <page_callback>CRM_CustomExtension_Page_Confirm</page_callback>
    <title>Confirmation</title>
    <access_arguments>Any</access_arguments>
  </item>

in CRM/CustomExtension/Page/Confirm.php

<?php
use CRM_CustomExtension_ExtensionUtil as E;
class CRM_CustomExtension_Page_Confirm extends CRM_Core_Page {
  public function run() {
    CRM_Utils_System::setTitle(E::ts('Confirmation'));

    // Parse the URL and get the context: success, error, refused
    $context = isset($this->urlPath[3]) ? $this->urlPath[3] : null;

    $transaction_id = null;
    $success_url = '';
    $fail_url = '';

    // Here, we cannot know the transaction ID
    // Let's parse sessionVars and fetch redirect URLs for success and error
    // The structure of their keys is "ipn_(success|fail)_url_($transaction_id)"
    CRM_Core_Session::singleton()->getVars($sessionVars);
    foreach($sessionVars as $key => $value) {
        if(strpos($key, 'ipn_success_url_') !== false) {
            $transaction_id = str_replace('ipn_success_url_', '', $key);
            $success_url = $value;
        }
        if(strpos($key, 'ipn_fail_url_') !== false) {
            $transaction_id = str_replace('ipn_fail_url_', '', $key);
            $fail_url = $value;
        }
    }

    // Redirect user to the correct URL
    if($context==='error' && $transaction_id && $fail_url){
        CRM_Utils_System::redirect($fail_url);
    }
    if($context==='refused' && $transaction_id && $fail_url){
        CRM_Utils_System::redirect($fail_url);
    }
    if($context==='success' && $transaction_id && $success_url){
        CRM_Utils_System::redirect($success_url);
    }

    // Fallback on the default page
    $this->assign('transaction_id', $transaction_id);
    $this->assign('success_url', $success_url);
    $this->assign('fail_url', $fail_url);
    $this->assign('context', $context);

    parent::run();
  }

}

The templates/CRM/CustomExtension/Page/Confirm.tpl should never be displayed, but we never know...

<h1>{$context}</h1>
<p>Return page for transaction #{$transaction_id}</p>

2. Adding redirect fields into the processor definition

'metadata' => [
      'pass_through_fields' => [
        'successUrl' => 'https://example.com/civicrm/customextension/confirm/success/',
        'errorUrl' => 'https://example.com/civicrm/customextension/confirm/error/',
        'refusedUrl' => 'https://example.com/civicrm/customextension/confirm/refused/',
      ],
    ],

I could not figure how to add pass_through_fields via hook, so it requires to be hardcoded after each update.

With that, after finishing the credit-card stuff, the final user is redirected to one of the civicrm/customextension/confirm/* page and then redirected to the correct CiviCRM page.

It would be better if successURL and errorURL were directly passed to the processor.

Does anyone notes the same as me or have a clean solution?

bastienho commented 1 year ago

I think this one can be closed.