Laravel 6 PayPal GateWay subTotal,shipping ,tax not working properly - paypal

Am using Laravel 6. And am trying to integrate PayPal Payment Gateway in my project.
Am following PayPal PHP Sdk's example source code.
I have sandbox personal & buyer account.
Payment and transaction working when am copying code from PayPal PHP Payment Example.
But whenever am trying to add Multiple items and subTotal then its generate error.
Code Below :
Static data from PayPal Sdk's Example.
$item1 = new Item();
$item1->setName('Ground Coffee 40 oz')
->setCurrency('USD')
->setQuantity(1)
->setSku("22222") // Similar to `item_number` in Classic API
->setPrice(7.5);
$item2 = new Item();
$item2->setName('Granola bars')
->setCurrency('USD')
->setQuantity(5)
->setSku("852520") // Similar to `item_number` in Classic API
->setPrice(2);
$iteamArr = [$item1,$item2];
$itemList = new ItemList();
$itemList->setItems($iteamArr);
Default example Payment Details Below :
and What am trying to make dynamic .
Code Below :
$details = new Details();
$details->setShipping(7.5)
->setTax(5.0)
->setSubtotal(17.50);
$amount = new Amount();
$amount->setCurrency("USD")
->setTotal(30)
->setDetails($details);
My Dynamic Process is :
for($loop=1;$loop<3;$loop++){
$item = new Item();
$itemInfo[]=$item->setName('Dynamic Name '.$loop)
->setCurrency('USD')
->setQuantity(1)
->setSku(rand(1111,9999).$loop) // Similar to `item_number` in Classic API
->setPrice(2);
}
According to My Dynamic Code , Payment Detail's below :
$details = new Details();
$details->setShipping(7.5)
->setTax(5.0)
->setSubtotal(4);
$amount = new Amount();
$amount->setCurrency("USD")
->setTotal(16.5)
->setDetails($details);
After this am getting reply from PayPal return
Got Http response code 400 when accessing
https://api.sandbox.paypal.com/v1/payments/payment.
Note : When am cloning PayPal item information from there documentation its successfully working.

I think that the problem probably should be ->setTotal(16.5)
This line should be dynamic too, since the total price is dynamic in base of checkout cart
I'm going to give you as example a part of code from my paypal PaymentController:
$totalPayment = ($request->get('actual_participants') * $trip->price);
$payer = new Payer();
$payer->setPaymentMethod('paypal');
$item = new Item();
$item->setName($trip->title) /** item name **/
->setCurrency($trip->currency->currency_type)
->setQuantity('1')
->setPrice($totalPayment); /** unit price **/
$itemList = new ItemList();
$itemList->setItems(array($item));
$amount = new Amount();
$amount->setCurrency($trip->currency->currency_type)
->setTotal($totalPayment);
11 months later I think that you already solved the problem but I wish good luck to other devs because I understand the struggle of paypal integration :)

Related

PAYMENT.CAPTURE.COMPLETED: How to get parent payment?

When getting an event PAYMENT.SALE.COMPLETED in a webhook, you can use this code to get more information about the payer:
$resource = $webhookEvent->getResource();
$Payment = \Paypal\Api\Payment::get($resource->parent_payment, $apiContext);
$Payer = $Payment->getPayer();
$Payerinfo = $Payer->getPayerInfo();
Now I updated to SDK V2, and get PAYMENT.CAPTURE.COMPLETED-events. How does this work here? It seems there is no $resource->parent_payment. I tried something like:
$request = new PayPalCheckoutSdk\Orders\OrdersGetRequest($resource->id);
But this only returns RESOURCE_NOT_FOUND.
How can I get the Payerinfo here?
The resource->id returned is a v2/payments id, not an Order ID.
v2/checkout/orders IDs are only used during payer approval, and have no accounting value.

how to calculate tax using paypal api

