+
PayPal payment buttons
+
Integrating with the experimental PayPal JavaScript buttons is as easy as including a small snippet of code. To get started:
+
+
+ - Customize your button
+ - Add the button to your site
+
+
+
Customize your button
+
+ - Click Customize & Preview to get a lightbox where you can customize your button code with your merchant ID, product name, price and other options.
+ - Click Preview in the lightbox to see a preview of your newly created button.
+ - Click on the button to test it out.
+
+
+
+
+
+
+
Buy Now buttons are perfect for single item purchases Customize & Preview
+
+
<script src="paypal-button.min.js?merchant=YOUR_MERCHANT_ID"
+ data-button="buynow"
+ data-name="My product"
+ data-amount="1.00"
+></script>
+
+
+
+
+
+
+
+
+
+
+
+
Add To Cart buttons let users add multiple items instantly giving your website a cart Customize & Preview
+
+
<script src="paypal-button-minicart.min.js?merchant=YOUR_MERCHANT_ID"
+ data-button="cart"
+ data-name="Product in your cart"
+ data-amount="1.00"
+></script>
+
+
+
+
+
+
+
+
+
+
+
Donate buttons are great for accepting donations from users Customize & Preview
+
+
<script src="paypal-button.min.js?merchant=YOUR_MERCHANT_ID"
+ data-button="donate"
+ data-name="My product"
+ data-amount="1.00"
+></script>
+
+
+
+
+
+
+
+
+
+
+
+
Subscribe buttons can be used to set up payment subscriptions with your users Customize & Preview
+
+
<script src="paypal-button.min.js?merchant=YOUR_MERCHANT_ID"
+ data-button="subscribe"
+ data-name="My product"
+ data-amount="1.00"
+ data-recurrence="1"
+ data-period="M"
+></script>
+
+
+
+
+
+
+
+
+
+
+
+
QR codes are ideal for allowing quick mobile payments Customize & Preview
+
+
<script src="paypal-button.min.js?merchant=YOUR_MERCHANT_ID"
+ data-button="qr"
+ data-name="Product via QR code"
+ data-amount="1.00"
+ data-size="250"
+></script>
+
+
+
+
+
+
+
+
+
+
+
Important: Unless you enable the sandbox environment, all payments made using this code will be live and not test payments.
+
+
+
+
+ -
+
Get your Merchant ID or email address. You'll need to add it to the code above. If you're logged in to PayPal and have a business account, you can get your Merchant ID on your account
+ profile page.
+
+ -
+
Download one of these two JavaScript files and add it to your site, depending on whether you want a simple button or a cart.
+
+ In the generated button code, you can edit the path to the PayPal Button JavaScript file, if needed.
+
+ -
+
Copy and paste the HTML snippet you customized above, and you're ready to start selling!
+
+
+
+
Environment
+
In order to test your implementation before going live you can use our sandbox environment. Please check the Developer Portal for further information.
+
+
Callback
+
On completion of a transaction you can get a payment notification (IPN) on a callback URL you specify using the callback attribute. An IPN simulator is available on the sandbox to help you test your integration.
+
Customization
+
For advanced needs, there's a JavaScript API that can be used to pragmatically create buttons, localization support, and the ability to create user-editable inputs. Find out how in the README file.
+
+
Browser support
+
The JavaScript buttons have been tested and work in all modern browsers including: Chrome, Safari, Firefox and Internet Explorer 7+.
+
+
Find out more
+
This project is hosted on Github. Feature requests and issues can be filed on the issue tracker.
+
+
+
+
+
+
+
+
diff --git a/js/app.js b/js/app.js
new file mode 100644
index 0000000..9ccfef7
--- /dev/null
+++ b/js/app.js
@@ -0,0 +1,97 @@
+/*jshint jquery:true */
+/*global PAYPAL:true */
+
+(function () {
+ 'use strict';
+
+
+ $('.modal').on('shown', function (e) {
+ // Focus on the first input when modal is available
+ $(this).find(':input:text:enabled:first').focus();
+ });
+
+
+ $(document).on('click', '[data-modal-save="true"]', function (e) {
+ var data = {},
+ modal = $(this).parents('.modal').first(),
+ example = modal.closest('.example'),
+ code = example.find('code'),
+ tryit = example.find('.tryit'),
+ inputs = modal.find('.modal-body :input'),
+ requiredInputs = modal.find('[required="required"]'),
+ input, merchant, el, len, i, key, button;
+
+
+ // Don't update if we don't have all of the required inputs
+ // TODO: This can be cleaned up
+ for (i = 0, len = requiredInputs.length; i < len; i++) {
+ var requiredInput = $(requiredInputs[i]),
+ controlGroup = requiredInput.parents('.control-group').first();
+
+ if (requiredInput.val() === '') {
+ controlGroup.addClass('error');
+ requiredInput.focus();
+
+ return;
+ } else {
+ controlGroup.removeClass('error');
+ }
+ }
+
+ // Build a map out of the form data
+ for (i = 0, len = inputs.length; i < len; i++) {
+ input = $(inputs[i]);
+
+ if(input.is(':checkbox')) {
+ if(input.is(':checked')) {
+ data[input.attr('name')] = {
+ value: input.val()
+ };
+ }
+ } else {
+ data[input.attr('name')] = {
+ value: input.val()
+ };
+ }
+ }
+
+ // Create a script tag to use as the HTML
+ el = document.createElement('script');
+
+ if (data.button && data.button.value === 'cart') {
+ el.src = 'paypal-button-minicart.min.js?merchant=' + data.business.value;
+ } else {
+ el.src = 'paypal-button.min.js?merchant=' + data.business.value;
+ }
+
+ for (key in data) {
+ if (key !== 'business' && data[key].value !== '') {
+ el.setAttribute('data-' + key, data[key].value);
+ }
+ }
+
+ code.text(el.outerHTML.replace(/data-/g, "\n data-").replace(">" + "script>", "\n>" + "script>"));
+
+ // Update the button
+ button = PAYPAL.apps.ButtonFactory.create(data.business.value, data, data.button.value);
+ button = $(button);
+ button.css('display', 'none');
+
+ tryit.empty();
+ tryit.append(button);
+ tryit.animate({
+ height: (button.height() || 130) * 2
+ }, 300, function () {
+ button.fadeTo(300, 1);
+ });
+
+ // Close the modal
+ modal.modal('hide');
+
+ // Track Events
+ if (data.button) {
+ _gaq.push(['_trackEvent', 'JavaScriptButtons', data.button.value]);
+ }
+ });
+
+}());
diff --git a/js/bootstrap.min.js b/js/bootstrap.min.js
new file mode 100644
index 0000000..55da8c3
--- /dev/null
+++ b/js/bootstrap.min.js
@@ -0,0 +1,6 @@
+/*!
+* Bootstrap.js by @fat & @mdo
+* Copyright 2012 Twitter, Inc.
+* http://www.apache.org/licenses/LICENSE-2.0.txt
+*/
+!function(e){"use strict";e(function(){e.support.transition=function(){var e=function(){var e=document.createElement("bootstrap"),t={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"},n;for(n in t)if(e.style[n]!==undefined)return t[n]}();return e&&{end:e}}()})}(window.jQuery),!function(e){"use strict";var t='[data-dismiss="alert"]',n=function(n){e(n).on("click",t,this.close)};n.prototype.close=function(t){function s(){i.trigger("closed").remove()}var n=e(this),r=n.attr("data-target"),i;r||(r=n.attr("href"),r=r&&r.replace(/.*(?=#[^\s]*$)/,"")),i=e(r),t&&t.preventDefault(),i.length||(i=n.hasClass("alert")?n:n.parent()),i.trigger(t=e.Event("close"));if(t.isDefaultPrevented())return;i.removeClass("in"),e.support.transition&&i.hasClass("fade")?i.on(e.support.transition.end,s):s()},e.fn.alert=function(t){return this.each(function(){var r=e(this),i=r.data("alert");i||r.data("alert",i=new n(this)),typeof t=="string"&&i[t].call(r)})},e.fn.alert.Constructor=n,e(document).on("click.alert.data-api",t,n.prototype.close)}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.button.defaults,n)};t.prototype.setState=function(e){var t="disabled",n=this.$element,r=n.data(),i=n.is("input")?"val":"html";e+="Text",r.resetText||n.data("resetText",n[i]()),n[i](r[e]||this.options[e]),setTimeout(function(){e=="loadingText"?n.addClass(t).attr(t,t):n.removeClass(t).removeAttr(t)},0)},t.prototype.toggle=function(){var e=this.$element.closest('[data-toggle="buttons-radio"]');e&&e.find(".active").removeClass("active"),this.$element.toggleClass("active")},e.fn.button=function(n){return this.each(function(){var r=e(this),i=r.data("button"),s=typeof n=="object"&&n;i||r.data("button",i=new t(this,s)),n=="toggle"?i.toggle():n&&i.setState(n)})},e.fn.button.defaults={loadingText:"loading..."},e.fn.button.Constructor=t,e(document).on("click.button.data-api","[data-toggle^=button]",function(t){var n=e(t.target);n.hasClass("btn")||(n=n.closest(".btn")),n.button("toggle")})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=n,this.options.slide&&this.slide(this.options.slide),this.options.pause=="hover"&&this.$element.on("mouseenter",e.proxy(this.pause,this)).on("mouseleave",e.proxy(this.cycle,this))};t.prototype={cycle:function(t){return t||(this.paused=!1),this.options.interval&&!this.paused&&(this.interval=setInterval(e.proxy(this.next,this),this.options.interval)),this},to:function(t){var n=this.$element.find(".item.active"),r=n.parent().children(),i=r.index(n),s=this;if(t>r.length-1||t<0)return;return this.sliding?this.$element.one("slid",function(){s.to(t)}):i==t?this.pause().cycle():this.slide(t>i?"next":"prev",e(r[t]))},pause:function(t){return t||(this.paused=!0),this.$element.find(".next, .prev").length&&e.support.transition.end&&(this.$element.trigger(e.support.transition.end),this.cycle()),clearInterval(this.interval),this.interval=null,this},next:function(){if(this.sliding)return;return this.slide("next")},prev:function(){if(this.sliding)return;return this.slide("prev")},slide:function(t,n){var r=this.$element.find(".item.active"),i=n||r[t](),s=this.interval,o=t=="next"?"left":"right",u=t=="next"?"first":"last",a=this,f;this.sliding=!0,s&&this.pause(),i=i.length?i:this.$element.find(".item")[u](),f=e.Event("slide",{relatedTarget:i[0]});if(i.hasClass("active"))return;if(e.support.transition&&this.$element.hasClass("slide")){this.$element.trigger(f);if(f.isDefaultPrevented())return;i.addClass(t),i[0].offsetWidth,r.addClass(o),i.addClass(o),this.$element.one(e.support.transition.end,function(){i.removeClass([t,o].join(" ")).addClass("active"),r.removeClass(["active",o].join(" ")),a.sliding=!1,setTimeout(function(){a.$element.trigger("slid")},0)})}else{this.$element.trigger(f);if(f.isDefaultPrevented())return;r.removeClass("active"),i.addClass("active"),this.sliding=!1,this.$element.trigger("slid")}return s&&this.cycle(),this}},e.fn.carousel=function(n){return this.each(function(){var r=e(this),i=r.data("carousel"),s=e.extend({},e.fn.carousel.defaults,typeof n=="object"&&n),o=typeof n=="string"?n:s.slide;i||r.data("carousel",i=new t(this,s)),typeof n=="number"?i.to(n):o?i[o]():s.interval&&i.cycle()})},e.fn.carousel.defaults={interval:5e3,pause:"hover"},e.fn.carousel.Constructor=t,e(document).on("click.carousel.data-api","[data-slide]",function(t){var n=e(this),r,i=e(n.attr("data-target")||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,"")),s=e.extend({},i.data(),n.data());i.carousel(s),t.preventDefault()})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.collapse.defaults,n),this.options.parent&&(this.$parent=e(this.options.parent)),this.options.toggle&&this.toggle()};t.prototype={constructor:t,dimension:function(){var e=this.$element.hasClass("width");return e?"width":"height"},show:function(){var t,n,r,i;if(this.transitioning)return;t=this.dimension(),n=e.camelCase(["scroll",t].join("-")),r=this.$parent&&this.$parent.find("> .accordion-group > .in");if(r&&r.length){i=r.data("collapse");if(i&&i.transitioning)return;r.collapse("hide"),i||r.data("collapse",null)}this.$element[t](0),this.transition("addClass",e.Event("show"),"shown"),e.support.transition&&this.$element[t](this.$element[0][n])},hide:function(){var t;if(this.transitioning)return;t=this.dimension(),this.reset(this.$element[t]()),this.transition("removeClass",e.Event("hide"),"hidden"),this.$element[t](0)},reset:function(e){var t=this.dimension();return this.$element.removeClass("collapse")[t](e||"auto")[0].offsetWidth,this.$element[e!==null?"addClass":"removeClass"]("collapse"),this},transition:function(t,n,r){var i=this,s=function(){n.type=="show"&&i.reset(),i.transitioning=0,i.$element.trigger(r)};this.$element.trigger(n);if(n.isDefaultPrevented())return;this.transitioning=1,this.$element[t]("in"),e.support.transition&&this.$element.hasClass("collapse")?this.$element.one(e.support.transition.end,s):s()},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}},e.fn.collapse=function(n){return this.each(function(){var r=e(this),i=r.data("collapse"),s=typeof n=="object"&&n;i||r.data("collapse",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.collapse.defaults={toggle:!0},e.fn.collapse.Constructor=t,e(document).on("click.collapse.data-api","[data-toggle=collapse]",function(t){var n=e(this),r,i=n.attr("data-target")||t.preventDefault()||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,""),s=e(i).data("collapse")?"toggle":n.data();n[e(i).hasClass("in")?"addClass":"removeClass"]("collapsed"),e(i).collapse(s)})}(window.jQuery),!function(e){"use strict";function r(){e(t).each(function(){i(e(this)).removeClass("open")})}function i(t){var n=t.attr("data-target"),r;return n||(n=t.attr("href"),n=n&&/#/.test(n)&&n.replace(/.*(?=#[^\s]*$)/,"")),r=e(n),r.length||(r=t.parent()),r}var t="[data-toggle=dropdown]",n=function(t){var n=e(t).on("click.dropdown.data-api",this.toggle);e("html").on("click.dropdown.data-api",function(){n.parent().removeClass("open")})};n.prototype={constructor:n,toggle:function(t){var n=e(this),s,o;if(n.is(".disabled, :disabled"))return;return s=i(n),o=s.hasClass("open"),r(),o||(s.toggleClass("open"),n.focus()),!1},keydown:function(t){var n,r,s,o,u,a;if(!/(38|40|27)/.test(t.keyCode))return;n=e(this),t.preventDefault(),t.stopPropagation();if(n.is(".disabled, :disabled"))return;o=i(n),u=o.hasClass("open");if(!u||u&&t.keyCode==27)return n.click();r=e("[role=menu] li:not(.divider) a",o);if(!r.length)return;a=r.index(r.filter(":focus")),t.keyCode==38&&a>0&&a--,t.keyCode==40&&a