I have integrated paypal into codeigniter with paypal_helper (didn't rememeber where I found it, but it is a slightly rewritten version of Paypals original code for express checkout. I try calling this function,
CallShortcutExpressCheckout( $paymentAmount, $currencyCodeType,
$paymentType, $returnURL, $cancelURL)
sending $paymentAmount as int, $currencyCodeType as "NOK" and $paymentType as "Sale".
Both in Sandbox and live, no amount appears on the paypal site...
What could be wrong?
Edit, to further explain my process. I use this, mostly as specified in the https://www.paypal-labs.com/integrationwizard/ecpaypal/cart.php. This should be doable without the form? The paymentAmount could be sent as a standard variable, when calling the function CallShortcutExpressCheckout?:
$resArray = CallShortcutExpressCheckout ($paymentAmount, $currencyCodeType, $paymentType, $returnURL, $cancelURL);
$ack = strtoupper($resArray["ACK"]);
if($ack=="SUCCESS" || $ack=="SUCCESSWITHWARNING")
{
RedirectToPayPal ( $resArray["TOKEN"] );
}
else
{
//Display a user friendly Error on the page using any of the following error information returned by PayPal
$ErrorCode = urldecode($resArray["L_ERRORCODE0"]);
$ErrorShortMsg = urldecode($resArray["L_SHORTMESSAGE0"]);
$ErrorLongMsg = urldecode($resArray["L_LONGMESSAGE0"]);
$ErrorSeverityCode = urldecode($resArray["L_SEVERITYCODE0"]);
echo "SetExpressCheckout API call failed. ";
echo "Detailed Error Message: " . $ErrorLongMsg;
echo "Short Error Message: " . $ErrorShortMsg;
echo "Error Code: " . $ErrorCode;
echo "Error Severity Code: " . $ErrorSeverityCode;
}
The token is saved in a database. The user gets redirected to Paypal, where no amount is listed.
As you're not passing so called 'line item details' (product data), PayPal doesn't display the total amount.
If you only want to show the amount for the current purchase, redirect buyers to https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-xxxxxx&useraction=commit (instead of https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-xxxxx)
If you want to start sending line-item details to PayPal, include the following in your SetExpressCheckout API request:
// Total amount of the purchase, incl shipping, tax, etc
PAYMENTREQUEST_0_AMT=300.0
// Total amount of items purchased, excl shipping, tax, etc
PAYMENTREQUEST_0_ITEMAMT=300.0
// Authorize the funds first (Authorization), or capture immediately (Sale)?
PAYMENTREQUEST_0_PAYMENTACTION=Sale
// First item
L_PAYMENTREQUEST_0_NAME0=Item1
L_PAYMENTREQUEST_0_QTY0=1
L_PAYMENTREQUEST_0_AMT0=100.00
// Second item
L_PAYMENTREQUEST_0_NAME1=Item2
L_PAYMENTREQUEST_0_QTY1=1
L_PAYMENTREQUEST_0_AMT1=200.00
If you want to see this in your own history as well, you'll also need to include this in DoExpressCheckoutPayment.
This was also posted in php paypal express checkout problem
After an extensive reading on messy Paypal docs site this is a short ExpressCheckout guide working on year 2013. I wanted to have item details shown on paypal payment page and merchant transaction history page.
Paypal documentation links
https://developer.paypal.com/webapps/developer/docs/classic/api/
https://developer.paypal.com/webapps/developer/docs/classic/api/merchant/SetExpressCheckout_API_Operation_NVP/
https://developer.paypal.com/webapps/developer/docs/classic/api/merchant/DoExpressCheckoutPayment_API_Operation_NVP/
https://developer.paypal.com/webapps/developer/docs/classic/api/merchant/GetExpressCheckoutDetails_API_Operation_NVP/
You can call following url methods directly on web browser, update token and payerid parameters accordingly.
This is a digital goods so shipping and handling fees are not given. Single item row. Amount and tax fees are given. Do not require a confirmed delivery address, no shipping address fields, no allow freetext note, payer don't need paypal account and no registration required (solutiontype=sole). Activate credit card section on paypal site (landingpage=billing). Use customized brand title on paypal site. Use custom field to give own value for tracking purpose. Merchant site transaction history must show item details (give item details on SetExpressCheckout and DoExpressCheckoutPayment methods).
SetExpressCheckout method opens a new transaction
https://api-3t.sandbox.paypal.com/nvp?
USER=<userid>
&PWD=<pwd>
&SIGNATURE=<mysig>
&METHOD=SetExpressCheckout
&VERSION=98
&PAYMENTREQUEST_0_PAYMENTACTION=SALE
&REQCONFIRMSHIPPING=0
&NOSHIPPING=1
&ALLOWNOTE=0
&SOLUTIONTYPE=Sole
&LANDINGPAGE=Billing
&BRANDNAME=MY+WEBSHOP+TITLE
&PAYMENTREQUEST_0_AMT=22.22
&PAYMENTREQUEST_0_TAXAMT=4.30
&PAYMENTREQUEST_0_ITEMAMT=17.92
&PAYMENTREQUEST_0_DESC=mypurdesc
&PAYMENTREQUEST_0_CUSTOM=custom1
&PAYMENTREQUEST_0_CURRENCYCODE=EUR
&L_PAYMENTREQUEST_0_NUMBER0=itemid1
&L_PAYMENTREQUEST_0_NAME0=MyItem1
&L_PAYMENTREQUEST_0_DESC0=Item1+description
&L_PAYMENTREQUEST_0_QTY0=1
&L_PAYMENTREQUEST_0_AMT0=17.92
&L_PAYMENTREQUEST_0_TAXAMT0=4.30
&RETURNURL=https://myserver.com/webapp/paypal.jsp%3Fcmd=successexp
&CANCELURL=https://myserver.com/webapp/paypal.jsp%3Fcmd=cancelexp
Reply must have ACK=Success or ACK=SuccessWithWarning, read TOKEN value
Redirect user browser to Paypal site, give token value
https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=<token>
User uses paypal account or credit card. Paypal redirects user to return or cancel url.
Redirect destination url gets token and PayerID parameter values.
Transaction is not completed yet we must call doExpressCheckoutPayment method.
Show confirm dialog on screen (with OK, CANCEL button) or simple case
commit a transaction and show "Thank you, purchase completed" message.
User has already accepted a payment in paypal site and expects transaction be finalized.
You may commit transaction within a same request-response handler or using
asynchronous background task. Paypal site may temporarily be unavailable so don't expect it to work immediately.
Commit transaction if redirect was success, use token and payerid
https://api-3t.sandbox.paypal.com/nvp?
USER=<userid>
&PWD=<pwd>
&SIGNATURE=<mysig>
&METHOD=DoExpressCheckoutPayment
&VERSION=98
&PAYMENTREQUEST_0_PAYMENTACTION=SALE
&PAYMENTREQUEST_0_AMT=22.22
&PAYMENTREQUEST_0_TAXAMT=4.30
&PAYMENTREQUEST_0_ITEMAMT=17.92
&PAYMENTREQUEST_0_CURRENCYCODE=EUR
&L_PAYMENTREQUEST_0_NUMBER0=itemid1
&L_PAYMENTREQUEST_0_NAME0=MyItem1
&L_PAYMENTREQUEST_0_QTY0=1
&L_PAYMENTREQUEST_0_AMT0=17.92
&L_PAYMENTREQUEST_0_TAXAMT0=4.30
&token=<token>
&payerid=<payerid>
Read ACK=Success and verify fields
ACK=Success
PAYMENTINFO_0_PAYMENTSTATUS=Completed
PAYMENTINFO_0_ACK=Success
PAYMENTINFO_0_AMT=22.22 total amount must match
PAYMENTINFO_0_FEEAMT=0.99 (just for fun, read paypal comission fee)
PAYMENTINFO_0_CURRENCYCODE=EUR currency must match
(Optional) Read transaction details from Paypal
You can use this during transaction workflow or any time if stored a token for later use.
https://api-3t.sandbox.paypal.com/nvp
?USER=<userid>
&PWD=<pwd>
&SIGNATURE=<mysig>
&METHOD=GetExpressCheckoutDetails
&VERSION=98
&token=<token>
Read response parameters.
ACK=Success
CHECKOUTSTATUS=PaymentActionCompleted
PAYMENTREQUEST_0_AMT=22.22
PAYMENTREQUEST_0_TAXAMT=4.30
PAYMENTREQUEST_0_CURRENCYCODE=EUR
(Optional) Read and save transaction id, correlation id and token id and write to logtable.
PAYMENTREQUEST_0_TRANSACTIONID=11E585715B622391E
CORRELATIONID=4534b683c335f
I'm willing to receive comments if there is any logic errors.
Check this link, hope it helps in some sense:
https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_ECGettingStarted
PAYMENTREQUEST_0_AMT=amount //for amount
Related
I'm trying to create a module for allowing Partial Payment during checkout process.
Let's take a cart with 2 products, first item = 1000€ and second item = 500€.
User has to pay 1500€ but I'm allowing to split the payments in two steps, first user will pay 1000€ and later he'll has to pay 500€.
When trying to use Paypal Express payment for this, I'm always getting this error:
PayPal gateway has rejected request.
Item total is invalid (#10426: Invalid Data).
The totals of the cart item amounts do not match order amounts
(#10413: Transaction refused because of an invalid argument.
See additional error messages for details).
Basically, what I'm doing is modifying app/code/local/Mage/Paypal/Model/Express overwriting the value of Amount:
$transaction_amount = $this->_quote->getBaseGrandTotal();
if ($this->_quote->getPartialpayment_price() > 0) {
$transaction_amount = $this->_quote->getPartialpayment_price();
}
$this->_api->setAmount($transaction_amount)
->setCurrencyCode($this->_quote->getBaseCurrencyCode())
->setInvNum($this->_quote->getReservedOrderId())
->setReturnUrl($returnUrl)
->setCancelUrl($cancelUrl)
->setSolutionType($solutionType)
->setPaymentAction($this->_config->paymentAction);
Is it somehow possible to avoid what Paypal is internally checking, to compare the final amount with the cart item amounts?
In order to not send the individual items to Paypal API Request, there's an option in the backend named Transfer Cart Line Items. If it's set to NO we won't add each cart item into that request.
i encountered an issue that sometimes arises on my Magento Community Edition 1.8 Store. The problem is that sometimes Magento adds the Cash on Delivery fee, to the order grand total, in spite of the user had selected Paypal as payment method. This happen only if the user selects Paypal as payment method and happen rarely. Sometimes even the amounts of the items through Paypal and Magento are not in compliance. Contact Paypal Support was not helpful.
Any help will be appreciate
Thanks in advance to everyone
Kind Regards
Steelwork Media Solutions
I feel like some necroposter, but I want to share some thoughts about solving this issue.
Recently I got the very same problem: user has chosen PayPal as payment method, but got charged with cash on delivery fee. After some investigating, I found out that cash on delivery module itself was a culprit.
The problem is in module's logic: it adds up COD fee when COD payment method is selected, but it DOES NOT clear that fee from quote, when payment method is changed to another one. So, when order is being created, fields with COD fee are being copied as is to order. And client gets charged for nothing.
The worst thing in this situation is that you don't see that fee applied in checkout. It pops up only in order.
For example, there is a part of code from MSP_CashOnDelivery module:
if (
($_helper->getQuote()->getPayment()->getMethod() == $_model->getCode()) &&
($address->getAddressType() == Mage_Sales_Model_Quote_Address::TYPE_SHIPPING)
) {
$address->setGrandTotal($address->getGrandTotal() + $amount);
$address->setBaseGrandTotal($address->getBaseGrandTotal() + $baseAmount);
$address->setMspCashondelivery($amount);
$address->setMspBaseCashondelivery($baseAmount);
$address->setMspCashondeliveryInclTax($amountInclTax);
$address->setMspBaseCashondeliveryInclTax($baseAmountInclTax);
$quote->setMspCashondelivery($amount);
$quote->setMspBaseCashondelivery($baseAmount);
$quote->setMspCashondeliveryInclTax($amountInclTax);
$quote->setMspBaseCashondeliveryInclTax($baseAmountInclTax);
}
To solve the problem, you need to add following code below:
if ($_helper->getQuote()->getPayment()->getMethod() != $_model->getCode())
{
$address->setMspCashondelivery(0);
$address->setMspBaseCashondelivery(0);
$address->setMspCashondeliveryInclTax(0);
$address->setMspBaseCashondeliveryInclTax(0);
$quote->setMspCashondelivery(0);
$quote->setMspBaseCashondelivery(0);
$quote->setMspCashondeliveryInclTax(0);
$quote->setMspBaseCashondeliveryInclTax(0);
}
As mentioned in above answer, setting the fields to zero works perfectly. However, it will add a row in invoice and order with a zero charge and that may sound weird to customers. so just add a simple if condition for checking if charge is zero in all the Totals.php block files.
$amt = $this->getSource()->getServiceCharge();
$nameAmt = $this->getSource()->getServiceChargeName();
if ($amt && $amt!=0) {
$this->addTotalBefore(new Varien_Object(array(
'code' => 'service_charge',
'value' => $amt,
'base_value'=> $this->getSource()->getBaseServiceCharge(),
'label' => $nameAmt,
)), 'service_charge');
}
I'm trying to get the gift option message to only show up when a customer is shipping to an address that's different from the billing address in the Onepage checkout flow. I can get the "Ship to same/different address" from the billing section with
$this->getQuote()->getShippingAddress()->getData('same_as_billing')
and it works great. However, if a customer makes it the shipping methods, and hits back to change the shipping address, that field doesn't seem to get updated. I tried checking
$this->getQuote()->getShippingAddress()->getData('use_billing_address')
But that data doesn't exist. In fact, when I have these two lines in additional.phtml:
Mage::log("Same as billing: ".$this->getQuote()->getShippingAddress()->getData('same_as_billing'));
Mage::log("Use billing: ".$this->getQuote()->getShippingAddress()->getData('use_billing_address'));
It doesn't trigger when I go from Shipping Address to Shipping methods. Can anyone give me some direction here?
I ended up using a javascript function instead of PHP, since it doesn't reload the page to get to each section.
In template/giftmessage/inline.phtml, I added the following:
function _showHideGift() {
var flag=document.getElementById('shipping:same_as_billing').checked;
if(!flag){
document.getElementById('gift-messages').style.display="block";
}else{
document.getElementById('gift-messages').style.display="none";
}}
And then called the function below the block inside of the CDATA, with the toogleVisilibityOnObjects calls.
So during login, I want to check if the user is in a specific customer group and prevent login if that check fails.
I have extended the AccountController, and added in a quick check:
$customer = Mage::getModel('customer/customer')->loadByEmail($login['username']);
if ($customer->getGroupId() != 2) {
$msg = Mage::getSingleton('core/session')->addError($this->__('You must have a wholesale account to access this area.'));
header('Location: '. Mage::getUrl('customer/account/login'));
exit;
}
However, running this returns session error message, "Customer website ID must be specified when using the website scope".
Basically, I just need to grab the group id of the user who is attempting to login, and I figured I could grab this through the method supplied in the customer model, loadByEmail(). But yeah, it's Friday, and apparently the MageLords want me to stay late.
I have tried a number of methods to get this working, including allowing the login, then checking the ID, then doing $session->logout() if the check fails, but this was preventing me from displaying a session error message since the logout() method is clearing all session messages (including 'core/session').
Any ideas?
You should set website_id before working with loadByEmail method. I know, it seems weird, but this is dictated by the fact, that customer could be a website-scoped entity. So the loadByEmail method will throw exception if customer model is not assigned to any website.
$customer = Mage::getModel('customer/customer');
$customer->setWebsiteId(Mage::app()->getStore()->getWebsiteId())
->loadByEmail($login['username']);
I'm using magento 1.7, and one of the payment options is Paypal (UK) express checkout.
The problem is that I don't want paypal to send out emails with any tax breakdown on, is there a more straightforward way of solving this (at the Magento or Paypal end) rather than hacking the core module to pass sub+tax as sub and 0 as tax?
I can see that a lot of the fields are mapped in Model/Api/Nvp.php, but can't immediately see where I'd modify these values.
As far as I investigated, there is no easy configurable way to prevent taxes to be submitted to Paypal.
But indeed there is a core hack if you don't mind that only the total amount is submitted (no line items, no taxes).
Go to System/Config/Paypal and set Transfer Cart Line Items to No.
In your code go to function _validate() in class Mage_Paypal_Model_Cart.
At the end of this function add the following lines:
$this->_areItemsValid = false;
$this->_areTotalsValid = false;
Of course it is nicer to to rewrite this class in your app/code/local folder.