I've create my custom payment module, it works on payment gateway, everything is working fine but I would like to set the order as paid when the return url give back a succes code. So far I've understand that I have to create an invoice for the order to be able to ave it set as paid into Magento panel.
So first of all please tell me if I'm wron until here.
Then I'm trying to create invoice on success.phtml with some codes like:
$invoice = Mage::getModel('sales/service_order', $order->prepareInvoice());
$invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::CAPTURE_OFFLINE);
$invoice->register();
$invoice->getOrder()->setCustomerNoteNotify(true);
$invoice->getOrder()->setIsInProcess(true);
$order->addStatusHistoryComment('Automatically INVOICED by Rico.', false);
$transactionSave = Mage::getModel('core/resource_transaction')
->addObject($invoice)
->addObject($invoice->getOrder());
$transactionSave->save();
But it gives me back always a magento error, so probably is not a good idea.
Any help will be appreciated
EDIT
From this http://blog.chapagain.com.np/magento-quick-way-to-create-order-invoice-programmatically/
I've used
$invoiceId = Mage::getModel('sales/order_invoice_api')
->create($_order->getIncrementId(), array());
instead the code above and it seems that the order is paid. But I'm not sure, if is enough.
I suggest you when customer is returning to your site from payment gateway and then it must goes to a magento controller and it an action you need to add your code at there
$order=Mage::getModel('sales/order')->load($orderID);
if($order->canInvoice() and $order->getIncrementId())
{
$items = array();
foreach ($order->getAllItems() as $item) {
$items[$item->getId()] = $item->getQtyOrdered();
}
$invoiceId=Mage::getModel('sales/order_invoice_api')->create($order->getIncrementId(),$items,null,false,true);
Mage::getModel('sales/order_invoice_api')->capture($invoiceId)};
}
See http://www.amitbera.com/programmatically-create-invoice-of-a-new-order-in-magento/
Related
I am using paypal adaptive payments for my website. I have many sellers and different products. when I am as a user try to buy any product from my website then I can't see product name in Paypal form summary instead there is the name and surname of the seller.
Let me know please which parameter is being used to Pass product name ..
Here is the screenshot
With Adaptive Payments you can't send itemized details in the Pay request itself. Instead, you have to call Pay like usual, but then follow that up with a call to SetPaymentOptions. With that you'll pass in the PayKey you get back from the Pay request, and then you can setup all the additional details like itemized info that SetPaymentsOptions provides.
Then you would redirect to PayPal after that, and it should show you what you're after.
With Adaptive Payments, the item details you set with SetPaymentOptions are only displayed to the customer via Embedded flow.
The Embedded flow uses either a lightbox or a minibrowser for the checkout pages.
Here’s a technical instruction on how to implement the embedded flow in your front-end page, https://developer.paypal.com/docs/classic/adaptive-payments/ht_ap-embeddedPayment-curl-etc/
I am having the same issue. It looks like it works only in an Embedded Payment Flow.
Embedded Payment Flow Using Adaptive Payments
$receiverOptions = new PayPal\Types\AP\ReceiverOptions();
$setPaymentOptionsRequest->receiverOptions[] = $receiverOptions;
$receiverOptions->description = 'Description';
$invoiceItems = array();
$item = new PayPal\Types\AP\InvoiceItem();
$item->name = 'Item Name';
$item->price = 10;
$item->itemPrice = 10;
$item->itemCount = 1;
$invoiceItems[] = $item;
$receiverOptions->invoiceData = new PayPal\Types\AP\InvoiceData();
$receiverOptions->invoiceData->item = $invoiceItems;
$receiverId = new PayPal\Types\AP\ReceiverIdentifier();
$receiverId->email = 'email#domain.com';//Change it
$receiverOptions->receiver = $receiverId;
$setPaymentOptionsRequest->payKey = $_POST['payKey'];
$servicePaymentOptions = new PayPal\Service\AdaptivePaymentsService($config);
try {
/* wrap API method calls on the service object with a try catch */
$responsePaymentOptions = $servicePaymentOptions->SetPaymentOptions($setPaymentOptionsRequest);
print_r($responsePaymentOptions); die;
} catch(Exception $ex) {
//error
}
if (isset($responsePaymentOptions) && $responsePaymentOptions->responseEnvelope->ack == "Success")
{
//Success
}
When a payment is validated, the order status becomes "Payment validated" ("Paiement accepté" in french). I want to set another status when payment is validated, so the history would show the following :
Current status : My personnal status
History :
My personnal status
Payment validated
To do so, I use the hook actionOrderStatusPostUpdate. This is my code :
public function hookActionOrderStatusPostUpdate($aParams) {
$oOrder = new Order($aParams['id_order']);
if($aParams['newOrderStatus']->id == Configuration::get('PS_OS_PAYMENT')) {
$oOrder->setCurrentState(Configuration::get('XXXXXX_STATUS_WAITING'));
$oOrder->save();
}
}
The Configuration values are correctly defined. This code works, because I see the status changed. But the thing is it changed BEFORE changing to "Payment validated". I don't understand why. The history looks like this :
Current status : Payment validated
History :
Payment validated
My personnal status
What should I do to make My personnal status appear as the last status ?
hookActionOrderStatusPostUpdate hook call is made by changeIdOrderState but the add to order_history table is made after the call of changeIdOrderState like in https://github.com/PrestaShop/PrestaShop/blob/1.6.1.x/controllers/admin/AdminOrdersController.php#L521-L542
You rather need to bind your module on a classic hook like hookActionObjectOrderHistoryAddAfter https://github.com/PrestaShop/PrestaShop/blob/1.6.1.x/classes/ObjectModel.php#L535-L537
public function hookActionObjectOrderHistoryAddAfter($params) {
$orderHistory = $params['object'];
if($orderHistory->id_order_state == Configuration::get('PS_OS_PAYMENT')) {
$oOrder->setCurrentState(Configuration::get('XXXXXX_STATUS_WAITING'));
$oOrder->save();
}
Best Regards
I think this is what you should use to change order status after payment validate those hooks are called when status changing or status changed.
$history = new OrderHistory();
$history->id_order = (int)$id_order;
$history->changeIdOrderState($status_id, (int)$id_order);
$history->addWithemail();
$history->save();
I think it'll work on other hook: actionOrderStatusUpdate
hello based on this thread: add tracking number automatically
i have managed to add tracking numbers to orders when button 'ship' is pressed
but the question is can i make somehow check before adding tracking number? cause i want to add tracking number only to specific shipping method (carrier)
how can i do that?
i have tried to add if statement before adding tracking number like this:
public function salesOrderShipmentSaveBefore($observer)
{
$rate = Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getShippingRatesCollection();
$method = $rate->getCarrier();
if ($method == 'mycompany_mycarrier'){
$trackNumber='123456789';
$shipment = $observer->getEvent()->getShipment();
$track = Mage::getModel('sales/order_shipment_track')
->setNumber($trackNumber)
->setCarrierCode('mycompany_mycarrier')
->setTitle('My Carrier');
$shipment->addTrack($track);
}
but when i press ship button error says that i am calling undefined method - Mage_Sales_Model_Resource_Quote_Address_Rate_Collection::getCarrier()
maybe there is other way how can i check that it is my carrier and then add tracking number; cause this code adds tracking number but to all orders, all i want is that it add tracking number to my own created shipping method
any help would be great
// After Order Place event
$iOrderId = Mage::getSingleton('checkout/session')->getLastRealOrderId();
$oOrder = Mage::getModel('sales/order')->loadByIncrementId($iOrderId);
$oOrder->getShippingDescription();
Does the method even exist?
It tells you that you are missing a piece of code.
solved my problem, the Observer.php:
public function salesOrderShipmentSaveBefore($observer)
{
$trackNumber='987654321';
$shipment = $observer->getEvent()->getShipment();
$order = $shipment->getOrder();
$orderIncrementId=$order->getIncrementId();
$oOrder = Mage::getModel('sales/order')->loadByIncrementId($orderIncrementId);
$shipping = $oOrder->getShippingDescription();
if($shipping =='My Carrier - My Method')
{
$track = Mage::getModel('sales/order_shipment_track')
->setNumber($trackNumber)
->setCarrierCode('mycompnay_mycarrier')
->setTitle('My Carrier');
$shipment->addTrack($track);
}
}
now everything works just like i wanted, the tracking number is added to my shipping carrier only.
Thank you Kingshuk Deb, you were right since the begining, i just didnt understood that.
I would just like to know what is that one property which when set would mark the order as failed so that failureAction() of app/code/core/Mage/Checkout/controller/OnepageController.php gets called.
I have an Observer.php where in I'm creating invoice for successful payments and for failed payments saving order with pending_payment status and wanting to redirect them to the cart page with an error message at the top.
All this happens fine. Just that for unsuccessful / failed payments, along with saving the order with pending_payment status n redirecting them to cart page with error message, I would also like to retain/save the cart from getting empty.
But to no luck
Observer.php
public function implementOrderStatus($event)
{
$order = $event->getEvent()->getOrder();
if ($this->_getPaymentMethod($order) == 'mypaymentmodule')
{
$quote = Mage::getModel('sales/quote')->load($order->getQuoteId());
if($order->getPayment()->getCcTransId() == NULL)
{
$order->cancel();
$order->setStatus('canceled');
$order->save();
$quote->setIsActive(1)->save();
/*$state = 'pending_payment';
$status = 'pending_payment';
$comment = 'Payment transaction failed due to incorrect AVS/CVD details.';
$isNotified = false;
$order->setState($state,$status,$comment,$isNotified)->save();
$order->setCanSendNewEmailFlag(false);*/
Mage::getSingleton('checkout/session')->addError('Sorry, either of your card information (billing address or card validation digits) dint match. Please try again');
Mage::app()->getFrontController()->getResponse()->setRedirect('checkout/cart/')->sendResponse();
}
else
{
if ($order->canInvoice())
$this->_processOrderStatus($order);
}
}
return $this;
}
But $quote->setIsActive(true)->save() does not seem to be doing the trick. Any help as to how can I save my cart from getting empty after saving the order with 'canceled' status.
You maybe should have a look at ./app/code/core/Mage/Sales/Model/Order.php. There you will find several constants for an order, which may be used to set the state of an order like this:
<?php
// [...] all your code within your custom action or script
//load your order by order_id (or by increment_id, if you like to, here, it's your order id
$order = Mage::getModel('sales/order')->load($your_order_id);
$order->setState(Mage_Sales_Model_Order::STATE_CANCELED); //or whatever distinct order status you'd like
$order->save();
The failureAction in the controiller action does nothing of the sort, if you want to call it manually, you can build it's url using Mage::getUrl()
I'm trying to mark a "Processing" order as Complete when I get a certain response back from a third party service. I've got everything set up for this, but the only problem is that orders are staying in the Processing state.
I'm generating an invoice (I don't think I need this though, as each item is marked as "invoiced" in the Magento backend) and a shipment like so:
$order = Mage::getModel('sales/order')... (etc)
$shipment = $order->prepareShipment($quantities);
$shipment->register();
$shipment->setOrder($order);
$shipment->save();
$invoice = $order->prepareInvoice($quantities);
$invoice->register();
$invoice->setOrder($order);
$invoice->save();
This doesn't seem to be doing it though - I get no errors back from this code, but the order remains as processing. In the backend I can still see the "Ship" button at the top of the order, and each item is in the "invoiced" state.
Any tips would be greatly appreciated.
Try
$order->setStateUnprotected('complete',
'complete',
'Order marked as complete automatically',
false);
This method is in app/code/local/Mage/Sales/Model/Order.php (in v1.6.1)
938: public function setStateUnprotected($state, $status = false, $comment = '', $isCustomerNotified = null)
In Magento 1.7.0.0 this method has been removed. Try this instead:
$order->setData('state', "complete");
$order->setStatus("complete");
$history = $order->addStatusHistoryComment('Order marked as complete automatically.', false);
$history->setIsCustomerNotified(false);
$order->save();
You can take a look at this article (in Russian).
Here is the code from the article:
$order = $observer->getEvent()->getOrder();
if (!$order->getId()) {
return false;
}
if (!$order->canInvoice()) {
return false;
}
$savedQtys = array();
$invoice = Mage::getModel('sales/service_order', $order)->prepareInvoice($savedQtys);
if (!$invoice->getTotalQty()) {
return false;
}
$invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::CAPTURE_OFFLINE);
$invoice->register();
$invoice->getOrder()->setCustomerNoteNotify(false);
$invoice->getOrder()->setIsInProcess(true);
$transactionSave = Mage::getModel('core/resource_transaction')
->addObject($invoice)
->addObject($invoice->getOrder());
$transactionSave->save();
I'm doing this that way:
$order->setState('complete', true, $this->__('Your Order History Message Here.'))
->save();
Code for processing order programmatically.
Can be put on success event or cron
$order = Mage::getModel('sales/order')->loadByIncrementId($orderIncrementId);
$order->setData('state', Mage_Sales_Model_Order::STATE_COMPLETE);
$order->setStatus(Mage_Sales_Model_Order::STATE_COMPLETE);
$history = $order->addStatusHistoryComment('Order is complete', false);
$history->setIsCustomerNotified(false);
$order->save();
Magento will automatically mark an order as complete if:
Payment has been made.
An invoice exists.
A shipment exists.
If you cannot do that, try to create a custom 'state' and set that. In the meantime, to set the order to processing, try this:
$order = Mage::getModel('sales/order')->load($id);
$order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true)->save();
Should work without errors. Tested in Magento 1.7.0.2
In my case, I needed the end users to see completed in the order grid, but the order state really made no difference. So I did just went to
System->Order Status
Create a new Status called Completed (note the d so it's easy to differentiate)
Assign that status to the state Processing/pending, whatever.
This worked for our client -- but wouldn't work if you heavily depend on order state (Different than order status).