killbill-paypal-express 1.0.1
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.
- data/.gitignore +36 -0
- data/.travis.yml +22 -0
- data/Gemfile +3 -0
- data/Jarfile +3 -0
- data/README.md +7 -0
- data/Rakefile +30 -0
- data/VERSION +1 -0
- data/config.ru +4 -0
- data/db/schema.rb +81 -0
- data/killbill-paypal-express.gemspec +41 -0
- data/killbill.properties +3 -0
- data/lib/paypal_express/api.rb +124 -0
- data/lib/paypal_express/config/application.rb +50 -0
- data/lib/paypal_express/config/configuration.rb +35 -0
- data/lib/paypal_express/config/properties.rb +27 -0
- data/lib/paypal_express/models/paypal_express_payment_method.rb +44 -0
- data/lib/paypal_express/models/paypal_express_response.rb +159 -0
- data/lib/paypal_express/models/paypal_express_transaction.rb +16 -0
- data/lib/paypal_express/paypal/gateway.rb +26 -0
- data/lib/paypal_express/paypal_express_utils.rb +17 -0
- data/lib/paypal_express/private_api.rb +53 -0
- data/lib/paypal_express.rb +129 -0
- data/pom.xml +35 -0
- data/release.sh +11 -0
- data/spec/paypal_express/base_plugin_spec.rb +31 -0
- data/spec/paypal_express/remote/integration_spec.rb +114 -0
- data/spec/spec_helper.rb +33 -0
- metadata +225 -0
data/.gitignore
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
*.swp
|
4
|
+
.bundle
|
5
|
+
.config
|
6
|
+
coverage
|
7
|
+
InstalledFiles
|
8
|
+
lib/bundler/man
|
9
|
+
pkg
|
10
|
+
rdoc
|
11
|
+
spec/reports
|
12
|
+
test/tmp
|
13
|
+
test/version_tmp
|
14
|
+
tmp
|
15
|
+
|
16
|
+
# YARD artifacts
|
17
|
+
.yardoc
|
18
|
+
_yardoc
|
19
|
+
doc/
|
20
|
+
|
21
|
+
.jbundler
|
22
|
+
Jarfile.lock
|
23
|
+
Gemfile.lock
|
24
|
+
|
25
|
+
.DS_Store
|
26
|
+
|
27
|
+
# Build directory
|
28
|
+
killbill-paypal-express/
|
29
|
+
|
30
|
+
# Config file
|
31
|
+
paypal_express.yml
|
32
|
+
|
33
|
+
# Testing database
|
34
|
+
test.db
|
35
|
+
|
36
|
+
target
|
data/.travis.yml
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
language: ruby
|
2
|
+
|
3
|
+
notifications:
|
4
|
+
email:
|
5
|
+
- killbilling-dev@googlegroups.com
|
6
|
+
|
7
|
+
rvm:
|
8
|
+
- 1.9.2
|
9
|
+
- 1.9.3
|
10
|
+
- ruby-head
|
11
|
+
- jruby-19mode
|
12
|
+
- jruby-head
|
13
|
+
|
14
|
+
jdk:
|
15
|
+
- openjdk7
|
16
|
+
- oraclejdk7
|
17
|
+
- openjdk6
|
18
|
+
|
19
|
+
matrix:
|
20
|
+
allow_failures:
|
21
|
+
- rvm: ruby-head
|
22
|
+
- rvm: jruby-head
|
data/Gemfile
ADDED
data/Jarfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
[](https://travis-ci.org/killbill/killbill-paypal-express-plugin)
|
2
|
+
[](https://codeclimate.com/github/killbill/killbill-paypal-express-plugin)
|
3
|
+
|
4
|
+
killbill-paypal-express-plugin
|
5
|
+
==============================
|
6
|
+
|
7
|
+
Plugin to use Express Checkout as a gateway
|
data/Rakefile
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
|
3
|
+
# Install tasks to build and release the plugin
|
4
|
+
require 'bundler/setup'
|
5
|
+
Bundler::GemHelper.install_tasks
|
6
|
+
|
7
|
+
# Install test tasks
|
8
|
+
require 'rspec/core/rake_task'
|
9
|
+
namespace :test do
|
10
|
+
desc "Run RSpec tests"
|
11
|
+
RSpec::Core::RakeTask.new do |task|
|
12
|
+
task.name = 'spec'
|
13
|
+
task.pattern = './spec/*/*_spec.rb'
|
14
|
+
end
|
15
|
+
|
16
|
+
namespace :remote do
|
17
|
+
desc "Run RSpec remote tests"
|
18
|
+
RSpec::Core::RakeTask.new do |task|
|
19
|
+
task.name = 'spec'
|
20
|
+
task.pattern = './spec/*/remote/*_spec.rb'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Install tasks to package the plugin for Killbill
|
26
|
+
require 'killbill/rake_task'
|
27
|
+
Killbill::PluginHelper.install_tasks
|
28
|
+
|
29
|
+
# Run tests by default
|
30
|
+
task :default => 'test:spec'
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.1
|
data/config.ru
ADDED
data/db/schema.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
ActiveRecord::Schema.define(:version => 20130311153635) do
|
4
|
+
create_table "paypal_express_payment_methods", :force => true do |t|
|
5
|
+
t.string "kb_account_id", :null => false
|
6
|
+
t.string "kb_payment_method_id" # NULL before Killbill knows about it
|
7
|
+
t.string "paypal_express_payer_id" # NULL before the express checkout is completed
|
8
|
+
t.string "paypal_express_baid" # NULL before the express checkout is completed
|
9
|
+
t.string "paypal_express_token", :null => false, :unique => true
|
10
|
+
t.boolean "is_deleted", :null => false, :default => false
|
11
|
+
t.datetime "created_at", :null => false
|
12
|
+
t.datetime "updated_at", :null => false
|
13
|
+
end
|
14
|
+
|
15
|
+
create_table "paypal_express_transactions", :force => true do |t|
|
16
|
+
t.integer "paypal_express_response_id", :null => false
|
17
|
+
t.string "api_call", :null => false
|
18
|
+
t.string "kb_payment_id", :null => false
|
19
|
+
t.string "paypal_express_txn_id", :null => false
|
20
|
+
t.integer "amount_in_cents", :null => false
|
21
|
+
t.datetime "created_at", :null => false
|
22
|
+
t.datetime "updated_at", :null => false
|
23
|
+
end
|
24
|
+
|
25
|
+
create_table "paypal_express_responses", :force => true do |t|
|
26
|
+
t.string "api_call", :null => false
|
27
|
+
t.string "kb_payment_id"
|
28
|
+
t.string "message"
|
29
|
+
t.string "authorization"
|
30
|
+
t.boolean "fraud_review"
|
31
|
+
t.boolean "test"
|
32
|
+
t.string "token"
|
33
|
+
t.string "payer_id"
|
34
|
+
t.string "billing_agreement_id"
|
35
|
+
t.string "payer_name"
|
36
|
+
t.string "payer_email"
|
37
|
+
t.string "payer_country"
|
38
|
+
t.string "contact_phone"
|
39
|
+
t.string "ship_to_address_name"
|
40
|
+
t.string "ship_to_address_company"
|
41
|
+
t.string "ship_to_address_address1"
|
42
|
+
t.string "ship_to_address_address2"
|
43
|
+
t.string "ship_to_address_city"
|
44
|
+
t.string "ship_to_address_state"
|
45
|
+
t.string "ship_to_address_country"
|
46
|
+
t.string "ship_to_address_zip"
|
47
|
+
t.string "ship_to_address_phone"
|
48
|
+
t.string "receiver_info_business"
|
49
|
+
t.string "receiver_info_receiver"
|
50
|
+
t.string "receiver_info_receiverid"
|
51
|
+
t.string "payment_info_transactionid"
|
52
|
+
t.string "payment_info_parenttransactionid"
|
53
|
+
t.string "payment_info_receiptid"
|
54
|
+
t.string "payment_info_transactiontype"
|
55
|
+
t.string "payment_info_paymenttype"
|
56
|
+
t.string "payment_info_paymentdate"
|
57
|
+
t.string "payment_info_grossamount"
|
58
|
+
t.string "payment_info_feeamount"
|
59
|
+
t.string "payment_info_taxamount"
|
60
|
+
t.string "payment_info_exchangerate"
|
61
|
+
t.string "payment_info_paymentstatus"
|
62
|
+
t.string "payment_info_pendingreason"
|
63
|
+
t.string "payment_info_reasoncode"
|
64
|
+
t.string "payment_info_protectioneligibility"
|
65
|
+
t.string "payment_info_protectioneligibilitytype"
|
66
|
+
t.string "payment_info_shipamount"
|
67
|
+
t.string "payment_info_shiphandleamount"
|
68
|
+
t.string "payment_info_shipdiscount"
|
69
|
+
t.string "payment_info_insuranceamount"
|
70
|
+
t.string "payment_info_subject"
|
71
|
+
t.string "avs_result_code"
|
72
|
+
t.string "avs_result_message"
|
73
|
+
t.string "avs_result_street_match"
|
74
|
+
t.string "avs_result_postal_match"
|
75
|
+
t.string "cvv_result_code"
|
76
|
+
t.string "cvv_result_message"
|
77
|
+
t.boolean "success"
|
78
|
+
t.datetime "created_at", :null => false
|
79
|
+
t.datetime "updated_at", :null => false
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
version = File.read(File.expand_path('../VERSION', __FILE__)).strip
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'killbill-paypal-express'
|
5
|
+
s.version = version
|
6
|
+
s.summary = 'Plugin to use Express Checkout as a gateway.'
|
7
|
+
s.description = 'Killbill payment plugin for Paypal Express Checkout.'
|
8
|
+
|
9
|
+
s.required_ruby_version = '>= 1.9.3'
|
10
|
+
|
11
|
+
s.license = 'Apache License (2.0)'
|
12
|
+
|
13
|
+
s.author = 'Killbill core team'
|
14
|
+
s.email = 'killbilling-users@googlegroups.com'
|
15
|
+
s.homepage = 'http://www.killbilling.org'
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.bindir = 'bin'
|
20
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
21
|
+
s.require_paths = ["lib"]
|
22
|
+
|
23
|
+
s.rdoc_options << '--exclude' << '.'
|
24
|
+
|
25
|
+
s.add_dependency 'killbill', '~> 1.0.12'
|
26
|
+
s.add_dependency 'activemerchant', '~> 1.31.1'
|
27
|
+
s.add_dependency 'activerecord', '~> 3.2.1'
|
28
|
+
s.add_dependency 'sinatra', '~> 1.3.4'
|
29
|
+
if defined?(JRUBY_VERSION)
|
30
|
+
s.add_dependency 'activerecord-jdbcmysql-adapter', '~> 1.2.9'
|
31
|
+
end
|
32
|
+
|
33
|
+
s.add_development_dependency 'jbundler', '~> 0.4.1'
|
34
|
+
s.add_development_dependency 'rake', '>= 10.0.0'
|
35
|
+
s.add_development_dependency 'rspec', '~> 2.12.0'
|
36
|
+
if defined?(JRUBY_VERSION)
|
37
|
+
s.add_development_dependency 'activerecord-jdbcsqlite3-adapter', '~> 1.2.6'
|
38
|
+
else
|
39
|
+
s.add_development_dependency 'sqlite3', '~> 1.3.7'
|
40
|
+
end
|
41
|
+
end
|
data/killbill.properties
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
module Killbill::PaypalExpress
|
2
|
+
class PaymentPlugin < Killbill::Plugin::Payment
|
3
|
+
def start_plugin
|
4
|
+
Killbill::PaypalExpress.initialize! "#{@root}/paypal_express.yml", @logger
|
5
|
+
@gateway = Killbill::PaypalExpress.gateway
|
6
|
+
|
7
|
+
@ip = Utils.ip
|
8
|
+
|
9
|
+
super
|
10
|
+
|
11
|
+
@logger.info "Killbill::PaypalExpress::PaymentPlugin started"
|
12
|
+
end
|
13
|
+
|
14
|
+
def process_payment(kb_account_id, kb_payment_id, kb_payment_method_id, amount_in_cents, currency, options = {})
|
15
|
+
options[:currency] ||= currency
|
16
|
+
options[:payment_type] ||= 'Any'
|
17
|
+
options[:invoice_id] ||= kb_payment_id
|
18
|
+
options[:description] ||= "Kill Bill payment for #{kb_payment_id}"
|
19
|
+
options[:ip] ||= @ip
|
20
|
+
|
21
|
+
if options[:reference_id].blank?
|
22
|
+
payment_method = PaypalExpressPaymentMethod.from_kb_payment_method_id(kb_payment_method_id)
|
23
|
+
options[:reference_id] = payment_method.paypal_express_baid
|
24
|
+
end
|
25
|
+
|
26
|
+
# Go to Paypal (DoReferenceTransaction call)
|
27
|
+
paypal_response = @gateway.reference_transaction amount_in_cents, options
|
28
|
+
response = save_response_and_transaction paypal_response, :charge, kb_payment_id, amount_in_cents
|
29
|
+
|
30
|
+
response.to_payment_response
|
31
|
+
end
|
32
|
+
|
33
|
+
def process_refund(kb_account_id, kb_payment_id, amount_in_cents, currency, options = {})
|
34
|
+
# Find one successful charge which amount is at least the amount we are trying to refund
|
35
|
+
paypal_express_transaction = PaypalExpressTransaction.where("paypal_express_transactions.amount_in_cents >= ?", amount_in_cents).find_last_by_api_call_and_kb_payment_id(:charge, kb_payment_id)
|
36
|
+
raise "Unable to find Paypal Express transaction id for payment #{kb_payment_id}" if paypal_express_transaction.nil?
|
37
|
+
|
38
|
+
options[:currency] ||= currency
|
39
|
+
options[:refund_type] ||= paypal_express_transaction.amount_in_cents != amount_in_cents ? 'Partial' : 'Full'
|
40
|
+
|
41
|
+
identification = paypal_express_transaction.paypal_express_txn_id
|
42
|
+
|
43
|
+
# Go to Paypal
|
44
|
+
paypal_response = @gateway.refund amount_in_cents, identification, options
|
45
|
+
response = save_response_and_transaction paypal_response, :refund, kb_payment_id, amount_in_cents
|
46
|
+
|
47
|
+
response.to_refund_response
|
48
|
+
end
|
49
|
+
|
50
|
+
def get_payment_info(kb_account_id, kb_payment_id, options = {})
|
51
|
+
paypal_express_transaction = PaypalExpressTransaction.from_kb_payment_id(kb_payment_id)
|
52
|
+
|
53
|
+
begin
|
54
|
+
transaction_id = paypal_express_transaction.paypal_express_txn_id
|
55
|
+
response = @gateway.transaction_details transaction_id
|
56
|
+
PaypalExpressResponse.from_response(:transaction_details, kb_payment_id, response).to_payment_response
|
57
|
+
rescue => e
|
58
|
+
@logger.warn("Exception while retrieving Paypal Express transaction detail for payment #{kb_payment_id}, defaulting to cached response: #{e}")
|
59
|
+
paypal_express_transaction.paypal_express_response.to_payment_response
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def add_payment_method(kb_account_id, kb_payment_method_id, payment_method_props, set_default=false, options = {})
|
64
|
+
token = payment_method_props.value('token')
|
65
|
+
return false if token.nil?
|
66
|
+
|
67
|
+
# The payment method should have been created during the setup step (see private api)
|
68
|
+
payment_method = PaypalExpressPaymentMethod.from_kb_account_id_and_token(kb_account_id, token)
|
69
|
+
|
70
|
+
# Go to Paypal to get the Payer id (GetExpressCheckoutDetails call)
|
71
|
+
paypal_express_details_response = @gateway.details_for token
|
72
|
+
response = save_response_and_transaction paypal_express_details_response, :details_for
|
73
|
+
return false unless response.success?
|
74
|
+
|
75
|
+
payer_id = response.payer_id
|
76
|
+
unless payer_id.nil?
|
77
|
+
# Go to Paypal to create the BAID for recurring payments (CreateBillingAgreement call)
|
78
|
+
paypal_express_baid_response = @gateway.create_billing_agreement :token => token
|
79
|
+
response = save_response_and_transaction paypal_express_baid_response, :create_billing_agreement
|
80
|
+
return false unless response.success?
|
81
|
+
|
82
|
+
payment_method.kb_payment_method_id = kb_payment_method_id
|
83
|
+
payment_method.paypal_express_payer_id = payer_id
|
84
|
+
payment_method.paypal_express_baid = response.billing_agreement_id
|
85
|
+
payment_method.save!
|
86
|
+
|
87
|
+
logger.info "Created BAID #{payment_method.paypal_express_baid} for payment method #{kb_payment_method_id} (account #{kb_account_id})"
|
88
|
+
true
|
89
|
+
else
|
90
|
+
logger.warn "Unable to retrieve Payer id details for token #{token} (account #{kb_account_id})"
|
91
|
+
false
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def delete_payment_method(kb_account_id, kb_payment_method_id, options = {})
|
96
|
+
PaypalExpressPaymentMethod.mark_as_deleted! kb_payment_method_id
|
97
|
+
end
|
98
|
+
|
99
|
+
def get_payment_method_detail(kb_account_id, kb_payment_method_id, options = {})
|
100
|
+
PaypalExpressPaymentMethod.from_kb_payment_method_id(kb_payment_method_id).to_payment_method_response
|
101
|
+
end
|
102
|
+
|
103
|
+
def get_payment_methods(kb_account_id, refresh_from_gateway = false, options = {})
|
104
|
+
PaypalExpressPaymentMethod.from_kb_account_id(kb_account_id).collect { |pm| pm.to_payment_method_response }
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
def save_response_and_transaction(paypal_express_response, api_call, kb_payment_id=nil, amount_in_cents=0)
|
110
|
+
@logger.warn "Unsuccessful #{api_call}: #{paypal_express_response.message}" unless paypal_express_response.success?
|
111
|
+
|
112
|
+
# Save the response to our logs
|
113
|
+
response = PaypalExpressResponse.from_response(api_call, kb_payment_id, paypal_express_response)
|
114
|
+
response.save!
|
115
|
+
|
116
|
+
if response.success and !response.authorization.blank?
|
117
|
+
# Record the transaction
|
118
|
+
transaction = response.create_paypal_express_transaction!(:amount_in_cents => amount_in_cents, :api_call => api_call, :kb_payment_id => kb_payment_id, :paypal_express_txn_id => response.authorization)
|
119
|
+
@logger.debug "Recorded transaction: #{transaction.inspect}"
|
120
|
+
end
|
121
|
+
response
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
configure do
|
2
|
+
# Usage: rackup -Ilib -E test
|
3
|
+
if development? or test?
|
4
|
+
Killbill::PaypalExpress.initialize! unless Killbill::PaypalExpress.initialized
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
helpers do
|
9
|
+
def plugin
|
10
|
+
Killbill::PaypalExpress::PrivatePaymentPlugin.instance
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# curl -v -XPOST http://127.0.0.1:9292/plugins/killbill-paypal-express/1.0/setup-checkout --data-binary '{"kb_account_id":"a6b33ba1"}'
|
15
|
+
post '/plugins/killbill-paypal-express/1.0/setup-checkout', :provides => 'json' do
|
16
|
+
begin
|
17
|
+
data = JSON.parse request.body.read
|
18
|
+
rescue JSON::ParserError => e
|
19
|
+
halt 400, {'Content-Type' => 'text/plain'}, "Invalid payload: #{e}"
|
20
|
+
end
|
21
|
+
|
22
|
+
response = plugin.initiate_express_checkout data['kb_account_id'],
|
23
|
+
data['amount_in_cents'] || 0,
|
24
|
+
data['currency'] || 'USD',
|
25
|
+
data['options'] || {}
|
26
|
+
unless response.success?
|
27
|
+
status 500
|
28
|
+
response.message
|
29
|
+
else
|
30
|
+
redirect response.to_express_checkout_url
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# curl -v http://127.0.0.1:9292/plugins/killbill-paypal-express/1.0/pms/1
|
35
|
+
get '/plugins/killbill-paypal-express/1.0/pms/:id', :provides => 'json' do
|
36
|
+
if pm = Killbill::PaypalExpress::PaypalExpressPaymentMethod.find_by_id(params[:id].to_i)
|
37
|
+
pm.to_json
|
38
|
+
else
|
39
|
+
status 404
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# curl -v http://127.0.0.1:9292/plugins/killbill-paypal-express/1.0/transactions/1
|
44
|
+
get '/plugins/killbill-paypal-express/1.0/transactions/:id', :provides => 'json' do
|
45
|
+
if transaction = Killbill::PaypalExpress::PaypalExpressTransaction.find_by_id(params[:id].to_i)
|
46
|
+
transaction.to_json
|
47
|
+
else
|
48
|
+
status 404
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module Killbill::PaypalExpress
|
4
|
+
mattr_reader :logger
|
5
|
+
mattr_reader :config
|
6
|
+
mattr_reader :gateway
|
7
|
+
mattr_reader :paypal_sandbox_url
|
8
|
+
mattr_reader :paypal_production_url
|
9
|
+
mattr_reader :initialized
|
10
|
+
mattr_reader :test
|
11
|
+
|
12
|
+
def self.initialize!(config_file='paypal_express.yml', logger=Logger.new(STDOUT))
|
13
|
+
@@logger = logger
|
14
|
+
|
15
|
+
@@config = Properties.new(config_file)
|
16
|
+
@@config.parse!
|
17
|
+
|
18
|
+
@@paypal_sandbox_url = @@config[:paypal][:sandbox_url] || 'https://www.sandbox.paypal.com/cgi-bin/webscr'
|
19
|
+
@@paypal_production_url = @@config[:paypal][:production_url] || 'https://www.paypal.com/cgi-bin/webscr'
|
20
|
+
@@test = @@config[:paypal][:test]
|
21
|
+
|
22
|
+
@@gateway = Killbill::PaypalExpress::Gateway.instance
|
23
|
+
@@gateway.configure(@@config[:paypal])
|
24
|
+
|
25
|
+
if defined?(JRUBY_VERSION)
|
26
|
+
# See https://github.com/jruby/activerecord-jdbc-adapter/issues/302
|
27
|
+
require 'jdbc/mysql'
|
28
|
+
Jdbc::MySQL.load_driver(:require) if Jdbc::MySQL.respond_to?(:load_driver)
|
29
|
+
end
|
30
|
+
|
31
|
+
ActiveRecord::Base.establish_connection(@@config[:database])
|
32
|
+
|
33
|
+
@@initialized = true
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Killbill::PaypalExpress
|
2
|
+
class Properties
|
3
|
+
def initialize(file = 'paypal_express.yml')
|
4
|
+
@config_file = Pathname.new(file).expand_path
|
5
|
+
end
|
6
|
+
|
7
|
+
def parse!
|
8
|
+
raise "#{@config_file} is not a valid file" unless @config_file.file?
|
9
|
+
@config = YAML.load_file(@config_file.to_s)
|
10
|
+
validate!
|
11
|
+
end
|
12
|
+
|
13
|
+
def [](key)
|
14
|
+
@config[key]
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def validate!
|
20
|
+
raise "Bad configuration for PaypalExpress plugin. Config is #{@config.inspect}" if @config.blank? ||
|
21
|
+
@config[:paypal].blank? ||
|
22
|
+
@config[:paypal][:signature].blank? ||
|
23
|
+
@config[:paypal][:login].blank? ||
|
24
|
+
@config[:paypal][:password].blank?
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Killbill::PaypalExpress
|
2
|
+
class PaypalExpressPaymentMethod < ActiveRecord::Base
|
3
|
+
attr_accessible :kb_account_id,
|
4
|
+
:kb_payment_method_id,
|
5
|
+
:paypal_express_payer_id,
|
6
|
+
:paypal_express_baid,
|
7
|
+
:paypal_express_token
|
8
|
+
|
9
|
+
def self.from_kb_account_id(kb_account_id)
|
10
|
+
find_all_by_kb_account_id_and_is_deleted(kb_account_id, false)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.from_kb_payment_method_id(kb_payment_method_id)
|
14
|
+
payment_methods = find_all_by_kb_payment_method_id_and_is_deleted(kb_payment_method_id, false)
|
15
|
+
raise "No payment method found for payment method #{kb_payment_method_id}" if payment_methods.empty?
|
16
|
+
raise "Killbill payment method mapping to multiple active PaypalExpress tokens for payment method #{kb_payment_method_id}" if payment_methods.size > 1
|
17
|
+
payment_methods[0]
|
18
|
+
end
|
19
|
+
|
20
|
+
# Used to complete the checkout process
|
21
|
+
def self.from_kb_account_id_and_token(kb_account_id, token)
|
22
|
+
payment_methods = find_all_by_kb_account_id_and_paypal_express_token_and_is_deleted(kb_account_id, token, false)
|
23
|
+
raise "No payment method found for account #{kb_account_id}" if payment_methods.empty?
|
24
|
+
raise "Paypal token mapping to multiple active PaypalExpress payment methods #{kb_account_id}" if payment_methods.size > 1
|
25
|
+
payment_methods[0]
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.mark_as_deleted!(kb_payment_method_id)
|
29
|
+
payment_method = from_kb_payment_method_id(kb_payment_method_id)
|
30
|
+
payment_method.is_deleted = true
|
31
|
+
payment_method.save!
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_payment_method_response
|
35
|
+
external_payment_method_id = paypal_express_baid
|
36
|
+
# No concept of default payment method in Paypal Express
|
37
|
+
is_default = false
|
38
|
+
# We don't store extra information in Paypal Express
|
39
|
+
properties = []
|
40
|
+
|
41
|
+
Killbill::Plugin::PaymentMethodResponse.new external_payment_method_id, is_default, properties
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|