spree_komoju 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +14 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +16 -0
  5. data/Gemfile +8 -0
  6. data/LICENSE +26 -0
  7. data/README.md +39 -0
  8. data/Rakefile +21 -0
  9. data/app/assets/javascripts/spree/backend/spree_komoju.js +2 -0
  10. data/app/assets/javascripts/spree/frontend/spree_komoju.js +2 -0
  11. data/app/assets/stylesheets/spree/backend/spree_komoju.css +4 -0
  12. data/app/assets/stylesheets/spree/frontend/spree_komoju.css +4 -0
  13. data/app/controllers/spree/checkout_controller_decorator.rb +18 -0
  14. data/app/models/spree/bank_transfer.rb +26 -0
  15. data/app/models/spree/gateway/komoju_bank_transfer.rb +25 -0
  16. data/app/models/spree/gateway/komoju_credit_card.rb +40 -0
  17. data/app/models/spree/gateway/komoju_konbini.rb +23 -0
  18. data/app/models/spree/komoju_gateway.rb +51 -0
  19. data/app/models/spree/konbini.rb +32 -0
  20. data/app/overrides/add_instruction_to_order_show.rb +8 -0
  21. data/app/views/spree/admin/payments/source_views/_komoju_credit_card.html.erb +1 -0
  22. data/app/views/spree/admin/payments/source_views/_komoju_konbini.html.erb +25 -0
  23. data/app/views/spree/checkout/payment/_komoju_bank_transfer.html.erb +35 -0
  24. data/app/views/spree/checkout/payment/_komoju_credit_card.html.erb +1 -0
  25. data/app/views/spree/checkout/payment/_komoju_konbini.html.erb +11 -0
  26. data/app/views/spree/orders/_bank_transfer.html.erb +10 -0
  27. data/app/views/spree/orders/_konbini.html.erb +17 -0
  28. data/bin/rails +7 -0
  29. data/config/locales/en.yml +16 -0
  30. data/config/routes.rb +2 -0
  31. data/db/migrate/20150331051027_create_spree_konbinis.rb +18 -0
  32. data/db/migrate/20150401074721_create_spree_bank_transfers.rb +22 -0
  33. data/db/migrate/20151126050103_add_gateway_profile_ids_to_spree_konbinis.rb +6 -0
  34. data/lib/active_merchant/billing/gateways/komoju.rb +135 -0
  35. data/lib/generators/spree_komoju/install/images/circle-k.png +0 -0
  36. data/lib/generators/spree_komoju/install/images/daily-yamazaki.png +0 -0
  37. data/lib/generators/spree_komoju/install/images/family-mart.png +0 -0
  38. data/lib/generators/spree_komoju/install/images/lawson.png +0 -0
  39. data/lib/generators/spree_komoju/install/images/ministop.png +0 -0
  40. data/lib/generators/spree_komoju/install/images/seven-eleven.png +0 -0
  41. data/lib/generators/spree_komoju/install/images/sunkus.png +0 -0
  42. data/lib/generators/spree_komoju/install/install_generator.rb +36 -0
  43. data/lib/spree_komoju.rb +2 -0
  44. data/lib/spree_komoju/engine.rb +29 -0
  45. data/lib/spree_komoju/factories.rb +6 -0
  46. data/spec/controllers/spree/checkout_controller_spec.rb +13 -0
  47. data/spec/models/spree/bank_transfer_spec.rb +69 -0
  48. data/spec/models/spree/gateway/komoju_bank_transfer_spec.rb +59 -0
  49. data/spec/models/spree/gateway/komoju_credit_card_spec.rb +117 -0
  50. data/spec/models/spree/gateway/komoju_konbini_spec.rb +41 -0
  51. data/spec/models/spree/komoju_gateway_spec.rb +50 -0
  52. data/spec/models/spree/konbini_spec.rb +69 -0
  53. data/spec/spec_helper.rb +87 -0
  54. data/spree_komoju.gemspec +32 -0
  55. metadata +66 -5
