├── .gitignore ├── home.html ├── main.go └── static ├── jquery.js ├── stripe.formHandler.js └── stripe.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 |
12 | 16 |
17 | 18 |
19 | 23 |
24 | 25 |
26 | 30 | / 31 | 32 |
33 | 34 |
35 | 36 | 37 | 38 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | stripe "github.com/stripe/stripe-go" 6 | "github.com/stripe/stripe-go/charge" 7 | "github.com/stripe/stripe-go/currency" 8 | "html/template" 9 | "log" 10 | "net/http" 11 | "os" 12 | ) 13 | 14 | const ( 15 | AmountToCharge uint64 = 10000 16 | ) 17 | 18 | type Home struct { 19 | PublishableKey string 20 | } 21 | 22 | func rootHandler(w http.ResponseWriter, r *http.Request) { 23 | t, _ := template.ParseFiles("home.html") 24 | home := Home{ 25 | PublishableKey: os.Getenv("STRIPE_PUBLISHABLE_KEY"), 26 | } 27 | t.Execute(w, home) 28 | } 29 | 30 | func createDebit(token string, amount uint64, description string) *stripe.Charge { 31 | stripe.Key = os.Getenv("STRIPE_KEY") 32 | 33 | params := &stripe.ChargeParams{ 34 | Amount: amount, 35 | Currency: currency.USD, 36 | Card: &stripe.CardParams{ 37 | Token: token, 38 | }, 39 | Desc: description, 40 | } 41 | 42 | ch, err := charge.New(params) 43 | 44 | if err != nil { 45 | log.Fatalf("error while trying to charge a cc", err) 46 | } 47 | 48 | log.Printf("debit created successfully %v\n", ch.ID) 49 | 50 | return ch 51 | } 52 | 53 | func debitsHandler(w http.ResponseWriter, r *http.Request) { 54 | if r.Method == "POST" { 55 | createDebit(r.FormValue("stripeToken"), AmountToCharge, "testing charge description!") 56 | fmt.Fprint(w, "successful payment.") 57 | } 58 | } 59 | 60 | func main() { 61 | http.HandleFunc("/", rootHandler) 62 | http.HandleFunc("/debits", debitsHandler) 63 | 64 | fs := http.FileServer(http.Dir("static")) 65 | http.Handle("/static/", http.StripPrefix("/static/", fs)) 66 | 67 | http.ListenAndServe(":8081", nil) 68 | } 69 | -------------------------------------------------------------------------------- /static/stripe.formHandler.js: -------------------------------------------------------------------------------- 1 | function stripeResponseHandler(status, response) { 2 | var $form = $('#payment-form'); 3 | 4 | if (response.error) { 5 | // Show the errors on the form 6 | $form.find('.payment-errors').text(response.error.message); 7 | $form.find('button').prop('disabled', false); 8 | } else { 9 | // response contains id and card, which contains additional card details 10 | var token = response.id; 11 | // Insert the token into the form so it gets submitted to the server 12 | $form.append($('').val(token)); 13 | // and submit 14 | $form.get(0).submit(); 15 | } 16 | }; 17 | 18 | $(function() { 19 | $('#payment-form').submit(function(event) { 20 | var $form = $(this); 21 | 22 | // Disable the submit button to prevent repeated clicks 23 | $form.find('button').prop('disabled', true); 24 | 25 | Stripe.card.createToken($form, stripeResponseHandler); 26 | 27 | // Prevent the form from submitting with the default action 28 | return false; 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /static/stripe.js: -------------------------------------------------------------------------------- 1 | (function(){var e,t,n,r,i,s={}.hasOwnProperty,o=function(e,t){function r(){this.constructor=e}for(var n in t)s.call(t,n)&&(e[n]=t[n]);return r.prototype=t.prototype,e.prototype=new r,e.__super__=t.prototype,e},u=this;this.Stripe=function(){function e(){}return e.version=2,e.endpoint="https://api.stripe.com/v1",e.setPublishableKey=function(t){return e.key=t,e.utils.validateProtocol(e.key)},e._corsGateAmount=0,e._corsGate=function(){return Math.random()0&&(r.amount=s)),r[n.tokenName]=e.token.formatData(t,n.whitelistedAttrs),e.token.create(r,i)},n.getToken=function(t,n){return e.token.get(t,n)},n.validateCardNumber=function(e){return e=(e+"").replace(/\s+|-/g,""),e.length>=10&&e.length<=16&&n.luhnCheck(e)},n.validateCVC=function(t){return t=e.utils.trim(t),/^\d+$/.test(t)&&t.length>=3&&t.length<=4},n.validateExpiry=function(t,n){var r,i;return t=e.utils.trim(t),n=e.utils.trim(n),/^\d+$/.test(t)?/^\d+$/.test(n)?1<=t&&t<=12?(n.length===2&&(n<70?n="20"+n:n="19"+n),n.length!==4?!1:(i=new Date(n,t),r=new Date,i.setMonth(i.getMonth()-1),i.setMonth(i.getMonth()+1,1),i>r)):!1:!1:!1},n.luhnCheck=function(e){var t,n,r,i,s,o;r=!0,i=0,n=(e+"").split("").reverse();for(s=0,o=n.length;s9&&(t-=9),i+=t}return i%10===0},n.cardType=function(e){return n.cardTypes[e.slice(0,2)]||"Unknown"},n.cardBrand=function(e){return n.cardType(e)},n.cardTypes=function(){var e,t,n,r;t={};for(e=n=40;n<=49;e=++n)t[e]="Visa";for(e=r=50;r<=59;e=++r)t[e]="MasterCard";return t[34]=t[37]="American Express",t[60]=t[62]=t[64]=t[65]="Discover",t[35]="JCB",t[30]=t[36]=t[38]=t[39]="Diners Club",t}(),n}.call(this,this.Stripe.token),this.Stripe.bankAccount=function(t){function n(){return n.__super__.constructor.apply(this,arguments)}return o(n,t),n.tokenName="bank_account",n.whitelistedAttrs=["country","routing_number","account_number"],n.createToken=function(t,r,i){return r==null&&(r={}),e.token.validate(t,"bank account"),typeof r=="function"&&(i=r,r={}),r[n.tokenName]=e.token.formatData(t,n.whitelistedAttrs),e.token.create(r,i)},n.getToken=function(t,n){return e.token.get(t,n)},n.validateRoutingNumber=function(t,r){t=e.utils.trim(t);switch(r){case"US":return/^\d+$/.test(t)&&t.length===9&&n.routingChecksum(t);case"CA":return/\d{5}\-\d{3}/.test(t)&&t.length===9;default:return!0}},n.validateAccountNumber=function(t,n){t=e.utils.trim(t);switch(n){case"US":return/^\d+$/.test(t)&&t.length>=1&&t.length<=17;default:return!0}},n.routingChecksum=function(e){var t,n,r,i,s,o;r=0,t=(e+"").split(""),o=[0,3,6];for(i=0,s=o.length;i=400&&r<500?(t._clearReceiverPoll(e),typeof n=="function"?n(r,i):void 0):(s=r===500?5e3:t._pollInterval,o=setTimeout(function(){return t._pollReceiver(e,n)},s),t._activeReceiverPolls[e].timeoutId=o)})},t.cancelReceiverPoll=function(e){var n;n=t._activeReceiverPolls[e];if(n==null)throw"You are not polling receiver "+e+".";n["timeoutId"]!=null&&clearTimeout(n.timeoutId),t._clearReceiverPoll(e)},t}.call(this),t=["createToken","getToken","cardType","validateExpiry","validateCVC","validateCardNumber"];for(r=0,i=t.length;r0&&(i=setTimeout(function(){return a.abort("timeout")},n.timeout)),a}}.call(this),function(){var e,t,n,r,i,s,o,u,a,f={}.hasOwnProperty;t={contentType:"application/x-www-form-urlencoded",accept:{json:"application/json"}},o=/^(20\d|1223)$/,s="invalid_json_response",r=function(e,t,n){return function(){if(e._aborted)return n("aborted");if(e.request&&e.request.readyState===4)return e.request.onreadystatechange=function(){},o.test(e.request.status)?t(e.request,e.request.status):(t(e.request,e.request.status),n("response_code"))}},u=function(e,n){var r,i,s;i=n.headers||{},i.Accept||(i.Accept=t.accept.json),i["Content-Type"]||(i["Content-Type"]=t.contentType),s=[];for(r in i){if(!f.call(i,r))continue;"setRequestHeader"in e?s.push(e.setRequestHeader(r,i[r])):s.push(void 0)}return s},a=function(e,t){return/\?/.test(e)?e+"&"+t:e+"?"+t},n=function(e,t){var n,i,s,o,f,l,c,h;return f=this.o,o=(f.method||"GET").toUpperCase(),l=f.url,s=(c=f.data)!=null?c.key:void 0,n=Stripe.utils.serialize(f.data),i=void 0,o==="GET"&&n&&(l=a(l,n),n=null),h=new XMLHttpRequest,h.open(o,l,!0),u(h,f),h.onreadystatechange=r(this,e,t),h.send(n),h},e=function(e){return this.o=e,i.apply(this,arguments)},i=function(e){var t,r,i,o=this;return this.url=e.url,this.timeout=null,this._successHandler=function(){},this._errorHandlers=[],this._completeHandlers=[],e.timeout&&(this.timeout=setTimeout(function(){return o.abort()},e.timeout)),e.success&&(this._successHandler=function(){return e.success.apply(e,arguments)}),e.error&&this._errorHandlers.push(function(){return e.error.apply(e,arguments)}),e.complete&&this._completeHandlers.push(function(){return e.complete.apply(e,arguments)}),t=function(t){var n;e.timeout&&clearTimeout(o.timeout),o.timeout=null,n=[];while(o._completeHandlers.length>0)n.push(o._completeHandlers.shift()("success",t,e));return n},i=function(e,n){var i;i=e.responseText;if(i)try{e=Stripe.utils.parseJSON(i)}catch(u){r(s)}return o._successHandler(e,n),t(e)},r=function(e){var n,r;r=o.request,n=r.responseText;if(n)try{r=Stripe.utils.parseJSON(n)}catch(i){e=s}while(o._errorHandlers.length>0)o._errorHandlers.shift()(r,e);return t(r)},this.request=n.call(this,i,r)},e.prototype={abort:function(){return this._aborted=!0,this.request.abort()}},this.Stripe.xhr=function(t){return new e(t)}}.call(this),function(){var e=[].indexOf||function(e){for(var t=0,n=this.length;t0))return"Enter a positive value"},range:function(t,n){var r;if(r=parseInt(n,10),e.call(t,r)<0)return"Needs to be between "+t[0]+" and "+t[t.length-1]},required:function(e,t){if(e&&(t==null||t===""))return"Required"},year:function(e,t){if(!/^\d{4}$/.test(t))return"Enter a 4-digit year"},birthYear:function(e,t){var n;n=this.year(e,t);if(n)return n;if(parseInt(t,10)>2e3)return"You must be over 18";if(parseInt(t,10)<1900)return"Enter your birth year"},month:function(e,t){if(this.integer(e,t))return"Please enter a month";if(this.range([1,2,3,4,5,6,7,8,9,10,11,12],t))return"Needs to be between 1 and 12"},choices:function(t,n){if(e.call(t,n)<0)return"Not an acceptable value for this field"},email:function(e,t){if(!/^[^@<\s>]+@[^@<\s>]+$/.test(t))return"That doesn't look like an email address"},url:function(e,t){if(!/^https?:\/\/.+\..+/.test(t))return"Not a valid url"},usTaxID:function(e,t){if(!/^\d{2}-?\d{1}-?\d{2}-?\d{4}$/.test(t))return"Not a valid tax ID"},ein:function(e,t){if(!/^\d{2}-?\d{7}$/.test(t))return"Not a valid EIN"},ssnLast4:function(e,t){if(!/^\d{4}$/.test(t))return"Not a valid last 4 digits for an SSN"},ownerPersonalID:function(e,t){var n;n=function(){switch(e){case"CA":return/^\d{3}-?\d{3}-?\d{3}$/.test(t);case"US":return!0}}();if(!n)return"Not a valid ID"},bizTaxID:function(e,t){var n,r,i,s,o,u,a,f;u={CA:["Tax ID",[/^\d{9}$/]],US:["EIN",[/^\d{2}-?\d{7}$/]]},o=u[e];if(o!=null){n=o[0],s=o[1],r=!1;for(a=0,f=s.length;a