PayPal classic API express checkout - tax issue - api

I am trying to create a payment using Express Checkout. it works fine if I don't include the TaxTotal. As soon as I do I get an error "Tax total is invalid".
var itemTotal = new BasicAmountType(Enum.GetValues(typeof(CurrencyCodeType)).Cast<CurrencyCodeType>().FirstOrDefault(t => t.ToString() == cart.Item.Currency.ToString()), cart.NetTotal.ToString());
var orderTotal = new BasicAmountType(Enum.GetValues(typeof(CurrencyCodeType)).Cast<CurrencyCodeType>().FirstOrDefault(t => t.ToString() == cart.Item.Currency.ToString()), cart.GrossTotal.ToString());
var taxTotal = new BasicAmountType(Enum.GetValues(typeof(CurrencyCodeType)).Cast<CurrencyCodeType>().FirstOrDefault(t => t.ToString() == cart.Item.Currency.ToString()), cart.TaxTotal.ToString());
paymentDetails.ItemTotal = itemTotal;
paymentDetails.OrderTotal = orderTotal;
paymentDetails.TaxTotal = taxTotal;
If I remove the ItemTotal and TaxTotal the payment processes fine, but I need to show the tax breakdown.
FYI, the amounts are, ItemTotal = 175, OrderTotal = 210, TaxTotal = 35.
Can anyone confirm what the problem is or what is missing from my code?
Thanks,
Andy

Try adding the decimals so it becomes 175.00. I would do that for all amount fields when using PayPal's API's.
If that doesn't work, post a copy of the actual request that you're sending so we can verify what is actually getting sent.

I solved the problem, it was similar to the solution suggested by Andrew.
I was using a decimal for the order total which was 210.000. I rounded this to 210.00 to knock a decimal off and it worked fine.

Related

Codeigniter 4 - WHERE clause in Model

It's me again, Van.
Hi everyone,
I hope you're doing well!
I am doing a tutorial on a chat application using Codeigniter 4 with Ajax.
Everything worked fine until I applied the following code in the Model below
public function load_chat_data($sender_id,$receiver_id) {
// $where = ['sender_id' => $sender_id, 'receiver_id' => $receiver_id];
$where1 = "sender_id = $sender_id OR sender_id = $receiver_id";
$where2 = "receiver_id = $receiver_id OR receiver_id = $sender_id";
$builder = $this->db->table('chat_messages');
// $builder->where($where);
$builder->where($where1);
$builder->where($where2);
$builder->orderBy('chat_messages_id','ASC');
$results = $builder->get();
$rows = $results->getResultArray();
if($rows > 0)
{
return $rows;
}
else
{
return false;
}
}
The lines that I commented worked well before they were commented but it was not enough data I wanted to get so I tried to get both data of sender and receiver to display on the view by adding more code. However, when I tried $where1 and $where2 for the WHERE clauses, it didn't work. I think it must be the syntax error. Please correct my codes or any ideas on how the codes work with the same meaning supposed.
Thank you so much!!!
I tried as below, but it still didn't work.
$where1 = "sender_id={$sender_id} OR sender_id={$receiver_id}";
$where2 = "receiver_id={$receiver_id} OR receiver_id={$sender_id}";
Also, I tried:
$where1 = "'sender_id'=$sender_id OR 'sender_id'=$receiver_id";
$where2 = "'receiver_id'=$receiver_id OR 'receiver_id'=$sender_id";
I think you are trying to receive the messages of the conversation between two people. Can you try the following code for this?
$builder->groupStart(); // or $builder->orGroupStart();
$builder->where('sender_id', $sender_id);
$builder->where('receiver_id', $receiver_id);
$builder->groupEnd();
$builder->orGroupStart();
$builder->where('sender_id', $receiver_id);
$builder->where('receiver_id', $sender_id);
$builder->groupEnd();

Prestashop 1.7.4.2 - free shipping based on final total price

