paypal IPN - how to know when money has moved? - paypal

I'm using a basic HTML form to call PayPal (webscr) and I am successfully getting IPN callbacks.
There is plenty of documentation about the contents of each individual variable that can be returned in an IPN. There is something important missing, or else I have missed it:
What paypal transaction types and payment statuses reflect actual changes in my account balance? For example, a "Completed" status certainly does, and a "Pending" status certainly does not.
However, there appear to be five or six relevant transaction types and eleven different payment statuses possible. Other than trying all 55 or 66 combinations in the IPN simulator, is there any document that clearly shows for which ones I should accumulate the mc_gross amount?
Or to put it another way, some IPN messages are just "in case I need to know", and some mean "money has changed hands; adjust your accounts accordingly". It's not clear to me which combinations of transaction type and payment status indicate the latter.
Thanks and Best Regards,

Related

What variables should be checked in IPN POST requests after a successful payment has been confirmed?

I have developed the IPN listener side of a PayPal-enabled website which records user subscriptions. Currently when I am interested for a successful transaction I look for the payment_status variable, ensuring that payment_status == "Completed", but as can be clearly noted in the PayPal IPN variables reference, there's lots of them and I can't say whether I'm overlooking some.
So, in the end, my questions are:
Is a payment transaction considered successful if and only if payment_status == "Completed", or is there any other variable that can determine it?
Are there any other important or common states associated with a payment transaction that is worth considering?
Have a look at all the sample code they provide. You will see that they go to a lot of trouble to make sure that the product being bought actually exists, and that the price is correct for the way they bought it (buy it now, subscription, trial period, ...).
Basically you cannot assume that the original transaction that gave rise to the IPN was not forged somehow. It's easy.

Paypal IPN getting delayed by hours

I'm using paypal adaptive payments to make transaction via paypal. Although few of transactions are taking more than 6 hours too receive IPN.
I've gone through forum posts and their documentation, I came through - https://developer.paypal.com/webapps/developer/docs/classic/products/instant-payment-notification/
"Because IPN is not a real-time service, your checkout flow should not wait for the IPN message before it is allowed to complete. If the checkout flow is dependent on receiving an IPN message, processing can be delayed by system load or other reasons. You should configure your checkout flow to handle a possible delay."
The callback is taking more than 6 hours is way too much. any suggestions ?
I've built several custom carts. On average, I see the PayPal IPN come back within 2 minutes at the longest, and usually recurring payments take longer than single payments because they send two IPN messages, not just one, on the initial setup. I usually take the 'custom' property and put a unique identifier that I have permanently cookied. So, even though I may see an initial IPN come in on a recurring payment, I wait for the one that says that txn_type is subscr_payment and also that payment_status is Completed. You can't really trust a subscription payment as being paid unless you see that second message. And if it's a single payment, then I look for txn_type to be web_accept and payment_status to Completed.
The way I handle things is to redirect the customer to PayPal to purchase using the form button technique. The customer pays and then gets redirected (thanks to the form hidden vars I created initially) back to my own custom cart URL that I specify. I call that URL the payment-confirmation script. I display a message with a progress bar to please wait while their payment is being confirmed with PayPal. I hold them there 10 seconds and then redirect to the receipt. It is on the receipt where I check the database to see if my IPN script has already processed this order. If not, then I redirect them back to the payment-confirmation script again for another 10 second progress bar delay. My receipt uses a session cookie to ensure I never send them into a loop more than one time to the payment-confirmation script. So, the customer waits another 10 seconds and then comes back to the receipt page, where I test again, reading my permanent cookie on the 'custom' property that I saved, versus the 'custom' property that comes in from the IPN that I use as the order key in the database. Usually within the first or second 10 second delay, the IPN has come in and I can proceed. However, if the IPN has still not come in, then I redirect to a friendly error message saying that their payment cannot be confirmed and to call our call center to remedy the issue. Our call center techs then see the delay problem in PayPal, back the other transaction out, and sell to the customer over the phone manually, instead.

Using PayPal subscription IPN fields to manage user accounts

