spree_conekta 0.5.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +59 -0
  4. data/Rakefile +24 -0
  5. data/app/assets/javascripts/admin/spree_conekta.js +0 -0
  6. data/app/assets/javascripts/spree_conekta.js +0 -0
  7. data/app/assets/javascripts/store/easyXDM.min.js +25 -0
  8. data/app/assets/javascripts/store/printThis.js +146 -0
  9. data/app/assets/javascripts/store/spree_conekta.js +2 -0
  10. data/app/assets/javascripts/store/utils.js.erb +35 -0
  11. data/app/assets/stylesheets/admin/print.css.sass +12 -0
  12. data/app/assets/stylesheets/admin/spree_conekta.css +3 -0
  13. data/app/assets/stylesheets/spree_conekta.css +3 -0
  14. data/app/assets/stylesheets/store/conekta.css.sass +40 -0
  15. data/app/assets/stylesheets/store/spree_conekta.css +3 -0
  16. data/app/controllers/spree/checkout_controller_decorator.rb +14 -0
  17. data/app/controllers/spree/conekta/payments_controller.rb +20 -0
  18. data/app/models/spree.rb +5 -0
  19. data/app/models/spree/billing_integration/conekta.rb +23 -0
  20. data/app/models/spree/conekta_payment.rb +11 -0
  21. data/app/models/spree/order_decorator.rb +19 -0
  22. data/app/models/spree/payment_decorator.rb +18 -0
  23. data/app/views/spree/admin/payments/_bank.html.erb +32 -0
  24. data/app/views/spree/admin/payments/_cash.html.erb +29 -0
  25. data/app/views/spree/admin/payments/source_forms/_conekta.html.erb +3 -0
  26. data/app/views/spree/admin/payments/source_views/_conekta.html.erb +1 -0
  27. data/app/views/spree/checkout/payment/_conekta.html.erb +3 -0
  28. data/app/views/spree/conekta/payments/_bank.html.erb +30 -0
  29. data/app/views/spree/conekta/payments/_card.html.erb +0 -0
  30. data/app/views/spree/conekta/payments/_cash.html.erb +32 -0
  31. data/app/views/spree/conekta/payments/show.html.erb +14 -0
  32. data/config/locales/en.yml +20 -0
  33. data/config/locales/es-MX.yml +20 -0
  34. data/config/routes.rb +5 -0
  35. data/db/migrate/20130904161251_create_spree_conekta_payments.rb +9 -0
  36. data/db/migrate/20130904172418_rename_type_column_to_conekta_payment.rb +7 -0
  37. data/lib/generators/spree_conekta/install/install_generator.rb +32 -0
  38. data/lib/spree/conekta/client.rb +39 -0
  39. data/lib/spree/conekta/payment_source/bank.rb +11 -0
  40. data/lib/spree/conekta/payment_source/card.rb +23 -0
  41. data/lib/spree/conekta/payment_source/cash.rb +11 -0
  42. data/lib/spree/conekta/provider.rb +40 -0
  43. data/lib/spree/conekta/response.rb +13 -0
  44. data/lib/spree_conekta.rb +8 -0
  45. data/lib/spree_conekta/engine.rb +32 -0
  46. data/lib/spree_conekta/version.rb +3 -0
  47. data/lib/tasks/spree_conekta_tasks.rake +4 -0
  48. metadata +175 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 451684edde4ec353fcda1d5a95510fa0298e17cd
