How do I prevent multiple paypal payments in nodeJs? - node.js

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.

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)

Related

Best way to handle one-time payments with STRIPE webhooks in nodeJS

I am using STRIPE as my payment processor, in an REACT + nodeJS app. I already have something that already works, but I would like some feedback, maybe I'm doing something wrong.
So... I have this Redirect-To-Checkout functionality thats made available by STRIPE, basically I redirect the user to this STRIPE page where all card-data (sensitive information) is processes in order for the payment to full-fill.
What I do in my nodeJS server part is the following:
Once the user acces the redirect to check-out page, I already create a PendingOrder, with the products selected by client (Here I save some information based on client/stripe payment-intent, in order to check in later steps)
Once webhook gives me the 'payment_intent.succeeded' I check for the payment-intent information to see if it exists in my PendingOrder collection, then proceed to add in to ConfirmedOrders and remove it from PendingOrders.
I have to do this whole process because Stripe no longer gives me access to some information I require when the user is checking-out his order(such as observation that the user has based on the type of service he chooses).
Are there any down-sides to this approach or is there any other way to do it?
Thanks in advance!
You’re not really far from the best practices that Stripe recommends here. The only thing that I would change is listening to checkout.session.completed instead of the payment_intent.succeeded event. As of the latest API version, a PaymentIntent is no longer created upfront so a better to way to handle order fulfillment is to either store the Checkout Session ID (e.g. cs_live_xxx) or you could add some metadata when creating the Checkout Session and use that instead to identify the order.
I have to do this whole process because Stripe no longer gives me access to some information I require when the user is checking-out his order
As for this, I’m not sure what you mean, you can always use your app with the success page customization described here alongside webhooks. I wouldn’t use that to fulfill the order though since the user might close the page before the redirection completes which means that the fulfillment wouldn’t be done in that case. As such, webhooks are essential to order fulfillment.

Stripe API testing automation

Background
I am integrating stripe API into my site to take one off payments. My site will be API first on server side with a separate web and mobile front end. I am working on the API server side code. I will eventually use stripe payment pages to take credit card payments. I am trying to automate the testing of my APIs and am bamboozled by the documentation (which are thorough) as I just can't see what steps to take next.
My server side initiates a call with stripe using stripe sdk to create a stripe Session object - this contains a URL to redirect to checkout.stripe.com/pay/..., a success URL when payment is successful and a cancel URL (these I set to handle the callback).
Problem
I can automate in Postman all my API calls from Browse Products, Select Product, Place Order but the next step I am stuck. After Placing Order I get back the stripe session but how can I mimick making the payment with stripe for the session and then call my Success URL ?
When the site is complete I will redirect the UI to stripe to take payments but I am testing and completing the back end flow first.
I have copied and pasted the session URL which is returned by the stripe Session object to bring up the page in a browser and used Dev tools on Chrome to inspect Network to see which APIs are being called by stripe in an attempt to reproduce and I can see a POST to stripe.com/api/payment_methods and I can see the posted values but I can't reproduce this in Postman. Also, the documentation (https://stripe.com/docs/api/payment_methods/create) says
"Instead of creating a PaymentMethod directly, we recommend using the
PaymentsIntents API to accept a payment immediately"
Question
Which stripe APIs do I need to call to automate the flow from a stripe Session object to make a payment and then check that it was successful? Payment Methods? Make a Charge? Payments Intents? ...and how. Happy to be pointed to the documentation if you can help me understand the flow.
TIA
Checkout is a Stripe product that looks like a "box" and you can't know (and shouldn't need to know) what happens inside. It is created for the purpose that merchants won't have to think about what's being done under the hood.
Speaking from an automation perspective, you can try to reproduce the whole process but there's no guarantee it won't change in the future, and it could leave you with more problems later.
For options to reproduce:
The closest way is simulating browser filling and submission, using automated browser tools (ie Selenium). But it's not as straightforward as PostMan. Generally you would want to simulate every browser action that a human could do.
Or you can try to accomplish the same with the logs and events you receive on Stripe's Dashboard, when you test a Checkout Session by yourself. From now there are 3 requests.
And your goal is to receive the same 5 events in Webhook:
TBH I recommend to reconsider the need of this test, to see if it worth your efforts.

How do you reflect order confirmation data to the frontend when using stripe + netlify?

