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

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.

Related

How do I prevent multiple paypal payments in nodeJs?

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)

Creating form data via rest doesn't trigger autoresponder

Kentico 10. When I make a rest request to post data to the kentico form module I get a successful http 201 back and I can see the data created in the kentico interface. This particular form I am posting data to has an autoresponder set up.
I have a default smtp server set up and can successfully email out through it, which leads me to believe that the autoresponder on the form does not get triggered when data is created in the kentico form via rest. I never see the autoresponder attempt to send an email in either the email queue module or the event viewer (with the proper web.config key set).
Is that the intended behavior, to not trigger the autoresponder when forms module data is created via a rest request? If so, any idea how to get it to trigger?
Yes you are correct. Kentico REST is meant to perform simple CRUD operations. Essentially what you doing is the same as if you do it inside the admin i.e. go inside admin -> forms -> your form name -> recorded data and add new record. It doesn't trigger anything like sending email or Redirect to URL etc.
What you can do if you want to send email using form global events and on insert send email yourself. Here is the example of using global events

Cakephp 3 Stripe payment form

I'm hoping someone out there can help me understand how Stripe should work with Cakephp 3.
I have a form with the Stripe payment fields and a couple of fields for my cake app. From the Stripe documentation this seems to be an acceptable way to set it up.
The HTML is fairly standard, but note how every input for sensitive
data—number, CVC, expiration, and postal code—omits the name
attribute. By omitting a name, the user-supplied data in those fields
won't be passed to your server when the form is submitted. Each
element also includes a data-stripe attribute, to be discussed later.
I'm using cakephp 3 now which doesn't seem to allow me to remove properties from the HTML generated by the form helper. I can only make the 'name' property be blank. I queried this with Stripe support and they were a little noncommittal. They are generally very good but in this instance the answer seemed to be 'better safe than sorry.'
My main question is this: does it really matter if you don't use the form helper for Stripe fields. The main benefit i can find in the cake docs is that the CSRF component will act on those fields. I am using the CSRF component throughout my app, but since the Stripe fields aren't even sent to the server the CSRF component is irrelevant. Isn't it?
Here's an excerpt from the Cakephp manual:
The CsrfComponent works by setting a cookie to the user’s browser.
When forms are created with the Cake\View\Helper\FormHelper, a hidden
field is added containing the CSRF token. During the
Controller.startup event, if the request is a POST, PUT, DELETE, PATCH
request the component will compare the request data & cookie value. If
either is missing or the two values mismatch the component will throw
aCake\Network\Exception\InvalidCsrfTokenException.
I can still use the form helper for the few fields that do get submitted to the database, and just add the Stripe fields with HTML?
Does that make sense?
Stripe support did suggest having two separate forms, one for the cake data and one for the Stripe data, but since their docs say you can add the Stripe fields to a form that gets submitted to the server that seems a bit odd.
I would really appreciate some input on this as it seems even Stripe themselves aren't sure how to structure a cakephp payment form!
Yes raw HTML appears to be the way to go.
Here's what i did.
Used the form helper to start and end the form (This means form tampering and CSRF will work for your non Stripe fields)
Added the Stripe fields within the Cake form using HTML (I haven't tested the HTML fields to see if the form tampering works on them. I'll test that later and post back)
Used the Form helper to unlock the stripeToken field so it could be added to the form without the form tampering blackholing the request.
Once i set all this up I used echo debug($_POST) in my controller to see what the form was submitting to the server and the only Stripe field that was showing up was stripeToken.
So it appears to me that this is working as it should.

How can I create an authenticated scraper for Amazon product detail in Node.js?

