Issue
I am really new to node js and trying to integrate Paypal's Payment Gateway into my application.
Upon the success of the payment, the user is redirected to http://localhost:3000/success?paymentId=PAYID-M8MU148234F&token=EC-2111Y&PayerID=YX82JX6Q
where our code executes the order and return a payment object (contains order details).
On this page, I want to display the order details to the user.
I want to store the payment object as a JSON.stringify into my Mongoose database for future reference. The issue is that if the user keeps on reloading this page, the code inside app.get('/success'..) will keep on adding the same columns to the mongoose database repeatedly. I am not sure how to prevent that.
Since the payment is actually executed only when this URL is visited by the user, multiple reloads by the user blocks me from Paypal API and gives me the following error:
response: {
name: 'MAX_NUMBER_OF_PAYMENT_ATTEMPTS_EXCEEDED',
message: 'You have exceeded the maximum number of 20 payment attempts.',
information_link: 'https://developer.paypal.com/docs/api/payments/#errors',..........
The only solution I can think of right now is that somehow my /success
route executes the payment and stores the data onto the database and then redirects the user to maybe /someOtherPage/
page with the order details as headers. I am not sure how to make this redirect happen and also pass some context (the payment object) at the same time.
Solution
You are using a deprecated v1/payments API and/or PayPal-Node-SDK. You should change your integration to the current v2/checkout/orders and Checkout-NodeJS-SDK.
Make two routes on your server, one for 'Create Order' and one for 'Capture Order', documented here. These routes should return only JSON data (no HTML or text). The latter one should (on success) store the payment details in your database before it does the return (particularly purchase_units[0].payments.captures[0].id
, the PayPal transaction ID)
Pair those two routes with the following approval flow: https://developer.paypal.com/demo/checkout/#/pattern/server
The above mostly takes care of this issue and is the recommended solution, as it does not rely on redirects and gives an improved user experience that increases buyer confidence by keeping your site loaded in the background. But to more directly address the issue posed here: when doing an execute or capture API call, set the PayPal-Request-Id
HTTP header to something that will persist across retries that are not expected to result in new actions/transactions -- for example simply set this header to the PAYID or OrderId being acted on. This will give idempotent behavior (see API idempotency)
Answered By - Preston PHX Answer Checked By - Dawn Plyler (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.