killbill-paypal-express 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://travis-ci.org/killbill/killbill-paypal-express-plugin.png)](https://travis-ci.org/killbill/killbill-paypal-express-plugin)
|
2
|
+
[![Code Climate](https://codeclimate.com/github/killbill/killbill-paypal-express-plugin.png)](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
|