I'm creating a script that grabs all the shipped items from Amazon and notifies me.
Authentication is needed to see the products though.
I've already tried sending a post request through "request" which returns an error because of the cookies and extra parameters needed.
It would be easy using cheerio afterwards to get the data if the authentication works.
Does anyone have any idea on how we can authenticate successfully?
The link from the email is: https://www.amazon.com/ap/signin/185-3199906-8918341?_encoding=UTF8&accountStatusPolicy=P1&openid.assoc_handle=usflex&openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.mode=checkid_setup&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.ns.pape=http%3A%2F%2Fspecs.openid.net%2Fextensions%2Fpape%2F1.0&openid.pape.max_auth_age=0&openid.return_to=https%3A%2F%2Fwww.amazon.com%2Fgp%2Fyour-account%2Forder-details%2F185-3199906-8918341%3Fie%3DUTF8%26eoid%3D1%253A1%253Arv%252FYwjiYmnOZY9MYltVnDyf2l6p5pMkMx9deoUeiiw%252FKpPrtZrWqs5l1GGQPVb%2520qaJqHXyCkPEpLZnmDZamKkVDWhtu3dKlW5Gx7Uvxtzs0xlPJ25vduijJrPpHt79P%2520RRZHopOtAyOP4s82VLoeeiDQgq%2520FCP540H%2520UYAV7goZQxB29WObWAVh8VveTwEeWenY3sTx8ZI9%252FBLM2BSqS3IUIURW8mzMnAB9t7wglUiAcoR%252FcUhSIx%25201eNV4MspVAp7fLkeANag72BxgmsjFfRhnsxfji1VhZXLawqFeK9SBnvbUfkNWUC%2520IXWh6VcuoStBG3x%2520ZUkzGHw1ORi4J%2520Hg%253D%253D%26orderID%3D105-6914722-5422613%26ref_%3DTE_simp_on_T1&pageId=webcs-yourorder&showRmrMe=1
You cannot guarantee any of the form input values of the sign in page. So you must also scrape the login form.
Here is the process:
In your server, make Request to the URL in your question
Using Cheerio parse the DOM and grab all of the form fields from "#ap_signin_form".
Add in your data (Username/Pass) then make a POST request to the form action "https://www.amazon.com/ap/signin" (This should also be scraped)
Hopefully that will get you past the login screen. You will need to ensure all future requests pass the cookies set from login.
Now this kind of thing is clearly against most TOS's so I would urge caution in doing this kind of thing often.

What structure should I use for an approval workflow?

This is a common problem that I find when programming a Lotus Notes App.
Use case: An employer fills out a request form in a Request database. A notification gets mailed to the person that may give them OK or REJECT for that request. The authority person visits the Request database and gives OK or REJECT.
Good. But, where would you save the approval status OK or REJECT:
Should the authority person have write access to the original request
and set the status directly (and may alter other data in the form)
Should the aproval action create a response doc to the original (and i cannot show in a view the current status)
Typically you are better off setting an approval status directly on the request. That may not seem initially ideal, but remember Lotus Notes isn't like a relational database where things would be more normalized.
Let's consider the alternative, putting a status in the response document. Now how do you show all the requests with their statuses? You'd probably have to write some code just to do that when with the first option you could just create a view.
You can control the access to the document using reader and writer access fields. See how the built in template does it (the approval workflow template). Essentially as the document changes state (i.e. New, Submitted for Approval, Approved or Denied, etc), you can also change the reader and writer access fields at that point.
Once, I designed a database that mailed that request to the approver with the form stored in the document. As long as the user accessed the document using a Notes client, they could click on a button in the message to approve, which would send a message back to the database with the field data to mark the request as approved. An agent in that request database was set to run when new mail arrived, read those messages and change status on the original requests. That way, the approver never had to leave their inbox and didn't even need rights to edit the request.
You could do it with URLs if the users would be approving via browser client - have the link to an agent and pass in the parameters.
Or, to go back to your scenario, once the requester has submitted the request, don't display the fields that you don't want changed, display the values as computed text instead.
Anyway you look at it, best to have the approval recorded on the original document.
For above, Everything is our concern. In SQL or any other RDMS, we are in need of normalize that. Similarly here we have view categorization, show response document in hierarchy, and a lot of great hide when functionality based on role, ACL, unique person and whatever you need. We can easily manipulate the data render depends on the current user.
For your Q:-
1. We can control the appropriate user[authority person] from editing the request form's item.
2. We can also do by the response document. There we can show the documents in view by using show the Response documents in hierarchy.

Resources