We have a few sites that use PayPal Express (via SOAP). On all but one, if the DoExpressCheckoutPayment returns the following message:
10413: "The totals of the cart item amounts do not match order amounts."
Then it is classed as an error, and the Ack field is 'Failure', and the Error.SeverityCode is 'Error'.
However, on one site (using a completely different PayPal account), the same error message returns 'SuccessWithWarning' as the Ack and 'Warning' for the Error.SeverityCode.
I can't find a setting that would control whether this error is a SuccessWithWarning or an Error. Does anyone know why I've receive different responses for the same error?
Related
I'm trying to handle error payment denied from Paypal after doCapture method.
https://developer.paypal.com/docs/api/sandbox/nt-classic/#test-api-error-handling-routines
You can force two types of API errors: those related to the transaction amount, and those not related to the amount.
To trigger an error condition on an amount-related field, specify a error code value as a number with two digits to the right of the decimal point. For example, specify a value of 107.55 to trigger the 10755 error.
To trigger errors on fields that are not amount related, specify the error code in whole. For example, use a value of 10539 to trigger a "payment declined" error.
How to set the amount to trigger error ‘payment declined’ in magento 2
Any advice.
Thanks.
Documentation: Negative testing for PayPal's classic APIs
I think this problem is not trivial, so I would like to express it in detail
Domain:
I have an endpoint (api rest) that receives a date and time of an appointment that I want to block (which will later be reserved). The operation is simple, when receiving the date and time, it is blocked so that another client can not book an appointment on the same day and time, while the one that blocks the appointment, completes the contact information.
So far, very simple. The problem begins when two different users select the same date and time in their browser and two requests are triggered simultaneously. As we already know, you can not block an appointment on the same day and time twice, so the application will fail (although this failure is properly controlled).
In short, two users try to block an appointment on the same date and time, and only the request that is processed first will succeed.
For the user who managed to block the appointment, the answer is clear: 200 OK status. The question is, which state code http corresponds to return to the second user?
Comment:
Very recently at work I have run into this dilemma, and I have argued strongly with a co-worker about it. Since then, I began to research hard and consult with several people with years of experience in the subject to be able to reach a conclusion.
2xx: Half of the people answered that the state code should be a 2xx. Why? first of all, because the request is well formulated (mainly the parameters, are written correctly) so it would not correspond to a client error (4xx) and on the other hand, it is not an unexpected error of the server (500), since it is duly controlled by the business logic itself. Since the query was done properly, it should send a 2xx status (more precisely a 200) indicating that the request was successful, with a message on the body, indicating the "status" of the action (the appointment could not be blocked) .
4xx: My position (and also that of the other 50% of those consulted) is that, as can be seen, the request fails because the desired action can not be completed. It does not seem logical at all, that a 200 OK is returned (indicating that everything went well) and a message describing the error or condition that occurred (in a way, it would be contradicting me). As an error occurred, there are only 2 possible guilty: the client and the server. In this case, it seems to me that the server is not, because it does not fail unexpectedly, but that business rule is well contemplated, and intentionally fails (so it would not be a 5xx). Everything seems to fit in that it is a client error, perhaps a semantic error, when trying to perform the same operation twice on the same resource. Therefore, my opinion is that an error 400 would adjust to the situation, and perhaps if we want to be a little more specific, a 409, indicating that we tried to modify concurrently a resource that does not allow this action.
What should be the appropriate option for this case?
Thanks!
Let us look at what the Wikipedia and MDN has to offer on this:
2xx (Successful): The request was successfully received, understood, and accepted
4xx (Client Error): The request contains bad syntax or cannot be fulfilled
(source: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
In the case of an appointment conflict, the request of the second user is received and understood but can not be accepted so it would seem to be wrong to return a 2xx for such a case.
A situation qualifies for a 4xx either when the request contains a bad syntax (which is not the case here as the request is well-formed) or when the request cannot be fulfilled (which seems to be the case here which you want to communicate back to the client).
A suggestion can be to go ahead with 422 for such kind of errors which are specific to a business use case (such as an appointment scheduler for your case)
As per MDN:
The HyperText Transfer Protocol (HTTP) 422 Unprocessable Entity response status code indicates that the server understands the content type of the request entity, and the syntax of the request entity is correct, but it was unable to process the contained instructions.
(source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422)
Also since booking an appointment would create a resource in the back-end (i.e. a valid appointment id with the details of visitor, time, etc.), I would prefer to send back 201 (Created) status code for the success case as you are executing the task in a synchronous manner. In my opinion, 200 (OK) status code is more suitable for situations when the resource would be asynchronously created and may not immediately be available when the server responses back to the client. In such cases we generally provide a GET request link from where the client can fetch the requested resource in future.
What's the best HTTP status code to use in response to an HTTP GET for a resource that's corrupt or semantically invalid?
E.g., consider a request to GET /person/1234 where data for person ID 1234 exists on the server but violates some business rule, so the server refuses to use it.
404 doesn't apply (because the data actually exists).
4xx in general seems not ideal (because the problem is on the server end, not under the client's control).
503 seems to apply to the service as a whole, not a particular resource.
500 certainly fits, but it's very vague in actually telling the client what might be wrong.
Any suggestions?
After reading the comments and the linked resources, it looks like #RemyLebeau's approach is best:
I think 500 is the only official response code that fits this situation. And there is nothing stopping you from including a response body that describes the reason for the failure.
according to iana.org:
4xx: Client Error - The request contains bad syntax or cannot be fulfilled
5xx: Server Error - The server failed to fulfill an apparently valid request
I think none of the 4xx status code should be valid as a response to an internal server error or migration or ... where client has no responsibilities or where user's inputs are expected to be rechecked. unless user's pre-filled data are involved like maybe user's package is not allowing him to access that data after a pre-determinate and known date, in such specific case It may be valid a 403 Forbidden as #Bari did suggest.
I'm not an expert but I think when the rejection or the decision of considering endpoint data as corrupt or invalid is made by server, then it will depends on what should be done next. I see 3 possible cases:
1. It is expected that somehow this is going to be fixed and client
should be invited to request it back but at some future moment ==> 503 (Service Unavailable):
503 (Service Unavailable)
status code indicates that the server
is currently unable to handle the request due to a temporary overload
or scheduled maintenance, which will likely be alleviated after some
delay. The server MAY send a Retry-After header field
(Section 7.1.3) to suggest an appropriate amount of time for the
client to wait before retrying the request.
2. Something is wrong, it is not client responsibility but there is an alternative way to access data, maybe following a specific process or sending further details ==> 510 Not Extended
2. Server cannot fulfill the request but there is an alternative way that requires it to include further details. Example: when requested data is corrupt, server error response may include a list of older (or unsaved, unversioned) versions of it and expect client to be more specific about which version to select so it could be fetched instead of the corrupted one ==> 510 Not Extended
510 Not Extended
The policy for accessing the resource has not been met in the
request. The server should send back all the information necessary
for the client to issue an extended request. It is outside the scope
of this specification to specify how the extensions inform the
client.
If the 510 response contains information about extensions that were
not present in the initial request then the client MAY repeat the
request if it has reason to believe it can fulfill the extension
policy by modifying the request according to the information provided
in the 510 response. Otherwise the client MAY present any entity
included in the 510 response to the user, since that entity may
include relevant diagnostic information.
case 2 was updated to include an example as IMHO it may fit in such case. but again I'm not any expert and I may be
wrong about it
3. No alternative ways, nothing to be expected or none of the other cases ==> 500 should be good
500 (Internal Server Error)
status code indicates that the server
encountered an unexpected condition that prevented it from fulfilling
the request.
For Every PaypPal interaction we Do:
1.SetExpressCheckoutReq
2.GetExpressCheckoutDetailsReq
3.DoExpressCheckOutPaymentReq
I do create a billing agreement first and only on scheduled/subsequent orders we use this billing agreement for reference transaction.
Our Issue is:
With a new PayPal account (testpaypal#abc.com) DoExpressCheckoutPaymentReq failed for CITY = SuttonsBay, with the address validation error “10736” (Shipping Address Invalid City State Postal Code) for a user (USER A). And this was corrected in the subsequent request as Suttons bay.
But the same PayPal account(testpaypal#abc.com ) used for the second time with a different user (USER B) on the site, DoExpressCheckoutPaymentReq call succeeds for the wrong CITY = SuttonsBay and allows us to complete the order.
It is to be noted that on all scheduled order of the user, we use the DoReferenceTransactionReq, which has strict validation and this fails every time, esp. for the second scenario described above.
I would like to know why there are inconsistencies in Shipping address validation for DoExpressCheckoutPayment. It is because of this difference that our scheduled orders fails (as described in scenario 2 that allows incorrect address)
Do we any way to have strict Validation in DoExpressChecOutPayment - which solves our purpose?
I am testing MIGS Virtual Payment Client on a test account. When I select payment, I am directed to the Payment Server page where I can choose between Visa and MasterCard. I have been given the following test data in the MIGS manual:
I use 123 as CSC value. However, the transaction always fail with
vpc_VerStatus=E
vpc_TxnResponseCode=2
vpc_Message=Declined //for Visa
vpc_Message=The+card+holder+was+not+authorised.+This+is+used+in+3-D+Secure+Authentication. //for MasterCard
By the way, if I select MasterCard, I am prompted "Please enter your OSID or the last 5 digits of your NAB ID" and a Credit Limit. I use OSID with value 123456 and Credit Limit 10000 respectively. (These are values I entered by myself as I was not given information what to input there).
I had a look at this Commonwealth bank and MIGS Virtual Payment Client error code but it does not solve my problem.
Any help why the transaction is being declined?
Okay, there's a handful of things here you need to understand/check out.
1. Ensure the transaction value ends in $xyz.00 or it will always decline
MIGS behaves differently in TEST and PROD. In TEST, MIGS uses the "cents" portion of your test transactions to determine what response code to return, NOT whether you have correctly provided the necessary data for the transaction. These cents values are as follows:
$ XXX.00 returns "0 Transaction approved"
$ XXX.10 returns "1 Transaction could not be processed"
$ XXX.05 returns "2 Transaction declined - contact issuing bank"
$ XXX.68 returns "3 No reply from Processing Host"
$ XXX.33 returns "4 Card has expired"
$ XXX.51 returns "5 Insufficient credit"
2. Disable 3-D Secure
It looks like you're also getting caught by 3DSECURE, also known as "Verified by Visa" and "Mastercard SecureCode". Call your acquirer/bank and ask them to disable this in TEST and Prod. Why? Invariably when this goes live, your customers will see a screen they are not expecting that asks for more information and then either pick up the phone and ask you to "fix it" or (even worse) leave your store thinking it's fraud.
Because 3-D secure has such low takeup, even most bank support staff don't know about it. Just today I had one of my clients call me about this "issue". One of their customers had called their card issuer to enquire as to what this "Verified by Visa" screen was. The bank (a major Australian bank) helpfully told them it was probably fraud and to not buy anything from that site.
3-D secure has such low penetration in Australia I'd suggest the only outcome of having it enabled is to reduce sales. Don't use it.