The setup:
/order has a button on it that once clicked, calls stripe.redirectToCheckout({...}), which redirects the browser to stripes payment page.
Stripe does its thing, and finally redirects to /success.
Heres my question: How would I 'reflect back' the customers order to them on the /success page?
It seems like there should be 2 options:
Option 1) /success somehow gets JSON data sent to it (I can not find documentation for how to do this but it seems the most natural way... maybe)
Option 2) On the backend, after stripe has confirmed the order, thats when I add/update the user data in the database. After they land back at /success, I grab that same data from the database and reflect it back to them using that.
Thoughts?
Pass in the session_id in the success_url and cancel_url, e.g. /success?session=<SESSION_ID>. When handling the routes, extract the query parameters and retrieve the Session by calling Stripe API https://stripe.com/docs/api/checkout/sessions/retrieve.
If you have stored data in your database, I would also recommend adding relevant metadatas (https://stripe.com/docs/api/checkout/sessions/create#create_checkout_session-metadata) such as transaction id or user id so you can query your database.

Does the DocuSign Intermediate API plan let me use the API to get PDF and form fields?

I tried calling DocuSign sales and support (transferred around 3 times) and no one could give me a straight answer on this. Their "support" actually told be to try stackoverflow, so here I am...
I'm looking at their API pricing levels here: https://www.docusign.com/products-and-pricing/api-plans-b
If I have the Intermediate API, can I make the following API requests?
GET /restapi/v2.1/accounts/{accountId}/envelopes/{envelopeId}/documents/{documentId}
GET /restapi/v2.1/accounts/{accountId}/envelopes/{envelopeId}/form_data
The part that's throwing me for a loop is the DocuSign Connect feature in the Advanced API plan. The description of it is:
The DocuSign Connect module lets you configure webhooks for envelope events and recipient actions for some or all users in your account. It can also be used to transport the completed documents back to your app or website and to retrieve any form field data entered by your recipients.
I don't need the webhooks, but I need to be able to get the completed documents as PDFs and get the form field data. Do I really need the DocuSign Connect feature for that?
You will be fine with the intermediate plan. Here is the basic distinction between polling and Connect - With Connect, we will proactively notify YOU when key envelope events occur.
Otherwise, it's up to you to call GET /envelopes and/or GET /form_data to retrieve that information. Be wary of the resource limits when you poll.
As a quick aside, instead of making two requests to retrive that information, just make one - GET /envelopes?include=recipients,tabs. This will provide you all the information you seek in one request.
The important excerpt from that guide:
You may not exceed one GET request per unique envelope endpoint per 15
minutes. If you exceed this limit the request will not fail, but it
will be flagged as a violation of rate limits which can cause your app
to fail review to go-live review.
For example, the following transactions violate API rules due to the repeated GET requests to the first document and second recipient:
[12:00:00] POST /accounts/12345/envelopes
[12:01:00] GET /accounts/12345/envelopes/AAA/documents/1
[12:02:00] GET /accounts/12345/envelopes/AAA/recipients/2
[12:03:00] POST /accounts/12345/envelopes
[12:04:00] GET /accounts/12345/envelopes/AAA/documents/1 *
[12:05:00] GET /accounts/12345/envelopes/AAA/recipients/2 *
However, the following set of requests comply with API rules and limits and would not be flagged by the platform:
[12:00:00] POST /accounts/12345/envelopes
[12:01:00] GET /accounts/12345/envelopes/AAA
[12:16:00] GET /accounts/12345/envelopes/AAA
[12:17:00] GET /accounts/12345/envelopes/AAA/documents/1
[12:32:00] GET /accounts/12345/envelopes/AAA/documents/1
[12:40:00] PUT /accounts/12345/envelopes/AAA/recipients/1
[12:41:00] PUT /accounts/12345/envelopes/AAA/recipients/1

Creating new payment method for Bigcommerce

I would like to know if this is possible to add new payment method for Bigcommerce. I tried to contact their support without any luck. If anyone is familiar with bigcommerce and know if this is possible, i would appreciate any advice.
I already read their API docs and didn't found anything useful - only method to obtain list of available payment methods.
I already tried to signup for their partner. Without any luck.
We've done this before for a couple stores to allow clients to process payments through their own processor. The way we achieved this, is essentially through the following high-level steps:
Allow payments by Check (or similar offline method). We are going to replace this with the custom processor.
You'll notice that if you attempt to checkout via Check, that BigCommerce automatically creates the order for you, but sets the order status to Awaiting Payment. Upon submission the user is automatically sent to a 'Thank You' Order Confirmation page that contains both the Order ID and some payment instructions (such as where to send the check to).
Here's the trick -- Modify this 'Order Thank You' page to prompt the user for her or his credit card information. A simple HTML form will suffice here, performing the actual request via JavaScript.
Once you have the user's credit card data, you can then POST it to your own external server, where you would connect to and send data to whichever processor you are using. Additionally, you should make sure to send the Order ID to this program, so that you can connect to the BigCommerce API to load billing information, and then subsequently adjust the order status to either approved or declined depending on the response from your processor. Finally, you should send back some sort of response to the client to inform of the result of the charge attempt.
That's pretty much it in a nutshell. The way you integrate with the payment processor (step 4) is unique to whichever processor you are using. I hope this makes sense.
Although opinion based, I'm a huge fan of serverless technologies, and would suggest looking into AWS Lambda + AWS API Gateway. The benefit here is that you don't need to worry about creating an infrastructure or the associated concerns of security and scale. Rather, AWS Lambda allows you to simply upload your software, and allows it to be executed via an HTTP request to some defined endpoint set through the API Gateway. Lambda will scale automatically for you, and you don't need to worry about system level security concerns - only security at the application level. It's truly a set and forget setup, and a bleeding edge technology. Not to mention dirt cheap!
Implementing a new payment method is unsupported and requires hacky workarounds since we implement payment gateways via the core app. You can do this on blueprint by using an offline payment method and then using the API to update payment statuses, etc. I'd recommend using ActiveMerchant if you do wish to go down this path.

Resources