I need shipping calculation after discount applied
Ex.
Total cart : 65$
Free shipping start : 65$
Discount : 5%
After discount it become under 65$ and still get free shipping
I need it to calculate discount before shipping
First set your ranges by carrier (0-65: X EUR, above 65: 0 EUR)
Do an override of the class Cart.php
Rewrite function getPackageShippingCost
After line
// Order total in default currency without fees
$order_total = $this->getOrderTotal(true, Cart::BOTH_WITHOUT_SHIPPING, $product_list);
Add this
//Recalcul total pour panier et livraison gratuite
$listeDiscounts = $this->getCartRules();
$total_discounts = 0;
if (is_array($listeDiscounts)) {
if (isset($listeDiscounts[0]['value_real']))
$total_discounts = $listeDiscounts[0]['value_real'];
}
$price_to_apply_shipment = floatval($order_total) - floatval($total_discounts);
Replace
//$check_delivery_price_by_price = Carrier::checkDeliveryPriceByPrice($row['id_carrier'], $total_order, (int)$id_zone, (int)$this->id_currency);
by
$check_delivery_price_by_price = Carrier::checkDeliveryPriceByPrice($row['id_carrier'], $price_to_apply_shipment, (int)$id_zone, (int)$this->id_currency);
And
//$shipping_cost += $carrier->getDeliveryPriceByPrice($the_total_price, $id_zone, (int)$this->id_currency);
By
$shipping_cost += $carrier->getDeliveryPriceByPrice($price_to_apply_shipment, $id_zone, (int)$this->id_currency);
Clear the cache and run
The bottom two changes can be replaced by:
$total_package_without_shipping_tax_inc
= $order_total
= $orderTotalwithDiscounts
= $price_to_apply_shipment;
These variables are only used in these two places along the way

Paypal Php Sdk - NotifyUrl is not a fully qualified URL Error

