Not sure if I understood correctly, but you should always create the order before before redirecting to paypal. Then when paypal notifies you that the payment was made the order should change status accordingly.
This is how I would create an order:
$quote = $this->getQuote();
try {
$quotePayment = $quote->getPayment();
$quotePayment->setMethod('payment_method_code');
$quote->setPayment($quotePayment);
$onePageCheckOut = \Mage::getSingleton('checkout/type_onepage');
$onePageCheckOut->getCheckout()->setQuoteId($quote->getId());
$onePageCheckOut->saveOrder();
$this->redirectUrl = $onePageCheckOut->getCheckout()->getRedirectUrl();
$quote->setIsActive(false)->save();
} catch (\Exception $e) {
throw new \Exception(
$e->getMessage(),
'some error code'
);
}
$order = \Mage::getModel('sales/order')->load($onePageCheckOut->getLastOrderId(), 'increment_id');
$order->save();
Then you need to wait for the payment notification and update the order:
//check how to get the params in your case
$paymentId = $this->param('payment_id');
$transactionId = $this->param('transaction_id');
if($order->getStatus() === \Mage_Sales_Model_Order::STATE_CANCELED) {
//do something if order is cancelled
}
$payment = $order->getPayment();
$amountOrdered = $payment->getAmountOrdered();
$payment->setAmountPaid($amountOrdered);
$payment->setAmountAuthorized($amountOrdered);
/** Save a comment regarding the transaction */
$order->addStatusHistoryComment(
sprintf(
"Transaction status: %s / Paypal id: %s",
strtoupper($this->paymentStatus),
$paymentId
)
);
$payment->save();
$order->save();
I have used a fresh installation for the following using Magento2 CE 2.2.0-dev, and left the default "Luma" theme as well.
Concerning external payment methods (gateways) such as MiGS, Braintree, PayPal, and others, Magento supports these gateways out of the box but provides NO APIs for them that you can use along with other "Checkout" APIs.
So, if you are planning to build a checkout app/page using Magento's APIs, you will need to manually integrate with these services using their SDK/API, fortunately, you can learn a lot by checking how Magento integrates with these services in the built-in integrations.
To understand this, i had to configure Braintree since it is the easiest:
- Create sandbox account at https://www.braintreepayments.com/sandbox
- Access Magento Admin Area.
- Stores > Configuration > Sales > Payment Methods > Braintree > Configure.
- Make sure "Environment" is "Sandbox", and enter "Merchant ID", "Public Key", and "Private Key".
- Save Config.
- You may need to reindex and/or refresh cache.
Upon adding a product to the cart and proceeding to checkout, in the last step, choose the Braintree payment method, then after clicking the "Place Order" button, you will notice the following AJAX requests:
- 2 requests to Braintree API to validate the card, perform the transaction, and responds with transaction status.
- A request to Magento's API
guest-carts/cartId/payment-information
with the usual body as explained in Magento's API documentation.
After that the process continues as expected with redirection to success page when the last request responds in JSON containing the order entity_id
This confirms that calls to external services -Braintree in our example- is performed by the checkout page NOT by Magento internally, so we will need to do the same if we are to develop our own checkout page/app.
As for controlling the order status, i dug deeper and found out that using payment methods like MiGS, Braintree, or PayPal, resulted in an order with status processing
instead of the usual pending
, i suspected that this is either a payment-method configuration or an observer, but it appeared to be a configuration, here are more details.
Class: Magento\Sales\Model\Order\Payment
Method: Place()
There is a conditional that checks if Initialization
is required for the method if ($methodInstance->isInitializeNeeded())
, if that's the case, a method initialize()
is executed which you define, and allows you to specify both state
and status
.
Best Answer
The full workflow should be like this:
Create a shopping cart (
'cart.create'
)Set the customer/guest to the shopping cart (
'cart_customer.set'
)Set customer addresses, for example guest's addresses (
'cart_customer.addresses'
)add/update/remove products to the shopping cart (
'cart_product.add', 'cart_product.update', cart_product.remove'
)get the list of shipping methods (
'cart_shipping.list'
)set shipping method (
'cart_shipping.method'
)get list of payment methods (
'cart_payment.list'
)set payment method (
'cart_payment.method'
)add/remove coupons if necessary (
'cart_coupon.add', 'cart_coupon.remove'
)get total prices (
'cart.totals'
)get information about the shopping cart (
'cart.info'
)get list of licenses (
'cart.licenseAgreement'
)create oder (
'cart.order'
)There is also a detailed code example for SOAP APIv1 on http://www.magentocommerce.com/api/soap/checkout/cart/cart.html