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.
Related
I'm currently building out a multipage form using Flutter (frontend) and Node/Express/MongoDB/Mongoose (backend) for which I would like to implement auto-saving as the user progresses through each page (ie. clicking the next button after each page saves form data to the DB).
I have client-side validation to ensure fields are filled out and in the correct format, but I believe server-side validation is more important to implement in the event the user bypasses the client-side. I was wondering if anyone had general design ideas/processes I could implement for this idea. Some ideas I have:
I'm thinking about sending a POST/PUT request to our server after each page, but I have no way of validating the incoming data server-side unless I create over 30 schemas for each of the pages. Each page has different questions so there isn't a single common validator I can use.
Another option was having a temporary object with all the fields, and only validate the object at the very end when the user clicks 'submit,' but this is bad UX design in my mind as any error may require the user to be set back to the 1st or 2nd page which is frustrating for sure.
My main concern is validating the incoming data on the server-side as well as the client-side, but I can't seem to think of a good way to do both in a clean manner. I believe this question is language-agnostic, but I added my tech stack just in case.
Any help would be greatly appreciated :)
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.
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.
While working on a DocuSign embedded signing process (which has worked in the past), I noticed that after signing the document the 'event' parameter was missing from the 'returnUrl' I was being sent back to.
The returnUrl looks like:
http://www.example.com/index.php?param1=value1 ... ¶m10=value10
The parameters were being passed on returning from signing, but no event=signing_complete parameter was being added. I tried removing the parameters, and suddenly the event parameter returned.
After further experimentation, I discovered that the returnUrl parameter has a 500 character limit. Anything more is truncated. This will also truncate the event parameter from the end of the returnUrl.
This does not seem to documented in the DocuSign REST API documentation (https://www.docusign.com/p/RESTAPIGuide/Content/REST%20API%20References/Post%20Recipient%20View.htm).
So, is this a feature or a bug? Other than using session or database storage, is there a recommended workaround for the 500-character limit?
There might be some limits to the URL that is being passed in by the web servers themselves. I have not seen a lot of people hit this limit because probably most of the time folks do not put that much information into a return URL.
If you are coming from software that has session state you can use the following technique:
1) add the information you were previously sending via URL to a dictionary or a collection object and save it in the session on the server. Follow the best security practices for that one so that this information can't be easily accessed (there is a ton of material on how to do this properly and it's probably beyond this answer)
2) in the url instead of all the keys and values just provide the key to your collection.
3) upon return from DocuSign look up the object and retrieve the passed in information.
If there is no state in your software you can try using other properties of the envelope to put the additional information such as envelope custom fields. You can populate those on create and you can retrieve the information back when the control comes back to your software. Here is the article about custom fields: https://www.docusign.com/p/RESTAPIGuide/RESTAPIGuide.htm#REST API References/Get Envelope Custom Field Information.htm
I want to make sure I am on the right track as I have been having some problems getting started with the API. I am looking to maintain a list of product application PDFs as templates on docusign. When a customer comes to our site and wants a particular product they need to fill out an application form. All the data would be collected on our site. I would then want to:
Create an envolope with the customer (and potentially other parties) that need to sign the document
Fill in the form fields from data collected on our site
Send the envelope out for signature and monitor the progress.
So in doing this I am trying to build this up a piece at a time and first task is to make sure that I can provide form data to docusign. I create a template with the docusign web user interface and all of the form fields seem to be preserved. However when I try and retrieve the template with API
https://demo.docusign.net/restapi/v2/accounts/xxxx/templates/yyyy
I see a very short response with an envelopeTemplateDefinition showing the correct name for the template but no documents object and no custom fields object. I have also tried this by creating an envelope with the document (in draft) but with similar results.
My apologies in advance for this newbie question.
I've repro'd the issue you describe -- i.e., the Response I get from a GET Template request contains only very limited information and is thereby not consistent with the expected Response as documented on pages 194-196 of the DocuSign REST API guide (http://www.docusign.com/sites/default/files/REST_API_Guide_v2.pdf). Not sure if this is a bug with the GET Template operation or with the Documentation -- someone at DocuSign will need to confirm (#Ergin).
In light of this limitation with the GET Template operation, you can alternatively retrieve the recipient information (including tabs) and document information about a Template by using the GET Envelope Recipients and GET Envelope Documents operations -- just specify the TEMPLATE Id in place of the Envelope Id, as shown here:
GET https://{{env}}.docusign.net/restapi/{{version}}/accounts/{{acctId}}/envelopes/{templateId}/documents
GET https://{{env}}.docusign.net/restapi/{{version}}/accounts/{{acctId}}/envelopes/{templateId}/recipients?include_tabs=true