I introduced 3rd party payment processor for our client. After successful payment user is redirected to notify-url, that causes now an infinite redirect loop in WordPress 4.3 (CiviCRM 4.6.8). Our membership payment form is embedded with the shortcode [civicrm component="contribution" id="2" mode="live"] in a WP page (/members/pay-fees/). Payments are registered correctly in CiviCRM.

Redirects are done in following order:

 1. /wp-content/plugins/civicrm/civicrm/extern/PaytrailNotify.php?A_QUERY_STRING
 2. /?page=CiviCRM&q=civicrm/contribute/transact&qfKey=4b1eea15240ba2ec1e48d4111f9dca79_6652&_qf_ThankYou_display=1
 3. /members/pay-fees/?page=CiviCRM&q=civicrm/contribute/transact&
 4. /members/pay-fees/?page=CiviCRM&q=civicrm/contribute/transact& 
 5. ...

I debugged the problem with PhpStorm Debugger and it seems, that redirect no. 2 returns correctly content for the thank you page, but after that WP launches do_action('template_redirect') in template-loader.php causing the redirect_canonical function to be run (in canonical.php). Because of the url in form of /?page=? redirect_canonical concludes, that user is needed to redirect to the front page with identical parameters, which leads to the erroneous redirect loop. After this rest of the loop seems to be related to the missing qfKey in CiviCRM.

So my question is how the user should be redirected to the correct WP page (/members/pay-fees/) after payment instead of redirecting user to the site root (/?page=CiviCRM...) or should the redirect_canonical be prevented?

Now in the PaytrailIPN (I modified a bit original 3rd party code) the redirect is done in following way:

$finalUrlAction = ($component == 'event') ? 'civicrm/event/register' : 'civicrm/contribute/transact';
$finalUrlParams = array(
    'qfKey' => $privateData['qfKey']
// Redirect our users to the correct url.
if ($success) {
  // Success. Process the transaction.
  if ($duplicateTransaction == 0) {
    $ipn = self::singleton($mode, $component, $paymentProcessor);
    $amount = (float) $privateData['amount'];
    $transactionId = $_GET["ORDER_NUMBER"];
    $ipn->newOrderNotify($success, $privateData, $component, $amount, $transactionId);
  $finalUrlParams['_qf_ThankYou_display'] = 1;

} else {
  $finalUrlParams[($component == 'event') ? '_qf_Register_display'   : '_qf_Main_display'] = 1;
  $finalUrlParams['cancel'] = 1;
CRM_Utils_System::redirect(CRM_Utils_System::url($finalUrlAction, $finalUrlParams, true, null, false, true));
  • Quick query on this: redirect 2 suggests you don't have a Base Page set. Is there one in "CiviCRM -> Administer -> System Settings -> CMS Database Integration"? Oct 5 '15 at 15:55

I solved the problem by using Ramesh's suggestion as a starting point. Instead of introducing hard coded Thank you & Cancel pages I stored the permalink address of the WordPress page along the other invoice stuff during the creation of the payment in Paytrail extension:

public function doTransferCheckout(&$params, $component) {
  $paymentHelper = new PaytrailPaymentHelper();

  // For now works only with WordPress & permalinks
  if (function_exists('get_permalink') && $contributionPageCmsUrl = get_permalink()) {
    $params['contributionPageCmsUrl'] = $contributionPageCmsUrl;
  //Save payment info for PaytrailIPN.php to retrieve
  $paymentHelper->insertInvoiceInfo($params, $component);

It's utilized in the IPN following way:

  static function main() {
    $invoiceData = self::readInvoiceData($invoiceID);
    $contributionPageCmsUrl = $invoiceData['contributionPageCmsUrl'] ?: '';
    if ($contributionPageCmsUrl) {
      $queryParams = array_merge(array(
        'page' => 'CiviCRM',
        'q' => $finalUrlAction,
      ), $finalUrlParams);
      $glue = strpos($contributionPageCmsUrl, '?') === FALSE ? '?' : '&';
      $finalUrl = $contributionPageCmsUrl . $glue . http_build_query($queryParams, null, '&');
    else {
      CRM_Utils_System::redirect(CRM_Utils_System::url($finalUrlAction, $finalUrlParams, true, null, false, true));

I guess there should be more logic for handling different situations and upgrade hook implemented. This behaviour could be made also optional and support for Joomla and Drupal introduced (if needed), but now it solves the problem for the client.

BTW, double title on the contribution WordPress page should be eliminated. Is the display:none way to go?


Please try to create an Thank-you Page in WP and ignore the payment processor (Thank-you) page URL (replace with WP Thank you page URL ).

Also try to create an cancel page in WP and replace payment processor URL.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.