Reputation: 15
I have created an issue on PayPal community support but it seems not active so I re-created at there...
I am an online service merchant. I have finished test on sandbox PayPal Express Checkout and trying to integrate on live now. But, the biggest difference on live is: After approving from checkout UI, the money is still temporarily on hold and the buyer must final confirm by clicking "confirm receipt". This is not occure on sandbox environment, money will be credited directly to merchant account. I have try to integrate both IPN and Webhook to listen event but none of them can catch this event "confirm receipt". Please help me to handle this event, because if I can not listen it, my service can't perform automatically. Thanks so much for help, any adivice or suggestion is really appriciated.
Previous issue here
Upvotes: 1
Views: 466
Reputation: 3281
It unfortunately doesn't seem that the Paypal Community Forum Support is very active - there are many unanswered questions, and I never got any answers to my questions.
Pending payments are common in the live environment, especially if your account is not fully verified, but it's not possible to test them in the sandbox. Therefore I've done a lot of observation and trial and error kind of testing on my live environment. Hopefully this answer can help others avoid testing on their live environment.
Pending payments are managed differently for subscription/billing plans or regular (once-off) payments.
There are two different webhooks to support:
1. PAYMENT.CAPTURE.COMPLETED is for regular payments and has a status
that you can use to check the state of the payment, which can be COMPLETED, PENDING, or FAILED (plus others).
See: Webhook event names - payments v2
For PAYMENT.CAPTURE.COMPLETE it seems that pending and on hold are one and the same.
2. PAYMENT.SALE.* are for subscriptions, and here pending payments are (or should be) managed using different webhooks.
See: Webhook event names - sales
PAYMENT.SALE.COMPLETED
A sale completes.PAYMENT.SALE.DENIED
The state of a sale changes from pending to denied.PAYMENT.SALE.PENDING
The state of a sale changes to pending.Payments can go straight to COMPLETED, they can go from PENDING to COMPLETED or from PENDING to DENIED.
The latter, I believe, is when a customer doesn't confirm the purchase -probably they want a refund but are too lazy to go through that process.
However, I have just noticed that Paypal is sending the PAYMENT.SALE.COMPLETED webhook twice for payments that are on hold. Once with no indication that the payment is on hold and the second which indicates the funds are released.
Here are two example (anonymised) webhook requests I have received:
First notification: payment completed with no indication of the funds being on hold:
{
"id": "WH-99J09075X12340123-12X4860914197212Z",
"event_version": "1.0",
"create_time": "2021-08-27T02:05:34.170Z",
"resource_type": "sale",
"event_type": "PAYMENT.SALE.COMPLETED",
"summary": "Payment completed for $ 15.0 USD",
"resource": {
"id": "5X123412X12341234",
"state": "completed",
"amount": {
"total": "15.00",
"currency": "USD",
"details": {
"subtotal": "15.00"
}
},
"payment_mode": "INSTANT_TRANSFER",
"protection_eligibility": "ELIGIBLE",
"protection_eligibility_type": "ITEM_NOT_RECEIVED_ELIGIBLE,UNAUTHORIZED_PAYMENT_ELIGIBLE",
"transaction_fee": {
"value": "0.96",
"currency": "USD"
},
"invoice_number": "",
"custom": "REF-017089",
"billing_agreement_id": "I-5X8313XXYYZZ",
"receipt_id": "I-12342635535001234",
"create_time": "2021-08-27T02:04:51Z",
"update_time": "2021-08-27T02:05:11Z",
"links": [],
"soft_descriptor": "PAYPAL *MY COMPANY"
},
"links": [],
"paypal": {}
}
Second notification: payment now released
{
"id": "WH-99J09075X12340123-12X4860914197211Z",
"event_version": "1.0",
"create_time": "2021-09-16T17:22:12.797Z",
"resource_type": "sale",
"event_type": "PAYMENT.SALE.COMPLETED",
"summary": "Payment completed for $ 15.0 USD",
"resource": {
"id": "5X123412X12341234",
"state": "completed",
"amount": {
"total": "15.00",
"currency": "USD",
"details": {
"subtotal": "15.00"
}
},
"payment_mode": "INSTANT_TRANSFER",
"protection_eligibility": "ELIGIBLE",
"protection_eligibility_type": "ITEM_NOT_RECEIVED_ELIGIBLE,UNAUTHORIZED_PAYMENT_ELIGIBLE",
"payment_hold_status": "RELEASED",
"transaction_fee": {
"value": "0.96",
"currency": "USD"
},
"invoice_number": "",
"custom": "REF-017089",
"billing_agreement_id": "I-5X8313XXYYZZ",
"receipt_id": "I-12342635535001234",
"create_time": "2021-08-27T02:04:51Z",
"update_time": "2021-09-16T17:22:12Z",
"links": [],
"soft_descriptor": "PAYPAL *MY COMPANY"
},
"links": [],
"paypal": {}
}
See the second notification has payment_hold_status
which is now RELEASED, but the first notification doesn't have payment_hold_status
.
For my implementation, to avoid counting payments more than once, I am going to ignore this notification. If anyone has a better solution, please leave me a comment. Thanks!
Note: Payments can take up to 3 weeks to go from pending to completed and often the user is required to confirm they received their product, so you need to deliver on pending payments. Paypal should be holding the money in escrow so as long as they are satisfied the order is legit you should get your money. See: https://www.paypal.com/us/smarthelp/article/how-do-i-get-my-money-sooner-for-a-transaction-on-hold-faq3743
Upvotes: 1
Reputation: 15
Webhook will send 2 event "Payment sale completed"
, first is user approve checkout "payment_hold_status": "HELD"
and second is user confirm receipt "payment_hold_status": "RELEASED"
.
Thanks @Preston PHX, I don't notice carefully.
Upvotes: 0