Reputation: 1122
I've followed the skeleton of GitHub and read the official documentation about payments. I'm relating to the "external" example, where the user is redirected to an external service, makes the payment, and then the gateway notifies the result. Anyway I don't get how to properly handle the response.
The example redirects the user to a page (validation.php) that, once opened, closes the order. But what if the user close the page before loading it? Or if the user is not logged-in anymore? I'd rather to send a trigger from the gateway-server to Prestashop, without the interaction of the user. But I don't know how to do that.
The gateway service already has 2 params: one for the user redirection, one for the cient webhook to trigger. But I don't know this last one.
This is the main .php file of the module, where I list my custom gateway, and then call external.php if the user chooses this payment method.
private function getExternalPaymentOption($cart)
{
$externalOption = new PaymentOption();
$externalOption->setModuleName($this->name);
$externalOption->setAction($this->context->link->getModuleLink($this->name, 'external', [], true));
return $externalOption;
}
This below is external.php
, that redirects the user to the external gateway. In the call, the redirect_ok
is user redirection in case of success, that url is the validation.php page. Anyway I don't know what to insert as webhook_ok: the webhook to trigger in case of success.
public function initContent()
{
parent::initContent();
// take the cart to pass to the external gateway
$cart = $this->context->cart;
// prepare the redirect url on success
$ok_redirect = $this->context->link->getModuleLink(
$this->module->name,
'validation',
[],
true
);
// === I DON'T KNOW WHAT INSERT HERE =====
$ok_webhook = "???????????";
// =======================================
// call the external gateway
$ch = curl_init("https://external-gatway.com");
$payload = [
cart => $cart,
redirect_ok => $ok_redirect,
webhook_ok => $ok_webhook
];
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
$response = curl_exec($ch);
// the response has the url to be opened by the user
$response = json_decode($response, true);
//redirect the user to that url
Tools::redirect($response['data']['url']);
}
Once the user makes the payment, it will be redirected to $ok_redirect, that is the validation.php
page.
public function postProcess()
{
$customer = new Customer($this->context->cart->id_customer);
// transform the cart in order
$this->module->validateOrder(
(int) $this->context->cart->id,
(int) $this->getOrderState(),
(float) $this->context->cart->getOrderTotal(true, Cart::BOTH),
$this->module->displayName, // $this->getOptionName(),
null,
[],
(int) $this->context->currency->id,
false,
$customer->secure_key
);
// redirect to the order confirmation page
Tools::redirect($this->context->link->getPageLink(
'order-confirmation',
true,
(int) $this->context->language->id,
[
'id_cart' => (int) $this->context->cart->id,
'id_module' => (int) $this->module->id,
'id_order' => (int) $this->module->currentOrder,
'key' => $customer->secure_key,
]
));
}
This last step works, but just if the user visit that page, and he is logged. I need to replicate this step just as Server-To-Server without the user visit.
Upvotes: 0
Views: 384
Reputation: 1122
I ended up creating 2 controllers, very similar but one has not checks on logged user:
validation
checks context, current user, current cart;webhook
checks a custom header for the server gateway signature. No user logged needed.Both of them close the order setting the status as 'paid'. Since 'webhook' can't take data from context, I retrieve them from the DB.
So steps are:
$ok_redirect = $this->context->link->getModuleLink($this->module->name, 'validation', [], true);
$ok_webhook = $this->context->link->getModuleLink($this->module->name, 'webhookok', [], true);
$ok_redirect
and $ok_webhook
;payment_id
together to the checkout_url
where to redirect the user to start the checkout process;payment_id
as primary key;checkout_url
;payment_id
;Upvotes: 1