dfg-paypal 0.8.2

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 (84) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/.gitignore +25 -0
  4. data/.rspec +2 -0
  5. data/.travis.yml +18 -0
  6. data/Gemfile +13 -0
  7. data/Rakefile +19 -0
  8. data/VERSION +1 -0
  9. data/dfg-paypal.gemspec +28 -0
  10. data/lib/paypal.rb +84 -0
  11. data/lib/paypal/base.rb +19 -0
  12. data/lib/paypal/exception.rb +4 -0
  13. data/lib/paypal/exception/api_error.rb +94 -0
  14. data/lib/paypal/exception/http_error.rb +12 -0
  15. data/lib/paypal/express.rb +1 -0
  16. data/lib/paypal/express/request.rb +207 -0
  17. data/lib/paypal/express/response.rb +35 -0
  18. data/lib/paypal/ipn.rb +23 -0
  19. data/lib/paypal/nvp/request.rb +64 -0
  20. data/lib/paypal/nvp/response.rb +234 -0
  21. data/lib/paypal/payment/common/amount.rb +13 -0
  22. data/lib/paypal/payment/recurring.rb +43 -0
  23. data/lib/paypal/payment/recurring/activation.rb +14 -0
  24. data/lib/paypal/payment/recurring/billing.rb +39 -0
  25. data/lib/paypal/payment/recurring/summary.rb +11 -0
  26. data/lib/paypal/payment/request.rb +67 -0
  27. data/lib/paypal/payment/request/item.rb +26 -0
  28. data/lib/paypal/payment/response.rb +73 -0
  29. data/lib/paypal/payment/response/address.rb +7 -0
  30. data/lib/paypal/payment/response/info.rb +45 -0
  31. data/lib/paypal/payment/response/item.rb +41 -0
  32. data/lib/paypal/payment/response/payer.rb +7 -0
  33. data/lib/paypal/payment/response/reference.rb +9 -0
  34. data/lib/paypal/payment/response/refund.rb +13 -0
  35. data/lib/paypal/util.rb +28 -0
  36. data/spec/fake_response/BillAgreementUpdate/fetch.txt +1 -0
  37. data/spec/fake_response/BillAgreementUpdate/revoke.txt +1 -0
  38. data/spec/fake_response/CreateBillingAgreement/success.txt +1 -0
  39. data/spec/fake_response/CreateRecurringPaymentsProfile/failure.txt +1 -0
  40. data/spec/fake_response/CreateRecurringPaymentsProfile/success.txt +1 -0
  41. data/spec/fake_response/DoCapture/failure.txt +1 -0
  42. data/spec/fake_response/DoCapture/success.txt +1 -0
  43. data/spec/fake_response/DoExpressCheckoutPayment/failure.txt +1 -0
  44. data/spec/fake_response/DoExpressCheckoutPayment/success.txt +1 -0
  45. data/spec/fake_response/DoExpressCheckoutPayment/success_with_billing_agreement.txt +1 -0
  46. data/spec/fake_response/DoExpressCheckoutPayment/success_with_many_items.txt +1 -0
  47. data/spec/fake_response/DoReferenceTransaction/failure.txt +1 -0
  48. data/spec/fake_response/DoReferenceTransaction/success.txt +1 -0
  49. data/spec/fake_response/DoVoid/success.txt +1 -0
  50. data/spec/fake_response/GetExpressCheckoutDetails/failure.txt +1 -0
  51. data/spec/fake_response/GetExpressCheckoutDetails/success.txt +1 -0
  52. data/spec/fake_response/GetExpressCheckoutDetails/with_billing_accepted_status.txt +1 -0
  53. data/spec/fake_response/GetRecurringPaymentsProfileDetails/failure.txt +1 -0
  54. data/spec/fake_response/GetRecurringPaymentsProfileDetails/success.txt +1 -0
  55. data/spec/fake_response/GetTransactionDetails/failure.txt +1 -0
  56. data/spec/fake_response/GetTransactionDetails/success.txt +1 -0
  57. data/spec/fake_response/IPN/invalid.txt +1 -0
  58. data/spec/fake_response/IPN/valid.txt +1 -0
  59. data/spec/fake_response/ManageRecurringPaymentsProfileStatus/failure.txt +1 -0
  60. data/spec/fake_response/ManageRecurringPaymentsProfileStatus/success.txt +1 -0
  61. data/spec/fake_response/RefundTransaction/full.txt +1 -0
  62. data/spec/fake_response/SetExpressCheckout/failure.txt +1 -0
  63. data/spec/fake_response/SetExpressCheckout/success.txt +1 -0
  64. data/spec/helpers/fake_response_helper.rb +33 -0
  65. data/spec/paypal/exception/api_error_spec.rb +78 -0
  66. data/spec/paypal/exception/http_error_spec.rb +8 -0
  67. data/spec/paypal/express/request_spec.rb +602 -0
  68. data/spec/paypal/express/response_spec.rb +80 -0
  69. data/spec/paypal/ipn_spec.rb +19 -0
  70. data/spec/paypal/nvp/request_spec.rb +116 -0
  71. data/spec/paypal/nvp/response_spec.rb +146 -0
  72. data/spec/paypal/payment/common/amount_spec.rb +36 -0
  73. data/spec/paypal/payment/recurring/activation_spec.rb +19 -0
  74. data/spec/paypal/payment/recurring_spec.rb +170 -0
  75. data/spec/paypal/payment/request/item_spec.rb +27 -0
  76. data/spec/paypal/payment/request_spec.rb +136 -0
  77. data/spec/paypal/payment/response/address_spec.rb +26 -0
  78. data/spec/paypal/payment/response/info_spec.rb +93 -0
  79. data/spec/paypal/payment/response/item_spec.rb +42 -0
  80. data/spec/paypal/payment/response/payer_spec.rb +26 -0
  81. data/spec/paypal/payment/response_spec.rb +16 -0
  82. data/spec/paypal/util_spec.rb +32 -0
  83. data/spec/spec_helper.rb +25 -0
  84. metadata +225 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 87cc60db564ca35531e6c121e313d3a8ceb0eeab
