Stripe checkout.js with coupons - stripe-payments

I'm using Stripe's checkout.js because it's so easy to setup and use. Is there a way to add coupons?
<script src="https://checkout.stripe.com/v2/checkout.js"
class="stripe-button"
data-key="pk_test_czwzkTp2tactuLOEOqbMTRzG"
data-amount="2000"
data-name="Demo Site"
data-description="2 widgets ($20.00)"
data-image="/128x128.png">
</script>

Stripe Checkout does not currently support coupons. It's not listed in the documentation, for either the button or the custom integration.
One might wonder if there is some secret feature. However, using undocumented features, especially when it comes to your payment processor is a bad idea. Full stop.
This being Stack Overflow - let's keep digging!
Fire up jsfiddle. Paste your code into the html section. Open up developer tools so you can see network requests.
There is a en.json, which is a internationalized strings file. If there is an input for coupons, there ought to be a label saying "Enter Coupon Code" or something similar. There is none. (Sure, there is the possibility that Stripe decided to hard code this particular string, but that seems unlikely).
https://checkout.stripe.com/v3/data/languages/en.json
You can also see that inner.js is used to power the popup. Copy the source into a js beautifier and you find that there is no mention. In fact, you can see the code that parses the options and none of them have to do with coupons.
"lib/optionParser": function(exports, require, module) {
(function() {
var BOOLEAN_OPTIONS, DEFAULTS, STRING_OPTIONS, URL_OPTIONS, extractValue, helpers, toBoolean, _;
_ = require("vendor/lodash");
helpers = require("lib/helpers");
DEFAULTS = {
currency: "usd",
allowRememberMe: true
};
BOOLEAN_OPTIONS = ["billingAddress", "shippingAddress", "notrack", "nostyle", "allowRememberMe", "allowPhoneVerification", "zipCode", "trace", "alipayReusable", "bitcoin"];
STRING_OPTIONS = ["key", "amount", "name", "description", "panelLabel", "currency", "email", "locale", "alipay"];
URL_OPTIONS = ["url", "referrer", "image"];
You can see how each of the options here align one to one with the options that available for custom integration, which map to the options for the button (you just need to use hyphens instead of camelcase)
At this point, you can keep digging if you want to convince yourself further, but I'd be reaching out to Stripe Support and making a feature request. Happy digging!

Checkout only creates the token. The coupon is applied to the customer after the token is returned to the server and customer is charged.
stripe.Customer.create(
source=token,
plan="basic_monthly",
email="payinguser#example.com",
coupon="coupon_ID"
)

Stripe have finally answered our prayers after having discount codes for Stripe checkout/payments on the roadmap for years
Discount codes are now here for Stripe checkout.
See here: https://stripe.com/docs/payments/checkout/discounts
You can also manually create it here: https://dashboard.stripe.com/coupons/create
For customer-facing promo codes, which is probably what we want, check out here: https://stripe.com/docs/billing/subscriptions/discounts/codes
(Technically, coupons are merchant-facing and promo codes are customer-facing)

If you want to pass a coupon code to your back end, you can just add an input field for it within the form. It won't alter the amounts in the pop-up form from stripe however, unless you wanted to get sophisticated and call additional javascript to check the parameters of the entered coupon code and change the stripe script parameters.
You can include any inputs you need within the form tags so long as they are not used by stripe.
<form action="/your-server-side-code" method="POST">
Coupon Code: <input type="text" name="coupon_code">
<br>
<script src="https://checkout.stripe.com/v2/checkout.js" class="stripe-button" data-key="pk_test_czwzkTp2tactuLOEOqbMTRzG" data-amount="2000" data-name="Demo Site" data-description="2 widgets ($20.00)" data-image="/128x128.png">
</script>
</form>

This maybe a new Stripe feature, use PaymentLinks and you can use the QueryString parameters like this.
https://buy.stripe.com/9AQ4gm66D7rl4129AD?prefilled_promo_code=SPORTISTAPP50

Related

Can we add fields to summary section in purchase order

How can i edit the Summary section in the purchase order record i.e., can i add extra fields to that section
Screencast:http://screencast.com/t/B4WWUvQN
The basic answer is No. Not if you follow NetSuites guidelines about DOM manipulation. With that said, you can just a client-side javascript library to access the table (class:"totallingtable") that holder the TR's for the fields. I would not use the below code in production, it's just an example you can run in your browser console to see it work.
jQuery('.totallingtable').append('<tr><td><div data-field-type="currency" class="uir-field-wrapper"><span class="smalltextnolink uir-label " id="sit_custom_fs_lbl_uir_label"><span style="" class="smalltextnolink" id="sit_custom_fs_lbl"><a onmouseout="this.className=\'smalltextnolink\'; " onmouseover="this.className=\'smalltextul\'; return true;" class="smalltextnolink" onclick="return nlFieldHelp(\'TRAN_PURCHORD\',\'total\', this)" style="cursor:help" href="javascript:void("help")" title="What\'s this?" tabindex="-1">CUSTOM</a></span></span><span class="uir-field inputreadonly">FIELD</span></div></td><td></td></tr>');

How to pre-populate email in the Stripe payments dialog popup

I cannot seem to find a way to pre-populate the email address in the stripe payment popup. However this weekend I signed up for two accounts on websites that use stripe payments and I realized those websites had my email pre-populated in the stripe dialog iframe box. So I know there must be a way but I am unsure of how to do that. The docs don't define that property.
Can someone explain how this is done using the javascript API and the basic Stripe dialog?
If you're using Simple Checkout you pass the email in data-email like this:
<form action="/charge" method="POST">
<script
src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="pk_test_6pRNASCoBOKtIshFeQd4XMUh"
data-image="/img/documentation/checkout/marketplace.png"
data-name="Stripe.com"
data-description="2 widgets"
data-amount="2000"
data-email="customer#email.com"
data-locale="auto">
</script>
</form>
If you're using Custom Checkout you pass the email in the email parameter to handler.open():
handler.open({
name: 'Stripe.com',
description: '2 widgets',
amount: 2000,
email: "customer#email.com"
});
If you want to dynamically set the email (for Simple Checkout ) using js you must dynamically create the whole script element to make sure it loads properly. This can be done like this:
//create our stipe script element
var stripescript = document.createElement('script'); //create script element
//dynamicaly load stripe checkout attributes
stripescript.setAttribute('src','https://checkout.stripe.com/checkout.js');
stripescript.setAttribute("data-key","[YOUR STRIPE TOKEN]" )
stripescript.setAttribute("data-amount","90" )
stripescript.setAttribute("data-locale","auto")
stripescript.setAttribute("class","stripe-button")
stripescript.setAttribute("data-billing-address",true)
stripescript.setAttribute("data-panel-label","Update")
stripescript.setAttribute("data-currency","gbp")
// any other attributes you want to add stripescript.setAttribute("[name]","[value]")
//insert script element inside of div or an other element
document.getElementById('[ID OF ELEMENT YOU WANT TO PUT THE FORM INTO]').appendChild(stripescript);

Gmail is trimming html email content. How to avoid the issue?

Gmail introduced a trimming feature in emails for "better readability". This causes a lot of pain for me, as I have a notification system for email, where I send some html email messages to users. Basically email looks like this:
divs and styling
Object alert in Project by User
tables and tr/td
User Action on Object in Project
/tables and tr/td
/divs and styling
link
footer
To group all emails in one conversation, first email has subject, subsequent emails have Re: subject.
Active users can receive significant amounts of emails like this, but due to "better readability" feature, ALL of the email content (starting from second email) is suppressed.
I am looking for advice - maybe I should redesign my html, or gmail has some anti-suppression code, or just a hack to go around this issue.
Issue from users perspective is described here: http://www.google.com/support/forum/p/gmail/thread?tid=756b83fa60ca1df7&hl=en
I had the trimming problem occurring on a table of an HTML newsletter.
It was very important that the entire table display because it was the
#1 content our client wanted to communicate. Here's the fix, or at least here's how we solved our problem. We eliminated any repetition.
So for this table, the lines in between each row, Gmail was seeing the
lines as repetitive. So I altered the pixel width by 1 px every other
line, which eliminated the repetition and fixed our problem. So that
said, look for repetition, and try to remove it. OR in some cases, you
might have to add type (in white) to create the variation.
Source.
PS: This is a bit unrelated, but I stumbled upon this question while looking for a way to disable the content trimming and keep the conversation view at the same time. I didn't find anything, so I developed a small extension for Chrome and Firefox.
It turns out that there is a very simple rule which causes this behaviour: Gmail will clip the email as soon as it sees the sender (From:) name in the body of the message, regardless of where this appears.
Solution: make sure that that the From: name in your email is not used in the message body (except in the signature, which will probably get clipped!).
This is an awful bug in Gmail, if you're unlucky enough to get bitten by it.
In my case, it was "trimming" an entire message, in a clean thread. See an example here, noting that the "trimmed" content is expanded in the screen-shot.
I ultimately worked around Gmail's bug by removing the entire header you see in that example ("Awesome Home Swap"), including the border below it. I stopped short of actually trying to figure out what specifically was making Gmail confuse that header as a "signature" (though I suspect it could have been the border, implemented using CSS directive border-bottom:1px dotted grey to style the <td> element).
I just found a solution that worked wonderfully for me. Simply create a bunch of hidden unique images throughout your emails to provide uniqueness to parts of the email that aren't actually unique. I'm building my emails with React so I have this Unique components that I'm using pretty much everywhere:
import * as React from "react"
function random() {
return Math.round(Math.random() * 10000000).toString()
}
class Unique extends React.PureComponent {
render() {
return (
<img style={Unique.style} src={`data:image/png;base64,${random()}`} />
)
}
static style = {
visibility: "hidden",
display: "none",
width: 0,
height: 0,
color: "transparent",
background: "transparent",
}
}
One thing I like about this solution is that it doesn't mess up the email preview text that would otherwise happen if you're using hidden text.
Add a double hyphen -- before the collapsed part. I was able to wrap it in a with font color matching the background. Worked for me...
I looked at the emails Gmail sent. Adds the following code (spacer.gif).
I guess this is the solution.
<img alt="" height="1" width="3" src="https://notifications.google.com/g/img/AD-FnEztup4OClDshQhMVXDbi6Oi0lSN-FgEY1jyW384aotccA.gif">
</td>
</tr>
</table>
</body>
</html>

How to prevent CSRF attacks when a CRUD action uses a link instead of a form?

I have implemented CSRF protection on my website using a CSRF token in a hidden input field in my forms. However at some places in my website I don't use a form for certain actions, e.g. a user can click a link to delete something (e.g. /post/11/delete). Currently this is open to a CSRF attack, so I want to implement a prevention for these links. How can I do this? I can think of two possible ways:
Make all links (which for example delete something) into tiny forms with only one hidden field (the CSRF token) and one submit button (styled as a normal link).
Add the CSRF token to the query-string
I don't like either of those options:
Styling a submit button to act exactly as a link might have some issues getting it correct (cross platform)?
Although it will never be picked up by search engines and don't like some random string in my URL (just aesthetics).
So is there a way I'm overlooking or are those two my options?
Add a token to your links.
styling submit to look like link is not hard. Though there will be issues with middle click or 'copy link location' command. Obviously.
facebook / google are not afraid of putting 'random strings' in urls. Neither should you. (Adding nofollow to those links, and excluding them in robots.txt should solve your fears with SEO. That is in case you for some reason show REST links to guest users / search engines).
If you really don't want URL parameters with long random values, you could implement a confirmation page for each Delete action, and have a form with your hidden field there.
Requests received at /post/11/delete without valid token will make the server respond with the confirmation page.
Requests received at /post/11/delete with valid token will trigger the deletion.
Best practice is to not perform updates via a GET operation.
Here's a clever little script that will hook into all of your links and make them POST a single hidden variable in addition to the payload in the querystring. Hope this is helpful!
document.ready = function () {
var makeLinkPost = function(link) {
var handleClick = function(event) {
event.preventDefault();
$("<form action='" + this.href + "' method='POST'><input type='hidden' value='CSRF'/></form>'").appendTo("body").submit();
}
$(link).click(handleClick);
}
$("a").each(function() {
makeLinkPost(this);
})
}

Best ways to secure form data from malicious users wielding Firebug?

I've read a couple of related questions on this, but they don't answer my question directly. Developer tools like Firebug allow anyone to see and manipulate form data before a form is sent. A good example of this is adjusting the value of a hidden "member ID" field so that the form submission is credited to another user.
What are the best ways to prevent this type of tampering? My research suggests moving sensitive form inputs to a server-side script, but are there any other options or considerations?
I'm familiar with PHP and jQuery, so my ideal solution would use one or both of those languages.
You can't use jQuery for security since it's all handled on the client side.
In your example just use a PHP session in staed of a hidden input field, because as you rightfully noted this can be manipulated.
Using sessions would look something like the following:
login page
<form action="login.php" method="post">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit" name="submit" value="submit">
</form>
login.php
// you have to include this on every page to be able to user sessions.
// also make sure that you include it before any output
session_start();
//Always sanitize the user input before doing any db actions.
//For example by using: `mysql_real_escape_string()` ( http://php.net/manual/en/function.mysql-real-escape-string.php ).
// check user credentials against db
$_SESSION['user'] = $dbresult['username'];
page-where-userid-is-required.php
session_start();
if (!isset($_SESSION['user'])) {
// user is not logged in!
} else {
// use user info to place order for example
}
The session will be active until the user closes his browser / until the session expires (which is a PHP setting)
The above is just some sample code to give you an idea.
It works smaller projects, however as projects get more complex I would suggest going for the MVC (Model, View, Controller) way. ( http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller )
But that's just a whole other story :)
Here are a few basic suggestions:
You need to validate form inputs using a server-side (PHP) script.
Instead of relying on sensitive pieces of information, such as member ID, from the form you could instead cache such data in your server session. That way there is no way for a malicious user to change the data on the fly.
You can still use jQuery validation as a convenience to catch basic input problems, but you can only trust data that is validated using server-side code.

Resources