Payum icon indicating copy to clipboard operation
Payum copied to clipboard

There isn't a status for PayPal pending payments

Open cundejo opened this issue 9 years ago • 10 comments

In PayPal Express Checkout (and I supose this is valid for others gateways) a payment could remain in a "pending" state because the buyer doesn't have funds in his PayPal account. In fact we can read this in PayPal: "...When you sell an item and the buyer pays through PayPal, the funds may be pending in your PayPal account for a period of time before becoming available. Funds may be pending for as few as three days after the buyer receives the item, but may be pending for up to 21 days..."

So, the payment was OK, but I don't have the money in my account yet for some reason (bank accounts checking process, multicurrency problems, etc.)

In this scenario, Payum put the payment status in "captured". But, if we dig in the payment details we can found this (chunked for clarity):

details(
    ...
    "ACK" => "Success",
    ...
    "CHECKOUTSTATUS" => "PaymentActionCompleted"
    ...
    "PAYMENTINFO_0_PAYMENTSTATUS" => "Pending",
    "PAYMENTINFO_0_PENDINGREASON" => "paymentreview",
    ...
)

I can't (or I should not) handle this special case like a success payment, because it isn't. Could happen that Paypal put the payment in "pending" status to check a bank account, but if this bank account is empty, the payment will be cancelled three days later for example.

So in the done script this is not valid:

//...

if ($status->isCaptured() || $status->isAuthorized()) {
  // the payment is in "captured" status for Payum, but not for PayPal.
}

//...

Payum has a "pending" status, but is not for this scenario, it's used when we waiting for a push notification from PayPal.

I think is needed another status in Payum for this scenario.

Although, a bunch of questions related: What happens when a Paypal Pending payment like described earlier is Cancelled or is Completed? Paypal send a notification to my payment notify URL? Is the model updated automatically? How can I intercept this?

I read almost all of the documentation but nothing about it, and no examples found in the Payum Bundle Sandbox.

cundejo avatar Sep 17 '16 04:09 cundejo

Payum has a "pending" status, but is not for this scenario, it's used when we waiting for a push notification from PayPal.

I disagree on this, The pending status is designed for all cases where we are in the middle of the process, including the one you described

makasim avatar Sep 17 '16 13:09 makasim

So looks like a bug.

makasim avatar Sep 17 '16 13:09 makasim

Hello @makasim

I've been traced the payment with payum:status task (Symfony) and the payment take this statuses:

1- status new: Payment created, PayPal not visited. 2- status pending: Payment redirected to PayPal to make the fund. 3- status captured: PayPal redirect back to my app. Regardless if payment is pending in PayPal it will always change to this status.

For now, my (not elegant) solution for this is:

//in done script
$token = $this->get('payum')->getHttpRequestVerifier()->verify($request);

$gateway = $this->get('payum')->getGateway($token->getGatewayName());

$gateway->execute($status = new GetHumanStatus($token));
/** @var Payment $payment */
$payment = $status->getFirstModel();

$details = $payment->getDetails();

$paypalStatus = isset($details['PAYMENTINFO_0_PAYMENTSTATUS']) ? $details['PAYMENTINFO_0_PAYMENTSTATUS'] : null;

if ($status->isPending() || ($paypalStatus == 'Pending')) {
    //Make things with payment pending on Payum, or Pending on PayPal
    //return ...;
}

if ($status->isCaptured() || $status->isAuthorized()) {
    //Make things with payment Complete successfully
    //return ...;
}

If the pending status is designed for all this type of cases like you said, it's easy to check if PAYMENTINFO_0_PAYMENTSTATUS comes with 'Pending' value from PayPal, and then put the payment in 'pending'.

Thanks for your reply.

PS: You could clarify me my previuos questions or tell me where can I find some doc related: What happens when a Paypal Pending payment like described earlier is Cancelled or is Completed? Paypal send a notification to my payment notify URL? Is the model updated automatically? How can I intercept this? Maybe dumb questions, but I need to understand what happens here.

cundejo avatar Sep 17 '16 17:09 cundejo

Here's the code responsible for status calculation: https://github.com/Payum/Payum/blob/master/src/Payum/Paypal/ExpressCheckout/Nvp/Action/PaymentDetailsStatusAction.php#L17

There is a bug in that logic, I guess.

makasim avatar Sep 17 '16 18:09 makasim

Hello again @makasim.

I read PaymentDetailsStatusAction.php, but I don't understand when it's executed the execute function. Sorry for my lack of knowledge in this area.

Also you said that there is a bug in my logic. Could you explain how do you resolve this issue?

Thanks again for your responses.

cundejo avatar Sep 18 '16 21:09 cundejo

not in your logic, but in payum's, must be fixed

makasim avatar Sep 19 '16 08:09 makasim

Are there any news about this bug or any idea of how can it could be resolved? If there is an idea I can try to help.

hisie avatar Dec 30 '16 09:12 hisie

If you have this in details

details(
    ...
    "ACK" => "Success",
    ...
    "CHECKOUTSTATUS" => "PaymentActionCompleted"
    ...
    "PAYMENTINFO_0_PAYMENTSTATUS" => "Pending",
    "PAYMENTINFO_0_PENDINGREASON" => "paymentreview",
    ...
)

This condition has to be true and the payment marked as pending

https://github.com/Payum/Payum/blob/master/src/Payum/Paypal/ExpressCheckout/Nvp/Action/PaymentDetailsStatusAction.php#L116

For some reason it is not, so that part of the code has to debugged

makasim avatar Dec 30 '16 09:12 makasim

One idea that we may use PAYMENTINFO_0_PAYMENTSTATUS https://github.com/Payum/Payum/blob/master/src/Payum/Paypal/ExpressCheckout/Nvp/Action/PaymentDetailsStatusAction.php#L96 here

makasim avatar Dec 30 '16 09:12 makasim

Could anyone please confirm the answer to this question which is not really very clear from the comments in the thread:

What happens when a Paypal Pending payment like described earlier is Cancelled or is Completed? Paypal send a notification to my payment notify URL? Is the model updated automatically? How can I intercept this?

I read almost all of the documentation but nothing about it, and no examples found in the Payum Bundle Sandbox.

Are we saying that Paypal is supposed to to notify us by an action already exposed by Payum and this is supposed to just happen. Are saying this function is broken? How can we hook into this action. There are things we will need to do when a payment is marked as complete. Can paypal make a second call to the verify action (this would actually work very nicely for us)?

What I want to be able to do is check whether paypal marked a payment as pending in the payment verify action and if it was then show the user a message telling them the payment was set up but has been held in pending and will go through in the next few days and then when Paypal decides to let the payment through we get another notification allowing us then do all the things we would have done if the payment had gone through in the first place. Does that make sense or am I not understanding the process?

warslett avatar Mar 13 '19 12:03 warslett