4
+ data.tar.gz: 31ffebf8041ed2a2787177572c97b0a2980427c5
5
+ SHA512:
6
+ metadata.gz: c0d718218a0560c6b7d26e92c0ca3c93a36b2fcdfc4815056e255ab2109300d9d626ceed447b56229260bb293d6c5ac04cb6584a1ce729ea9b449889fc9d8129
7
+ data.tar.gz: fecc36ac1ad2d8127f4147b81b3d19e940cf45b3e2e02fb839f2e880931537b644081b6083f0667655369ca8fd2f119f170275c082f267589bb720fdb8c02f26
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,25 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage*
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
22
+ Gemfile.lock
23
+
24
+ # 2016-12-12
25
+ *.gem
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format=documentation
@@ -0,0 +1,18 @@
1
+ before_install:
2
+ - gem install bundler
3
+
4
+ rvm:
5
+ - 2.1.10
6
+ - 2.2.5
7
+ - 2.3.1
8
+
9
+ env:
10
+ - RAILS_VERSION="~> 2.3"
11
+ - RAILS_VERSION="~> 3.0"
12
+ - RAILS_VERSION="~> 4.0"
13
+ - RAILS_VERSION="~> 5.0"
14
+
15
+ matrix:
16
+ exclude:
17
+ - rvm: 2.1.10
18
+ env: RAILS_VERSION="~> 5.0"
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source 'https://rubygems.org'
2
+
3
+ platform :jruby do
4
+ gem 'jruby-openssl', '>= 0.7'
5
+ end
6
+
7
+ if ENV['RAILS_VERSION']
8
+ gem 'activesupport', ENV['RAILS_VERSION']
9
+
10
+ gem 'iconv' if ENV['RAILS_VERSION'] == '~> 2.3'
11
+ end
12
+
13
+ gemspec
@@ -0,0 +1,19 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ namespace :coverage do
8
+ desc "Open coverage report"
9
+ task :report do
10
+ require 'simplecov'
11
+ `open "#{File.join SimpleCov.coverage_path, 'index.html'}"`
12
+ end
13
+ end
14
+
15
+ task :spec do
16
+ Rake::Task[:'coverage:report'].invoke unless ENV['TRAVIS_RUBY_VERSION']
17
+ end
18
+
19
+ task :default => :spec
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.8.2
@@ -0,0 +1,28 @@
1
+ # 2016-12-12
2
+ # vagrant ssh "gem build ./_my/gems/dfg-paypal/dfg-paypal.gemspec"
3
+ Gem::Specification.new do |s|
4
+ s.add_dependency "activesupport", ">= 2.3"
5
+ s.add_dependency "rest-client"
6
+ s.add_dependency "attr_required", ">= 0.0.5"
7
+ s.add_development_dependency "rake", ">= 0.8"
8
+ s.add_development_dependency "simplecov"
9
+ s.add_development_dependency "rspec", "< 2.99"
10
+ s.add_development_dependency "fakeweb", ">= 1.3.0"
11
+ s.authors = ["Dmitry Fedyuk"]
12
+ s.description = %q{This gem is used for my Discourse plugins.}
13
+ s.email = "admin@discourse.pro"
14
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
15
+ s.extra_rdoc_files = []
16
+ s.files = `git ls-files`.split("\n")
17
+ s.homepage = "https://github.com/discourse-pro/dfg-paypal"
18
+ # 2016-12-12
19
+ # Иначе при выполнении gem build будет предупреждение: «licenses is empty, but is recommended».
20
+ s.license = "Nonstandard"
21
+ s.name = "dfg-paypal"
22
+ s.require_paths = ["lib"]
23
+ s.rdoc_options = ["--charset=UTF-8"]
24
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.3.6") if s.respond_to? :required_rubygems_version=
25
+ s.summary = %q{PayPal Express Checkout API Client for Instance, Recurring and Digital Goods Payment.}
26
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
27
+ s.version = File.read(File.join(File.dirname(__FILE__), "VERSION"))
28
+ end
@@ -0,0 +1,84 @@
1
+ require 'logger'
2
+ require 'active_support'
3
+ require 'active_support/core_ext'
4
+ require 'attr_required'
5
+ require 'attr_optional'
6
+ require 'rest_client'
7
+
8
+ module Paypal
9
+ mattr_accessor :api_version
10
+ self.api_version = '204.0'
11
+
12
+ ENDPOINT = {
13
+ :production => 'https://www.paypal.com/cgi-bin/webscr',
14
+ :sandbox => 'https://www.sandbox.paypal.com/cgi-bin/webscr'
15
+ }
16
+ POPUP_ENDPOINT = {
17
+ :production => 'https://www.paypal.com/incontext',
18
+ :sandbox => 'https://www.sandbox.paypal.com/incontext'
19
+ }
20
+
21
+ def self.endpoint
22
+ if sandbox?
23
+ Paypal::ENDPOINT[:sandbox]
24
+ else
25
+ Paypal::ENDPOINT[:production]
26
+ end
27
+ end
28
+ def self.popup_endpoint
29
+ if sandbox?
30
+ Paypal::POPUP_ENDPOINT[:sandbox]
31
+ else
32
+ Paypal::POPUP_ENDPOINT[:production]
33
+ end
34
+ end
35
+
36
+ def self.log(message, mode = :info)
37
+ self.logger.send mode, message
38
+ end
39
+ def self.logger
40
+ @@logger
41
+ end
42
+ def self.logger=(logger)
43
+ @@logger = logger
44
+ end
45
+ @@logger = Logger.new(STDERR)
46
+ @@logger.progname = 'Paypal::Express'
47
+
48
+ def self.sandbox?
49
+ @@sandbox
50
+ end
51
+ def self.sandbox!
52
+ self.sandbox = true
53
+ end
54
+ def self.sandbox=(boolean)
55
+ @@sandbox = boolean
56
+ end
57
+ self.sandbox = false
58
+
59
+ end
60
+
61
+ require 'paypal/util'
62
+ require 'paypal/exception'
63
+ require 'paypal/exception/http_error'
64
+ require 'paypal/exception/api_error'
65
+ require 'paypal/base'
66
+ require 'paypal/ipn'
67
+ require 'paypal/nvp/request'
68
+ require 'paypal/nvp/response'
69
+ require 'paypal/payment/common/amount'
70
+ require 'paypal/express/request'
71
+ require 'paypal/express/response'
72
+ require 'paypal/payment/request'
73
+ require 'paypal/payment/request/item'
74
+ require 'paypal/payment/response'
75
+ require 'paypal/payment/response/info'
76
+ require 'paypal/payment/response/item'
77
+ require 'paypal/payment/response/payer'
78
+ require 'paypal/payment/response/reference'
79
+ require 'paypal/payment/response/refund'
80
+ require 'paypal/payment/response/address'
81
+ require 'paypal/payment/recurring'
82
+ require 'paypal/payment/recurring/activation'
83
+ require 'paypal/payment/recurring/billing'
84
+ require 'paypal/payment/recurring/summary'
@@ -0,0 +1,19 @@
1
+ module Paypal
2
+ class Base
3
+ include AttrRequired, AttrOptional, Util
4
+
5
+ def initialize(attributes = {})
6
+ if attributes.is_a?(Hash)
7
+ (required_attributes + optional_attributes).each do |key|
8
+ value = if numeric_attribute?(key)
9
+ Util.to_numeric(attributes[key])
10
+ else
11
+ attributes[key]
12
+ end
13
+ self.send "#{key}=", value
14
+ end
15
+ end
16
+ attr_missing!
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,4 @@
1
+ module Paypal
2
+ class Exception < StandardError
3
+ end
4
+ end
@@ -0,0 +1,94 @@
1
+ module Paypal
2
+ class Exception
3
+ class APIError < Exception
4
+ attr_accessor :response
5
+ def initialize(response = {})
6
+ @response = if response.is_a?(Hash)
7
+ Response.new response
8
+ else
9
+ response
10
+ end
11
+ end
12
+
13
+ def message
14
+ if response.respond_to?(:short_messages) && response.short_messages.any?
15
+ "PayPal API Error: " <<
16
+ response.short_messages.map{ |m| "'#{m}'" }.join(", ")
17
+ else
18
+ "PayPal API Error"
19
+ end
20
+ end
21
+
22
+ class Response
23
+ cattr_reader :attribute_mapping
24
+ @@attribute_mapping = {
25
+ :ACK => :ack,
26
+ :BUILD => :build,
27
+ :CORRELATIONID => :correlation_id,
28
+ :TIMESTAMP => :timestamp,
29
+ :VERSION => :version,
30
+ :ORDERTIME => :order_time,
31
+ :PENDINGREASON => :pending_reason,
32
+ :PAYMENTSTATUS => :payment_status,
33
+ :PAYMENTTYPE => :payment_type,
34
+ :REASONCODE => :reason_code,
35
+ :TRANSACTIONTYPE => :transaction_type
36
+ }
37
+ attr_accessor *@@attribute_mapping.values
38
+ attr_accessor :raw, :details
39
+ alias_method :colleration_id, :correlation_id # NOTE: I made a typo :p
40
+
41
+ class Detail
42
+ cattr_reader :attribute_mapping
43
+ @@attribute_mapping = {
44
+ :ERRORCODE => :error_code,
45
+ :SEVERITYCODE => :severity_code,
46
+ :LONGMESSAGE => :long_message,
47
+ :SHORTMESSAGE => :short_message
48
+ }
49
+ attr_accessor *@@attribute_mapping.values
50
+
51
+ def initialize(attributes = {})
52
+ @raw = attributes
53
+ attrs = attributes.dup
54
+ @@attribute_mapping.each do |key, value|
55
+ self.send "#{value}=", attrs.delete(key)
56
+ end
57
+
58
+ # warn ignored params
59
+ attrs.each do |key, value|
60
+ Paypal.log "Ignored Parameter (#{self.class}): #{key}=#{value}", :warn
61
+ end
62
+ end
63
+ end
64
+
65
+ def initialize(attributes = {})
66
+ attrs = attributes.dup
67
+ @raw = attributes
68
+ @@attribute_mapping.each do |key, value|
69
+ self.send "#{value}=", attrs.delete(key)
70
+ end
71
+ details = []
72
+ attrs.keys.each do |attribute|
73
+ key, index = attribute.to_s.scan(/^L_(\S+)(\d+)$/).first
74
+ next if [key, index].any?(&:blank?)
75
+ details[index.to_i] ||= {}
76
+ details[index.to_i][key.to_sym] = attrs.delete(attribute)
77
+ end
78
+ @details = details.collect do |_attrs_|
79
+ Detail.new _attrs_
80
+ end
81
+
82
+ # warn ignored params
83
+ attrs.each do |key, value|
84
+ Paypal.log "Ignored Parameter (#{self.class}): #{key}=#{value}", :warn
85
+ end
86
+ end
87
+
88
+ def short_messages
89
+ details.map(&:short_message).compact
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,12 @@
1
+ module Paypal
2
+ class Exception
3
+ class HttpError < Exception
4
+ attr_accessor :code, :message, :body
5
+ def initialize(code, message, body = '')
6
+ @code = code
7
+ @message = message
8
+ @body = body
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1 @@
1
+ require 'paypal'
@@ -0,0 +1,207 @@
1
+ module Paypal
2
+ module Express
3
+ class Request < NVP::Request
4
+
5
+ # Common
6
+
7
+ def setup(payment_requests, return_url, cancel_url, options = {})
8
+ params = {
9
+ :RETURNURL => return_url,
10
+ :CANCELURL => cancel_url,
11
+ :version => Paypal.api_version
12
+ }
13
+ if options[:no_shipping]
14
+ params[:REQCONFIRMSHIPPING] = 0
15
+ params[:NOSHIPPING] = 1
16
+ end
17
+
18
+ params[:ALLOWNOTE] = 0 if options[:allow_note] == false
19
+
20
+ {
21
+ :solution_type => :SOLUTIONTYPE,
22
+ :landing_page => :LANDINGPAGE,
23
+ :email => :EMAIL,
24
+ :brand => :BRANDNAME,
25
+ :locale => :LOCALECODE,
26
+ :logo => :LOGOIMG,
27
+ :cart_border_color => :CARTBORDERCOLOR,
28
+ :payflow_color => :PAYFLOWCOLOR
29
+ }.each do |option_key, param_key|
30
+ params[param_key] = options[option_key] if options[option_key]
31
+ end
32
+ Array(payment_requests).each_with_index do |payment_request, index|
33
+ params.merge! payment_request.to_params(index)
34
+ end
35
+ response = self.request :SetExpressCheckout, params
36
+ Response.new response, options
37
+ end
38
+
39
+ def details(token)
40
+ response = self.request :GetExpressCheckoutDetails, {
41
+ :TOKEN => token,
42
+ :version => Paypal.api_version
43
+ }
44
+ Response.new response
45
+ end
46
+
47
+ def transaction_details(transaction_id)
48
+ response = self.request :GetTransactionDetails, {:TRANSACTIONID=> transaction_id}
49
+ Response.new response
50
+ end
51
+
52
+ def checkout!(token, payer_id, payment_requests)
53
+ params = {
54
+ :TOKEN => token,
55
+ :PAYERID => payer_id,
56
+ :version => Paypal.api_version
57
+ }
58
+ Array(payment_requests).each_with_index do |payment_request, index|
59
+ params.merge! payment_request.to_params(index)
60
+ end
61
+ response = self.request :DoExpressCheckoutPayment, params
62
+ Response.new response
63
+ end
64
+
65
+ def capture!(authorization_id, amount, currency_code, complete_type = 'Complete')
66
+ params = {
67
+ :AUTHORIZATIONID => authorization_id,
68
+ :COMPLETETYPE => complete_type,
69
+ :AMT => amount,
70
+ :CURRENCYCODE => currency_code
71
+ }
72
+
73
+ response = self.request :DoCapture, params
74
+ Response.new response
75
+ end
76
+
77
+ def void!(authorization_id, params={})
78
+ params = {
79
+ :AUTHORIZATIONID => authorization_id,
80
+ :NOTE => params[:note]
81
+ }
82
+
83
+ response = self.request :DoVoid, params
84
+ Response.new response
85
+ end
86
+
87
+ # Recurring Payment Specific
88
+
89
+ def subscribe!(token, recurring_profile)
90
+ params = {
91
+ :TOKEN => token,
92
+ :version => Paypal.api_version
93
+ }
94
+ params.merge! recurring_profile.to_params
95
+ response = self.request :CreateRecurringPaymentsProfile, params
96
+ Response.new response
97
+ end
98
+
99
+ def subscription(profile_id)
100
+ params = {
101
+ :PROFILEID => profile_id,
102
+ :version => Paypal.api_version
103
+ }
104
+ response = self.request :GetRecurringPaymentsProfileDetails, params
105
+ Response.new response
106
+ end
107
+
108
+ def renew!(profile_id, action, options = {})
109
+ params = {
110
+ :PROFILEID => profile_id,
111
+ :ACTION => action,
112
+ :version => Paypal.api_version
113
+ }
114
+ if options[:note]
115
+ params[:NOTE] = options[:note]
116
+ end
117
+ response = self.request :ManageRecurringPaymentsProfileStatus, params
118
+ Response.new response
119
+ end
120
+
121
+ def suspend!(profile_id, options = {})
122
+ renew!(profile_id, :Suspend, options)
123
+ end
124
+
125
+ def cancel!(profile_id, options = {})
126
+ renew!(profile_id, :Cancel, options)
127
+ end
128
+
129
+ def reactivate!(profile_id, options = {})
130
+ renew!(profile_id, :Reactivate, options)
131
+ end
132
+
133
+
134
+ # Reference Transaction Specific
135
+
136
+ def agree!(token, options = {})
137
+ params = {
138
+ :TOKEN => token,
139
+ :version => Paypal.api_version
140
+ }
141
+ if options[:max_amount]
142
+ params[:MAXAMT] = Util.formatted_amount options[:max_amount]
143
+ end
144
+ response = self.request :CreateBillingAgreement, params
145
+ Response.new response
146
+ end
147
+
148
+ def agreement(reference_id)
149
+ params = {
150
+ :REFERENCEID => reference_id,
151
+ :version => Paypal.api_version
152
+ }
153
+ response = self.request :BillAgreementUpdate, params
154
+ Response.new response
155
+ end
156
+
157
+ def charge!(reference_id, amount, options = {})
158
+ params = {
159
+ :REFERENCEID => reference_id,
160
+ :AMT => Util.formatted_amount(amount),
161
+ :version => Paypal.api_version,
162
+ :PAYMENTACTION => options[:payment_action] || :Sale
163
+ }
164
+ if options[:currency_code]
165
+ params[:CURRENCYCODE] = options[:currency_code]
166
+ end
167
+ response = self.request :DoReferenceTransaction, params
168
+ Response.new response
169
+ end
170
+
171
+ def revoke!(reference_id)
172
+ params = {
173
+ :REFERENCEID => reference_id,
174
+ :BillingAgreementStatus => :Canceled,
175
+ :version => Paypal.api_version
176
+ }
177
+ response = self.request :BillAgreementUpdate, params
178
+ Response.new response
179
+ end
180
+
181
+
182
+ # Refund Specific
183
+
184
+ def refund!(transaction_id, options = {})
185
+ params = {
186
+ :TRANSACTIONID => transaction_id,
187
+ :REFUNDTYPE => :Full,
188
+ :version => Paypal.api_version
189
+ }
190
+ if options[:invoice_id]
191
+ params[:INVOICEID] = options[:invoice_id]
192
+ end
193
+ if options[:type]
194
+ params[:REFUNDTYPE] = options[:type]
195
+ params[:AMT] = options[:amount]
196
+ params[:CURRENCYCODE] = options[:currency_code]
197
+ end
198
+ if options[:note]
199
+ params[:NOTE] = options[:note]
200
+ end
201
+ response = self.request :RefundTransaction, params
202
+ Response.new response
203
+ end
204
+
205
+ end
206
+ end
207
+ end