I'm using Paypal Orders API (v2) on a website and multiple times there has been an approved order that are missing captures complete.
I get this event for all orders:
CHECKOUT.ORDER.APPROVED
But for some orders, this event does not occur:
PAYMENT.CAPTURE.COMPLETED
How does this happen, is it because a customers credit card got declined?
Make sure the actions.order.capture() function is being called properly.
I had the issue where I wanted my server to validate the payment was successful. So, I replaced the onApprove function, with a call to my server. When my server requested the order, it always said it was APPROVED, but no money was ever transferred.
The issue was that you don't replace the onApprove function, rather, the onApprove function still needs to call actions.order.capture(). This method will then transfer the money, and mark the order as COMPLETED.
A decline is one possible scenario.
Reaching an order review page and not clicking on the final action that triggers the capture, is another.
Those are both normal events and not indicative of any problem.
Theoretically some type of technical error could also interrupt the process and contribute to this type of drop off, but that is not likely unless you receive specific reports of an issue.
Related
I'm creating an android application that uses PayPal as a payment method. I have already implemented IPN in PHP but I have some questions about the PDT. From what I understood, the PDT is a notification that occurs when the user pays and returns to the merchant website. My question is, what if the user before being redirected closes the PayPal page? The user never visits the "return page" and I don't receive any immediate notification about the purchase.
I'm selling digital products, so I can't wait for the IPN to allow the user to download the product, as it could take several minutes or even hours to arrive.
What do you think I can do? Do you have any suggestions? Thanks.
PDT and IPN are ~20 years old. PDT in particular is only suitable for informational purposes, since as you mention the user may never return to the redirect page--for any number of reasons. IPN can be relied on but is an asynchronous notification and may delay as you also mention.
The best solution is to use neither of those very old things, and instead capture transactions with a v2/checkout/orders API call. This gives an immediate, synchronous notification when a transaction completes.
Create two routes, one for Create Order and one for Capture Order (first using a function that obtains an access token). These routes should return/output only JSON data (no HTML or text).
Pair those two routes with the following approval flow: https://developer.paypal.com/demo/checkout/#/pattern/server
I have an ipn listener that update my transactions (from pending to completed) and my contracts payments from finished to paid. This is perfect! I has also a return page... From PayPal to my site... This page show "thanks" and "button to allow download their last paid online contract" (paid with PayPal). My problem is that.... Ipn listener sometimes comes 3 seconds after my return page is shown to the the user....
In my return page in this case. Has the transaction and contract unpaid... And when ipn listener catch the results... Then this transaction and contract change to paid status. But ipn listener is executed at back-end. In my server. And my return page was shown 3 o 2 seconds before to my user. What can I do?
Should I add a timer (a delay) in my return page waiting until ipn updates my transaction and contract status? And then, show to the user a button "you can download your last paid contract!". Or better I should forget this step. And in my return page always without wait show to user "thanks for your payment". "you can download your last paid contract!"
You should not regard or show the transaction as complete, or allow any further business action to occur, until you have actually received the money, and only the IPN tells you that.
You need to adjust what you show on your return page accordingly.
All you should really do here is thank the customer for his business and tell him that the download or the delivery or whatever it is will become available immediately PayPal has notified you of the actual transfer.
And note that it can take a lot longer than three seconds. If they chose to fund the payment from their bank account, it can take 3-5 days: and there is always the possibility of that process failing altogether due to insufficient funds.
So don't be too optimistic in designing your return page. The deal isn't done until the money is in the bank.
This page show "thanks"
Good.
and "button to allow download their last paid online contract"
Bad. That should be somewhere in 'My Account'.
I also have my return page wait for the IPN notification to come into my server, and you can definitely make that work if you do it right.
Initially, the return page polls on a field in my back-end database that the IPN handler updates. Then, when the return page sees that field update, the customer gets his 'here are the items you paid for' button.
I also have a one minute timeout on this process. When that expires (although I can't remember the last time that actually happened), I display a catch-all error message ('There was a problem processing your transaction') and invite the customer to contact me for help.
I also tell them that their license key (which is what they are buying, in my case) might be on its way by email, since, usually, it is. IPN notifications can sometimes take a little while to arrive for some reason but my IPN handler sends out a confirmation email as a backup so they will get that in due course. That usually sorts things out, I rarely need to get directly involved.
If PayPal puts the transaction on hold, it doesn't seem to ever forward the customer to the return page (I have certainly never seen that happen). Instead, I assume it lets the customer know that he must wait for the funds to clear and leaves it at that.
An IPN notification does get sent however when the transaction eventually clears, and then you can have your handler send that email.
Lest this sounds like a lot of work, you should be sending an email from your IPN handler anyway since customers like to have a record of their purchases. Once you put that mechanism in place, the rest is easy.
Note: Watch out for IPN transactions flagged as 'echeque'. The funds haven't cleared yet, you will get another notification when they do. Then you can send them their contract by email. If memory serves,this does forward them to your return page so you have to handle that by letting them know that they must wait. In practise, this doesn't seem to happen very often.
Suggestion: have your scripts send you an email when something unexpected happens. This has saved my bacon more than once when PayPal have changed the names of the fields passed to the IPN handler for no obvious reason.
Summary: This is a practical, experience-based write-up of the way my website works, and it works well. I hope readers of this post find it helpful, despite the mysterious downvotes.
I have the following flow with Paypal:
I create a payment with intent "order", and I redirect the user to Paypal's website.
Once the user returns, I execute the payment.
Then, I authorize the order.
At this point, I can still look up the payment or the order and I get expected result.
Finally, I capture the order.
After I capture the order, I can't lookup the payment with /v1/payments/payment/PAY-XYZ or retrieve the order with /v1/payments/orders/O-ABC. I get a 500 Internal Service Error.
Before you tell me to send debug id to Paypal because I stumbled upon their bug: I tried, but they are not responding. I had them on the phone, sent support requests, etc. I got no reply from them, so I have to turn to community.
After capture, I can still lookup a payment by listing payment resources. Since I store paypal's create time, I send a GET request that looks like:
/v1/payments/payment?start_time=2016-06-21T09:08:56Z&end_time=2016-06-21T09:08:58Z
Sure enough, I can get the payment object back, but that looks awfully hacky to me.
The reason why I need the entire payment object is because I need a definitive information about the status of the payment. E.g. I can stumble upon a network error when I send a capture request and I won't get capture ID, so I can't check what's going on. Or I can miss a webhook event (for any reason, e.g. bug in my code), and the payment can become refunded without me knowing, so it would be ver nice to be able to fetch a payment.
I noticed the REST API documentation here https://developer.paypal.com/docs/api/payments/#payment_get says that I should use that endpoint for incomplete payments, but I don't understand why I can't check the order, or why list payment resources works, but fetching a single payment doesn't.
Retrieving the payment used to work though, so I could look up related_resources of transactions of the response (like I can do now with listing all payments by date).
My question is: what is the recommended way to get the definitive information about a payment?
Also, if someone from Paypal is reading this, here are some debug_id's so you can perhaps look into it: 3ffa3007a7561 (result of https://api.sandbox.paypal.com/v1/payments/orders/O-3PA36862ST053572T) or 85576d66784cd (response from https://api.sandbox.paypal.com/v1/payments/payment/PAY-7N237030X85089344K5UQIKI)
This happens on both sandbox and live.
Thanks,
Dejan
We have a production game that uses PayPal as one of the methods of payment. In some cases, we're never receiving webhook notifications.
Here's the sequence that's occurring. Sometimes we get the webhook from this sequence, and other times we don't. On the server, we're using the Java API. All of this is the behavior with the production (NOT SANDBOX) PayPal servers.
After the user selects a product, it calls our server, which creates the Payment object via Payment.create(). At that point the state is 'created' and we redirect the user to the approval_url returned in the links.
The user approves the payment and is sent back to our server. We fetch the payment via Payment.get(), which is successful and has a state of 'created'.
We execute the payment using a PaymentExecution. This returns the payment with an updated state of "approved".
We then wait for a WebHook to inform us that the payment was completed. On occasion, this webhook is never sent, leaving the purchase incomplete. Checking the PayPal console, no webhook event exists for the payment, even though the payment is showing up as completed.
The questions here are:
Is this the correct sequence? Or is something missing?
Shouldn't the payment be "approved" when the user is returned from PayPal rather than still "created"?
Shouldn't the payment be either "completed" or "in_progress" after a successful execute?
What is the correct way to handle the case where the webhook never arrives? Keep polling the payment until the state updates?
I do not see any problem with your sequence. You can also refer to the steps here as an example - https://developer.paypal.com/docs/integration/web/accept-paypal-payment/
Regarding Webhooks, you mentioned sometimes you get Webhooks and only some times you do not. Can you please provide a correlation or debug id for the calls where you don't see any Webhook? We will trouble shoot and get back?
Hey guys was hoping you could help me out.
I am integrating paypal (for the first time) in a website using PHP. From what I have read, there are two methods for confirming a successful transaction, PDT and IPN.
Now the thing is, the item's being sold can have a limited stock. So if suppose a person reserves an item and is taken to the PAYPAL site for final payment, I have to stop all other people from making a purchase since the last piece of the item will be "reserved".
But suppose the person (who has reserved the final piece of the item) goes to the paypal page, and then simply closes it. Will this result in a "fail" ipn coming to me (so I should un-reserve the item so others can buy)?
If so, how long will it take for the failed IPN to come?
If not, how exactly should I handle this.
And is there any scenario where an IPN does not come?
You could use the Express Checkout API.
With EC, the payment is a two step process. In the first step, you make an API call (SetExpressCheckout) where you set up the transaction, and redirect the buyer to PayPal. Once there, the buyer authorizes the payment, and returns to your site.
At this point no money has changed hands. You need to make a second API call in order to capture the funds (DoExpressCheckout).
You can hold the item for a specific period, and if the buyer abandons the transaction, or is very slow to approve the payment, you can release the item back to the public. If he eventually approves it, and does come back to your site, you would simply skip the second step, and inform the user that his transaction timed out. No money changes hands, no items are double sold.