@@ -0,0 +1 @@
1
+ <%= render "spree/checkout/payment/gateway", payment_method: payment_method %>
@@ -0,0 +1,11 @@
1
+ <div class="well clearfix">
2
+ <% param_prefix = "payment_source[#{payment_method.id}]" %>
3
+
4
+ <% Spree::Konbini::STORES.each do |store| %>
5
+ <label>
6
+ <%= radio_button "#{param_prefix}", "convenience", store %>
7
+ <%= image_tag "#{store}.png" %>
8
+ <span><%= Spree.t("conveniences.#{store}") %></span>
9
+ </label><br />
10
+ <% end %>
11
+ </div>
@@ -0,0 +1,10 @@
1
+ <div>
2
+ Thank you for your order. Instructions have been sent to your e-mail address.<br>
3
+ <br>
4
+ <h4>Banktransfer ID: <%= source.order_id %></h4>
5
+ The Banktransfer ID is very important! Please make a note of it and bring it with you when you go to pay at the ATM.<br>
6
+ If you have chosen to use bank transfer payment, please use a bank transfer form which your bank offers, or please remit at ATM.<br>
7
+ <br>
8
+ Please make sure to include your banktransfer ID in the payer's name. Please enter your banktransfer ID shown in this email in front of your name as Payer when remitting.<br>
9
+ Please see the confirmation email for further payment instructions.
10
+ </div>
@@ -0,0 +1,17 @@
1
+ <div>
2
+ Thank you for your order. Instructions have been sent to your e-mail address.<br>
3
+ To complete a payment at <%= source.convenience.camelcase %>, Receipt Number and Confirmation Number are required.<br>
4
+ <br>
5
+ <%= link_to source.instructions_url do %>
6
+ How to make a payment at <%= source.convenience.camelcase %>
7
+ <% end %>
8
+ </div>
9
+ <br>
10
+ <div class='alert alert-info' role='alert'>
11
+ <h4>Receipt Number</h4>
12
+ <p><%= source.receipt %></p>
13
+ <h4>Confirmation Number</h4>
14
+ <p><%= source.confirmation_code %></p>
15
+ <h4>End Date</h4>
16
+ <p><%= source.expires_at %></p>
17
+ </div>
data/bin/rails ADDED
@@ -0,0 +1,7 @@
1
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
2
+
3
+ ENGINE_ROOT = File.expand_path('../..', __FILE__)
4
+ ENGINE_PATH = File.expand_path('../../lib/spree_komoju/engine', __FILE__)
5
+
6
+ require 'rails/all'
7
+ require 'rails/engine/commands'
@@ -0,0 +1,16 @@
1
+ en:
2
+ spree:
3
+ conveniences:
4
+ lawson: Lawson
5
+ family-mart: Family Mart
6
+ sunkus: Sunkus
7
+ circle-k: Circle K
8
+ ministop: Ministop
9
+ daily-yamazaki: Daily Yamazaki
10
+ seven-eleven: Seven Eleven
11
+ email: Email
12
+ phone: Phone
13
+ given_name: Given Name
14
+ family_name: Family Name
15
+ given_name_kana: Given Name Kana
16
+ family_name_kana: Family Name Kana
data/config/routes.rb ADDED
@@ -0,0 +1,2 @@
1
+ Spree::Core::Engine.routes.draw do
2
+ end
@@ -0,0 +1,18 @@
1
+ class CreateSpreeKonbinis < ActiveRecord::Migration
2
+ def change
3
+ create_table :spree_konbinis do |t|
4
+ t.string :convenience
5
+ t.integer :user_id
6
+ t.integer :payment_method_id
7
+ t.string :brand, default: "konbini"
8
+ t.string :receipt
9
+ t.string :confirmation_code
10
+ t.string :instructions_url
11
+ t.datetime :expires_at
12
+
13
+ t.timestamps null: false
14
+ end
15
+ add_index :spree_konbinis, :user_id
16
+ add_index :spree_konbinis, :payment_method_id
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ class CreateSpreeBankTransfers < ActiveRecord::Migration
2
+ def change
3
+ create_table :spree_bank_transfers do |t|
4
+ t.string :email
5
+ t.string :phone
6
+ t.string :given_name
7
+ t.string :family_name
8
+ t.string :given_name_kana
9
+ t.string :family_name_kana
10
+ t.integer :user_id
11
+ t.integer :payment_method_id
12
+ t.string :brand, default: "bank_transfers"
13
+ t.string :order_id
14
+ t.string :bank_number
15
+ t.datetime :expires_at
16
+
17
+ t.timestamps null: false
18
+ end
19
+ add_index :spree_bank_transfers, :user_id
20
+ add_index :spree_bank_transfers, :payment_method_id
21
+ end
22
+ end
@@ -0,0 +1,6 @@
1
+ class AddGatewayProfileIdsToSpreeKonbinis < ActiveRecord::Migration
2
+ def change
3
+ add_column :spree_konbinis, :gateway_customer_profile_id, :string
4
+ add_column :spree_konbinis, :gateway_payment_profile_id, :string
5
+ end
6
+ end
@@ -0,0 +1,135 @@
1
+ require 'json'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ class KomojuGateway < Gateway
6
+ self.test_url = "https://sandbox.komoju.com/api/v1"
7
+ self.live_url = "https://komoju.com/api/v1"
8
+ self.supported_countries = ['JP']
9
+ self.default_currency = 'JPY'
10
+ self.money_format = :cents
11
+ self.homepage_url = 'https://www.komoju.com/'
12
+ self.display_name = 'Komoju'
13
+ self.supported_cardtypes = [:visa, :master, :american_express, :jcb]
14
+
15
+ STANDARD_ERROR_CODE_MAPPING = {
16
+ "bad_verification_value" => "incorrect_cvc",
17
+ "card_expired" => "expired_card",
18
+ "card_declined" => "card_declined",
19
+ "invalid_number" => "invalid_number"
20
+ }
21
+
22
+ def initialize(options = {})
23
+ requires!(options, :login)
24
+ super
25
+ end
26
+
27
+ def purchase(money, payment, options = {})
28
+ post = {}
29
+ post[:amount] = amount(money)
30
+ post[:description] = options[:description]
31
+ add_payment_details(post, payment, options)
32
+ post[:currency] = options[:currency] || default_currency
33
+ post[:external_order_num] = options[:order_id] if options[:order_id]
34
+ post[:tax] = options[:tax] if options[:tax]
35
+ add_fraud_details(post, options)
36
+
37
+ commit("/payments", post)
38
+ end
39
+
40
+ def refund(money, identification, options = {})
41
+ commit("/payments/#{identification}/refund", {})
42
+ end
43
+
44
+ def store(payment, options = {})
45
+ post = {}
46
+ add_payment_details(post, payment, options)
47
+
48
+ if options[:customer_profile]
49
+ post[:email] = options[:email]
50
+ commit("/customers", post)
51
+ else
52
+ commit("/tokens", post)
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ def add_payment_details(post, payment, options)
59
+ case payment
60
+ when CreditCard
61
+ details = {}
62
+
63
+ details[:type] = 'credit_card'
64
+ details[:number] = payment.number
65
+ details[:month] = payment.month
66
+ details[:year] = payment.year
67
+ details[:verification_value] = payment.verification_value
68
+ details[:given_name] = payment.first_name
69
+ details[:family_name] = payment.last_name
70
+ details[:email] = options[:email] if options[:email]
71
+ post[:payment_details] = details
72
+ when String
73
+ if payment.match(/^tok_/)
74
+ post[:payment_details] = payment
75
+ else
76
+ post[:customer] = payment
77
+ end
78
+ end
79
+ end
80
+
81
+ def add_fraud_details(post, options)
82
+ details = {}
83
+
84
+ details[:customer_ip] = options[:ip] if options[:ip]
85
+ details[:customer_email] = options[:email] if options[:email]
86
+ details[:browser_language] = options[:browser_language] if options[:browser_language]
87
+ details[:browser_user_agent] = options[:browser_user_agent] if options[:browser_user_agent]
88
+
89
+ post[:fraud_details] = details unless details.empty?
90
+ end
91
+
92
+ def api_request(path, data)
93
+ raw_response = nil
94
+ begin
95
+ raw_response = ssl_post("#{url}#{path}", data, headers)
96
+ rescue ResponseError => e
97
+ raw_response = e.response.body
98
+ end
99
+
100
+ JSON.parse(raw_response)
101
+ end
102
+
103
+ def commit(path, params)
104
+ response = api_request(path, params.to_json)
105
+ success = !response.key?("error")
106
+ message = (success ? "Transaction succeeded" : response["error"]["message"])
107
+ Response.new(
108
+ success,
109
+ message,
110
+ response,
111
+ test: test?,
112
+ error_code: (success ? nil : error_code(response["error"]["code"])),
113
+ authorization: (success ? response["id"] : nil)
114
+ )
115
+ end
116
+
117
+ def error_code(code)
118
+ STANDARD_ERROR_CODE_MAPPING[code] || code
119
+ end
120
+
121
+ def url
122
+ test? ? self.test_url : self.live_url
123
+ end
124
+
125
+ def headers
126
+ {
127
+ "Authorization" => "Basic " + Base64.encode64(@options[:login].to_s + ":").strip,
128
+ "Accept" => "application/json",
129
+ "Content-Type" => "application/json",
130
+ "User-Agent" => "Komoju/v1 ActiveMerchantBindings/#{ActiveMerchant::VERSION}"
131
+ }
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,36 @@
1
+ module SpreeKomoju
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+
5
+ class_option :auto_run_migrations, :type => :boolean, :default => false
6
+ source_root File.expand_path('../', __FILE__)
7
+
8
+ def add_javascripts
9
+ append_file 'vendor/assets/javascripts/spree/frontend/all.js', "//= require spree/frontend/spree_komoju\n"
10
+ append_file 'vendor/assets/javascripts/spree/backend/all.js', "//= require spree/backend/spree_komoju\n"
11
+ end
12
+
13
+ def add_stylesheets
14
+ inject_into_file 'vendor/assets/stylesheets/spree/frontend/all.css', " *= require spree/frontend/spree_komoju\n", :before => /\*\//, :verbose => true
15
+ inject_into_file 'vendor/assets/stylesheets/spree/backend/all.css', " *= require spree/backend/spree_komoju\n", :before => /\*\//, :verbose => true
16
+ end
17
+
18
+ def add_migrations
19
+ run 'bundle exec rake railties:install:migrations FROM=spree_komoju'
20
+ end
21
+
22
+ def add_images
23
+ directory "images", "app/assets/images"
24
+ end
25
+
26
+ def run_migrations
27
+ run_migrations = options[:auto_run_migrations] || ['', 'y', 'Y'].include?(ask 'Would you like to run the migrations now? [Y/n]')
28
+ if run_migrations
29
+ run 'bundle exec rake db:migrate'
30
+ else
31
+ puts 'Skipping rake db:migrate, don\'t forget to run it!'
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,2 @@
1
+ require 'spree_core'
2
+ require 'spree_komoju/engine'
@@ -0,0 +1,29 @@
1
+ module SpreeKomoju
2
+ mattr_accessor :enable_customer_profiles
3
+
4
+ class Engine < Rails::Engine
5
+ require 'spree/core'
6
+ isolate_namespace Spree
7
+ engine_name 'spree_komoju'
8
+
9
+ initializer "spree.gateway.payment_methods", after: "spree.register.payment_methods" do |app|
10
+ app.config.spree.payment_methods << Spree::Gateway::KomojuCreditCard
11
+ app.config.spree.payment_methods << Spree::Gateway::KomojuKonbini
12
+ app.config.spree.payment_methods << Spree::Gateway::KomojuBankTransfer
13
+ end
14
+
15
+ # use rspec for tests
16
+ config.generators do |g|
17
+ g.test_framework :rspec
18
+ end
19
+
20
+ def self.activate
21
+ Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')) do |c|
22
+ Rails.configuration.cache_classes ? require(c) : load(c)
23
+ end
24
+ require "active_merchant/billing/gateways/komoju"
25
+ end
26
+
27
+ config.to_prepare &method(:activate).to_proc
28
+ end
29
+ end
@@ -0,0 +1,6 @@
1
+ FactoryGirl.define do
2
+ # Define your Spree extensions Factories within this file to enable applications, and other extensions to use and override them.
3
+ #
4
+ # Example adding this to your spec_helper will load these Factories for use:
5
+ # require 'spree_komoju/factories'
6
+ end
@@ -0,0 +1,13 @@
1
+ require "spec_helper"
2
+
3
+ describe Spree::CheckoutController, type: :controller do
4
+ describe "#permitted_source_attributes" do
5
+ it "returns added attributes" do
6
+ source_attributes = [:number, :month, :year, :expiry, :verification_value, :first_name, :last_name, :cc_type,
7
+ :gateway_customer_profile_id, :gateway_payment_profile_id, :last_digits, :name,
8
+ :encrypted_data, :convenience, :email, :phone, :family_name, :given_name, :family_name_kana,
9
+ :given_name_kana]
10
+ expect(controller.permitted_source_attributes).to eq source_attributes
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,69 @@
1
+ require "spec_helper"
2
+
3
+ describe Spree::BankTransfer, type: :model do
4
+ subject { described_class.new }
5
+
6
+ describe "#actions" do
7
+ it { expect(subject.actions).to eq ["capture", "void"] }
8
+ end
9
+
10
+ describe "#can_capture?" do
11
+ let(:payment) { double(Spree::Payment, state: state) }
12
+
13
+ before do
14
+ allow(subject).to receive(:payment) { payment }
15
+ end
16
+
17
+ context "when payment state is not checkout or pending" do
18
+ let(:state) { "void" }
19
+
20
+ it { expect(subject.can_capture?(payment)).to be_falsy }
21
+ end
22
+
23
+ context "when payment state is pending" do
24
+ let(:payment) { double(Spree::Payment, state: state, source: source) }
25
+ let(:state) { "pending" }
26
+ let(:source) { double(Spree::BankTransfer, expires_at: expires_at) }
27
+
28
+ before do
29
+ allow(subject).to receive(:payment) { payment }
30
+ end
31
+
32
+ context "when expires_at is tomorrow" do
33
+ let(:expires_at) { Date.tomorrow }
34
+
35
+ it { expect(subject.can_capture?(payment)).to be_truthy }
36
+ end
37
+
38
+ context "when expires_at is yesterday" do
39
+ let(:expires_at) { Date.yesterday}
40
+
41
+ it { expect(subject.can_capture?(payment)).to be_falsy }
42
+ end
43
+ end
44
+ end
45
+
46
+ describe "#can_void?" do
47
+ let(:payment) { double(Spree::Payment, state: state) }
48
+
49
+ before do
50
+ allow(subject).to receive(:payment) { payment }
51
+ end
52
+
53
+ context "when payment state is void" do
54
+ let(:state) { "void" }
55
+
56
+ it { expect(subject.can_void?(payment)).to be_falsy }
57
+ end
58
+
59
+ context "when payment state is pending" do
60
+ let(:state) { "pending" }
61
+
62
+ it { expect(subject.can_void?(payment)).to be_truthy }
63
+ end
64
+ end
65
+
66
+ describe "#instructions_partial_path" do
67
+ it { expect(subject.instructions_partial_path).to eq "spree/orders/bank_transfer" }
68
+ end
69
+ end