I have this code
$product_info = array();
if(isset($cms['site']['url_data']['product_id'])){
$product_info = $cms['class']['product']->get($cms['site']['url_data']['product_id']);
}
if(!isset($product_info['id'])){
/*
echo 'No product info.';
exit();
*/
header_url(SITE_URL.'?subpage=user_subscription#xl_xr_page_my%20account');
}
$fee = $product_info['yearly_price_end'] / 100 * $product_info['fee'];
$yearly_price_end = $product_info['yearly_price_end'] + $fee;
$fee = ($product_info['setup_price_end'] / 100) * $product_info['fee'];
$setup_price_end = $product_info['setup_price_end'] + $fee;
if(isset($_SESSION['discountcode_amount'])){
$setup_price_end = $setup_price_end - $_SESSION['discountcode_amount'];
unset($_SESSION['discountcode_amount']);
}
$error = false;
$plan_id = '';
$approvalUrl = '';
$ReturnUrl = SITE_URL.'payment/?payment_type=paypal&payment_page=process_agreement';
$CancelUrl = SITE_URL.'payment/?payment_type=paypal&payment_page=cancel_agreement';
$now = $cms['date'];
$now->modify('+5 minutes');
$apiContext = new \PayPal\Rest\ApiContext(
new \PayPal\Auth\OAuthTokenCredential(
$cms['options']['plugin_paypal_clientid'], // ClientID
$cms['options']['plugin_paypal_clientsecret'] // ClientSecret
)
);
use PayPal\Api\ChargeModel;
use PayPal\Api\Currency;
use PayPal\Api\MerchantPreferences;
use PayPal\Api\PaymentDefinition;
use PayPal\Api\Plan;
use PayPal\Api\Patch;
use PayPal\Api\PatchRequest;
use PayPal\Common\PayPalModel;
use PayPal\Api\Agreement;
use PayPal\Api\Payer;
use PayPal\Api\ShippingAddress;
// Create a new instance of Plan object
$plan = new Plan();
// # Basic Information
// Fill up the basic information that is required for the plan
$plan->setName($product_info['name'])
->setDescription($product_info['desc_text'])
->setType('fixed');
// # Payment definitions for this billing plan.
$paymentDefinition = new PaymentDefinition();
// The possible values for such setters are mentioned in the setter method documentation.
// Just open the class file. e.g. lib/PayPal/Api/PaymentDefinition.php and look for setFrequency method.
// You should be able to see the acceptable values in the comments.
$setFrequency = 'Year';
//$setFrequency = 'Day';
$paymentDefinition->setName('Regular Payments')
->setType('REGULAR')
->setFrequency($setFrequency)
->setFrequencyInterval("1")
->setCycles("999")
->setAmount(new Currency(array('value' => $yearly_price_end, 'currency' => $cms['session']['client']['currency']['iso_code'])));
// Charge Models
$chargeModel = new ChargeModel();
$chargeModel->setType('SHIPPING')
->setAmount(new Currency(array('value' => 0, 'currency' => $cms['session']['client']['currency']['iso_code'])));
$paymentDefinition->setChargeModels(array($chargeModel));
$merchantPreferences = new MerchantPreferences();
// ReturnURL and CancelURL are not required and used when creating billing agreement with payment_method as "credit_card".
// However, it is generally a good idea to set these values, in case you plan to create billing agreements which accepts "paypal" as payment_method.
// This will keep your plan compatible with both the possible scenarios on how it is being used in agreement.
$merchantPreferences->setReturnUrl($ReturnUrl)
->setCancelUrl($CancelUrl)
->setAutoBillAmount("yes")
->setInitialFailAmountAction("CONTINUE")
->setMaxFailAttempts("0")
->setSetupFee(new Currency(array('value' => $setup_price_end, 'currency' => $cms['session']['client']['currency']['iso_code'])));
$plan->setPaymentDefinitions(array($paymentDefinition));
$plan->setMerchantPreferences($merchantPreferences);
// ### Create Plan
try {
$output = $plan->create($apiContext);
} catch (Exception $ex){
die($ex);
}
echo $output->getId().'<br />';
echo $output.'<br />';
Been working with paypal php sdk for some days now and my code stop working.
So i went back to basic and i am still getting the same damn error.
I am trying to create a plan for subscription but getting the following error:
"NotifyUrl is not a fully qualified URL"
I have no idea how to fix this as i dont use NotfifyUrl in my code?
Could be really nice if anyone had an idea how to fix this problem :)
Thanks
PayPal did a update to their API last night which has caused problem within their SDK.
They are sending back null values in their responses.
I MUST stress the error is not on sending the request to PayPal, but on processing their response.
BUG Report : https://github.com/paypal/PayPal-PHP-SDK/issues/1151
Pull Request : https://github.com/paypal/PayPal-PHP-SDK/pull/1152
Hope this helps, but their current SDK is throwing exceptions.
Use below simple fix.
Replace below function in vendor\paypal\rest-api-sdk-php\lib\PayPal\Api\MerchantPreferences.php
public function setNotifyUrl($notify_url)
{
if(!empty($notify_url)){
UrlValidator::validate($notify_url, "NotifyUrl");
}
$this->notify_url = $notify_url;
return $this;
}
If you get the same error for return_url/cancel_url, add the if condition as above.
Note: This is not a permanent solution, you can use this until getting the update from PayPal.
From the GitHub repo for the PayPal PHP SDK, I see that the error you mentioned is thrown when MerchantPreferences is not given a valid NotifyUrl. I see you're setting the CancelUrl and ReturnUrl, but not the NotifyUrl. You may simply need to set that as well, i.e.:
$NotifyUrl = (some url goes here)
$obj->setNotifyUrl($NotifyUrl);
Reason behind it!
error comes from.
vendor\paypal\rest-api-sdk-php\lib\PayPal\Validation\UrlValidator.php
line.
if (filter_var($url, FILTER_VALIDATE_URL) === false) {
throw new \InvalidArgumentException("$urlName is not a fully qualified URL");
}
FILTER_VALIDATE_URL: according to this php function.
INVALID URL: "http://cat_n.domain.net.in/"; // IT CONTAIN _ UNDERSCORE.
VALID URL: "http://cat-n.domain.net.in/"; it separated with - dash
here you can dump your url.
vendor\paypal\rest-api-sdk-php\lib\PayPal\Validation\UrlValidator.php
public static function validate($url, $urlName = null)
{
var_dump($url);
}
And then check this here: https://www.w3schools.com/PHP/phptryit.asp?filename=tryphp_func_validate_url
you can check here what character will reason for invalid.

