I am having a issue with a paypal cart since the update around march (bit late but the site is not used yet and we just discovered it now).
I already checked this question but it did not solve the issue for a shopping cart (Paypal : hosted button payments fail with code=AMOUNT_ERROR)
We send a object that contains the request data through a plugin called neo.js, this works fine as far as we know.
This is our data we send to paypal as a js object.
{
amount_1: 10.01,
business: "noreply#domain.com",
cancel_return: "https://dev.domain.com",
charset: "utf-8",
cmd: "_cart",
currency_code: "US",
custom: "username",
item_name_1: "$10 item",
item_number_1: "1",
no_shipping: 1,
notify_url: "https://dev.domain.com/callback/paypal.php",
quantity_1: 1,
return: "https://dev.domain.com",
upload: 1
}
It has to do something with the amount, but using a , instead of . but that only gives a normal error message on screen that the format is incorrect.
We have tried multiple things including the dollar sign and making it a string but nothing seem to be working.
I reproduced the error and it is due to the wrong currency code passed.
You are passing "US" but the currency code (that is a parameter that refers to the AMOUNT as in the error returned) must be of 3 characters as you can see on PayPal guide: https://developer.paypal.com/webapps/developer/docs/classic/api/currency_codes/
Change it to "USD" instead and you will have a working checkout.
Related
After spending a full day on this dangerous thing, I can't understand how a transaction show APPROVED, I get an order ID, but there is no charge (not for buyer or receiver).
I am on live environment after tested on sandbox successfully.
So the code is long but basically on the server side we first create the transaction:
const request = new paypal.orders.OrdersCreateRequest();
request.prefer("return=representation");
request.requestBody({
intent: 'CAPTURE', //CAPTURE
purchase_units: [{
amount: {
currency_code: currency,
value: finalPrice
},
payee: {
email_address: payee
},
shipping: shipObj
}]
});
and later we approve the order with PayPal :
let request = new paypal.orders.OrdersGetRequest(orderID);
let order;
try {
order = await client.execute(request);
}
catch (err) {
console.error("error",err);
return res.sendStatus(500);
}
At this point i get order.result.status = APPROVED .
This is a live environment (the client and secret keys).
How can you send APPROVED to developer, and give an orderID but not charge ?
This is such a dangerous thing to do and can literally ruin businesses.
So then i found out there is a link to your order ID :
https://api.paypal.com/v2/checkout/orders/4PE63643WC652674S
If you look in this page you get this :
"message":"Authentication failed due to invalid authentication credentials or a missing Authorization header."
Now, only god knows what this means, and this is a failur message on an order ID page, which mean the orderID means nothing ??
So i also check the paypal link with my client-ID (should be identical to my client id in sdk right?) :
https://www.paypal.com/sdk/js?client-id=xxxxxxxxx&merchant-id=xxx#yyyy.com&disable-funding=credit,card¤cy=USD
Which seems ok and contains the right email.
Seems like you may have solved the issue and that you were missing the capture step, which is a required step to commit the transaction and must always occur after approval.
Just to review the best ways to integrate, if you are doing so with API calls from a server, you'll want to set make two routes on your server, one for 'Set up Transaction' and one for 'Capture Transaction', documented here: https://developer.paypal.com/docs/checkout/reference/server-integration/
Then, the best JS customer approval flow to pair with those server-side routes is this: https://developer.paypal.com/demo/checkout/#/pattern/server
I'm trying to perform a super-simple call to the PayPal Payments API.
{
"intent":"sale",
"payer": {
"payment_method":"credit_card",
"funding_instruments": {
"credit_card_token": {
"credit_card_id":"CARD-XXXXXXXXXXXXXXXXXXXXXXXX"
}
}
}
}
I've tried adding/removing various parts of the request, and I've had minimal success, but inevitably, I come across an error of "Incoming JSON request does not map to API request MALFORMED_REQUEST".
According to the documentation, these are the only required parameters, but I've tried different funding_instruments, adding payer_info, adding transactions, using credit_card_token and credit_card... nothing seems to work, and the documentation is useless for troubleshooting.
Is there a way to be able to determine WHY this is a malformed request? Most of the documentation I am coming across uses payment_method: paypal instead of credit_card. What are better ways for me to troubleshoot why this request is failing?
There are a few things to consider first. Are you in the US?
if not you will need to consider if your country can use the API. You can find Information of which countries can use the API here https://developer.paypal.com/docs/integration/direct/rest/country-codes/
You might also need to validate your json. I've tested what you have posted here, but you might not be generating the information properly in your app. check the output and make sure that it is valid json--MALFORMED_REQUEST is an indicator that required key/value pairs are missing or that the json is not valid... this website will help you validate the json output https://jsonlint.com/
check your headers carefully to ensure that you have a properly formatted header request header. you can check your headers against the api requirements here https://developer.paypal.com/docs/api/overview/#http-request-headers
paypal notes that they provide an error code as a json string for errors arising in this manner, and that details may or may not be provided in the response. error response codes are in the 400 and 500 ranges and correspond to error messages (these are listed on the headers page given above)
However, given your error message which is not listed i'm going to guess that you are missing required key/value pairs in your json...
paypal says that INTENT AND PAYER OBJECTS ARE REQUIRED, but the example payment that they give lists a great deal of information that your sample json is missing--
among those items are the transaction details which are required...
per paypal's api docs "Include payer, transaction details...
paypal api documentation gives examples of of the required payer and intent objects here https://developer.paypal.com/docs/api/payments/
restrictions are further placed on direct credit card payments: they may only be accepted from the UK or US, and only if the account is payment pro enabled...
options for avoiding this issue are:
1) paypal classic api direct payments--https://developer.paypal.com/docs/classic/paypal-payments-pro/integration-guide/direct-payment/
2) braintree direct: https://www.braintreepayments.com/products/braintree-direct
3) or payflow pro: https://developer.paypal.com/docs/classic/products/payflow
Funding instruments in an array so the request should be something like below.
Transaction is required as that's the only way you will be able to specify what amount you are capturing.
{
"intent":"sale",
"payer": {
"payment_method":"credit_card",
"funding_instruments": [ {
"credit_card_token": {
"credit_card_id":"CARD-27V22453CF057824JLLDIA7Q"
} }
]
},
"transactions": [
{
"amount": {
"total": "30.11",
"currency": "GBP",
"details": {
"subtotal": "30",
"tax": "0.07",
"shipping": "0.03",
"handling_fee": "1.00",
"shipping_discount": "-1.00",
"insurance": "0.01"
}
}
}]
}
I am currently testing credit card payments using the PayPal payments pro Rest API.
I keep getting the following error:
Exception in HttpConnection Execute: Invalid HTTP response The remote server returned an error: (400) Bad Request. --->
I created and activated my PayPal test account and as following:
Credit card
Credit card number:
ccnumber here
Credit card type:
Visa
Expiration date:
3/2019
When I enter the above information in my payment form and submit I keep getting the 400 bad request error.
I have gotton this to work before with the PayPAl joe shopper account but lost the test cc number.
I am 100% sure I have authenticated with the oauth2 credentials
What is the likely cause of this error?:
I am entering a random payer first name and last name .
Does the name have to exsist?
What could be causing the error
If anything goes wrong in the data given, paypal api will return a 400 - Bad request error.
When I got the error(PHP SDK), I caught the exception and $ex->getData() returned a json which contains the details about the bad request, in my case the currency code I given was wrong.
try {
$payment->create($apiContext);
} catch (PayPal\Exception\PPConnectionException $ex) {
var_dump(json_decode($ex->getData()));
exit(1);
}
Like others here have said, there are several things that can cause the (HTTP 400 - Bad Request).
In my case it was due to using the same invoice number. For temporary testing I just used the ShoppingCartID that I generated with a guid. You could also use a Random number generator as well. Ultimately you will need to generate an invoice number to the clients specifications.
-Good luck
I just had the same problem (HTTP 400 - Bad Request). The cause is a REST API request with "errors". In my case I had two causes:
I passed amount details to an Amount object but the sum of subtotal, shipping an tax was not equal to the amount total.
I passed amount currency values including a fracture, but passed not exactly two decimals but only one. Obviously the REST API is a bit touchy and accepts only either no or two decimals.
I passed an item_list in the Transaction object but the sum of the prices in the Item object was not equal to the subtotal given in the amount details.
I don't know a way of finding the actual cause of the error (if there is one).
In your case it could be the name of the payer that you add. Try without.
Edit:
I just tried out: It is indeed the payer info. I passed a payer_info with first and lastname and got HTTP 400 (without everything worked). I assume that payer_info must not be set by us but is set by PayPal when returning a Payment object.
Payer payer = new Payer { payment_method = "paypal", payer_info = new PayerInfo {
first_name = "Zaphod", last_name = "Beeblebrox"} }; // => HTTP 400 - Bad Request
firstly find out what exactly what Your error is
payment = PayPal::SDK::REST::DataTypes::Payment.new(...)
payment.create
# got Response[400]: Bad Request here
payment.error
# got {"name"=>"VALIDATION_ERROR", "details"=>[{"field"=>"transactions", "issue"=>"
then find out what Your issue here to get more info
https://developer.paypal.com/webapps/developer/docs/api/#validation-issues
I had the same issue. In my case it was Credit Card issue which might be over used. So I have taken new Credit card Number from this site Testing Credit card and replaced with the old one.
Here is Credit Card Information that I used
credit_card = new CreditCard()
{
billing_address = new Address()
{
city = "Johnstown",
country_code = "US",
line1 = "52 N Main ST",
postal_code = "43210",
state = "OH"
},
cvv2 = "874",
expire_month = 11,
expire_year = 2018,
first_name = "Joe",
last_name = "Shopper",
number = "4024007185826731", //New Credit card Number, Only Card type should match other details does not matter
type = "visa"
}
Note: All the Credit Card mentioned in PayPal site are not working, giving same issue for me. If it working for you then it's good otherwise use new testing Credit Card Number. Hope this will help someone.
Thank you! Enjoy Coding!
I too got struck with this issue, there might be many other possible root cause for this failure but then in my case all my passing argument is correct, but then it failed in sandbox environment, I just changed Payment option from PayPal Balance to Visa then it started working.
I recently had a 400 bad request error as well. In my case, I was processing a refund using RefundRequest, and it appears that PayPal recently changed the constraints on the "reason" field (although it isn't documented that I can find) so my lengthy descriptions of what was being returned were no longer acceptable. I found the error only because I saw another field where PayPal was now requiring that it be only single-byte alphanumeric characters. What actually helped though, was shortening the data I was putting through as a reason to simply "Returned items".
Obviously this is an old thread, and I'm sure the original problem was solved long ago, but if using some of the above methods to determine more information about an error don't yield results I would suggest submitting a request with the bare minimum of information until you can get it to go through. Then, start adding additional fields/information back to see if you can identify which field contains the information causing the bad request. That would have worked for my issue, at least.
Understand your errors
PayPal returns detailed data on every exception (except 500 INTERNAL_SERVER_ERROR), explaining what was the exact error you are seeing. You can retrieve that as follows:
Update your exception handling to catch PayPalConnectionException and print $ex->getData() as shown below:
try {
$payment->create($apiContext);
} catch (PayPal\Exception\PayPalConnectionException $ex) {
echo $ex->getCode(); // Prints the Error Code
echo $ex->getData(); // Prints the detailed error message
die($ex);
} catch (Exception $ex) {
die($ex);
}
It is due to the wrong currency or amount you have given.
I faced the issue in React JS
I was doing this. in the createOrder method.
purchase_units: [{
amount: {
currency_code: 'PHP',
value: totalAmount
}
}],
that was the issue. If i gave any currency other than USD i will get the 400 Error. So i removed the currency_code from here
And I moved the currency declaration into my component declaration.
like this.
options={{
clientId: " Your_ID " ,
currency: "PHP"
}}
Here you can give any currency you want. This solves my 400 Error
If you use Paypal Sandbox for testing Driver and on first try with buggy code it shows the client a 400 Bad request error.
Reason:- Paypal sent JWT auth and it was stored in the client's local storage.
Suggestion:- Try to clear the client's local storage cache (You only need to clear the Paypal Token).
This works for me, I hope it works for you :)
I want to display description of items like this:
I wrote my solution according to this article and attached to this asp.net solution.
However, on the PayPal login page (such as in the first picture), I see only the purchase and amount (not as in the first picture).
I use these URLs to create a transaction:
Sandbox - https://pilot-payflowpro.paypal.com/
Live - https://payflowpro.paypal.com
To setup transaction I send these parameters:
"PARTNER"
"VENDOR"
"USER"
"PWD"
"TRXTYPE"
"AMT"
"CURRENCY"
"CREATESECURETOKEN"
"SECURETOKENID"
"RETURNURL"
"CANCELURL"
"ERRORURL"
"VERBOSITY"
"BILLTOFIRSTNAME"
"BILLTOLASTNAME"
"BILLTOSTREET"
"BILLTOCITY"
"BILLTOSTATE"
"BILLTOZIP"
"BILLTOCOUNTRY"
"SHIPTOFIRSTNAME"
"SHIPTOLASTNAME"
"SHIPTOSTREET"
"SHIPTOCITY"
"SHIPTOSTATE"
"SHIPTOZIP"
"SHIPTOCOUNTRY"
I have tried to define line-items description using those parameters:
"L_QTYn"
"L_NAMEn"
"L_DESCn"
"L_COSTn"
"L_TAXAMTn"
where n - line number from 0 or 1 (I can't remember now)
I have also tried those parameters:
"L_PAYMENTREQUEST_m_NAMEn"
"L_PAYMENTREQUEST_m_NUMBERn"
... and so on
I didn't get any changes in all cases.
So, what have I missed? Is it possible to display items for PayflowPro Express Checkout?
Thanks for referencing my article :)
To pass EC line items through Payflow, there are two solutions:
A) Contact www.paypal.com/mts and ask them to toggle the Features BitMap that enables EC line items
B) Add this to your request: "_TRAILER_PASSTHROUGH__=Y"
Note that (B) can change the format of the responses you receive from Payflow to have value length tags, i.e. NAME[5]=VALUE instead of NAME=VALUE, so parse accordingly...
(In particular, this will happen when the VALUE returned from PayPal contains special characters such as "&" within it, so you can't simply split the string on "&")
I disovered a wired issue using Paypal ExpressCheckout with discounts:
I pass 2 Items like:
L_NAME0 : "test2",
L_AMT0: 2, // 2 EUR
L_QTY0: 1
and
L_NAME1 : "Discount",
L_AMT1: -0.60, // 60 cent
L_QTY1: 1
After redirect to Paypal everything seems fine:
But after closing this transaction, paypal charges the full amount (2 EUR) from my paypal-account:
What is wrong with this paypal discount? It seems to be cheating on the customer and he must feel betrayed.
I dont believe its paypals fault, so any ideas on what i did wrong are appreciated :)
It looks like you applied the discount line item to your SetExpressCheckout call, but the DoExpressCheckoutPayment call must not have had the same thing..??
You need to make sure DECP has all of the same line item details in it.