i installed the .net sdk of paypal and created an app in sandbox environment
next i picked up the clientId and secret and used the following sample code to make a payment.
static void Main(string[] args)
{
// Get a reference to the config
var config = ConfigManager.Instance.GetProperties();
// Use OAuthTokenCredential to request an access token from PayPal
var accessToken = new OAuthTokenCredential(config["clientId"], config["clientSecret"]);
var apiContext = new APIContext(accessToken.GetAccessToken());
var payment = Payment.Create(apiContext, new Payment
{
intent = "sale",
payer = new Payer
{
payment_method = "paypal"
},
transactions = new List<Transaction>
{
new Transaction
{
description = "Test",
invoice_number = "009",
amount = new Amount
{
currency = "EUR",
total = "41.00",
details = new Details
{
tax = "0",
shipping = "0",
subtotal = "40",
handling_fee = "1"
}
},
item_list = new ItemList
{
items = new List<Item>
{
new Item
{
name = "Room 12",
currency = "EUR",
price = "10",
quantity = "4",
}
}
}
}
},
redirect_urls = new RedirectUrls
{
return_url = "https://google.de/",
cancel_url = "https://google.de/"
}
});
}
in the transaction i have to pass Tax information.
Is there was that i let paypal calculate the tax and i just pass amount information along with address and some other information if required ?
No, you must calculate the tax yourself.
By default the user will be able to select their shipping address at PayPal, which is recommended as this saves them from having to type it manually. Given that their address can change during the PayPal checkout, you may wish to calculate a new tax amount and/or shipping amount based on the selected address. You can do this using the JS SDK's onShippingChange callback.
Firstly, though, it appears you may be using a deprecated SDK and deprecated v1/payments API, and also a redirect away from your site to PayPal, all of which is old. Don't do any of this.
Instead: follow the PayPal Checkout integration guide and make 2 routes on your server, one for 'Create Order' and one for 'Capture Order' (see the optional step 5 in 'Add and modify the code'). Both of these routes should return only JSON data (no HTML or text). There is a Checkout-Java-SDK you can use, or integrate with your own direct HTTPS API calls (obtain an access_token first, it can be cached but expires in 9 hours).
Inside the 2nd capture route on your server, when the capture API call is successful you should store its resulting payment details in your database (particularly purchase_units[0].payments.captures[0].id, which is the PayPal transaction ID) and perform any necessary business logic (such as sending confirmation emails or reserving product) immediately before forwarding your return JSON to the frontend caller.
Pair those 2 routes with the frontend approval flow: https://developer.paypal.com/demo/checkout/#/pattern/server

Is it possible to allow partial payments using the PayPal Invoicing SDK?

Is it possible to allow partial payments using the PayPal Invoicing SDK?
I have tried setting the allowPartialPayments attribute to true on the InvoiceType object(see below) although once the invoice has been received there is no option to change the amount being paid.
InvoiceItemListType itemList = new InvoiceItemListType(invoiceItemList);
InvoiceType invoice = new InvoiceType(_MerchantEmailAddress, payerEmailAddress, itemList, "GBP");
invoice.number = brightStartInvoiceId.ToString();
invoice.merchantMemo = brightStartChildId.ToString();
invoice.allowPartialPayments = true;
CreateAndSendInvoiceRequest requestCreateAndSendInvoice = new CreateAndSendInvoiceRequest(envelopeRequest, invoice);

Paypal Invoicing API, SendInvoiceRequest returns invoice null error

I'm using the C# SDK for our implementation (Classic API).
I can create an invoice fine, but whenever I try to send an invoice the response comes back with an error "Invalid request parameter: invoice cannot be null".
var result = new SendInvoiceResult();
var service = new PayPal.Invoice.InvoiceService(PayPalConfig());
var envelopeRequest = new RequestEnvelope
{
errorLanguage = "en_US", detailLevel = DetailLevelCode.RETURNALL
};
var request = new SendInvoiceRequest ( envelopeRequest, invoiceId );
var response = service.SendInvoice(request);
If I use the CreateAndSendInvoice method instead then a similar thing happens - the invoice gets created (I can view the URLs and the invoice shows as in draft) but it never sends.
Does anyone know what I'm doing wrong here?

Coupon Code For Paypal Express Checkout