I'm using PayPal to take subscription payments for access to a website service.
I'm using PayPal's IPN to manage the payments and user accounts.
I'm sending a custom random key to PayPal, unique to each user, when the subscription is first instantiated so the same key is sent back with every IPN. This means I can bind together my users table with my PayPal notifications very positively.
Accordingly I can now generate from my database a list of user_ids and notification details.
So now I need to figure out the best logic to use to calculate each users current payment status and, as a consequence, what to do with their account - whether to continue allowing access, suspend or even delete their user account. This decision will all come down to whether their payments are still coming through or not.
A bunch of interesting an varied data comes through on PayPal's IPN - most looks irrelevant in terms of user account management but a couple of columns look quite useful. Specifically...
Field outstanding_balance appears to contain exactly that - a value to 2dp of money still owing. So far during my testing this figure has only ever been 0.00
Field txn_type shows me any from a selection of different codes: subscr_signup (when the user initially sets up the subscription), subscr_payment (when a payment appears to be successful), subscr_cancel (this seems to appear whether the customer or vendor cancels the subscription), and subscr_eot (end of term - this one crops up shortly after the subscription is cancelled).
My impulse is to search the table for the most recent txn_type="subscr_payment" entry for each user account, and check the date this last notification arrived. If it is date stamped over, say, 28 days ago the account can be suspended... if it's over 56 days the account can be deleted.
Is this a good idea? Or is there better logic I can employ?
I've done this. Quite simple:
Don't grant access until you receive the first payment. You can get the intial signup and payment in either order.
PayPal will notify you if they cancel their subscription or it expires. When you get either of those, deny access as from the effective date.
If the most recent payment status on an account is 'reverse', suspend access until you either get 'cancel reverse' or the situation is sorted out in some other way.
Don't count the days. PayPal counts the days. All you can get from repeating that yourself is a disagreement, and guess who's right? PayPal. And guess who isn't wrong? The customer. You don't want to penalise the customer because PayPal got behind or had a different idea of 28 days from yours. You've handed responsibility for collections and renewals to PayPal: let them do it.
Beware of building policy into this. It should just be a mechanism, and it should be manually overridable. For example, the actual evaluation of whether this user has access to this product now mustn't be a computation over their payment history. Just a simple lookup of another table, which your IPN code can modify, but so can humans. For example: there is a dispute. You lost. You might well as a matter of business want to keep the customer alive for a grace period anyway. Alternatively you might in extremis want to fire the customer immediately, e.g. for usage violations.
You can ignore the balance field. The only important thing is the txn_type.

Handling Paypal payment status 'Completed-Funds-Held' with time-sensitive goods

Good morning, I'm working with DoExpressCheckout's Payment Status response for an InstantPaymentOnly Sale.
https://developer.paypal.com/docs/classic/api/merchant/DoExpressCheckoutPayment_API_Operation_NVP/
By PAYMENTINFO_n_PAYMENTSTATUS all possible responses are shown, Completed-Funds-Held is the latest addition.
I'm providing a service that expires and must be used by a certain time. If the payments final status is not known by the time the service must start, its looks like we're going to have to collect payment (again) in person and refund the online payment. Needless to say, that doesn't sound good.
Q. Could Completed-Funds-Held result in funds never being deposited to the main balance?
The documentation for that particular status lists two possible response codes that go along with Completed-Funds-Held: newsellerpaymenthold (not applicable in my case) and paymenthold which vaguely states "A hold is placed on the merchant's transaction for a reason not listed."
Basically is Completed-Funds-Held a "successful" transaction where the purchaser can receive his product without risk of the seller never receiving payment?
EDIT: Is Completed-Funds-Held a final status if the payment is successful? Or will a Completed IPN request come if and when the hold is settled?
Those payments will eventually become available. What you should do is setup an IPN solution so that you can automatically update your system when a payment hold is released. The same would be true for things like e-checks where the payment status is simply pending and then clears a few days later.

What variable is sent in every PayPal IPN?

I've been trying to base my IPN off txn_type, then payment_status but I've been getting exceptions since not every IPN has those. What variable can I base my IPN off of?
txn_type was not sent in refund IPNs.
As you noted, txn_type isn't sent with every IPN type. There isn't really any one field you can look at and always count on. What you need to do is setup logic to check for different fields and their availability as well as their value.
So I would check for txn_type, and if it exists, go ahead process according to that type. If it doesn't exist, though, then you can fall to other parameters to figure out what's going on and how to process it within your logic.
For example, if you take a look at this sample refund IPN data, you'll see it includes a payment_status of "Refunded" as well as a reason_code of "refund". So your logic can look for those values accordingly, and it would then know it's a refund.