0

I want to implement an offsite payment method and everything is going well except the fact that I can't find how to redirect the user to the offsite payment gateway after submitting the cart checkout review

When the user submits the checkout review, the orderSubmit function is called. Inside this function I create the array with all the parameters required in the request, but I don't know how to send this request

public function orderSubmit(OrderInterface $order) {
    $fields = array(
      'version' => $this->configuration['version'],
      'TPE' => $this->configuration['tpe'],
      'date' => date('d/m/Y:H:i:s', time()),
      'montant' => round($order->getTotal(), 2).\Drupal::state()->get('uc_currency_code', 'USD'),
      'reference' => $order->id(),
      'texte-libre' => md5(uniqid(rand(), TRUE)),
      'mail' => $order->getEmail(),
      'lgue' => 'FR',
      'societe' => $this->configuration['company'],
      'url_retour' => Url::fromRoute('uc_cmic.cancel', array('absolute' => TRUE)),
      'url_retour_ok' => Url::fromRoute('uc_cmic.success', array('absolute' => TRUE)),
      'url_retour_err' => Url::fromRoute('uc_cmic.return', array('absolute' => TRUE)),
      'MAC' => "",
      'options' => ""
    );
    $fields = uc_cmcic_complete_request($this->configuration['security_key'], $fields); // This function fills the 'MAC' key by using the security key
    $host = UC_CMCIC_URL_CM_TEST;

//TODO send the request and redirect the user to the offsite payment gateway here
  }

What I tried to do and didn't work :

$response = \Drupal::httpClient()->request('POST', $host, [
  'form_params' => $fields,
]);

I tried some other variations of this too (like returning the $response after), which didn't work either

Question : What can I do to redirect the user to the offsite payment gateway while sending POST data in the request ?

2 Answers 2

0

You are defining an orderSubmit() method, which implies you are trying to write a payment method plugin that implements PaymentMethodPluginInterface.

That interface is not designed for offsite payment methods. Instead, you should be implementing OffsitePaymentMethodPluginInterface which has a buildRedirectForm() method exactly for the purpose of redirecting to the other site to complete payment.

The example for this is PayPalPaymentsStandard plugin which is part of the uc_paypal module bundled with Ubercart.

-1

In D8 for redirection you need to use RedirectResponse Object & thats best way forward. However for improved security the same RedirectResponse object does not allow External URL redirections. For this You may want to use TrustedRedirectResponse. Sample below with assumption that you are trying to post data to the payment getway which can be added as a query string on the URL.

use Drupal\Core\Routing\TrustedRedirectResponse;

public function myController() {
  return new TrustedRedirectResponse($host.'?xyz=abc);
}

PREFERRED

However the above suggestion does has security implications as the data is exposed on the URL. Below solution is a minor tweak from your code.

$response = \Drupal::httpClient()->post($host, [
        'form_params' => $fields,
        'headers' => [
          'Content-type' => 'application/x-www-form-urlencoded',
        ],
    ]);

You can try below if you would like to capture response (If its an XML / JSON)

$response = \Drupal::httpClient()->post($host, [
        'form_params' => $fields,
        'headers' => [
          'Content-type' => 'application/x-www-form-urlencoded',
        ],
    ])->getBody()->getContents();
2
  • How would you do this and redirect to the $host at the same time? That is, how to do you set the action to an external URL as well as implement a post method?
    – drupalphil
    Jan 9, 2020 at 21:53
  • This answer does not help and will not work because it ignores the context that this redirect is part of an Ubercart payment method.
    – anonymous
    Aug 15, 2021 at 6:25

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.