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.
- 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
|