spree_komoju 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +14 -0
- data/.rspec +1 -0
- data/.travis.yml +16 -0
- data/Gemfile +8 -0
- data/LICENSE +26 -0
- data/README.md +39 -0
- data/Rakefile +21 -0
- data/app/assets/javascripts/spree/backend/spree_komoju.js +2 -0
- data/app/assets/javascripts/spree/frontend/spree_komoju.js +2 -0
- data/app/assets/stylesheets/spree/backend/spree_komoju.css +4 -0
- data/app/assets/stylesheets/spree/frontend/spree_komoju.css +4 -0
- data/app/controllers/spree/checkout_controller_decorator.rb +18 -0
- data/app/models/spree/bank_transfer.rb +26 -0
- data/app/models/spree/gateway/komoju_bank_transfer.rb +25 -0
- data/app/models/spree/gateway/komoju_credit_card.rb +40 -0
- data/app/models/spree/gateway/komoju_konbini.rb +23 -0
- data/app/models/spree/komoju_gateway.rb +51 -0
- data/app/models/spree/konbini.rb +32 -0
- data/app/overrides/add_instruction_to_order_show.rb +8 -0
- data/app/views/spree/admin/payments/source_views/_komoju_credit_card.html.erb +1 -0
- data/app/views/spree/admin/payments/source_views/_komoju_konbini.html.erb +25 -0
- data/app/views/spree/checkout/payment/_komoju_bank_transfer.html.erb +35 -0
- data/app/views/spree/checkout/payment/_komoju_credit_card.html.erb +1 -0
- data/app/views/spree/checkout/payment/_komoju_konbini.html.erb +11 -0
- data/app/views/spree/orders/_bank_transfer.html.erb +10 -0
- data/app/views/spree/orders/_konbini.html.erb +17 -0
- data/bin/rails +7 -0
- data/config/locales/en.yml +16 -0
- data/config/routes.rb +2 -0
- data/db/migrate/20150331051027_create_spree_konbinis.rb +18 -0
- data/db/migrate/20150401074721_create_spree_bank_transfers.rb +22 -0
- data/db/migrate/20151126050103_add_gateway_profile_ids_to_spree_konbinis.rb +6 -0
- data/lib/active_merchant/billing/gateways/komoju.rb +135 -0
- data/lib/generators/spree_komoju/install/images/circle-k.png +0 -0
- data/lib/generators/spree_komoju/install/images/daily-yamazaki.png +0 -0
- data/lib/generators/spree_komoju/install/images/family-mart.png +0 -0
- data/lib/generators/spree_komoju/install/images/lawson.png +0 -0
- data/lib/generators/spree_komoju/install/images/ministop.png +0 -0
- data/lib/generators/spree_komoju/install/images/seven-eleven.png +0 -0
- data/lib/generators/spree_komoju/install/images/sunkus.png +0 -0
- data/lib/generators/spree_komoju/install/install_generator.rb +36 -0
- data/lib/spree_komoju.rb +2 -0
- data/lib/spree_komoju/engine.rb +29 -0
- data/lib/spree_komoju/factories.rb +6 -0
- data/spec/controllers/spree/checkout_controller_spec.rb +13 -0
- data/spec/models/spree/bank_transfer_spec.rb +69 -0
- data/spec/models/spree/gateway/komoju_bank_transfer_spec.rb +59 -0
- data/spec/models/spree/gateway/komoju_credit_card_spec.rb +117 -0
- data/spec/models/spree/gateway/komoju_konbini_spec.rb +41 -0
- data/spec/models/spree/komoju_gateway_spec.rb +50 -0
- data/spec/models/spree/konbini_spec.rb +69 -0
- data/spec/spec_helper.rb +87 -0
- data/spree_komoju.gemspec +32 -0
- 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,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,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
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -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
|
data/lib/spree_komoju.rb
ADDED
@@ -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
|