Croonical Posted May 24, 2013 Share Posted May 24, 2013 (edited) Hello, I really need your help. I've developed a payment module which uses a paygate (a redirection on an external website). My order is created with : $this->module->validateOrder((int)$cart->id, Configuration::get('MY_STATUS'), $total, $this->module->displayName, "Customer redirected", NULL, (int)$currency->id, false, $customer->secure_key); When the callback is done from the other website, i need my module to save the payment. I wrote a controllers to do this <?php include('../../../../config/config.inc.php'); $order = new Order(Tools::getValue($id_order)); if (!Validate::isLoadedObject($order)) throw new PrestaShopException('Can\'t load Order object'); Now i need to save the order as done like "ok now you're paid, save the transaction and so on.." How can i do this ? I didn't find any example. I was thinking using addOrderPayment but i think it's too far from what i want. Any clues ? Thanks ! Edited May 27, 2013 by Croonical (see edit history) Link to comment Share on other sites More sharing options...
Croonical Posted May 27, 2013 Author Share Posted May 27, 2013 Hi guys, I'm still looking for that answer. At the moment, i'm using this : $order->addOrderPayment((float)$order->total_paid); but this isn't enough. I mean, the payment is now recorded, but some things are still missing. For example, the amount paid by the customer isn't increased. I'm sure it's quite simple, but i don't find it. Please help me. Thanks Link to comment Share on other sites More sharing options...
NemoPS Posted May 27, 2013 Share Posted May 27, 2013 Hi, Actually, as far as I know the order should be saved once you validate it. Then you can simply redirect. See bankwire in action here Tools::redirect('index.php?controller=order-confirmation&id_cart='.$cart->id.'&id_module='.$this->module->id.'&id_order='.$this->module->currentOrder.'&key='.$customer->secure_key); Link to comment Share on other sites More sharing options...
Croonical Posted May 27, 2013 Author Share Posted May 27, 2013 (edited) Hi Nemo1, thanks for your answer. Actually i've already wrote that line, but it is called when the customer validate his cart. $this->module->validateOrder((int)$cart->id, Configuration::get('MY_STATUS'), $total, $this->module->displayName, "Customer redirected", NULL, (int)$currency->id, false, $customer->secure_key); Tools::redirect('index.php?controller=order-confirmation&id_cart='.(int)$cart->id.'&id_module='.(int)$this->module->id.'&id_order='.$this->module->currentOrder.'&key='.$customer->secure_key); My need is to set the order (or cart) as paid when the callback from the paygate occurs. I only know the $id_order. Edited May 27, 2013 by Croonical (see edit history) Link to comment Share on other sites More sharing options...
Croonical Posted May 27, 2013 Author Share Posted May 27, 2013 Ok i found the solution ! (in ipn.php from paypal module) As i was expecting it, it is really really simple. Here is the code : $history = new OrderHistory(); $history->id_order = (int)$id_order; $history->changeIdOrderState((int)Configuration::get('PS_OS_PAYMENT'), $history->id_order); $history->addWithemail(); $history->save(); Link to comment Share on other sites More sharing options...
NemoPS Posted May 27, 2013 Share Posted May 27, 2013 Uh I see. I was about to tell you to use change order state but you found the solution yourself Link to comment Share on other sites More sharing options...
Beluga Posted October 14, 2013 Share Posted October 14, 2013 Ok i found the solution ! (in ipn.php from paypal module) As i was expecting it, it is really really simple. Here is the code : $history = new OrderHistory(); $history->id_order = (int)$id_order; $history->changeIdOrderState((int)Configuration::get('PS_OS_PAYMENT'), $history->id_order); $history->addWithemail(); $history->save(); This is exactly the scenario in my unfinished payment module. But how can I get $id_order for the above solution? Paypal's IPN has its own getIPNTransactionDetails method. Link to comment Share on other sites More sharing options...
Croonical Posted October 14, 2013 Author Share Posted October 14, 2013 (edited) Hi, When the payment is done, the server must proceed to a "callback" on a controller of your module. This callback (or IPN, it's the same thing) is actually a HTTP push, and it must contains an identifier of the paid order. This identifier depends on the payment method you use : sometimes you can use the order_id from your prestashop website, but other times you'll have an independant identifier. In this case you have to retrieve the order_id by yourself (for example you can use a table for that). Check the ipn.php example : function getIPNTransactionDetails(){ $transaction_id = pSQL(Tools::getValue('txn_id')); //Here the module gets the transaction ID stored in the callback as a parameter return array( 'id_invoice' => null, 'id_transaction' => $transaction_id, 'transaction_id' => $transaction_id, 'currency' => pSQL(Tools::getValue('mc_currency')), 'total_paid' => (float)Tools::getValue('mc_gross'), 'shipping' => (float)Tools::getValue('mc_shipping'), 'payment_date' => pSQL(Tools::getValue('payment_date')), 'payment_status' => pSQL(Tools::getValue('payment_status')), ); } if (Tools::getValue('payment_status') !== false) { $details = getIPNTransactionDetails(); $id_order = PayPalOrder::getIdOrderByTransactionId($details['id_transaction']); PayPalOrder::updateOrder($id_order, $details); $history = new OrderHistory(); $history->id_order = (int)$id_order; $history->changeIdOrderState((int)Configuration::get('PS_OS_PAYMENT'), $history->id_order); $history->addWithemail(); $history->save(); } The paypal callback returns the transaction id. From that id, the paypal module is able to retrieve the order_id (getIdOrderByTransactionId function). I hope it's clear enough. Good luck ! Edited October 14, 2013 by Croonical (see edit history) Link to comment Share on other sites More sharing options...
Beluga Posted October 14, 2013 Share Posted October 14, 2013 Thanks for dropping by, I appreciate it. Maybe what I was trying to say is how can I create the order at the validation.php stage and get its id and then change the state with the above-mentioned changeIdOrderState? Link to comment Share on other sites More sharing options...
Croonical Posted October 14, 2013 Author Share Posted October 14, 2013 (edited) To create the order at the validation.php, you need the validateOrder function. On the cheque module example : $this->module->validateOrder((int)$cart->id, Configuration::get('PS_OS_CHEQUE'), $total, $this->module->displayName, NULL, $mailVars, (int)$currency->id, false, $customer->secure_key); Tools::redirect('index.php?controller=order-confirmation&id_cart='.(int)$cart->id.'&id_module='.(int)$this->module->id.'&id_order='.$this->module->currentOrder.'&key='.$customer->secure_key); This will call the hookPaymentReturn (in your [module].php). From that block, you can get the order_id function hookPaymentReturn($params) { [...] $my_order_id = $params['objOrder']->id; } Edited October 14, 2013 by Croonical (see edit history) Link to comment Share on other sites More sharing options...
Beluga Posted October 14, 2013 Share Posted October 14, 2013 (edited) Thanks. I still can't get orders validated from my payment gateway's "lone GET request" (meaning without returning to the store using the browser). Here is my main module php-file's hookPaymentReturn: public function hookPaymentReturn($params) { if (!$this->active) return; $state = $params['objOrder']->getCurrentState(); if ($state == Configuration::get('PS_OS_PAYMENT') || $state == Configuration::get('PS_OS_OUTOFSTOCK')) { $id_order = $params['objOrder']->id; $history = new OrderHistory(); $history->id_order = (int)$id_order; $history->changeIdOrderState((int)Configuration::get('PS_OS_PAYMENT'), $history->id_order); $history->addWithemail(); $history->save(); $this->smarty->assign(array( 'total_to_pay' => Tools::displayPrice($params['total_to_pay'], $params['currencyObj'], false), 'status' => 'ok', 'id_order' => $params['objOrder']->id )); if (isset($params['objOrder']->reference) && !empty($params['objOrder']->reference)) $this->smarty->assign('reference', $params['objOrder']->reference); } else $this->smarty->assign('status', 'failed'); return $this->display(__FILE__, 'payment_return.tpl'); } Here is my validation.php: class checkoutfiValidationModuleFrontController extends ModuleFrontController { /** * @see FrontController::postProcess() */ public function postProcess() { $customer = new Customer($_GET['customerId']); $currency = $_GET['currency']; $total = $_GET['amountPaid']; $cartId = $_GET['cartId']; $co = new checkoutData(Configuration::get('CHECKOUTFI_MERCHANT'), Configuration::get('CHECKOUTFI_PASSWORD')); // merchantID and securitykey (normally about 80 chars) $md5 = md5(Configuration::get('CHECKOUTFI_PASSWORD')."&{$_GET['VERSION']}&{$_GET['STAMP']}&{$_GET['REFERENCE']}&{$_GET['PAYMENT']}&{$_GET['STATUS']}&{$_GET['ALGORITHM']}"); if (strtoupper($md5) == $_GET['MAC']) { if ($_GET['STATUS'] == 2 || $_GET['STATUS'] == 3) { // 2 = maksu suoritettu / payment done // 3 = maksu viivästetty / payment delayed // I commented out the below for testing with the gateway return, just to make sure it doesn't get stuck on any cookie mismatch /*if ($this->context->cookie->shopContext) { $psStamp = md5($this->context->cookie->date_add . $_GET['STAMP'] . Configuration::get('CHECKOUTFI_PASSWORD')); if ($psStamp != $_GET['psStamp']){ die("Tilauksen tunnisteesta '" . $_GET['STAMP'] . "' laskettu md5 '" . $psStamp . "' tilauksen md5:n '" . $_GET['psStamp'] . "' kanssa."); } }*/ if ($_GET['STATUS'] == 2) { $this->module->validateOrder($cartId, Configuration::get('PS_OS_PAYMENT'), $total, $this->module->displayName, NULL, NULL, $currency, false, $customer->secure_key); Tools::redirect('index.php?controller=order-confirmation&id_cart='.$cartId.'&id_module='.$this->module->id.'&id_order='.$this->module->currentOrder.'&key='.$customer->secure_key); } else { $this->module->validateOrder($cartId, Configuration::get('PS_OS_DELAYED'), $total, $this->module->displayName, NULL, NULL, $currency, false, $customer->secure_key); Tools::redirect('index.php?controller=order-confirmation&id_cart='.$cartId.'&id_module='.$this->module->id.'&id_order='.$this->module->currentOrder.'&key='.$customer->secure_key); } } else { die("Tilauksen tila väärä (arvot 2 ja 3 sallittuja): " . $_GET['STATUS']); // State of the order is invalid } } else { die("MAC-tarkiste ei täsmää: " . strtoupper($md5) . " vs. " . $_GET['MAC']); // MAC checksum doesn't match } } } Edited October 14, 2013 by Beluga (see edit history) Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now