4
+ data.tar.gz: e905ba096e13f41a7159def6806654b4ab414af2
5
+ SHA512:
6
+ metadata.gz: ea6531e0e33c95a4c76fbd870b7b7a28385df4e999076b246847851dfbfa6706953fa22d16e650c5e27f9283a7c34d4edda5cbe76073fe1268b77149dcee6e08
7
+ data.tar.gz: 4afc3472a6ba1ebdcbb83df952ac66caa79315df0dc68042c17de21f73157c0326ce7ba81c9c7af1f0c57db10230377b478e01b87db96d2f47592562d4b90879
@@ -0,0 +1,20 @@
1
+ Copyright 2013 Crowd Interactive
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,59 @@
1
+ # Spree Conekta
2
+ [![Code Climate](https://codeclimate.com/github/crowdint/spree_conekta.png)](https://codeclimate.com/github/crowdint/spree_conekta)
3
+ [![Build Status](https://travis-ci.org/crowdint/spree_conekta.png?branch=conekta-apiv2)](https://travis-ci.org/crowdint/spree_conekta)
4
+
5
+ Setup
6
+ -----
7
+
8
+ Add this extension to your Gemfile:
9
+
10
+ ```ruby
11
+ gem 'spree_conekta', git: 'git://github.com/crowdint/spree_conekta.git'
12
+ ```
13
+
14
+ Then run:
15
+
16
+ ```
17
+ bundle
18
+ rails g spree_conekta:install
19
+ ```
20
+
21
+ ##Setup Conekta Payments
22
+
23
+ 1. You need to go to [Conekta](https://www.conekta.io/), create an account and retrieve your public api key.
24
+
25
+ 2. On the spree application admin side go to:
26
+ ```
27
+ /admin/payment_methods/new
28
+ ```
29
+
30
+ 3. In the provider box, choose:
31
+ ```
32
+ Spree::BillingIntegration::Conekta
33
+ ```
34
+
35
+ 4. On the source method field, add the value of one of the following:
36
+ * card
37
+ * cash
38
+ * bank
39
+
40
+ ###Source Methods
41
+
42
+ Conekta currently supports three different methods:
43
+
44
+ ####Card
45
+ >Card method will let you pay using your credit or debit card. More info: [Conekta Card](https://www.conekta.io/docs/crear_cargo#tarjetas)
46
+
47
+ ####Cash
48
+ >Cash method will generate a bar code with the order information so you'll be able to take it to your nearest OXXO store to pay it. More info: [Conekta Cash](https://www.conekta.io/docs/crear_cargo#oxxo)
49
+
50
+ ####Bank
51
+ >Bank method will let you generate a deposit or transfer reference. More info: [Conekta Bank](https://www.conekta.io/docs/crear_cargo#bancos)
52
+
53
+
54
+ **Important Note:** If you want to support all source methods, you'll need to create a payment method for each one.
55
+
56
+ # About the Author
57
+
58
+ [Crowd Interactive](http://www.crowdint.com) is an American web design and development company that happens to work in Colima, Mexico.
59
+ We specialize in building and growing online retail stores. We don’t work with everyone – just companies we believe in. Call us today to see if there’s a fit.
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ require 'spree/testing_support/common_rake'
10
+
11
+ rescue LoadError
12
+ require 'rdoc/rdoc'
13
+ require 'rake/rdoctask'
14
+ RDoc::Task = Rake::RDocTask
15
+ end
16
+
17
+ Bundler::GemHelper.install_tasks
18
+
19
+ require 'rspec/core'
20
+ require 'rspec/core/rake_task'
21
+
22
+ desc "Run all specs in spec directory (excluding plugin specs)"
23
+ RSpec::Core::RakeTask.new(:spec => 'app:db:test:prepare')
24
+ task :default => :spec
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @license
3
+ * easyXDM
4
+ * http://easyxdm.net/
5
+ * Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ * of this software and associated documentation files (the "Software"), to deal
9
+ * in the Software without restriction, including without limitation the rights
10
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be included in
15
+ * all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ * THE SOFTWARE.
24
+ */
25
+ (function(N,d,p,K,k,H){var b=this;var n=Math.floor(Math.random()*10000);var q=Function.prototype;var Q=/^((http.?:)\/\/([^:\/\s]+)(:\d+)*)/;var R=/[\-\w]+\/\.\.\//;var F=/([^:])\/\//g;var I="";var o={};var M=N.easyXDM;var U="easyXDM_";var E;var y=false;var i;var h;function C(X,Z){var Y=typeof X[Z];return Y=="function"||(!!(Y=="object"&&X[Z]))||Y=="unknown"}function u(X,Y){return !!(typeof(X[Y])=="object"&&X[Y])}function r(X){return Object.prototype.toString.call(X)==="[object Array]"}function c(){var Z="Shockwave Flash",ad="application/x-shockwave-flash";if(!t(navigator.plugins)&&typeof navigator.plugins[Z]=="object"){var ab=navigator.plugins[Z].description;if(ab&&!t(navigator.mimeTypes)&&navigator.mimeTypes[ad]&&navigator.mimeTypes[ad].enabledPlugin){i=ab.match(/\d+/g)}}if(!i){var Y;try{Y=new ActiveXObject("ShockwaveFlash.ShockwaveFlash");i=Array.prototype.slice.call(Y.GetVariable("$version").match(/(\d+),(\d+),(\d+),(\d+)/),1);Y=null}catch(ac){}}if(!i){return false}var X=parseInt(i[0],10),aa=parseInt(i[1],10);h=X>9&&aa>0;return true}var v,x;if(C(N,"addEventListener")){v=function(Z,X,Y){Z.addEventListener(X,Y,false)};x=function(Z,X,Y){Z.removeEventListener(X,Y,false)}}else{if(C(N,"attachEvent")){v=function(X,Z,Y){X.attachEvent("on"+Z,Y)};x=function(X,Z,Y){X.detachEvent("on"+Z,Y)}}else{throw new Error("Browser not supported")}}var W=false,J=[],L;if("readyState" in d){L=d.readyState;W=L=="complete"||(~navigator.userAgent.indexOf("AppleWebKit/")&&(L=="loaded"||L=="interactive"))}else{W=!!d.body}function s(){if(W){return}W=true;for(var X=0;X<J.length;X++){J[X]()}J.length=0}if(!W){if(C(N,"addEventListener")){v(d,"DOMContentLoaded",s)}else{v(d,"readystatechange",function(){if(d.readyState=="complete"){s()}});if(d.documentElement.doScroll&&N===top){var g=function(){if(W){return}try{d.documentElement.doScroll("left")}catch(X){K(g,1);return}s()};g()}}v(N,"load",s)}function G(Y,X){if(W){Y.call(X);return}J.push(function(){Y.call(X)})}function m(){var Z=parent;if(I!==""){for(var X=0,Y=I.split(".");X<Y.length;X++){Z=Z[Y[X]]}}return Z.easyXDM}function e(X){N.easyXDM=M;I=X;if(I){U="easyXDM_"+I.replace(".","_")+"_"}return o}function z(X){return X.match(Q)[3]}function f(X){return X.match(Q)[4]||""}function j(Z){var X=Z.toLowerCase().match(Q);var aa=X[2],ab=X[3],Y=X[4]||"";if((aa=="http:"&&Y==":80")||(aa=="https:"&&Y==":443")){Y=""}return aa+"//"+ab+Y}function B(X){X=X.replace(F,"$1/");if(!X.match(/^(http||https):\/\//)){var Y=(X.substring(0,1)==="/")?"":p.pathname;if(Y.substring(Y.length-1)!=="/"){Y=Y.substring(0,Y.lastIndexOf("/")+1)}X=p.protocol+"//"+p.host+Y+X}while(R.test(X)){X=X.replace(R,"")}return X}function P(X,aa){var ac="",Z=X.indexOf("#");if(Z!==-1){ac=X.substring(Z);X=X.substring(0,Z)}var ab=[];for(var Y in aa){if(aa.hasOwnProperty(Y)){ab.push(Y+"="+H(aa[Y]))}}return X+(y?"#":(X.indexOf("?")==-1?"?":"&"))+ab.join("&")+ac}var S=(function(X){X=X.substring(1).split("&");var Z={},aa,Y=X.length;while(Y--){aa=X[Y].split("=");Z[aa[0]]=k(aa[1])}return Z}(/xdm_e=/.test(p.search)?p.search:p.hash));function t(X){return typeof X==="undefined"}var O=function(){var Y={};var Z={a:[1,2,3]},X='{"a":[1,2,3]}';if(typeof JSON!="undefined"&&typeof JSON.stringify==="function"&&JSON.stringify(Z).replace((/\s/g),"")===X){return JSON}if(Object.toJSON){if(Object.toJSON(Z).replace((/\s/g),"")===X){Y.stringify=Object.toJSON}}if(typeof String.prototype.evalJSON==="function"){Z=X.evalJSON();if(Z.a&&Z.a.length===3&&Z.a[2]===3){Y.parse=function(aa){return aa.evalJSON()}}}if(Y.stringify&&Y.parse){O=function(){return Y};return Y}return null};function T(X,Y,Z){var ab;for(var aa in Y){if(Y.hasOwnProperty(aa)){if(aa in X){ab=Y[aa];if(typeof ab==="object"){T(X[aa],ab,Z)}else{if(!Z){X[aa]=Y[aa]}}}else{X[aa]=Y[aa]}}}return X}function a(){var Y=d.body.appendChild(d.createElement("form")),X=Y.appendChild(d.createElement("input"));X.name=U+"TEST"+n;E=X!==Y.elements[X.name];d.body.removeChild(Y)}function A(Y){if(t(E)){a()}var ac;if(E){ac=d.createElement('<iframe name="'+Y.props.name+'"/>')}else{ac=d.createElement("IFRAME");ac.name=Y.props.name}ac.id=ac.name=Y.props.name;delete Y.props.name;if(typeof Y.container=="string"){Y.container=d.getElementById(Y.container)}if(!Y.container){T(ac.style,{position:"absolute",top:"-2000px",left:"0px"});Y.container=d.body}var ab=Y.props.src;Y.props.src="javascript:false";T(ac,Y.props);ac.border=ac.frameBorder=0;ac.allowTransparency=true;Y.container.appendChild(ac);if(Y.onLoad){v(ac,"load",Y.onLoad)}if(Y.usePost){var aa=Y.container.appendChild(d.createElement("form")),X;aa.target=ac.name;aa.action=ab;aa.method="POST";if(typeof(Y.usePost)==="object"){for(var Z in Y.usePost){if(Y.usePost.hasOwnProperty(Z)){if(E){X=d.createElement('<input name="'+Z+'"/>')}else{X=d.createElement("INPUT");X.name=Z}X.value=Y.usePost[Z];aa.appendChild(X)}}}aa.submit();aa.parentNode.removeChild(aa)}else{ac.src=ab}Y.props.src=ab;return ac}function V(aa,Z){if(typeof aa=="string"){aa=[aa]}var Y,X=aa.length;while(X--){Y=aa[X];Y=new RegExp(Y.substr(0,1)=="^"?Y:("^"+Y.replace(/(\*)/g,".$1").replace(/\?/g,".")+"$"));if(Y.test(Z)){return true}}return false}function l(Z){var ae=Z.protocol,Y;Z.isHost=Z.isHost||t(S.xdm_p);y=Z.hash||false;if(!Z.props){Z.props={}}if(!Z.isHost){Z.channel=S.xdm_c.replace(/["'<>\\]/g,"");Z.secret=S.xdm_s;Z.remote=S.xdm_e.replace(/["'<>\\]/g,"");ae=S.xdm_p;if(Z.acl&&!V(Z.acl,Z.remote)){throw new Error("Access denied for "+Z.remote)}}else{Z.remote=B(Z.remote);Z.channel=Z.channel||"default"+n++;Z.secret=Math.random().toString(16).substring(2);if(t(ae)){if(j(p.href)==j(Z.remote)){ae="4"}else{if(C(N,"postMessage")||C(d,"postMessage")){ae="1"}else{if(Z.swf&&C(N,"ActiveXObject")&&c()){ae="6"}else{if(navigator.product==="Gecko"&&"frameElement" in N&&navigator.userAgent.indexOf("WebKit")==-1){ae="5"}else{if(Z.remoteHelper){ae="2"}else{ae="0"}}}}}}}Z.protocol=ae;switch(ae){case"0":T(Z,{interval:100,delay:2000,useResize:true,useParent:false,usePolling:false},true);if(Z.isHost){if(!Z.local){var ac=p.protocol+"//"+p.host,X=d.body.getElementsByTagName("img"),ad;var aa=X.length;while(aa--){ad=X[aa];if(ad.src.substring(0,ac.length)===ac){Z.local=ad.src;break}}if(!Z.local){Z.local=N}}var ab={xdm_c:Z.channel,xdm_p:0};if(Z.local===N){Z.usePolling=true;Z.useParent=true;Z.local=p.protocol+"//"+p.host+p.pathname+p.search;ab.xdm_e=Z.local;ab.xdm_pa=1}else{ab.xdm_e=B(Z.local)}if(Z.container){Z.useResize=false;ab.xdm_po=1}Z.remote=P(Z.remote,ab)}else{T(Z,{channel:S.xdm_c,remote:S.xdm_e,useParent:!t(S.xdm_pa),usePolling:!t(S.xdm_po),useResize:Z.useParent?false:Z.useResize})}Y=[new o.stack.HashTransport(Z),new o.stack.ReliableBehavior({}),new o.stack.QueueBehavior({encode:true,maxLength:4000-Z.remote.length}),new o.stack.VerifyBehavior({initiate:Z.isHost})];break;case"1":Y=[new o.stack.PostMessageTransport(Z)];break;case"2":Z.remoteHelper=B(Z.remoteHelper);Y=[new o.stack.NameTransport(Z),new o.stack.QueueBehavior(),new o.stack.VerifyBehavior({initiate:Z.isHost})];break;case"3":Y=[new o.stack.NixTransport(Z)];break;case"4":Y=[new o.stack.SameOriginTransport(Z)];break;case"5":Y=[new o.stack.FrameElementTransport(Z)];break;case"6":if(!i){c()}Y=[new o.stack.FlashTransport(Z)];break}Y.push(new o.stack.QueueBehavior({lazy:Z.lazy,remove:true}));return Y}function D(aa){var ab,Z={incoming:function(ad,ac){this.up.incoming(ad,ac)},outgoing:function(ac,ad){this.down.outgoing(ac,ad)},callback:function(ac){this.up.callback(ac)},init:function(){this.down.init()},destroy:function(){this.down.destroy()}};for(var Y=0,X=aa.length;Y<X;Y++){ab=aa[Y];T(ab,Z,true);if(Y!==0){ab.down=aa[Y-1]}if(Y!==X-1){ab.up=aa[Y+1]}}return ab}function w(X){X.up.down=X.down;X.down.up=X.up;X.up=X.down=null}T(o,{version:"2.4.17.1",query:S,stack:{},apply:T,getJSONObject:O,whenReady:G,noConflict:e});o.DomHelper={on:v,un:x,requiresJSON:function(X){if(!u(N,"JSON")){d.write('<script type="text/javascript" src="'+X+'"><\/script>')}}};(function(){var X={};o.Fn={set:function(Y,Z){X[Y]=Z},get:function(Z,Y){var aa=X[Z];if(Y){delete X[Z]}return aa}}}());o.Socket=function(Y){var X=D(l(Y).concat([{incoming:function(ab,aa){Y.onMessage(ab,aa)},callback:function(aa){if(Y.onReady){Y.onReady(aa)}}}])),Z=j(Y.remote);this.origin=j(Y.remote);this.destroy=function(){X.destroy()};this.postMessage=function(aa){X.outgoing(aa,Z)};X.init()};o.Rpc=function(Z,Y){if(Y.local){for(var ab in Y.local){if(Y.local.hasOwnProperty(ab)){var aa=Y.local[ab];if(typeof aa==="function"){Y.local[ab]={method:aa}}}}}var X=D(l(Z).concat([new o.stack.RpcBehavior(this,Y),{callback:function(ac){if(Z.onReady){Z.onReady(ac)}}}]));this.origin=j(Z.remote);this.destroy=function(){X.destroy()};X.init()};o.stack.SameOriginTransport=function(Y){var Z,ab,aa,X;return(Z={outgoing:function(ad,ae,ac){aa(ad);if(ac){ac()}},destroy:function(){if(ab){ab.parentNode.removeChild(ab);ab=null}},onDOMReady:function(){X=j(Y.remote);if(Y.isHost){T(Y.props,{src:P(Y.remote,{xdm_e:p.protocol+"//"+p.host+p.pathname,xdm_c:Y.channel,xdm_p:4}),name:U+Y.channel+"_provider"});ab=A(Y);o.Fn.set(Y.channel,function(ac){aa=ac;K(function(){Z.up.callback(true)},0);return function(ad){Z.up.incoming(ad,X)}})}else{aa=m().Fn.get(Y.channel,true)(function(ac){Z.up.incoming(ac,X)});K(function(){Z.up.callback(true)},0)}},init:function(){G(Z.onDOMReady,Z)}})};o.stack.FlashTransport=function(aa){var ac,X,ab,ad,Y,ae;function af(ah,ag){K(function(){ac.up.incoming(ah,ad)},0)}function Z(ah){var ag=aa.swf+"?host="+aa.isHost;var aj="easyXDM_swf_"+Math.floor(Math.random()*10000);o.Fn.set("flash_loaded"+ah.replace(/[\-.]/g,"_"),function(){o.stack.FlashTransport[ah].swf=Y=ae.firstChild;var ak=o.stack.FlashTransport[ah].queue;for(var al=0;al<ak.length;al++){ak[al]()}ak.length=0});if(aa.swfContainer){ae=(typeof aa.swfContainer=="string")?d.getElementById(aa.swfContainer):aa.swfContainer}else{ae=d.createElement("div");T(ae.style,h&&aa.swfNoThrottle?{height:"20px",width:"20px",position:"fixed",right:0,top:0}:{height:"1px",width:"1px",position:"absolute",overflow:"hidden",right:0,top:0});d.body.appendChild(ae)}var ai="callback=flash_loaded"+ah.replace(/[\-.]/g,"_")+"&proto="+b.location.protocol+"&domain="+z(b.location.href)+"&port="+f(b.location.href)+"&ns="+I;ae.innerHTML="<object height='20' width='20' type='application/x-shockwave-flash' id='"+aj+"' data='"+ag+"'><param name='allowScriptAccess' value='always'></param><param name='wmode' value='transparent'><param name='movie' value='"+ag+"'></param><param name='flashvars' value='"+ai+"'></param><embed type='application/x-shockwave-flash' FlashVars='"+ai+"' allowScriptAccess='always' wmode='transparent' src='"+ag+"' height='1' width='1'></embed></object>"}return(ac={outgoing:function(ah,ai,ag){Y.postMessage(aa.channel,ah.toString());if(ag){ag()}},destroy:function(){try{Y.destroyChannel(aa.channel)}catch(ag){}Y=null;if(X){X.parentNode.removeChild(X);X=null}},onDOMReady:function(){ad=aa.remote;o.Fn.set("flash_"+aa.channel+"_init",function(){K(function(){ac.up.callback(true)})});o.Fn.set("flash_"+aa.channel+"_onMessage",af);aa.swf=B(aa.swf);var ah=z(aa.swf);var ag=function(){o.stack.FlashTransport[ah].init=true;Y=o.stack.FlashTransport[ah].swf;Y.createChannel(aa.channel,aa.secret,j(aa.remote),aa.isHost);if(aa.isHost){if(h&&aa.swfNoThrottle){T(aa.props,{position:"fixed",right:0,top:0,height:"20px",width:"20px"})}T(aa.props,{src:P(aa.remote,{xdm_e:j(p.href),xdm_c:aa.channel,xdm_p:6,xdm_s:aa.secret}),name:U+aa.channel+"_provider"});X=A(aa)}};if(o.stack.FlashTransport[ah]&&o.stack.FlashTransport[ah].init){ag()}else{if(!o.stack.FlashTransport[ah]){o.stack.FlashTransport[ah]={queue:[ag]};Z(ah)}else{o.stack.FlashTransport[ah].queue.push(ag)}}},init:function(){G(ac.onDOMReady,ac)}})};o.stack.PostMessageTransport=function(aa){var ac,ad,Y,Z;function X(ae){if(ae.origin){return j(ae.origin)}if(ae.uri){return j(ae.uri)}if(ae.domain){return p.protocol+"//"+ae.domain}throw"Unable to retrieve the origin of the event"}function ab(af){var ae=X(af);if(ae==Z&&af.data.substring(0,aa.channel.length+1)==aa.channel+" "){ac.up.incoming(af.data.substring(aa.channel.length+1),ae)}}return(ac={outgoing:function(af,ag,ae){Y.postMessage(aa.channel+" "+af,ag||Z);if(ae){ae()}},destroy:function(){x(N,"message",ab);if(ad){Y=null;ad.parentNode.removeChild(ad);ad=null}},onDOMReady:function(){Z=j(aa.remote);if(aa.isHost){var ae=function(af){if(af.data==aa.channel+"-ready"){Y=("postMessage" in ad.contentWindow)?ad.contentWindow:ad.contentWindow.document;x(N,"message",ae);v(N,"message",ab);K(function(){ac.up.callback(true)},0)}};v(N,"message",ae);T(aa.props,{src:P(aa.remote,{xdm_e:j(p.href),xdm_c:aa.channel,xdm_p:1}),name:U+aa.channel+"_provider"});ad=A(aa)}else{v(N,"message",ab);Y=("postMessage" in N.parent)?N.parent:N.parent.document;Y.postMessage(aa.channel+"-ready",Z);K(function(){ac.up.callback(true)},0)}},init:function(){G(ac.onDOMReady,ac)}})};o.stack.FrameElementTransport=function(Y){var Z,ab,aa,X;return(Z={outgoing:function(ad,ae,ac){aa.call(this,ad);if(ac){ac()}},destroy:function(){if(ab){ab.parentNode.removeChild(ab);ab=null}},onDOMReady:function(){X=j(Y.remote);if(Y.isHost){T(Y.props,{src:P(Y.remote,{xdm_e:j(p.href),xdm_c:Y.channel,xdm_p:5}),name:U+Y.channel+"_provider"});ab=A(Y);ab.fn=function(ac){delete ab.fn;aa=ac;K(function(){Z.up.callback(true)},0);return function(ad){Z.up.incoming(ad,X)}}}else{if(d.referrer&&j(d.referrer)!=S.xdm_e){N.top.location=S.xdm_e}aa=N.frameElement.fn(function(ac){Z.up.incoming(ac,X)});Z.up.callback(true)}},init:function(){G(Z.onDOMReady,Z)}})};o.stack.NameTransport=function(ab){var ac;var ae,ai,aa,ag,ah,Y,X;function af(al){var ak=ab.remoteHelper+(ae?"#_3":"#_2")+ab.channel;ai.contentWindow.sendMessage(al,ak)}function ad(){if(ae){if(++ag===2||!ae){ac.up.callback(true)}}else{af("ready");ac.up.callback(true)}}function aj(ak){ac.up.incoming(ak,Y)}function Z(){if(ah){K(function(){ah(true)},0)}}return(ac={outgoing:function(al,am,ak){ah=ak;af(al)},destroy:function(){ai.parentNode.removeChild(ai);ai=null;if(ae){aa.parentNode.removeChild(aa);aa=null}},onDOMReady:function(){ae=ab.isHost;ag=0;Y=j(ab.remote);ab.local=B(ab.local);if(ae){o.Fn.set(ab.channel,function(al){if(ae&&al==="ready"){o.Fn.set(ab.channel,aj);ad()}});X=P(ab.remote,{xdm_e:ab.local,xdm_c:ab.channel,xdm_p:2});T(ab.props,{src:X+"#"+ab.channel,name:U+ab.channel+"_provider"});aa=A(ab)}else{ab.remoteHelper=ab.remote;o.Fn.set(ab.channel,aj)}var ak=function(){var al=ai||this;x(al,"load",ak);o.Fn.set(ab.channel+"_load",Z);(function am(){if(typeof al.contentWindow.sendMessage=="function"){ad()}else{K(am,50)}}())};ai=A({props:{src:ab.local+"#_4"+ab.channel},onLoad:ak})},init:function(){G(ac.onDOMReady,ac)}})};o.stack.HashTransport=function(Z){var ac;var ah=this,af,aa,X,ad,am,ab,al;var ag,Y;function ak(ao){if(!al){return}var an=Z.remote+"#"+(am++)+"_"+ao;((af||!ag)?al.contentWindow:al).location=an}function ae(an){ad=an;ac.up.incoming(ad.substring(ad.indexOf("_")+1),Y)}function aj(){if(!ab){return}var an=ab.location.href,ap="",ao=an.indexOf("#");if(ao!=-1){ap=an.substring(ao)}if(ap&&ap!=ad){ae(ap)}}function ai(){aa=setInterval(aj,X)}return(ac={outgoing:function(an,ao){ak(an)},destroy:function(){N.clearInterval(aa);if(af||!ag){al.parentNode.removeChild(al)}al=null},onDOMReady:function(){af=Z.isHost;X=Z.interval;ad="#"+Z.channel;am=0;ag=Z.useParent;Y=j(Z.remote);if(af){T(Z.props,{src:Z.remote,name:U+Z.channel+"_provider"});if(ag){Z.onLoad=function(){ab=N;ai();ac.up.callback(true)}}else{var ap=0,an=Z.delay/50;(function ao(){if(++ap>an){throw new Error("Unable to reference listenerwindow")}try{ab=al.contentWindow.frames[U+Z.channel+"_consumer"]}catch(aq){}if(ab){ai();ac.up.callback(true)}else{K(ao,50)}}())}al=A(Z)}else{ab=N;ai();if(ag){al=parent;ac.up.callback(true)}else{T(Z,{props:{src:Z.remote+"#"+Z.channel+new Date(),name:U+Z.channel+"_consumer"},onLoad:function(){ac.up.callback(true)}});al=A(Z)}}},init:function(){G(ac.onDOMReady,ac)}})};o.stack.ReliableBehavior=function(Y){var aa,ac;var ab=0,X=0,Z="";return(aa={incoming:function(af,ad){var ae=af.indexOf("_"),ag=af.substring(0,ae).split(",");af=af.substring(ae+1);if(ag[0]==ab){Z="";if(ac){ac(true);ac=null}}if(af.length>0){aa.down.outgoing(ag[1]+","+ab+"_"+Z,ad);if(X!=ag[1]){X=ag[1];aa.up.incoming(af,ad)}}},outgoing:function(af,ad,ae){Z=af;ac=ae;aa.down.outgoing(X+","+(++ab)+"_"+af,ad)}})};o.stack.QueueBehavior=function(Z){var ac,ad=[],ag=true,aa="",af,X=0,Y=false,ab=false;function ae(){if(Z.remove&&ad.length===0){w(ac);return}if(ag||ad.length===0||af){return}ag=true;var ah=ad.shift();ac.down.outgoing(ah.data,ah.origin,function(ai){ag=false;if(ah.callback){K(function(){ah.callback(ai)},0)}ae()})}return(ac={init:function(){if(t(Z)){Z={}}if(Z.maxLength){X=Z.maxLength;ab=true}if(Z.lazy){Y=true}else{ac.down.init()}},callback:function(ai){ag=false;var ah=ac.up;ae();ah.callback(ai)},incoming:function(ak,ai){if(ab){var aj=ak.indexOf("_"),ah=parseInt(ak.substring(0,aj),10);aa+=ak.substring(aj+1);if(ah===0){if(Z.encode){aa=k(aa)}ac.up.incoming(aa,ai);aa=""}}else{ac.up.incoming(ak,ai)}},outgoing:function(al,ai,ak){if(Z.encode){al=H(al)}var ah=[],aj;if(ab){while(al.length!==0){aj=al.substring(0,X);al=al.substring(aj.length);ah.push(aj)}while((aj=ah.shift())){ad.push({data:ah.length+"_"+aj,origin:ai,callback:ah.length===0?ak:null})}}else{ad.push({data:al,origin:ai,callback:ak})}if(Y){ac.down.init()}else{ae()}},destroy:function(){af=true;ac.down.destroy()}})};o.stack.VerifyBehavior=function(ab){var ac,aa,Y,Z=false;function X(){aa=Math.random().toString(16).substring(2);ac.down.outgoing(aa)}return(ac={incoming:function(af,ad){var ae=af.indexOf("_");if(ae===-1){if(af===aa){ac.up.callback(true)}else{if(!Y){Y=af;if(!ab.initiate){X()}ac.down.outgoing(af)}}}else{if(af.substring(0,ae)===Y){ac.up.incoming(af.substring(ae+1),ad)}}},outgoing:function(af,ad,ae){ac.down.outgoing(aa+"_"+af,ad,ae)},callback:function(ad){if(ab.initiate){X()}}})};o.stack.RpcBehavior=function(ad,Y){var aa,af=Y.serializer||O();var ae=0,ac={};function X(ag){ag.jsonrpc="2.0";aa.down.outgoing(af.stringify(ag))}function ab(ag,ai){var ah=Array.prototype.slice;return function(){var aj=arguments.length,al,ak={method:ai};if(aj>0&&typeof arguments[aj-1]==="function"){if(aj>1&&typeof arguments[aj-2]==="function"){al={success:arguments[aj-2],error:arguments[aj-1]};ak.params=ah.call(arguments,0,aj-2)}else{al={success:arguments[aj-1]};ak.params=ah.call(arguments,0,aj-1)}ac[""+(++ae)]=al;ak.id=ae}else{ak.params=ah.call(arguments,0)}if(ag.namedParams&&ak.params.length===1){ak.params=ak.params[0]}X(ak)}}function Z(an,am,ai,al){if(!ai){if(am){X({id:am,error:{code:-32601,message:"Procedure not found."}})}return}var ak,ah;if(am){ak=function(ao){ak=q;X({id:am,result:ao})};ah=function(ao,ap){ah=q;var aq={id:am,error:{code:-32099,message:ao}};if(ap){aq.error.data=ap}X(aq)}}else{ak=ah=q}if(!r(al)){al=[al]}try{var ag=ai.method.apply(ai.scope,al.concat([ak,ah]));if(!t(ag)){ak(ag)}}catch(aj){ah(aj.message)}}return(aa={incoming:function(ah,ag){var ai=af.parse(ah);if(ai.method){if(Y.handle){Y.handle(ai,X)}else{Z(ai.method,ai.id,Y.local[ai.method],ai.params)}}else{var aj=ac[ai.id];if(ai.error){if(aj.error){aj.error(ai.error)}}else{if(aj.success){aj.success(ai.result)}}delete ac[ai.id]}},init:function(){if(Y.remote){for(var ag in Y.remote){if(Y.remote.hasOwnProperty(ag)){ad[ag]=ab(Y.remote[ag],ag)}}}aa.down.init()},destroy:function(){for(var ag in Y.remote){if(Y.remote.hasOwnProperty(ag)&&ad.hasOwnProperty(ag)){delete ad[ag]}}aa.down.destroy()}})};b.easyXDM=o})(window,document,location,window.setTimeout,decodeURIComponent,encodeURIComponent);
@@ -0,0 +1,146 @@
1
+ /*
2
+ * printThis v1.2
3
+ * @desc Printing plug-in for jQuery
4
+ * @author Jason Day
5
+ *
6
+ * Resources (based on) :
7
+ * jPrintArea: http://plugins.jquery.com/project/jPrintArea
8
+ * jqPrint: https://github.com/permanenttourist/jquery.jqprint
9
+ * Ben Nadal: http://www.bennadel.com/blog/1591-Ask-Ben-Print-Part-Of-A-Web-Page-With-jQuery.htm
10
+ *
11
+ * Dual licensed under the MIT and GPL licenses:
12
+ * http://www.opensource.org/licenses/mit-license.php
13
+ * http://www.gnu.org/licenses/gpl.html
14
+ *
15
+ * (c) Jason Day 2013
16
+ *
17
+ * Usage:
18
+ *
19
+ * $("#mySelector").printThis({
20
+ * debug: false, * show the iframe for debugging
21
+ * importCSS: true, * import page CSS
22
+ * printContainer: true, * grab outer container as well as the contents of the selector
23
+ * loadCSS: "path/to/my.css", * path to additional css file
24
+ * pageTitle: "", * add title to print page
25
+ * removeInline: false * remove all inline styles from print elements
26
+ * });
27
+ *
28
+ * Notes:
29
+ * - the loadCSS will load additional css (with or without @media print) into the iframe, adjusting layout
30
+ */
31
+ ;(function ($) {
32
+ var opt;
33
+ $.fn.printThis = function (options) {
34
+ opt = $.extend({}, $.fn.printThis.defaults, options);
35
+ var $element = this instanceof jQuery ? this : $(this);
36
+
37
+ var strFrameName = "printThis-" + (new Date()).getTime();
38
+
39
+ if(window.location.hostname !== document.domain && navigator.userAgent.match(/msie/i)){
40
+ // Ugly IE hacks due to IE not inheriting document.domain from parent
41
+ // checks if document.domain is set by comparing the host name against document.domain
42
+ var iframeSrc = "javascript:document.write(\"<head><script>document.domain=\\\"" + document.domain + "\\\";</script></head><body></body>\")";
43
+ var printI= document.createElement('iframe');
44
+ printI.name = "printIframe";
45
+ printI.id = strFrameName;
46
+ printI.className = "MSIE";
47
+ document.body.appendChild(printI);
48
+ printI.src = iframeSrc;
49
+
50
+ } else {
51
+ // other browsers inherit document.domain, and IE works if document.domain is not explicitly set
52
+ var $frame = $("<iframe id='" + strFrameName +"' name='printIframe' />");
53
+ $frame.appendTo("body");
54
+ }
55
+
56
+
57
+ var $iframe = $("#" + strFrameName);
58
+
59
+ // show frame if in debug mode
60
+ if (!opt.debug) $iframe.css({
61
+ position: "absolute",
62
+ width: "0px",
63
+ height: "0px",
64
+ left: "-600px",
65
+ top: "-600px"
66
+ });
67
+
68
+
69
+ // $iframe.ready() and $iframe.load were inconsistent between browsers
70
+ setTimeout ( function () {
71
+
72
+ var $doc = $iframe.contents();
73
+
74
+ // import page stylesheets
75
+ if (opt.importCSS) $("link[rel=stylesheet]").each(function () {
76
+ var href = $(this).attr("href");
77
+ if (href) {
78
+ var media = $(this).attr("media") || "all";
79
+ $doc.find("head").append("<link type='text/css' rel='stylesheet' href='" + href + "' media='" + media + "'>")
80
+ }
81
+ });
82
+
83
+ //add title of the page
84
+ if (opt.pageTitle) $doc.find("head").append("<title>" + opt.pageTitle + "</title>");
85
+
86
+ // import additional stylesheet
87
+ if (opt.loadCSS) $doc.find("head").append("<link type='text/css' rel='stylesheet' href='" + opt.loadCSS + "'>");
88
+
89
+ // grab $.selector as container
90
+ if (opt.printContainer) $doc.find("body").append($element.outer());
91
+
92
+ // otherwise just print interior elements of container
93
+ else $element.each(function () {
94
+ $doc.find("body").append($(this).html())
95
+ });
96
+
97
+ // remove inline styles
98
+ if (opt.removeInline) {
99
+ // $.removeAttr available jQuery 1.7+
100
+ if ($.isFunction($.removeAttr)) {
101
+ $doc.find("body *").removeAttr("style");
102
+ } else {
103
+ $doc.find("body *").attr("style", "");
104
+ }
105
+ }
106
+
107
+ setTimeout(function () {
108
+ if($iframe.hasClass("MSIE")){
109
+ // check if the iframe was created with the ugly hack
110
+ // and perform another ugly hack out of neccessity
111
+ window.frames["printIframe"].focus();
112
+ $doc.find("head").append("<script> window.print(); </script>");
113
+ } else {
114
+ // proper method
115
+ $iframe[0].contentWindow.focus();
116
+ $iframe[0].contentWindow.print();
117
+ }
118
+
119
+ //remove iframe after print
120
+ if (!opt.debug) {
121
+ setTimeout(function () {
122
+ $iframe.remove();
123
+ }, 1000);
124
+ }
125
+
126
+ }, 333);
127
+
128
+ }, 333 );
129
+
130
+ };
131
+
132
+ // defaults
133
+ $.fn.printThis.defaults = {
134
+ debug: false, // show the iframe for debugging
135
+ importCSS: true, // import parent page css
136
+ printContainer: true, // print outer container/$.selector
137
+ loadCSS: "", // load an additional css file
138
+ pageTitle: "", // add title to print page
139
+ removeInline: false // remove all inline styles
140
+ };
141
+
142
+ // $.selector container
143
+ jQuery.fn.outer = function () {
144
+ return $($("<div></div>").html(this.clone())).html()
145
+ }
146
+ })(jQuery);
@@ -0,0 +1,2 @@
1
+ //
2
+ //= require_tree .
@@ -0,0 +1,35 @@
1
+ window.spreeConekta || (window.spreeConekta = {})
2
+
3
+ spreeConekta.Utils = (function(){
4
+ function Utils(args) {
5
+ this.printable = args.printable;
6
+ this.options = args.options;
7
+ if (args.trigger) {
8
+ this.setup(args.trigger)
9
+ };
10
+ };
11
+
12
+ Utils.prototype.print = function (){
13
+ this.printable.printThis(this.options);
14
+ };
15
+
16
+ Utils.prototype.setup = function(trigger) {
17
+ _this_ = this;
18
+ trigger.on('click', function(event){
19
+ event.preventDefault();
20
+ _this_.print();
21
+ })
22
+ };
23
+
24
+
25
+ return Utils;
26
+ })();
27
+
28
+
29
+ function printDoc(printable) {
30
+ printer = new spreeConekta.Utils({
31
+ printable: $(printable),
32
+ options: { loadCSS: "<%= asset_path('admin/print.css.sass') %>" }
33
+ });
34
+ printer.print();
35
+ };
@@ -0,0 +1,12 @@
1
+ @media print
2
+ .conekta-oxxo
3
+ width: 100px
4
+
5
+ .order-title, .order-footer
6
+ display: none
7
+
8
+ .print
9
+ border: 1px solid black
10
+
11
+ .title
12
+ border-bottom: 1px solid black
@@ -0,0 +1,3 @@
1
+ /*
2
+ *= require_tree .
3
+ */
@@ -0,0 +1,3 @@
1
+ /*
2
+ *= require_tree .
3
+ */
@@ -0,0 +1,40 @@
1
+ .align-right
2
+ text-align: right
3
+
4
+ .align-center
5
+ text-align: center
6
+
7
+ .conekta-brand
8
+ float: left
9
+
10
+ .conekta-oxxo
11
+ width: 100px
12
+ display: inline
13
+
14
+ .order-footer
15
+ border-top: 1px solid #cee1f4
16
+ margin-top: 20px
17
+ padding-top: 10px
18
+
19
+ .order-title
20
+ margin-bottom: 20px
21
+ border-bottom: 1px solid #cee1f4
22
+
23
+ .payment-title
24
+ padding: 10px 0
25
+ clear: both
26
+
27
+ table.payment-information
28
+ width: 100%
29
+ thead
30
+ background-color: #cee1f4
31
+
32
+ #barcode
33
+ padding: 20px
34
+
35
+ #order_payment
36
+ padding: 20px
37
+
38
+ #oxxo-title
39
+ display: inline
40
+
@@ -0,0 +1,3 @@
1
+ /*
2
+ *= require_tree .
3
+ */
@@ -0,0 +1,14 @@
1
+ module Spree
2
+ CheckoutController.class_eval do
3
+ def completion_route
4
+ payment_method = @order.payments.last.payment_method
5
+
6
+ if payment_method.class == Spree::BillingIntegration::Conekta || !payment_method.preferred_source_method == 'card'
7
+ conekta_payment_path(@order)
8
+ else
9
+ @order.payments.last.complete if payment_method.preferred_source_method == 'card'
10
+ spree.order_path(@order)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,20 @@
1
+ module Spree::Conekta
2
+ class PaymentsController < Spree::StoreController
3
+ ssl_required
4
+
5
+ def show
6
+ @order = Spree::Order.find_by_number(params[:id])
7
+ @order_details = @order.last_payment_details.params
8
+ end
9
+
10
+ def create
11
+ update_order_payment if params['type'].eql? 'charge.paid'
12
+ render nothing: true
13
+ end
14
+
15
+ private
16
+ def update_order_payment
17
+ Spree::Payment.capture_by_order_id params['data']['object']['reference_id']
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,5 @@
1
+ module Spree
2
+ def self.table_name_prefix
3
+ 'spree_'
4
+ end
5
+ end
@@ -0,0 +1,23 @@
1
+ module Spree
2
+ class BillingIntegration::Conekta < Gateway
3
+ preference :auth_token, :string
4
+ preference :source_method, :string, default: ['card, cash, bank']
5
+
6
+ def provider_class
7
+ Spree::Conekta::Provider
8
+ end
9
+
10
+ def payment_source_class
11
+ card? ? CreditCard : Spree::ConektaPayment
12
+ end
13
+
14
+ def method_type
15
+ card? ? 'gateway' : 'conekta'
16
+ end
17
+
18
+ def card?
19
+ preferred_source_method.eql?('card')
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,11 @@
1
+ class Spree::ConektaPayment < ActiveRecord::Base
2
+ has_many :payments, as: :source
3
+
4
+ def actions
5
+ %w{capture}
6
+ end
7
+
8
+ def can_capture?(payment)
9
+ ['checkout', 'pending'].include?(payment.state)
10
+ end
11
+ end
@@ -0,0 +1,19 @@
1
+ module Spree
2
+ Order.class_eval do
3
+ #HACK
4
+ Spree::Conekta
5
+ Spree::Conekta::Response
6
+ Spree::Conekta::PaymentSource
7
+ Spree::Conekta::PaymentSource::Card
8
+ Spree::Conekta::PaymentSource::Bank
9
+ Spree::Conekta::PaymentSource::Cash
10
+
11
+ def last_payment_details
12
+ YAML.load payments.last.log_entries.last.details
13
+ end
14
+
15
+ def last_payment_source
16
+ payments.last.payment_method_source
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ module Spree
2
+ Payment.class_eval do
3
+ def payment_method_source
4
+ payment_method.options[:source_method]
5
+ end
6
+
7
+ def self.find_by_order_id(order_id)
8
+ Spree::Payment.joins(:order)
9
+ .where(state: 'pending', spree_orders: {
10
+ number: order_id
11
+ }).readonly(false).first
12
+ end
13
+
14
+ def self.capture_by_order_id(order_id)
15
+ Spree::Payment.find_by_order_id(order_id.split('-')[0]).try(:capture!)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,32 @@
1
+ <%- @order_details = @order.last_payment_details.params %>
2
+
3
+ <table class='print' id='conekta_bank'>
4
+ <thead>
5
+ <tr>
6
+ <th class='title' colspan='2'> <%= t('conekta.order_number', number: @order.number) %> </th>
7
+ </tr>
8
+ <tr>
9
+ <th> <%= t('conekta.bank.service_number') %> </th>
10
+ <th> <%= t('conekta.bank.reference') %> </th>
11
+ </tr>
12
+ </thead>
13
+ <tfoot>
14
+ <tr>
15
+ <td colspan='2'> <%= raw t('conekta.bank.payment_message') %> </td>
16
+ </tr>
17
+ </tfoot>
18
+ <tbody>
19
+ <tr>
20
+ <td class='align-center'> <%= @order_details['bank']['service_number'] %> </td>
21
+ <td class='align-center'> <%= @order_details['bank']['reference'] %> </td>
22
+ </tr>
23
+ <tr>
24
+ <td class='align-right'> <%= t('conekta.total') %> </td>
25
+ <td class='align-center'><%= money(@order.total) %></td>
26
+ </tr>
27
+ </tbody>
28
+ </table>
29
+
30
+ <a id='pbutton' href='#' class='icon-print' onclick='printDoc("#conekta_bank")'>
31
+ <%= t('conekta.cash.print_payment_form') %>
32
+ </a>
@@ -0,0 +1,29 @@
1
+ <%- @order_details = @order.last_payment_details.params %>
2
+
3
+ <table class='print' id='conekta_cash'>
4
+ <thead>
5
+ <tr>
6
+ <th class='title' colspan='2'> <%= t('conekta.order_number', number: @order.number) %> </th>
7
+ </tr>
8
+ <tr>
9
+ <th> <%= t('conekta.cash.bar_code') %> </th>
10
+ </tr>
11
+ </thead>
12
+ <tfoot>
13
+ <tr>
14
+ <td colspan='2'> <%= raw t('conekta.cash.payment_message') %> </td>
15
+ </tr>
16
+ </tfoot>
17
+ <tbody>
18
+ <tr>
19
+ <td class='align-center'>
20
+ <%= image_tag(@order_details['cash']['barcode_url']) %>
21
+ <div><%= @order_details['cash']['barcode'] %></div>
22
+ </td>
23
+ </tr>
24
+ </tbody>
25
+ </table>
26
+
27
+ <a id='pbutton' href='#' class='icon-print' onclick='printDoc("#conekta_cash")'>
28
+ <%= t('conekta.cash.print_payment_form') %>
29
+ </a>
@@ -0,0 +1,3 @@
1
+ <% param_prefix = "payment_source[#{payment_method.id}]" %>
2
+ <%= hidden_field param_prefix, 'first_name', :value => @order.billing_firstname %>
3
+ <%= hidden_field param_prefix, 'last_name', :value => @order.billing_lastname %>
@@ -0,0 +1 @@
1
+ <%= render partial: @order.last_payment_source %>
@@ -0,0 +1,3 @@
1
+ <% param_prefix = "payment_source[#{payment_method.id}]" %>
2
+ <%= hidden_field param_prefix, 'first_name', :value => @order.billing_firstname %>
3
+ <%= hidden_field param_prefix, 'last_name', :value => @order.billing_lastname %>
@@ -0,0 +1,30 @@
1
+ <h1><%= t('conekta.bank.payment_title') %></h1>
2
+
3
+ <table id='conekta_bank' class='payment-information'>
4
+ <thead>
5
+ <tr>
6
+ <th colspan='2'> <%= t('conekta.order_number', number: @order.number) %> </th>
7
+ </tr>
8
+ <tr>
9
+ <th> <%= t('conekta.bank.service_number') %> </th>
10
+ <th> <%= t('conekta.bank.reference') %> </th>
11
+ </tr>
12
+ </thead>
13
+ <tfoot>
14
+ <tr>
15
+ <td colspan='2'> <%= raw t('conekta.bank.payment_message') %> </td>
16
+ </tr>
17
+ </tfoot>
18
+ <tbody>
19
+ <tr>
20
+ <td class='align-center'> <%= @order_details['payment_method']['service_number'] %> </td>
21
+ <td class='align-center'> <%= @order_details['payment_method']['reference'] %> </td>
22
+ </tr>
23
+ <tr>
24
+ <td class='align-right' colspan='2'>
25
+ <b><%= t('conekta.total') %></b>
26
+ <%= @order.display_total.to_html %>
27
+ </td>
28
+ </tr>
29
+ </tbody>
30
+ </table>
@@ -0,0 +1,32 @@
1
+ <img class='conekta-oxxo' src='https://s3.amazonaws.com/pagalo/oxxo_logo.png'></img>
2
+ <h1 id='oxxo-title'><%= t("conekta.cash.payment_title") %></h1>
3
+
4
+ <table id='conekta_cash' class='payment-information'>
5
+ <thead>
6
+ <tr>
7
+ <th colspan='2'> <%= t('conekta.order_number', number: @order.number) %> </th>
8
+ </tr>
9
+ <tr>
10
+ <th colspan='2'> <%= t('conekta.cash.bar_code') %> </th>
11
+ </tr>
12
+ </thead>
13
+ <tfoot>
14
+ <tr>
15
+ <td colspan='2'> <%= raw t('conekta.cash.payment_message') %> </td>
16
+ </tr>
17
+ </tfoot>
18
+ <tbody>
19
+ <tr>
20
+ <td class='align-center' id='barcode'>
21
+ <%= image_tag(@order_details['payment_method']['barcode_url']) %>
22
+ <div><%= @order_details['payment_method']['barcode'] %></div>
23
+ </td>
24
+ </tr>
25
+ <tr>
26
+ <td class='align-right'>
27
+ <b><%= t('conekta.total') %></b>
28
+ <%= @order.display_total.to_html %>
29
+ </td>
30
+ </tr>
31
+ </tbody>
32
+ </table>
@@ -0,0 +1,14 @@
1
+ <section id='order-payment'>
2
+ <header class='order-title'>
3
+ <div class='logos'>
4
+ <img class='conekta-brand' src='https://s3.amazonaws.com/conekta/v5/img/conekta-brand.png' alt='Conekta'></img>
5
+ </div>
6
+ <h2 class='payment-title'><%= t('conekta.title') %></h2>
7
+ </header>
8
+ <div class='order-body'>
9
+ <%= render partial: @order.last_payment_source %>
10
+ </div>
11
+ <footer class='order-footer'>
12
+ <%= button_tag t('conekta.print_payment_form'), class: 'right', onclick: 'printDoc("#order-payment")' %>
13
+ </footer>
14
+ </section>
@@ -0,0 +1,20 @@
1
+ en:
2
+ conekta:
3
+ additional_steps_warning: Additional steps to complete your payment
4
+ card:
5
+ processing_order: Processing order please wait
6
+ cash:
7
+ bar_code: Barcode
8
+ next_step: Next step
9
+ payment_message: Print this form and take it to the nearest OXXO to make your payment.
10
+ payment_title: Payment through OXXO
11
+ print_payment_form: Print payment form
12
+ title: Payment information
13
+ total: Total
14
+ bank:
15
+ payment_title: Banorte deposit
16
+ service_number: Service Number
17
+ reference: Reference
18
+ payment_message: Give this reference number at any Banorte bank.
19
+ order_number: 'Order Number: %{number}'
20
+ total: 'Total:'
@@ -0,0 +1,20 @@
1
+ es-MX:
2
+ conekta:
3
+ additional_steps_warning: Pasos adicionales para completar su pago
4
+ card:
5
+ processing_order: Procesando su pago espere un momento
6
+ cash:
7
+ bar_code: Código de barras
8
+ payment_message: Imprime este formulario y preséntalo en el Oxxo mas cercano para realizar tu pago.
9
+ payment_title: Pago a través de Oxxo
10
+ total: Total
11
+ bank:
12
+ payment_title: Depósito en ventanilla Banorte
13
+ service_number: Número de servicio
14
+ reference: Referencia
15
+ payment_message: 'Presente este número de referencia en cualquier sucursal: <strong> Banorte </strong>'
16
+ title: Información de pago
17
+ next_step: Siguiente paso
18
+ order_number: 'Número de orden: %{number}'
19
+ print_payment_form: Imprimir ficha de pago
20
+ total: 'Total a pagar:'
@@ -0,0 +1,5 @@
1
+ Spree::Core::Engine.routes.draw do
2
+ namespace :conekta do
3
+ resources :payments, only: [:create, :show]
4
+ end
5
+ end
@@ -0,0 +1,9 @@
1
+ class CreateSpreeConektaPayments < ActiveRecord::Migration
2
+ def change
3
+ create_table :spree_conekta_payments do |t|
4
+ t.string :type
5
+
6
+ t.timestamps
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ class RenameTypeColumnToConektaPayment < ActiveRecord::Migration
2
+ def change
3
+ rename_column :spree_conekta_payments, :type, :payment_type
4
+ add_column :spree_conekta_payments, :first_name, :string
5
+ add_column :spree_conekta_payments, :last_name, :string
6
+ end
7
+ end
@@ -0,0 +1,32 @@
1
+ module SpreeConekta
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+
5
+ class_option :auto_run_migrations, :type => :boolean, :default => false
6
+
7
+ def add_javascripts
8
+ append_file 'app/assets/javascripts/store/all.js', "\n//= require spree_conekta\n"
9
+ append_file 'app/assets/javascripts/admin/all.js', "\n//= require spree_conekta\n"
10
+ end
11
+
12
+ def add_stylesheets
13
+ inject_into_file 'app/assets/stylesheets/store/all.css', "\n *= require spree_conekta\n", :before => /\*\//, :verbose => true
14
+ inject_into_file 'app/assets/stylesheets/admin/all.css', "\n *= require spree_conekta\n", :before => /\*\//, :verbose => true
15
+ end
16
+
17
+ def add_migrations
18
+ run 'bundle exec rake railties:install:migrations'
19
+ end
20
+
21
+ def run_migrations
22
+ res = ask 'Would you like to run the migrations now? [Y/n]'
23
+ if res == '' || res.downcase == 'y'
24
+ run 'bundle exec rake db:migrate'
25
+ else
26
+ puts 'Skipping rake db:migrate, don\'t forget to run it!'
27
+ end
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,39 @@
1
+ module Spree::Conekta
2
+ class Client
3
+ CONEKTA_API = 'https://api.conekta.io/'
4
+ CHARGE_ENDPOINT = 'charges'
5
+
6
+ attr_accessor :auth_token
7
+
8
+ PAYMENT_SOURCES = {
9
+ 'card' => Spree::Conekta::PaymentSource::Card,
10
+ 'bank' => Spree::Conekta::PaymentSource::Bank,
11
+ 'cash' => Spree::Conekta::PaymentSource::Cash
12
+ }
13
+
14
+ def post(params)
15
+ Oj.load connection.post(CHARGE_ENDPOINT, Oj.dump(params)).body
16
+ end
17
+
18
+ def payment_processor(source_name)
19
+ PAYMENT_SOURCES[source_name]
20
+ end
21
+
22
+ def connection
23
+ Faraday.new(:url => CONEKTA_API) do |faraday|
24
+ faraday.request :url_encoded
25
+
26
+ faraday.headers = headers
27
+ faraday.adapter :typhoeus
28
+ faraday.basic_auth(auth_token, nil)
29
+ end
30
+ end
31
+
32
+ def headers
33
+ {
34
+ 'Accept' => ' application/vnd.conekta-v0.2.0+json',
35
+ 'Content-type' => ' application/json'
36
+ }
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,11 @@
1
+ module Spree::Conekta::PaymentSource
2
+ module Bank
3
+ def request(common, method, gateway_options)
4
+ common['bank'] = {
5
+ 'type' => 'banorte'
6
+ }
7
+ end
8
+
9
+ module_function :request
10
+ end
11
+ end
@@ -0,0 +1,23 @@
1
+ module Spree::Conekta::PaymentSource
2
+ module Card
3
+ def request(common, method, gateway_options)
4
+ common['card'] = {
5
+ 'name' => "#{method.first_name} #{method.last_name}",
6
+ 'cvc' => method.verification_value,
7
+ 'number' => method.number,
8
+ 'exp_year' => method.year.to_s[-2,2],
9
+ 'exp_month' => sprintf('%02d', method.month),
10
+ 'address' => customer_address(gateway_options)
11
+ }
12
+ end
13
+
14
+ def self.customer_address(gateway_options)
15
+ customer = gateway_options[:billing_address]
16
+ customer['street1'] = customer.delete(:address1)
17
+ customer['street2'] = customer.delete(:address2)
18
+ customer
19
+ end
20
+
21
+ module_function :request
22
+ end
23
+ end
@@ -0,0 +1,11 @@
1
+ module Spree::Conekta::PaymentSource
2
+ module Cash
3
+ def request(common, method, gateway_options)
4
+ common['cash'] = {
5
+ 'type' => 'oxxo'
6
+ }
7
+ end
8
+
9
+ module_function :request
10
+ end
11
+ end
@@ -0,0 +1,40 @@
1
+ module Spree::Conekta
2
+ class Provider < Client
3
+ attr_accessor :auth_token, :source_method
4
+
5
+ def initialize(options = {})
6
+ self.auth_token = options[:auth_token]
7
+ self.source_method = payment_processor(options[:source_method])
8
+ end
9
+
10
+ def authorize(amount, method_params, gateway_options = {})
11
+ common = build_common(amount, gateway_options)
12
+ commit common, method_params, gateway_options
13
+ end
14
+
15
+ def capture(amount, method_params, gateway_options = {})
16
+ Response.new({}, gateway_options)
17
+ end
18
+
19
+ private
20
+ def commit(common, method_params, gateway_options)
21
+ source_method.request(common, method_params, gateway_options)
22
+ response = Spree::Conekta::Response.new post(common), source_method
23
+
24
+ if response.status.eql? 'paid'
25
+ Spree::Payment.capture_by_order_id gateway_options[:order_id]
26
+ end
27
+
28
+ response
29
+ end
30
+
31
+ def build_common(amount, gateway_params)
32
+ {
33
+ 'amount' => amount,
34
+ 'reference_id' => gateway_params[:order_id],
35
+ 'currency' => gateway_params[:currency],
36
+ 'description' => gateway_params[:order_id]
37
+ }
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,13 @@
1
+ module Spree::Conekta
2
+ class Response < ActiveMerchant::Billing::Response
3
+ attr_accessor :response, :source_method, :status
4
+
5
+ def initialize(response, source_method)
6
+ @success = !(response.eql?('null') || response.include?('type')) if response
7
+ @message = @success ? 'Ok' : response['message']
8
+ @params = response
9
+ @status = response['status']
10
+ @source_method = source_method
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,8 @@
1
+ require 'spree_core'
2
+ require 'spree_backend'
3
+ require 'spree_frontend'
4
+ require 'nokogiri'
5
+ require 'typhoeus/adapters/faraday'
6
+ require 'faraday'
7
+ require 'faraday_middleware'
8
+ require 'spree_conekta/engine'
@@ -0,0 +1,32 @@
1
+ module SpreeConekta
2
+ class Engine < ::Rails::Engine
3
+ require 'spree'
4
+
5
+ engine_name 'spree_gateway'
6
+
7
+ config.autoload_paths += %W(#{config.root}/lib)
8
+
9
+ # use rspec for tests
10
+ config.generators do |g|
11
+ g.test_framework :rspec
12
+ end
13
+
14
+ if Rails.version >= '3.1'
15
+ initializer :assets do |config|
16
+ Rails.application.config.assets.precompile += %w( spree_conekta.js )
17
+ end
18
+ end
19
+
20
+ def self.activate
21
+ Dir.glob(File.join(File.dirname(__FILE__), "../../app/**/*_decorator*.rb")) do |c|
22
+ Rails.env.production? ? require(c) : load(c)
23
+ end
24
+ end
25
+
26
+ initializer "spree.gateway.payment_methods", :after => "spree.register.payment_methods" do |app|
27
+ app.config.spree.payment_methods << Spree::BillingIntegration::Conekta
28
+ end
29
+
30
+ config.to_prepare &method(:activate).to_proc
31
+ end
32
+ end
@@ -0,0 +1,3 @@
1
+ module SpreeConekta
2
+ VERSION = "0.5.9"
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :spree_conekta do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,175 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spree_conekta
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.9
5
+ platform: ruby
6
+ authors:
7
+ - Jonathan Garay
8
+ - Fernando Barajas
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-12-02 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: oj
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - '>='
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - '>='
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: faraday
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - '>='
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: typhoeus
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: faraday_middleware
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: activemerchant
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: spree
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ~>
89
+ - !ruby/object:Gem::Version
90
+ version: '2.1'
91
+ type: :runtime
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ~>
96
+ - !ruby/object:Gem::Version
97
+ version: '2.1'
98
+ description: Spree Engine for Conekta Mexican Payment gateway
99
+ email:
100
+ - jonathan.garay@crowdint.com
101
+ - fernando.barajas@crowdint.com
102
+ executables: []
103
+ extensions: []
104
+ extra_rdoc_files: []
105
+ files:
106
+ - app/assets/javascripts/admin/spree_conekta.js
107
+ - app/assets/javascripts/spree_conekta.js
108
+ - app/assets/javascripts/store/easyXDM.min.js
109
+ - app/assets/javascripts/store/printThis.js
110
+ - app/assets/javascripts/store/spree_conekta.js
111
+ - app/assets/javascripts/store/utils.js.erb
112
+ - app/assets/stylesheets/admin/print.css.sass
113
+ - app/assets/stylesheets/admin/spree_conekta.css
114
+ - app/assets/stylesheets/spree_conekta.css
115
+ - app/assets/stylesheets/store/conekta.css.sass
116
+ - app/assets/stylesheets/store/spree_conekta.css
117
+ - app/controllers/spree/checkout_controller_decorator.rb
118
+ - app/controllers/spree/conekta/payments_controller.rb
119
+ - app/models/spree/billing_integration/conekta.rb
120
+ - app/models/spree/conekta_payment.rb
121
+ - app/models/spree/order_decorator.rb
122
+ - app/models/spree/payment_decorator.rb
123
+ - app/models/spree.rb
124
+ - app/views/spree/admin/payments/_bank.html.erb
125
+ - app/views/spree/admin/payments/_cash.html.erb
126
+ - app/views/spree/admin/payments/source_forms/_conekta.html.erb
127
+ - app/views/spree/admin/payments/source_views/_conekta.html.erb
128
+ - app/views/spree/checkout/payment/_conekta.html.erb
129
+ - app/views/spree/conekta/payments/_bank.html.erb
130
+ - app/views/spree/conekta/payments/_card.html.erb
131
+ - app/views/spree/conekta/payments/_cash.html.erb
132
+ - app/views/spree/conekta/payments/show.html.erb
133
+ - config/locales/en.yml
134
+ - config/locales/es-MX.yml
135
+ - config/routes.rb
136
+ - db/migrate/20130904161251_create_spree_conekta_payments.rb
137
+ - db/migrate/20130904172418_rename_type_column_to_conekta_payment.rb
138
+ - lib/generators/spree_conekta/install/install_generator.rb
139
+ - lib/spree/conekta/client.rb
140
+ - lib/spree/conekta/payment_source/bank.rb
141
+ - lib/spree/conekta/payment_source/card.rb
142
+ - lib/spree/conekta/payment_source/cash.rb
143
+ - lib/spree/conekta/provider.rb
144
+ - lib/spree/conekta/response.rb
145
+ - lib/spree_conekta/engine.rb
146
+ - lib/spree_conekta/version.rb
147
+ - lib/spree_conekta.rb
148
+ - lib/tasks/spree_conekta_tasks.rake
149
+ - MIT-LICENSE
150
+ - Rakefile
151
+ - README.md
152
+ homepage: http://github.com/crowdint/spree_conekta
153
+ licenses: []
154
+ metadata: {}
155
+ post_install_message:
156
+ rdoc_options: []
157
+ require_paths:
158
+ - lib
159
+ required_ruby_version: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - '>='
162
+ - !ruby/object:Gem::Version
163
+ version: '0'
164
+ required_rubygems_version: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - - '>='
167
+ - !ruby/object:Gem::Version
168
+ version: '0'
169
+ requirements: []
170
+ rubyforge_project:
171
+ rubygems_version: 2.1.10
172
+ signing_key:
173
+ specification_version: 4
174
+ summary: Spree Engine for Conekta Mexican Payment gateway
175
+ test_files: []