Null value returned from time to time by google geocoding API

I have a problem with the google geocoding API.
Indeed, I am using coordinates (latitude and longitude) to find the city and the country. Because of this, I use this google geocoding API.
On the other hand, this is where I have a problem, sometimes it works but most often instead of recovering the city and the country I get NULL values.
I also checked in the Google API dashboard (where I saved the key number), and I see that a lot of calls go wrong: there is a 403 error. He passes, that's where I do not understand.
If I only take the URL directly in a browser, then I get the right values.
I do not understand why sometimes it works and other times (but more often) I get NULL.
here is the PHP code that I use:
$latitude = (isset($_GET["lat"])) ? $_GET["lat"] : NULL;
$longitude = (isset($_GET["long"])) ? $_GET["long"] : NULL;
if ($latitude && $longitude) {
$url = "http://maps.googleapis.com/maps/api/geocode/json? latlng=".$latitude.",".$longitude."&key=NUMCLE";
$data = #file_get_contents($url);
$jsondata = json_decode($data,true);
if(is_array($jsondata) && $jsondata['status'] == "OK")
{
$city = $jsondata['results']['0']['address_components']['2'] ['long_name'];
$country = $jsondata['results']['0']['address_components']['5']['long_name'];
$street = $jsondata['results']['0']['address_components']['1']['long_name'];
?>
If you could help me with this problem it would be cool.
Thank you in advance for your help.
SSL/TLS is reqired for google web services.
Change
$url = "http://maps.googleapis.com/maps/api/geocode/json? latlng=".$latitude.",".$longitude."&key=NUMCLE";
to
$url = "https://maps.googleapis.com/maps/api/geocode/json? latlng=".$latitude.",".$longitude."&key=NUMCLE";

Paypal ipn/cart variables

Wondered if anyone could give me any pointers?
The website I'm currently building sells 'event' tickets....holidays.
What I'm trying to do is decrease the number of tickets in a database field by the number purchased BUT can't find a paypal cart variable which will pull the information back. The custom variable it seems can only be used once and the item_name and item_number variables are already being used, the (item_number) to identify the 'event_id' field in the database and the (item_name) to obviously identify the event name.
I can pass the correct number of tickets to be updated over to Paypal by decreasing the amount and echoing that out in a hidden form field prior to sumbitting to Paypal BUT I can't get the results back. I'm looking for a Paypal form 'name' field that can be adapted to my needs, if one exists
Below is the database loop: The 'custom' variable doesn't work as it can't be custom1, custom2 etc.
mysql_connect('xxxxxxxx', 'xxxxxx', 'xxxxxxxx') or exit(0);
mysql_select_db('xxxxxx') or exit(0);
$num_cart_items = $_POST['num_cart_items'];
$i=1;
while (isset($_POST['item_number'.$i]))//read the item details
{
$item_ID[$i]=$_POST['item_number'.$i];
$custom[$i]=$_POST['custom'.$i];
$i++;
}
$item_count = $i-1;
for ($j=1;$j<=$item_count;$j++)
{
$struery = "UPDATE events SET event_tickets = '".$custom[$j]."' WHERE event_id = '".$item_ID[$j]."'";
$result = mysql_query($struery) or die("Cart - paypal_cart_info, Query failed:<br>" . mysql_error() . "<br>" . mysql_errno());
$i++;
}// end database loop
Thanks for any info.
Os
You can put custom variable as JSON encoded string. Then decode it.
$i=1;
$custom = json_decode($_POST['custom], TRUE);
while (isset($_POST['item_number'.$i]))//read the item details
{
$item_ID[$i] = $_POST['item_number'.$i];
$custom[$i] = $custom[$i];
$i++;
}
Or you can even base64_encode it on send to paypal and верут decode it back it you want variable not to be readable when you redirect user to paypal.