I'm using Paypal Express Checkout system on my website. But I want to put a coupon (discount) code area. It will make a reduction if code is true. (Like GoDaddy.com's cart system)
Have you any idea, where should I start for this?
(I'm not using any eCommerce framework)
I know this is an old thread but wanted to put here my experience for others looking for the same thing, and maybe this did not apply then but it does apply now, at least on the sandbox meaning I have not tested this in a real transaction
When adding items that you send to paypal you basically send this
L_PAYMENTREQUEST_0_QTY0 = 1
L_PAYMENTREQUEST_0_AMT0 = 1.00
L_PAYMENTREQUEST_0_NAME0 = my item 0 name
L_PAYMENTREQUEST_0_NUMBER0 = myitem0id
Then we add another item
L_PAYMENTREQUEST_0_QTY1 = 1
L_PAYMENTREQUEST_0_AMT1 = 1.00
L_PAYMENTREQUEST_0_NAME1 = my item 1 name
L_PAYMENTREQUEST_0_NUMBER1 = myitem1id
And now we add the coupon
L_PAYMENTREQUEST_0_QTY2 = 1
L_PAYMENTREQUEST_0_AMT2 = -0.50
L_PAYMENTREQUEST_0_NAME2 = my coupon name
L_PAYMENTREQUEST_0_NUMBER2 = mycouponcode
And then we add the subtotal and total values
PAYMENTREQUEST_0_AMT = 1.50
AMT = 1.50
What I think paypal does is ads up all item totals so it would do for this order something like
1.00+1.00-0.50 = 1.50
Then compares it to your total amounts
if they match then it is a go, the customer sees this as an extra item, but obviously with the minus sign, this picture below is from a paypal sandbox express checkout transaction
One approach is to have a shopping cart on your site where the user can enter a promo code. Once they've entered their promo codes, and are ready to begin the checkout process, this is when you redirect them to the Express Checkout (where you send Paypal the final amount of your order, etc).
According to this post on Paypal forum, they do not have a feature to pass the discount details to the checkout process: https://www.x.com/thread/39681 ("With express checkout all discount calculations will need to be done on your site.")
How to calculate before sending price to paypal
1) Add a SEPARATE form for the promo code to your page:
<form method="GET">
<input type="text" name="promocode">
<input type="submit" value="Add Promo">
</form>
2) On the server side, check the code, update the page accordingly with new prices (e.g. re-build your select menu with new prices). Example with PHP:
<?
if(isset($_GET('promocode')) {
$prices = processPromo($_GET('promocode'));
}
else {
$prices = array(2000, 4000, 6000);
}
?>
If you don't have access to the server, you would have to do this with JavaScript I guess (i.e. have your promo-code and price hard-coded into the page)
To initiate express checkout on server side
Download PHP NVP SDK & examples from Paypal's website:
https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/library_download_sdks
<?php
require_once 'CallerService.php';
session_start();
ini_set('session.bug_compat_42',0);
ini_set('session.bug_compat_warn',0);
/* Gather the information to make the final call to
finalize the PayPal payment. The variable nvpstr
holds the name value pairs
*/
$token =urlencode( $_SESSION['token']);
$paymentAmount =urlencode ($_SESSION['TotalAmount']);
$paymentType = urlencode($_SESSION['paymentType']);
$currCodeType = urlencode($_SESSION['currCodeType']);
$payerID = urlencode($_SESSION['payer_id']);
$serverName = urlencode($_SERVER['SERVER_NAME']);
$nvpstr='&TOKEN='.$token.'&PAYERID='.$payerID.'&PAYMENTACTION='.$paymentType.'&AMT='.$paymentAmount.'&CURRENCYCODE='.$currCodeType.'&IPADDRESS='.$serverName ;
/* Make the call to PayPal to finalize payment
If an error occured, show the resulting errors
*/
$resArray=hash_call("DoExpressCheckoutPayment",$nvpstr);
/* Display the API response back to the browser.
If the response from PayPal was a success, display the response parameters'
If the response was an error, display the errors received using APIError.php.
*/
$ack = strtoupper($resArray["ACK"]);
if($ack != 'SUCCESS' && $ack != 'SUCCESSWITHWARNING'){
$_SESSION['reshash']=$resArray;
$location = "APIError.php";
header("Location: $location");
}
?>