Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

2.5.0

  • Loading branch information...
commit e68d54b0fe554d344515c5aaa146016a9bedf218 1 parent 4dc4fc1
Braintree Open Source braintreeps authored
Showing with 3,380 additions and 2,799 deletions.
  1. +20 −0 CHANGELOG.rdoc
  2. +4 −0 README.rdoc
  3. +7 −40 Rakefile
  4. +0 −409 bt_rdoc_template/960.css
  5. +0 −83 bt_rdoc_template/braintree.css
  6. +0 −464 bt_rdoc_template/braintree.css~
  7. BIN  bt_rdoc_template/braintree.gif
  8. +0 −216 bt_rdoc_template/braintree.rb
  9. +0 −53 bt_rdoc_template/reset.css
  10. BIN  bt_rdoc_template/ruby.png
  11. +0 −95 bt_rdoc_template/text.css
  12. +1 −1  cruise_config.rb
  13. +43 −32 lib/braintree.rb
  14. +4 −0 lib/braintree/add_on.rb
  15. +18 −72 lib/braintree/address.rb
  16. +76 −0 lib/braintree/address_gateway.rb
  17. +31 −13 lib/braintree/advanced_search.rb
  18. +6 −0 lib/braintree/base_module.rb
  19. +56 −37 lib/braintree/configuration.rb
  20. +75 −129 lib/braintree/credit_card.rb
  21. +133 −0 lib/braintree/credit_card_gateway.rb
  22. +8 −0 lib/braintree/credit_card_verification.rb
  23. +70 −123 lib/braintree/customer.rb
  24. +121 −0 lib/braintree/customer_gateway.rb
  25. +2 −2 lib/braintree/digest.rb
  26. +4 −0 lib/braintree/discount.rb
  27. +50 −5 lib/braintree/error_codes.rb
  28. +4 −18 lib/braintree/error_result.rb
  29. +1 −2  lib/braintree/errors.rb
  30. +11 −16 lib/braintree/exceptions.rb
  31. +39 −0 lib/braintree/gateway.rb
  32. +30 −26 lib/braintree/http.rb
  33. +23 −0 lib/braintree/modification.rb
  34. +1 −1  lib/braintree/resource_collection.rb
  35. +29 −129 lib/braintree/subscription.rb
  36. +122 −0 lib/braintree/subscription_gateway.rb
  37. +6 −7 lib/braintree/subscription_search.rb
  38. +1 −12 lib/braintree/successful_result.rb
  39. +4 −2 lib/braintree/test/credit_card_numbers.rb
  40. +3 −0  lib/braintree/test/transaction_amounts.rb
  41. +83 −243 lib/braintree/transaction.rb
  42. +4 −4 lib/braintree/transaction/credit_card_details.rb
  43. +124 −0 lib/braintree/transaction_gateway.rb
  44. +5 −3 lib/braintree/transaction_search.rb
  45. +19 −112 lib/braintree/transparent_redirect.rb
  46. +105 −0 lib/braintree/transparent_redirect_gateway.rb
  47. +4 −0 lib/braintree/util.rb
  48. +1 −0  lib/braintree/validation_error.rb
  49. +5 −23 lib/braintree/validation_error_collection.rb
  50. +1 −1  lib/braintree/version.rb
  51. +1 −1  lib/braintree/xml/parser.rb
  52. +2 −2 lib/braintree/xml/rexml.rb
  53. +532 −0 spec/integration/braintree/advanced_search_spec.rb
  54. +5 −8 spec/integration/braintree/credit_card_spec.rb
  55. +53 −39 spec/integration/braintree/http_spec.rb
  56. +678 −213 spec/integration/braintree/subscription_spec.rb
  57. +318 −43 spec/integration/braintree/transaction_search_spec.rb
  58. +134 −3 spec/integration/braintree/transaction_spec.rb
  59. +1 −1  spec/integration/braintree/transparent_redirect_spec.rb
  60. +55 −4 spec/spec_helper.rb
  61. +8 −8 spec/unit/braintree/address_spec.rb
  62. +1 −1  spec/unit/braintree/base_module_spec.rb
  63. +29 −29 spec/unit/braintree/configuration_spec.rb
  64. +14 −12 spec/unit/braintree/credit_card_spec.rb
  65. +16 −0 spec/unit/braintree/credit_card_verification_spec.rb
  66. +10 −8 spec/unit/braintree/customer_spec.rb
  67. +8 −17 spec/unit/braintree/digest_spec.rb
  68. +12 −2 spec/unit/braintree/error_result_spec.rb
  69. +2 −2 spec/unit/braintree/http_spec.rb
  70. +77 −0 spec/unit/braintree/subscription_search_spec.rb
  71. +16 −8 spec/unit/braintree/subscription_spec.rb
  72. +17 −12 spec/unit/braintree/transaction_spec.rb
  73. +12 −12 spec/unit/braintree/transparent_redirect_spec.rb
  74. +24 −0 spec/unit/braintree/util_spec.rb
  75. +1 −1  spec/unit/braintree/xml/parser_spec.rb
20 CHANGELOG.rdoc
View
@@ -1,3 +1,23 @@
+== 2.5.0
+
+* Added AddOns/Discounts
+* Enhanced Subscription search
+* Made gateway operations threadsafe when using multiple configurations
+* Allow specifying prorate_charges on Subscription update
+* Added AddOn/Discount details to transactions that were created from a Subscription
+* Added Expired and Pending statuses to Subscription
+* Added constants for CreditCardVerification statuses
+* Renamed GatewayRejectionReason constants to make them more idiomatic
+* Removed 13 digit Visa Sandbox Credit Card number and replaced it with a 16 digit Visa
+* Added refund class method on Transaction
+* Deprecated instance methods on Resource classes in favor of class methods
+* Added new fields to Subscription:
+ * billing_day_of_month
+ * first_billing_date
+ * number_of_billing_cycles
+ * never_expires
+ * days_past_due
+
== 2.4.0
* Added unified message to result objects
4 README.rdoc
View
@@ -65,6 +65,10 @@ Example of using bang method:
We recommend using the bang methods when you assume that the data is valid and do not expect validations to fail.
Otherwise, we recommend using the non-bang methods.
+== More Information
+
+* Documentation[http://www.braintreepaymentsolutions.com/docs/ruby]
+
== Tests
The unit specs can be run by anyone on any system, but the integration specs are meant to be run against a local development
47 Rakefile
View
@@ -29,8 +29,7 @@ task :cruise do
Rake::Task["spec:unit"].invoke
Rake::Task["spec:integration"].invoke
ensure
- Rake::Task["stop_gateway"].invoke
- Rake::Task["stop_sphinx"].invoke
+ Rake::Task["stop_gateway"].invoke rescue nil
end
end
@@ -45,25 +44,6 @@ Rake::RDocTask.new do |t|
t.rdoc_dir = "rdoc"
end
-Rake::RDocTask.new(:bt_rdoc) do |t|
- configure_rdoc_task(t)
- t.rdoc_dir = "bt_rdoc"
- t.template = "bt_rdoc_template/braintree"
-end
-Rake::Task["bt_rdoc"].prerequisites.unshift "clean"
-
-task :bt_rdoc_postprocessing do
- FileUtils.cp "bt_rdoc_template/braintree.gif", "bt_rdoc"
- FileUtils.cp "bt_rdoc_template/ruby.png", "bt_rdoc"
- Dir.glob("bt_rdoc/**/*.html") do |html_file|
- original = File.read(html_file)
- next unless original =~ /STYLE_URL/
- base_url = original[/STYLE_URL = (.*)\/.*/, 1]
- updated = original.gsub("BASE_URL", base_url)
- File.open(html_file, "w") { |f| f.write updated }
- end
-end
-task(:bt_rdoc) { Rake::Task["bt_rdoc_postprocessing"].invoke }
require File.dirname(__FILE__) + "/lib/braintree/version.rb"
gem_spec = Gem::Specification.new do |s|
@@ -88,28 +68,21 @@ require File.dirname(__FILE__) + "/lib/braintree/configuration.rb"
CRUISE_BUILD = "CRUISE_BUILD=#{ENV['CRUISE_BUILD']}"
GATEWAY_ROOT = File.dirname(__FILE__) + "/../gateway" unless defined?(GATEWAY_ROOT)
-Braintree::Configuration.environment = :development
-PID_FILE = "/tmp/gateway_server_#{Braintree::Configuration.port}.pid"
+GATEWAY_PORT = Braintree::Configuration.new(:environment => :development).port
+PID_FILE = "/tmp/gateway_server_#{GATEWAY_PORT}.pid"
task :prep_gateway do
Dir.chdir(GATEWAY_ROOT) do
sh "git pull"
- sh "env RAILS_ENV=integration #{CRUISE_BUILD} SPHINX_PORT=#{ENV['SPHINX_PORT']} rake db:migrate:reset --trace"
- sh "env RAILS_ENV=integration #{CRUISE_BUILD} SPHINX_PORT=#{ENV['SPHINX_PORT']} ruby script/populate_data"
+ sh "env RAILS_ENV=integration #{CRUISE_BUILD} rake db:migrate:reset --trace"
+ sh "env RAILS_ENV=integration #{CRUISE_BUILD} ruby script/populate_data"
Rake::Task[:start_gateway].invoke
- Rake::Task[:start_sphinx].invoke
end
end
task :start_gateway do
Dir.chdir(GATEWAY_ROOT) do
- spawn_server(PID_FILE, Braintree::Configuration.port, "integration")
- end
-end
-
-task :start_sphinx do
- Dir.chdir(GATEWAY_ROOT) do
- sh "env RAILS_ENV=integration #{CRUISE_BUILD} SPHINX_PORT=#{ENV['SPHINX_PORT']} rake ts:rebuild --trace"
+ spawn_server(PID_FILE, GATEWAY_PORT, "integration")
end
end
@@ -119,17 +92,11 @@ task :stop_gateway do
end
end
-task :stop_sphinx do
- Dir.chdir(GATEWAY_ROOT) do
- sh "env RAILS_ENV=integration rake ts:stop --trace"
- end
-end
-
desc 'Cleans generated files'
task :clean do
rm_f Dir.glob('*.gem').join(" ")
- rm_rf "bt_rdoc"
rm_rf "rdoc"
+ rm_rf "bt_rdoc"
end
def spawn_server(pid_file, port, environment="test")
409 bt_rdoc_template/960.css
View
@@ -1,409 +0,0 @@
-/*
- 960 Grid System ~ Core CSS.
- Learn more ~ http://960.gs/
-
- Licensed under GPL and MIT.
-*/
-
-/* `Containers
-----------------------------------------------------------------------------------------------------*/
-
-.container_12,
-.container_16 {
- margin-left: auto;
- margin-right: auto;
- width: 960px;
-}
-
-/* `Grid >> Global
-----------------------------------------------------------------------------------------------------*/
-
-.grid_1,
-.grid_2,
-.grid_3,
-.grid_4,
-.grid_5,
-.grid_6,
-.grid_7,
-.grid_8,
-.grid_9,
-.grid_10,
-.grid_11,
-.grid_12,
-.grid_13,
-.grid_14,
-.grid_15,
-.grid_16 {
- display: inline;
- float: left;
- margin-left: 10px;
- margin-right: 10px;
-}
-
-.container_12 .grid_3,
-.container_16 .grid_4 {
- width: 220px;
-}
-
-.container_12 .grid_6,
-.container_16 .grid_8 {
- width: 460px;
-}
-
-.container_12 .grid_9,
-.container_16 .grid_12 {
- width: 700px;
-}
-
-.container_12 .grid_12,
-.container_16 .grid_16 {
- width: 940px;
-}
-
-/* `Grid >> Children (Alpha ~ First, Omega ~ Last)
-----------------------------------------------------------------------------------------------------*/
-
-.alpha {
- margin-left: 0;
-}
-
-.omega {
- margin-right: 0;
-}
-
-/* `Grid >> 12 Columns
-----------------------------------------------------------------------------------------------------*/
-
-.container_12 .grid_1 {
- width: 60px;
-}
-
-.container_12 .grid_2 {
- width: 140px;
-}
-
-.container_12 .grid_4 {
- width: 300px;
-}
-
-.container_12 .grid_5 {
- width: 380px;
-}
-
-.container_12 .grid_7 {
- width: 540px;
-}
-
-.container_12 .grid_8 {
- width: 620px;
-}
-
-.container_12 .grid_10 {
- width: 780px;
-}
-
-.container_12 .grid_11 {
- width: 860px;
-}
-
-/* `Grid >> 16 Columns
-----------------------------------------------------------------------------------------------------*/
-
-.container_16 .grid_1 {
- width: 40px;
-}
-
-.container_16 .grid_2 {
- width: 100px;
-}
-
-.container_16 .grid_3 {
- width: 160px;
-}
-
-.container_16 .grid_5 {
- width: 280px;
-}
-
-.container_16 .grid_6 {
- width: 340px;
-}
-
-.container_16 .grid_7 {
- width: 400px;
-}
-
-.container_16 .grid_9 {
- width: 520px;
-}
-
-.container_16 .grid_10 {
- width: 580px;
-}
-
-.container_16 .grid_11 {
- width: 640px;
-}
-
-.container_16 .grid_13 {
- width: 760px;
-}
-
-.container_16 .grid_14 {
- width: 820px;
-}
-
-.container_16 .grid_15 {
- width: 880px;
-}
-
-/* `Prefix Extra Space >> Global
-----------------------------------------------------------------------------------------------------*/
-
-.container_12 .prefix_3,
-.container_16 .prefix_4 {
- padding-left: 240px;
-}
-
-.container_12 .prefix_6,
-.container_16 .prefix_8 {
- padding-left: 480px;
-}
-
-.container_12 .prefix_9,
-.container_16 .prefix_12 {
- padding-left: 720px;
-}
-
-/* `Prefix Extra Space >> 12 Columns
-----------------------------------------------------------------------------------------------------*/
-
-.container_12 .prefix_1 {
- padding-left: 80px;
-}
-
-.container_12 .prefix_2 {
- padding-left: 160px;
-}
-
-.container_12 .prefix_4 {
- padding-left: 320px;
-}
-
-.container_12 .prefix_5 {
- padding-left: 400px;
-}
-
-.container_12 .prefix_7 {
- padding-left: 560px;
-}
-
-.container_12 .prefix_8 {
- padding-left: 640px;
-}
-
-.container_12 .prefix_10 {
- padding-left: 800px;
-}
-
-.container_12 .prefix_11 {
- padding-left: 880px;
-}
-
-/* `Prefix Extra Space >> 16 Columns
-----------------------------------------------------------------------------------------------------*/
-
-.container_16 .prefix_1 {
- padding-left: 60px;
-}
-
-.container_16 .prefix_2 {
- padding-left: 120px;
-}
-
-.container_16 .prefix_3 {
- padding-left: 180px;
-}
-
-.container_16 .prefix_5 {
- padding-left: 300px;
-}
-
-.container_16 .prefix_6 {
- padding-left: 360px;
-}
-
-.container_16 .prefix_7 {
- padding-left: 420px;
-}
-
-.container_16 .prefix_9 {
- padding-left: 540px;
-}
-
-.container_16 .prefix_10 {
- padding-left: 600px;
-}
-
-.container_16 .prefix_11 {
- padding-left: 660px;
-}
-
-.container_16 .prefix_13 {
- padding-left: 780px;
-}
-
-.container_16 .prefix_14 {
- padding-left: 840px;
-}
-
-.container_16 .prefix_15 {
- padding-left: 900px;
-}
-
-/* `Suffix Extra Space >> Global
-----------------------------------------------------------------------------------------------------*/
-
-.container_12 .suffix_3,
-.container_16 .suffix_4 {
- padding-right: 240px;
-}
-
-.container_12 .suffix_6,
-.container_16 .suffix_8 {
- padding-right: 480px;
-}
-
-.container_12 .suffix_9,
-.container_16 .suffix_12 {
- padding-right: 720px;
-}
-
-/* `Suffix Extra Space >> 12 Columns
-----------------------------------------------------------------------------------------------------*/
-
-.container_12 .suffix_1 {
- padding-right: 80px;
-}
-
-.container_12 .suffix_2 {
- padding-right: 160px;
-}
-
-.container_12 .suffix_4 {
- padding-right: 320px;
-}
-
-.container_12 .suffix_5 {
- padding-right: 400px;
-}
-
-.container_12 .suffix_7 {
- padding-right: 560px;
-}
-
-.container_12 .suffix_8 {
- padding-right: 640px;
-}
-
-.container_12 .suffix_10 {
- padding-right: 800px;
-}
-
-.container_12 .suffix_11 {
- padding-right: 880px;
-}
-
-/* `Suffix Extra Space >> 16 Columns
-----------------------------------------------------------------------------------------------------*/
-
-.container_16 .suffix_1 {
- padding-right: 60px;
-}
-
-.container_16 .suffix_2 {
- padding-right: 120px;
-}
-
-.container_16 .suffix_3 {
- padding-right: 180px;
-}
-
-.container_16 .suffix_5 {
- padding-right: 300px;
-}
-
-.container_16 .suffix_6 {
- padding-right: 360px;
-}
-
-.container_16 .suffix_7 {
- padding-right: 420px;
-}
-
-.container_16 .suffix_9 {
- padding-right: 540px;
-}
-
-.container_16 .suffix_10 {
- padding-right: 600px;
-}
-
-.container_16 .suffix_11 {
- padding-right: 660px;
-}
-
-.container_16 .suffix_13 {
- padding-right: 780px;
-}
-
-.container_16 .suffix_14 {
- padding-right: 840px;
-}
-
-.container_16 .suffix_15 {
- padding-right: 900px;
-}
-
-/* `Clear Floated Elements
-----------------------------------------------------------------------------------------------------*/
-
-/* http://sonspring.com/journal/clearing-floats */
-
-html body div.clear,
-html body span.clear {
- background: none;
- border: 0;
- clear: both;
- display: block;
- float: none;
- font-size: 0;
- margin: 0;
- padding: 0;
- overflow: hidden;
- visibility: hidden;
- width: 0;
- height: 0;
-}
-
-/* http://www.positioniseverything.net/easyclearing.html */
-
-.clearfix:after {
- clear: both;
- content: '.';
- display: block;
- visibility: hidden;
- height: 0;
-}
-
-.clearfix {
- display: inline-block;
-}
-
-* html .clearfix {
- height: 1%;
-}
-
-.clearfix {
- display: block;
-}
83 bt_rdoc_template/braintree.css
View
@@ -1,83 +0,0 @@
-body {
- background: #F5F5F5;
- color: #2F4F4F;
- font-family: "MS Sans Serif", Geneva, sans-serif;
-}
-
-#wrapper {
- background-color: white;
- padding: .5em 1em;
- border: 1px solid #e5e5e5;
- margin: 1.5em auto;
-}
-
-a { font-family: Arial, Arial, Helvetica, sans-serif; }
-
-a:link, a:visited {
- text-decoration: none;
- color: #2277cc;
-}
-
-h1,h2,h3,h4,h5,h6 {
- font-family: Verdana, Verdana, Geneva, sans-serif;
-}
-
-h1 { margin-bottom: 0; padding-bottom: 0; }
-h2 { margin-bottom: 0.5em; font-size: large; border-bottom: 2px solid #999; }
-h3 { margin-bottom: 0; font-size: medium; }
-h4 { margin-bottom: 0; font-size: medium; }
-
-
-hr {
- color: #F58025;
- background-color: #F58025;
-
- clear: both;
- height: 3px;
- border: none;
- margin: 0.5em 0.5pc;
-}
-
-
-.sectiontitle {
- margin-bottom: 0.5em;
- font-size: large;
-}
-
-.method {
- margin-top: 10px;
- margin-left: 20px;
- border-bottom: 1px dashed black;
-}
-
-.method .description {
- margin-left: 20px;
-}
-
-.method p {
- margin-top: 3px;
- margin-bottom: 3px;
-}
-
-#class_index a {
- font-size: smaller;
-}
-
-.box h3 { margin-bottom: 0; }
-.box ul { list-style: none; padding: 0; margin: 0 0 .5em 0; }
-.box li { padding: 0; margin-left: 1em;}
-
-a:hover, a:active {
- text-decoration: underline;
-}
-
-a:link, a:visited {
- color: #2277CC;
- text-decoration: none;
-}
-
-pre {
- border: 1px dotted black;
- padding: 0.5em;
- background: #FFFFEE none repeat scroll 0 0;
-}
464 bt_rdoc_template/braintree.css~
View
@@ -1,464 +0,0 @@
-/*
- 960 Grid System ~ Core CSS.
- Learn more ~ http://960.gs/
-
- Licensed under GPL and MIT.
-*/
-
-/* `Containers
-----------------------------------------------------------------------------------------------------*/
-
-.container_12,
-.container_16 {
- margin-left: auto;
- margin-right: auto;
- width: 960px;
-}
-
-/* `Grid >> Global
-----------------------------------------------------------------------------------------------------*/
-
-.grid_1,
-.grid_2,
-.grid_3,
-.grid_4,
-.grid_5,
-.grid_6,
-.grid_7,
-.grid_8,
-.grid_9,
-.grid_10,
-.grid_11,
-.grid_12,
-.grid_13,
-.grid_14,
-.grid_15,
-.grid_16 {
- display: inline;
- float: left;
- margin-left: 10px;
- margin-right: 10px;
-}
-
-.container_12 .grid_3,
-.container_16 .grid_4 {
- width: 220px;
-}
-
-.container_12 .grid_6,
-.container_16 .grid_8 {
- width: 460px;
-}
-
-.container_12 .grid_9,
-.container_16 .grid_12 {
- width: 700px;
-}
-
-.container_12 .grid_12,
-.container_16 .grid_16 {
- width: 940px;
-}
-
-/* `Grid >> Children (Alpha ~ First, Omega ~ Last)
-----------------------------------------------------------------------------------------------------*/
-
-.alpha {
- margin-left: 0;
-}
-
-.omega {
- margin-right: 0;
-}
-
-/* `Grid >> 12 Columns
-----------------------------------------------------------------------------------------------------*/
-
-.container_12 .grid_1 {
- width: 60px;
-}
-
-.container_12 .grid_2 {
- width: 140px;
-}
-
-.container_12 .grid_4 {
- width: 300px;
-}
-
-.container_12 .grid_5 {
- width: 380px;
-}
-
-.container_12 .grid_7 {
- width: 540px;
-}
-
-.container_12 .grid_8 {
- width: 620px;
-}
-
-.container_12 .grid_10 {
- width: 780px;
-}
-
-.container_12 .grid_11 {
- width: 860px;
-}
-
-/* `Grid >> 16 Columns
-----------------------------------------------------------------------------------------------------*/
-
-.container_16 .grid_1 {
- width: 40px;
-}
-
-.container_16 .grid_2 {
- width: 100px;
-}
-
-.container_16 .grid_3 {
- width: 160px;
-}
-
-.container_16 .grid_5 {
- width: 280px;
-}
-
-.container_16 .grid_6 {
- width: 340px;
-}
-
-.container_16 .grid_7 {
- width: 400px;
-}
-
-.container_16 .grid_9 {
- width: 520px;
-}
-
-.container_16 .grid_10 {
- width: 580px;
-}
-
-.container_16 .grid_11 {
- width: 640px;
-}
-
-.container_16 .grid_13 {
- width: 760px;
-}
-
-.container_16 .grid_14 {
- width: 820px;
-}
-
-.container_16 .grid_15 {
- width: 880px;
-}
-
-/* `Prefix Extra Space >> Global
-----------------------------------------------------------------------------------------------------*/
-
-.container_12 .prefix_3,
-.container_16 .prefix_4 {
- padding-left: 240px;
-}
-
-.container_12 .prefix_6,
-.container_16 .prefix_8 {
- padding-left: 480px;
-}
-
-.container_12 .prefix_9,
-.container_16 .prefix_12 {
- padding-left: 720px;
-}
-
-/* `Prefix Extra Space >> 12 Columns
-----------------------------------------------------------------------------------------------------*/
-
-.container_12 .prefix_1 {
- padding-left: 80px;
-}
-
-.container_12 .prefix_2 {
- padding-left: 160px;
-}
-
-.container_12 .prefix_4 {
- padding-left: 320px;
-}
-
-.container_12 .prefix_5 {
- padding-left: 400px;
-}
-
-.container_12 .prefix_7 {
- padding-left: 560px;
-}
-
-.container_12 .prefix_8 {
- padding-left: 640px;
-}
-
-.container_12 .prefix_10 {
- padding-left: 800px;
-}
-
-.container_12 .prefix_11 {
- padding-left: 880px;
-}
-
-/* `Prefix Extra Space >> 16 Columns
-----------------------------------------------------------------------------------------------------*/
-
-.container_16 .prefix_1 {
- padding-left: 60px;
-}
-
-.container_16 .prefix_2 {
- padding-left: 120px;
-}
-
-.container_16 .prefix_3 {
- padding-left: 180px;
-}
-
-.container_16 .prefix_5 {
- padding-left: 300px;
-}
-
-.container_16 .prefix_6 {
- padding-left: 360px;
-}
-
-.container_16 .prefix_7 {
- padding-left: 420px;
-}
-
-.container_16 .prefix_9 {
- padding-left: 540px;
-}
-
-.container_16 .prefix_10 {
- padding-left: 600px;
-}
-
-.container_16 .prefix_11 {
- padding-left: 660px;
-}
-
-.container_16 .prefix_13 {
- padding-left: 780px;
-}
-
-.container_16 .prefix_14 {
- padding-left: 840px;
-}
-
-.container_16 .prefix_15 {
- padding-left: 900px;
-}
-
-/* `Suffix Extra Space >> Global
-----------------------------------------------------------------------------------------------------*/
-
-.container_12 .suffix_3,
-.container_16 .suffix_4 {
- padding-right: 240px;
-}
-
-.container_12 .suffix_6,
-.container_16 .suffix_8 {
- padding-right: 480px;
-}
-
-.container_12 .suffix_9,
-.container_16 .suffix_12 {
- padding-right: 720px;
-}
-
-/* `Suffix Extra Space >> 12 Columns
-----------------------------------------------------------------------------------------------------*/
-
-.container_12 .suffix_1 {
- padding-right: 80px;
-}
-
-.container_12 .suffix_2 {
- padding-right: 160px;
-}
-
-.container_12 .suffix_4 {
- padding-right: 320px;
-}
-
-.container_12 .suffix_5 {
- padding-right: 400px;
-}
-
-.container_12 .suffix_7 {
- padding-right: 560px;
-}
-
-.container_12 .suffix_8 {
- padding-right: 640px;
-}
-
-.container_12 .suffix_10 {
- padding-right: 800px;
-}
-
-.container_12 .suffix_11 {
- padding-right: 880px;
-}
-
-/* `Suffix Extra Space >> 16 Columns
-----------------------------------------------------------------------------------------------------*/
-
-.container_16 .suffix_1 {
- padding-right: 60px;
-}
-
-.container_16 .suffix_2 {
- padding-right: 120px;
-}
-
-.container_16 .suffix_3 {
- padding-right: 180px;
-}
-
-.container_16 .suffix_5 {
- padding-right: 300px;
-}
-
-.container_16 .suffix_6 {
- padding-right: 360px;
-}
-
-.container_16 .suffix_7 {
- padding-right: 420px;
-}
-
-.container_16 .suffix_9 {
- padding-right: 540px;
-}
-
-.container_16 .suffix_10 {
- padding-right: 600px;
-}
-
-.container_16 .suffix_11 {
- padding-right: 660px;
-}
-
-.container_16 .suffix_13 {
- padding-right: 780px;
-}
-
-.container_16 .suffix_14 {
- padding-right: 840px;
-}
-
-.container_16 .suffix_15 {
- padding-right: 900px;
-}
-
-/* `Clear Floated Elements
-----------------------------------------------------------------------------------------------------*/
-
-/* http://sonspring.com/journal/clearing-floats */
-
-html body div.clear,
-html body span.clear {
- background: none;
- border: 0;
- clear: both;
- display: block;
- float: none;
- font-size: 0;
- margin: 0;
- padding: 0;
- overflow: hidden;
- visibility: hidden;
- width: 0;
- height: 0;
-}
-
-/* http://www.positioniseverything.net/easyclearing.html */
-
-.clearfix:after {
- clear: both;
- content: '.';
- display: block;
- visibility: hidden;
- height: 0;
-}
-
-.clearfix {
- display: inline-block;
-}
-
-* html .clearfix {
- height: 1%;
-}
-
-.clearfix {
- display: block;
-}
-
-/*
-END 960.js
-*/
-
-body {
- background: #F5F5F5;
- color: #2F4F4F;
- font-family: "MS Sans Serif", Geneva, sans-serif;
-}
-
-#wrapper {
- background-color: white;
- padding: .5em 1em;
- border: 1px solid #e5e5e5;
- margin: 1.5em auto;
-}
-
-hr {
- color: #F58025;
- background-color: #F58025;
- clear: both;
- height: 3px;
- border: none;
- margin: 0.5em 0.5pc;
-}
-
-h1 {
- margin-bottom: 0;
- padding-bottom: 0;
-}
-
-h1,h2,h3,h4,h5,h6 { font-family: Verdana, Geneva, sans-serf; }
-
-.sectiontitle {
- margin-bottom: 0.5em;
- font-size: large;
-}
-
-.method {
- margin-left: 20px;
- border-bottom: 1px dashed black;
-}
-
-.method .title {
-}
-
-.method .description {
- margin-left: 20px;
-}
-
-.method p {
- margin-top: 3px;
- margin-bottom: 3px;
-}
BIN  bt_rdoc_template/braintree.gif
View
Deleted file not rendered
216 bt_rdoc_template/braintree.rb
View
@@ -1,216 +0,0 @@
-module RDoc
-module Page
-FONTS = ""
-METHOD_LIST = ""
-SRC_PAGE = ""
-FILE_PAGE = ""
-CLASS_PAGE = ""
-FR_INDEX_BODY = "!INCLUDE!"
-
-STYLE = ""
-JAVASCRIPT = ""
-
-
-FILE_INDEX = <<-END_FILE_INDEX
-START:entries
-<a href="%href%">%name%</a><br />
-END:entries
-END_FILE_INDEX
-METHOD_INDEX = "methods"
-CLASS_INDEX = <<-END_CLASS_INDEX
-<div id="class_index">
-#{FILE_INDEX}
-</div>
-END_CLASS_INDEX
-
-BODY = <<-END_BODY
-<html>
-<head>
- <title>%title% - Braintree Ruby Documentation</title>
-<style type="text/css">
-#{File.read(File.dirname(__FILE__) + "/reset.css")}
-#{File.read(File.dirname(__FILE__) + "/text.css")}
-#{File.read(File.dirname(__FILE__) + "/960.css")}
-#{File.read(File.dirname(__FILE__) + "/braintree.css")}
-</style>
-<!-- STYLE_URL = %style_url% -->
-</head>
-<body>
-<div class="container_16" id="wrapper">
-<div class="grid_16">
- <div class="grid_14 alpha">
- <a href="BASE_URL">
- <img src="BASE_URL/ruby.png" alt="Ruby" />
- <img src="BASE_URL/braintree.gif" alt="Braintree" />
- </a>
- </div>
- <div class="grid_2 omega">
- </div>
-</div>
-<hr style="background-color: #999;" />
-<div class="clear"></div>
-<div class="grid_4" id="navigation">
- <div class="box">
- <h3>Files</h3>
- <ul>
- <li><a href="BASE_URL/files/CHANGELOG_rdoc.html">CHANGELOG</a></li>
- <li><a href="BASE_URL/files/LICENSE.html">LICENSE</a></li>
- <li><a href="BASE_URL/files/README_rdoc.html">README</a></li>
- </ul>
- </div>
-
- <div class="box">
- <h3>Resources</h3>
- <ul>
- <li><a href="BASE_URL/classes/Braintree/Address.html">Address</a></li>
- <li><a href="BASE_URL/classes/Braintree/CreditCard.html">CreditCard</a></li>
- <li><a href="BASE_URL/classes/Braintree/Customer.html">Customer</a></li>
- <li><a href="BASE_URL/classes/Braintree/Subscription.html">Subscription</a></li>
- <li><a href="BASE_URL/classes/Braintree/Transaction.html">Transaction</a></li>
- </ul>
- </div>
-
- <div class="box">
- <h3>Classes</h3>
- <ul>
- <li><a href="BASE_URL/classes/Braintree/Configuration.html">Configuration</a></li>
- <li><a href="BASE_URL/classes/Braintree/ErrorResult.html">ErrorResult</a></li>
- <li><a href="BASE_URL/classes/Braintree/Errors.html">Errors</a></li>
- <li><a href="BASE_URL/classes/Braintree/ResourceCollection.html">ResourceCollection</a></li>
- <li><a href="BASE_URL/classes/Braintree/SuccessfulResult.html">SuccessfulResult</a></li>
- <li><a href="BASE_URL/classes/Braintree/Test/CreditCardNumbers.html">Test::CreditCardNumbers</a></li>
- <li><a href="BASE_URL/classes/Braintree/Test/TransactionAmounts.html">Test::TransactionAmounts</a></li>
- <li><a href="BASE_URL/classes/Braintree/Transaction/Status.html">Transaction::Status</a></li>
- <li><a href="BASE_URL/classes/Braintree/TransparentRedirect.html">TransparentRedirect</a></li>
- <li><a href="BASE_URL/classes/Braintree/ValidationErrorCollection.html">ValidationErrorCollection</a></li>
- <li><a href="BASE_URL/classes/Braintree/Version.html">Version</a></li>
- </ul>
- </div>
-
- <div class="box">
- <h3>Error Codes</h3>
- <ul>
- <li><a href="BASE_URL/classes/Braintree/ErrorCodes.html">ErrorCodes</a></li>
- <li><a href="BASE_URL/classes/Braintree/ErrorCodes/Address.html">ErrorCodes::Address</a></li>
- <li><a href="BASE_URL/classes/Braintree/ErrorCodes/CreditCard.html">ErrorCodes::CreditCard</a></li>
- <li><a href="BASE_URL/classes/Braintree/ErrorCodes/Customer.html">ErrorCodes::Customer</a></li>
- <li><a href="BASE_URL/classes/Braintree/ErrorCodes/Transaction.html">ErrorCodes::Transaction</a></li>
- </ul>
- </div>
-
- <div class="box">
- <h3>Exceptions</h3>
- <ul>
- <li><a href="BASE_URL/classes/Braintree/AuthenticationError.html">AuthenticationError</a></li>
- <li><a href="BASE_URL/classes/Braintree/AuthorizationError.html">AuthorizationError</a></li>
- <li><a href="BASE_URL/classes/Braintree/BraintreeError.html">BraintreeError</a></li>
- <li><a href="BASE_URL/classes/Braintree/ConfigurationError.html">ConfigurationError</a></li>
- <li><a href="BASE_URL/classes/Braintree/DownForMaintenanceError.html">DownForMaintenanceError</a></li>
- <li><a href="BASE_URL/classes/Braintree/ForgedQueryString.html">ForgedQueryString</a></li>
- <li><a href="BASE_URL/classes/Braintree/NotFoundError.html">NotFoundError</a></li>
- <li><a href="BASE_URL/classes/Braintree/SSLCertificateError.html">SSLCertificateError</a></li>
- <li><a href="BASE_URL/classes/Braintree/ServerError.html">ServerError</a></li>
- <li><a href="BASE_URL/classes/Braintree/UnexpectedError.html">UnexpectedError</a></li>
- <li><a href="BASE_URL/classes/Braintree/ValidationsFailed.html">ValidationsFailed</a></li>
- </ul>
- </div>
-</div>
-<div class="grid_12">
-<h1>%title%</h1>
-
-IF:description
- <hr />
- <div class="description">
- %description%
- </div>
-ENDIF:description
-
-START:sections
-IF:sectitle
-<div class="sectiontitle"><a nem="%secsequence%">%sectitle%</a></div>
-IF:seccomment
-<div class="description">
-%seccomment%
-</div>
-ENDIF:seccomment
-ENDIF:sectitle
-
-IF:constants
-<hr />
-<div class="sectiontitle">Constants</div>
-<table>
-<thead><tr><th>Constant</th><th>Value</th></tr></thead>
-<tboyd>
-START:constants
-<tr><td>%name%</td><td>%value%</td></tr>
-END:constants
-</tbody>
-</table>
-ENDIF:constants
-
-IF:attributes
-<hr />
-<div class="sectiontitle">Attributes</div>
-<table>
-START:attributes
-<tr>
-<td class='attr-rw'>
-IF:rw
-[%rw%]
-ENDIF:rw
-</td>
-<td class='attr-name'>%name%</td>
-<td class='attr-desc'>%a_desc%</td>
-</tr>
-END:attributes
-</table>
-ENDIF:attributes
-
-IF:method_list
-START:method_list
-IF:methods
-<hr />
-<div class="sectiontitle">%type% %category% Methods</div>
-START:methods
-<div class="method">
-<div class="title">
-IF:callseq
-<a name="%aref%"></a><b>%callseq%</b>
-ENDIF:callseq
-IFNOT:callseq
-<a name="%aref%"></a><b>%name%</b>%params%
-ENDIF:callseq
-</div><!-- end class=title -->
-IF:m_desc
-<div class="description"> %m_desc% </div>
-ENDIF:m_desc
-</div><!-- end class=method -->
-END:methods
-ENDIF:methods
-END:method_list
-ENDIF:method_list
-END:sections
-</div><!-- end grid_13 -->
-
-<hr />
-<div class="grid_16">&copy; Copyright 2009 Braintree Payment Solutions. All Rights Reserved.</div>
-
-<div class="clear"></div>
-</div><!-- end wrapper -->
-</body>
-</html>
-END_BODY
-
-INDEX = <<-END_INDEX
-<html>
- <head>
- <title>%title%</title>
- <meta http-equiv="refresh" content="0;url=%initial_page%" />
- </head>
- <body>
- <div>You are being redirected to <a href="%initial_page%">%initial_page%</a></div>
- </body>
-</html>
-END_INDEX
-end
-end
53 bt_rdoc_template/reset.css
View
@@ -1,53 +0,0 @@
-/* http://meyerweb.com/eric/tools/css/reset/ */
-/* v1.0 | 20080212 */
-
-html, body, div, span, applet, object, iframe,
-h1, h2, h3, h4, h5, h6, p, blockquote, pre,
-a, abbr, acronym, address, big, cite, code,
-del, dfn, em, font, img, ins, kbd, q, s, samp,
-small, strike, strong, sub, sup, tt, var,
-b, u, i, center,
-dl, dt, dd, ol, ul, li,
-fieldset, form, label, legend,
-table, caption, tbody, tfoot, thead, tr, th, td {
- margin: 0;
- padding: 0;
- border: 0;
- outline: 0;
- font-size: 100%;
- vertical-align: baseline;
- background: transparent;
-}
-body {
- line-height: 1;
-}
-ol, ul {
- list-style: none;
-}
-blockquote, q {
- quotes: none;
-}
-blockquote:before, blockquote:after,
-q:before, q:after {
- content: '';
- content: none;
-}
-
-/* remember to define focus styles! */
-:focus {
- outline: 0;
-}
-
-/* remember to highlight inserts somehow! */
-ins {
- text-decoration: none;
-}
-del {
- text-decoration: line-through;
-}
-
-/* tables still need 'cellspacing="0"' in the markup */
-table {
- border-collapse: collapse;
- border-spacing: 0;
-}
BIN  bt_rdoc_template/ruby.png
View
Deleted file not rendered
95 bt_rdoc_template/text.css
View
@@ -1,95 +0,0 @@
-/*
- 960 Grid System ~ Text CSS.
- Learn more ~ http://960.gs/
-
- Licensed under GPL and MIT.
-*/
-
-/* `Basic HTML
-----------------------------------------------------------------------------------------------------*/
-
-body {
- font: 13px/1.5 Helvetica, Arial, 'Liberation Sans', FreeSans, sans-serif;
-}
-
-a:focus {
- outline: 1px dotted invert;
-}
-
-hr {
- border-color: #ccc;
- border-style: solid;
- border-width: 1px 0 0;
- clear: both;
- height: 0;
-}
-
-/* `Headings
-----------------------------------------------------------------------------------------------------*/
-
-h1 {
- font-size: 25px;
-}
-
-h2 {
- font-size: 23px;
-}
-
-h3 {
- font-size: 21px;
-}
-
-h4 {
- font-size: 19px;
-}
-
-h5 {
- font-size: 17px;
-}
-
-h6 {
- font-size: 15px;
-}
-
-/* `Spacing
-----------------------------------------------------------------------------------------------------*/
-
-ol {
- list-style: decimal;
-}
-
-ul {
- list-style: square;
-}
-
-li {
- margin-left: 30px;
-}
-
-p,
-dl,
-hr,
-h1,
-h2,
-h3,
-h4,
-h5,
-h6,
-ol,
-ul,
-pre,
-table,
-address,
-fieldset {
- margin-bottom: 20px;
-}
-
-/* `Sizing
-----------------------------------------------------------------------------------------------------*/
-.large {
- font-size: 2em;
-}
-
-.small {
- font-size: 0.9em;
-}
2  cruise_config.rb
View
@@ -3,7 +3,7 @@
case project.name
when "client_library_ruby_integration_master"
- project.build_command = "CRUISE_BUILD=#{project.name} GATEWAY_PORT=3010 SPHINX_PORT=3322 rake cruise --trace"
+ project.build_command = "CRUISE_BUILD=#{project.name} GATEWAY_PORT=3010 rake cruise --trace"
project.triggered_by :gateway_master
end
end
75 lib/braintree.rb
View
@@ -3,6 +3,7 @@
require "date"
require "digest/sha1"
require "enumerator"
+require "forwardable"
require "logger"
require "net/http"
require "net/https"
@@ -18,41 +19,51 @@ module Braintree
require "braintree/exceptions"
require "braintree/base_module"
+require "braintree/modification"
-require "braintree/address.rb"
-require "braintree/advanced_search.rb"
-require "braintree/configuration.rb"
-require "braintree/credit_card.rb"
-require "braintree/credit_card_verification.rb"
-require "braintree/customer.rb"
-require "braintree/digest.rb"
-require "braintree/error_codes.rb"
-require "braintree/error_result.rb"
-require "braintree/errors.rb"
-require "braintree/http.rb"
-require "braintree/resource_collection.rb"
-require "braintree/ssl_expiration_check.rb"
+require "braintree/add_on"
+require "braintree/address"
+require "braintree/address_gateway"
+require "braintree/advanced_search"
+require "braintree/configuration"
+require "braintree/credit_card"
+require "braintree/credit_card_gateway"
+require "braintree/credit_card_verification"
+require "braintree/customer"
+require "braintree/customer_gateway"
+require "braintree/digest"
+require "braintree/discount"
+require "braintree/error_codes"
+require "braintree/error_result"
+require "braintree/errors"
+require "braintree/gateway"
+require "braintree/http"
+require "braintree/resource_collection"
+require "braintree/ssl_expiration_check"
require "braintree/subscription"
+require "braintree/subscription_gateway"
require "braintree/subscription_search"
-require "braintree/successful_result.rb"
-require "braintree/test/credit_card_numbers.rb"
-require "braintree/test/transaction_amounts.rb"
-require "braintree/transaction.rb"
-require "braintree/transaction_search.rb"
-require "braintree/transaction/address_details.rb"
-require "braintree/transaction/credit_card_details.rb"
-require "braintree/transaction/customer_details.rb"
-require "braintree/transaction/status_details.rb"
-require "braintree/transparent_redirect.rb"
-require "braintree/util.rb"
-require "braintree/validation_error.rb"
-require "braintree/validation_error_collection.rb"
-require "braintree/version.rb"
-require "braintree/xml.rb"
-require "braintree/xml/generator.rb"
-require "braintree/xml/libxml.rb"
-require "braintree/xml/rexml.rb"
-require "braintree/xml/parser.rb"
+require "braintree/successful_result"
+require "braintree/test/credit_card_numbers"
+require "braintree/test/transaction_amounts"
+require "braintree/transaction"
+require "braintree/transaction/address_details"
+require "braintree/transaction/credit_card_details"
+require "braintree/transaction/customer_details"
+require "braintree/transaction_gateway"
+require "braintree/transaction_search"
+require "braintree/transaction/status_details"
+require "braintree/transparent_redirect"
+require "braintree/transparent_redirect_gateway"
+require "braintree/util"
+require "braintree/validation_error"
+require "braintree/validation_error_collection"
+require "braintree/version"
+require "braintree/xml"
+require "braintree/xml/generator"
+require "braintree/xml/libxml"
+require "braintree/xml/rexml"
+require "braintree/xml/parser"
Braintree::SSLExpirationCheck.check_dates
4 lib/braintree/add_on.rb
View
@@ -0,0 +1,4 @@
+module Braintree
+ class AddOn < Modification
+ end
+end
90 lib/braintree/address.rb
View
@@ -1,7 +1,5 @@
module Braintree
- # An Address belongs to a Customer. It can be associated to a
- # CreditCard as the billing address. It can also be used
- # as the shipping address when creating a Transaction.
+ # See http://www.braintreepaymentsolutions.com/docs/ruby/addresses/details
class Address
include BaseModule # :nodoc:
@@ -10,21 +8,7 @@ class Address
:country_code_alpha2, :country_code_alpha3, :country_code_numeric
def self.create(attributes)
- Util.verify_keys(_create_signature, attributes)
- unless attributes[:customer_id]
- raise ArgumentError, "Expected hash to contain a :customer_id"
- end
- unless attributes[:customer_id] =~ /\A[0-9A-Za-z_-]+\z/
- raise ArgumentError, ":customer_id contains invalid characters"
- end
- response = Http.post "/customers/#{attributes.delete(:customer_id)}/addresses", :address => attributes
- if response[:address]
- SuccessfulResult.new(:address => new(response[:address]))
- elsif response[:api_error_response]
- ErrorResult.new(response[:api_error_response])
- else
- raise UnexpectedError, "expected :address or :api_error_response"
- end
+ Configuration.gateway.address.create(attributes)
end
def self.create!(attributes)
@@ -32,39 +16,23 @@ def self.create!(attributes)
end
def self.delete(customer_or_customer_id, address_id)
- customer_id = _determine_customer_id(customer_or_customer_id)
- Http.delete("/customers/#{customer_id}/addresses/#{address_id}")
- SuccessfulResult.new
+ Configuration.gateway.address.delete(customer_or_customer_id, address_id)
end
- # Finds the address with the given +address_id+ that is associated to the given +customer_or_customer_id+.
- # If the address cannot be found, a NotFoundError will be raised.
def self.find(customer_or_customer_id, address_id)
- customer_id = _determine_customer_id(customer_or_customer_id)
- response = Http.get("/customers/#{customer_id}/addresses/#{address_id}")
- new(response[:address])
- rescue NotFoundError
- raise NotFoundError, "address for customer #{customer_id.inspect} with id #{address_id.inspect} not found"
+ Configuration.gateway.address.find(customer_or_customer_id, address_id)
end
def self.update(customer_or_customer_id, address_id, attributes)
- Util.verify_keys(_update_signature, attributes)
- customer_id = _determine_customer_id(customer_or_customer_id)
- response = Http.put "/customers/#{customer_id}/addresses/#{address_id}", :address => attributes
- if response[:address]
- SuccessfulResult.new(:address => new(response[:address]))
- elsif response[:api_error_response]
- ErrorResult.new(response[:api_error_response])
- else
- raise UnexpectedError, "expected :address or :api_error_response"
- end
+ Configuration.gateway.address.update(customer_or_customer_id, address_id, attributes)
end
def self.update!(customer_or_customer_id, address_id, attributes)
return_object_or_raise(:address) { update(customer_or_customer_id, address_id, attributes) }
end
- def initialize(attributes) # :nodoc:
+ def initialize(gateway, attributes) # :nodoc:
+ @gateway = gateway
set_instance_variables_from_hash(attributes)
end
@@ -73,25 +41,25 @@ def ==(other) # :nodoc:
id == other.id && customer_id == other.customer_id
end
- # Deletes the address.
+ # Deprecated. Use Braintree::Address.delete
def delete
- Address.delete(customer_id, self.id)
+ warn "[DEPRECATED] delete as an instance method is deprecated. Please use CreditCard.delete"
+ @gateway.address.delete(customer_id, self.id)
end
+ # Deprecated. Use Braintree::Address.update
def update(attributes)
- Util.verify_keys(self.class._update_signature, attributes)
- response = Http.put "/customers/#{customer_id}/addresses/#{id}", :address => attributes
- if response[:address]
- set_instance_variables_from_hash response[:address]
- SuccessfulResult.new(:address => self)
- elsif response[:api_error_response]
- ErrorResult.new(response[:api_error_response])
- else
- raise UnexpectedError, "expected :address or :api_error_response"
+ warn "[DEPRECATED] update as an instance method is deprecated. Please use CreditCard.update"
+ result = @gateway.address.update(customer_id, id, attributes)
+ if result.success?
+ copy_instance_variables_from_object result.address
end
+ result
end
+ # Deprecated. Use Braintree::Address.update!
def update!(attributes)
+ warn "[DEPRECATED] update! as an instance method is deprecated. Please use CreditCard.update!"
return_object_or_raise(:address) { update(attributes) }
end
@@ -99,30 +67,8 @@ class << self
protected :new
end
- def self._create_signature # :nodoc:
- _shared_signature + [:customer_id]
- end
-
- def self._determine_customer_id(customer_or_customer_id) # :nodoc:
- customer_id = customer_or_customer_id.is_a?(Customer) ? customer_or_customer_id.id : customer_or_customer_id
- unless customer_id =~ /\A[\w_-]+\z/
- raise ArgumentError, "customer_id contains invalid characters"
- end
- customer_id
- end
-
- def self._shared_signature # :nodoc:
- [:company, :country_code_alpha2, :country_code_alpha3, :country_code_numeric,
- :country_name, :extended_address, :first_name,
- :last_name, :locality, :postal_code, :region, :street_address]
- end
-
def self._new(*args) # :nodoc:
self.new *args
end
-
- def self._update_signature # :nodoc:
- _create_signature
- end
end
end
76 lib/braintree/address_gateway.rb
View
@@ -0,0 +1,76 @@
+module Braintree
+ class AddressGateway # :nodoc
+ def initialize(gateway)
+ @gateway = gateway
+ @config = gateway.config
+ end
+
+ def create(attributes)
+ Util.verify_keys(AddressGateway._create_signature, attributes)
+ unless attributes[:customer_id]
+ raise ArgumentError, "Expected hash to contain a :customer_id"
+ end
+ unless attributes[:customer_id] =~ /\A[0-9A-Za-z_-]+\z/
+ raise ArgumentError, ":customer_id contains invalid characters"
+ end
+ response = @config.http.post "/customers/#{attributes.delete(:customer_id)}/addresses", :address => attributes
+ if response[:address]
+ SuccessfulResult.new(:address => Address._new(@gateway, response[:address]))
+ elsif response[:api_error_response]
+ ErrorResult.new(@gateway, response[:api_error_response])
+ else
+ raise UnexpectedError, "expected :address or :api_error_response"
+ end
+ end
+
+ def delete(customer_or_customer_id, address_id)
+ customer_id = _determine_customer_id(customer_or_customer_id)
+ @config.http.delete("/customers/#{customer_id}/addresses/#{address_id}")
+ SuccessfulResult.new
+ end
+
+ def find(customer_or_customer_id, address_id)
+ customer_id = _determine_customer_id(customer_or_customer_id)
+ response = @config.http.get("/customers/#{customer_id}/addresses/#{address_id}")
+ Address._new(@gateway, response[:address])
+ rescue NotFoundError
+ raise NotFoundError, "address for customer #{customer_id.inspect} with id #{address_id.inspect} not found"
+ end
+
+ def update(customer_or_customer_id, address_id, attributes)
+ Util.verify_keys(AddressGateway._update_signature, attributes)
+ customer_id = _determine_customer_id(customer_or_customer_id)
+ response = @config.http.put "/customers/#{customer_id}/addresses/#{address_id}", :address => attributes
+ if response[:address]
+ SuccessfulResult.new(:address => Address._new(@gateway, response[:address]))
+ elsif response[:api_error_response]
+ ErrorResult.new(@gateway, response[:api_error_response])
+ else
+ raise UnexpectedError, "expected :address or :api_error_response"
+ end
+ end
+
+ def _determine_customer_id(customer_or_customer_id) # :nodoc:
+ customer_id = customer_or_customer_id.is_a?(Customer) ? customer_or_customer_id.id : customer_or_customer_id
+ unless customer_id =~ /\A[\w_-]+\z/
+ raise ArgumentError, "customer_id contains invalid characters"
+ end
+ customer_id
+ end
+
+ def self._create_signature # :nodoc:
+ _shared_signature + [:customer_id]
+ end
+
+ def self._shared_signature # :nodoc:
+ [:company, :country_code_alpha2, :country_code_alpha3, :country_code_numeric,
+ :country_name, :extended_address, :first_name,
+ :last_name, :locality, :postal_code, :region, :street_address]
+ end
+
+ def self._update_signature # :nodoc:
+ _create_signature
+ end
+ end
+end
+
44 lib/braintree/advanced_search.rb
View
@@ -1,6 +1,6 @@
module Braintree
- class AdvancedSearch
- class SearchNode
+ class AdvancedSearch # :nodoc:
+ class SearchNode # :nodoc:
def self.operators(*operator_names)
operator_names.each do |operator|
define_method(operator) do |value|
@@ -14,25 +14,25 @@ def initialize(name, parent)
end
end
- class EqualityNode < SearchNode
+ class EqualityNode < SearchNode # :nodoc:
operators :is, :is_not
end
- class PartialMatchNode < EqualityNode
+ class PartialMatchNode < EqualityNode # :nodoc:
operators :ends_with, :starts_with
end
- class TextNode < PartialMatchNode
+ class TextNode < PartialMatchNode # :nodoc:
operators :contains
end
- class KeyValueNode < SearchNode
+ class KeyValueNode < SearchNode # :nodoc:
def is(value)
@parent.add_criteria(@node_name, value)
end
end
- class MultipleValueNode < SearchNode
+ class MultipleValueNode < SearchNode # :nodoc:
def in(*values)
values.flatten!
@@ -44,10 +44,6 @@ def in(*values)
@parent.add_criteria(@node_name, values)
end
- def is(value)
- self.in(value)
- end
-
def initialize(name, parent, options)
super(name, parent)
@options = options
@@ -56,9 +52,25 @@ def initialize(name, parent, options)
def allowed_values
@options[:allows]
end
+
+ def is(value)
+ self.in(value)
+ end
+ end
+
+ class MultipleValueOrTextNode < MultipleValueNode
+ extend Forwardable
+ def_delegators :@text_node, :contains, :ends_with, :is, :is_not, :starts_with
+
+ def initialize(name, parent, options)
+ super
+ @text_node = TextNode.new(name, parent)
+ end
end
- class RangeNode < SearchNode
+ class RangeNode < SearchNode # :nodoc:
+ operators :is
+
def between(min, max)
self >= min
self <= max
@@ -73,7 +85,7 @@ def <=(max)
end
end
- def self.search_fields(*fields)
+ def self.text_fields(*fields)
_create_field_accessors(fields, TextNode)
end
@@ -91,6 +103,12 @@ def self.multiple_value_field(field, options={})
end
end
+ def self.multiple_value_or_text_field(field, options={})
+ define_method(field) do
+ MultipleValueOrTextNode.new(field, self, options)
+ end
+ end
+
def self.key_value_fields(*fields)
_create_field_accessors(fields, KeyValueNode)
end
6 lib/braintree/base_module.rb
View
@@ -10,6 +10,12 @@ def return_object_or_raise(object_to_return)
end
end
+ def copy_instance_variables_from_object(object)
+ object.instance_variables.each do |ivar|
+ instance_variable_set ivar, object.instance_variable_get(ivar)
+ end
+ end
+
def set_instance_variables_from_hash(hash)
hash.each do |key, value|
instance_variable_set "@#{key}", value
93 lib/braintree/configuration.rb
View
@@ -1,19 +1,13 @@
module Braintree
- # The following configuration attributes need to be set to use the gem:
- # * merchant_id
- # * public_key
- # * private_key
- # * environment
- #
- # By default, the logger will log to +STDOUT+. The log level is set to info.
- # The logger can be set to any Logger object.
- module Configuration
+ # See http://www.braintreepaymentsolutions.com/docs/ruby
+ class Configuration
API_VERSION = "2" # :nodoc:
class << self
- attr_accessor :logger
- attr_writer :merchant_id, :public_key, :private_key
+ attr_reader :logger
+ attr_writer :custom_user_agent, :logger, :merchant_id, :public_key, :private_key
end
+ attr_reader :merchant_id, :public_key, :private_key
def self.expectant_reader(*attributes) # :nodoc:
attributes.each do |attribute|
@@ -26,16 +20,49 @@ def self.expectant_reader(*attributes) # :nodoc:
end
expectant_reader :environment, :merchant_id, :public_key, :private_key
- def self.base_merchant_url # :nodoc:
- "#{protocol}://#{server}:#{port}#{base_merchant_path}"
+ # Sets the Braintree environment to use. Valid values are <tt>:sandbox</tt> and <tt>:production</tt>
+ def self.environment=(env)
+ unless [:development, :qa, :sandbox, :production].include?(env)
+ raise ArgumentError, "#{env.inspect} is not a valid environment"
+ end
+ @environment = env
+ end
+
+ def self.gateway # :nodoc:
+ Braintree::Gateway.new(instantiate)
+ end
+
+ def self.instantiate # :nodoc:
+ config = new(
+ :custom_user_agent => @custom_user_agent,
+ :environment => environment,
+ :logger => @logger,
+ :merchant_id => merchant_id,
+ :private_key => private_key,
+ :public_key => public_key
+ )
+ end
+
+ def initialize(options = {})
+ [:environment, :merchant_id, :public_key, :private_key, :custom_user_agent, :logger].each do |attr|
+ instance_variable_set "@#{attr}", options[attr]
+ end
end
- def self.base_merchant_path # :nodoc:
- "/merchants/#{Braintree::Configuration.merchant_id}"
+ def api_version # :nodoc:
+ API_VERSION
end
- def self.ca_file # :nodoc:
- case environment
+ def base_merchant_path # :nodoc:
+ "/merchants/#{merchant_id}"
+ end
+
+ def base_merchant_url # :nodoc:
+ "#{protocol}://#{server}:#{port}#{base_merchant_path}"
+ end
+
+ def ca_file # :nodoc:
+ case @environment
when :qa, :sandbox
File.expand_path(File.join(File.dirname(__FILE__), "..", "ssl", "sandbox_braintreegateway_com.ca.crt"))
when :production
@@ -43,20 +70,16 @@ def self.ca_file # :nodoc:
end
end
- # Sets the Braintree environment to use. Valid values are <tt>:sandbox</tt> and <tt>:production</tt>
- def self.environment=(env)
- unless [:development, :qa, :sandbox, :production].include?(env)
- raise ArgumentError, "#{env.inspect} is not a valid environment"
- end
- @environment = env
+ def http # :nodoc:
+ Http.new(self)
end
- def self.logger # :nodoc:
+ def logger # :nodoc:
@logger ||= _default_logger
end
- def self.port # :nodoc:
- case environment
+ def port # :nodoc:
+ case @environment
when :development
ENV['GATEWAY_PORT'] || 3000
when :production, :qa, :sandbox
@@ -64,12 +87,12 @@ def self.port # :nodoc:
end
end
- def self.protocol # :nodoc:
+ def protocol # :nodoc:
ssl? ? "https" : "http"
end
- def self.server # :nodoc:
- case environment
+ def server # :nodoc:
+ case @environment
when :development
"localhost"
when :production
@@ -81,8 +104,8 @@ def self.server # :nodoc:
end
end
- def self.ssl? # :nodoc:
- case environment
+ def ssl? # :nodoc:
+ case @environment
when :development
false
when :production, :qa, :sandbox
@@ -90,16 +113,12 @@ def self.ssl? # :nodoc:
end
end
- def self.custom_user_agent=(custom_user_agent)
- @custom_user_agent = custom_user_agent
- end
-
- def self.user_agent
+ def user_agent # :nodoc:
base_user_agent = "Braintree Ruby Gem #{Braintree::Version::String}"
@custom_user_agent ? "#{base_user_agent} (#{@custom_user_agent})" : base_user_agent
end
- def self._default_logger # :nodoc:
+ def _default_logger # :nodoc:
logger = Logger.new(STDOUT)
logger.level = Logger::INFO
logger
204 lib/braintree/credit_card.rb
View
@@ -1,8 +1,5 @@
module Braintree
- # == More Information
- #
- # For more detailed documentation on CreditCards, see http://www.braintreepaymentsolutions.com/gateway/credit-card-api
- # For more detailed documentation on CreditCard verification, see http://www.braintreepaymentsolutions.com/gateway/credit-card-verification-api
+ # See http://www.braintreepaymentsolutions.com/docs/ruby
class CreditCard
include BaseModule # :nodoc:
@@ -32,131 +29,125 @@ module CustomerLocation
attr_reader :billing_address, :bin, :card_type, :cardholder_name, :created_at, :customer_id, :expiration_month,
:expiration_year, :last_4, :subscriptions, :token, :updated_at
+ # See http://www.braintreepaymentsolutions.com/docs/ruby/credit_cards/create
def self.create(attributes)
- if attributes.has_key?(:expiration_date) && (attributes.has_key?(:expiration_month) || attributes.has_key?(:expiration_year))
- raise ArgumentError.new("create with both expiration_month and expiration_year or only expiration_date")
- end
- Util.verify_keys(_create_signature, attributes)
- _do_create("/payment_methods", :credit_card => attributes)
+ Configuration.gateway.credit_card.create(attributes)
end
+ # See http://www.braintreepaymentsolutions.com/docs/ruby/credit_cards/create
def self.create!(attributes)
return_object_or_raise(:credit_card) { create(attributes) }
end
- # The transparent redirect URL to use to create a credit card.
+ # Deprecated. Use Braintree::TransparentRedirect.url
+ # See http://www.braintreepaymentsolutions.com/docs/ruby/credit_cards/create_tr
def self.create_credit_card_url
warn "[DEPRECATED] CreditCard.create_credit_card_url is deprecated. Please use TransparentRedirect.url"
- "#{Braintree::Configuration.base_merchant_url}/payment_methods/all/create_via_transparent_redirect_request"
+ Configuration.gateway.credit_card.create_credit_card_url
end
+ # Deprecated. Use Braintree::TransparentRedirect.confirm
+ # See http://www.braintreepaymentsolutions.com/docs/ruby/credit_cards/create_tr
def self.create_from_transparent_redirect(query_string)
warn "[DEPRECATED] CreditCard.create_from_transparent_redirect is deprecated. Please use TransparentRedirect.confirm"
- params = TransparentRedirect.parse_and_validate_query_string query_string
- _do_create("/payment_methods/all/confirm_transparent_redirect_request", :id => params[:id])
+ Configuration.gateway.credit_card.create_from_transparent_redirect(query_string)
end
+ # See http://www.braintreepaymentsolutions.com/docs/ruby/transactions/create_from_vault
def self.credit(token, transaction_attributes)
- Transaction.credit(transaction_attributes.merge(
- :payment_method_token => token
- ))
+ Transaction.credit(transaction_attributes.merge(:payment_method_token => token))
end
+ # See http://www.braintreepaymentsolutions.com/docs/ruby/transactions/create_from_vault
def self.credit!(token, transaction_attributes)
return_object_or_raise(:transaction) { credit(token, transaction_attributes) }
end
+ # See http://www.braintreepaymentsolutions.com/docs/ruby/credit_cards/delete
def self.delete(token)
- Http.delete("/payment_methods/#{token}")
+ Configuration.gateway.credit_card.delete(token)
end
- # Returns a ResourceCollection of expired credit cards.
+ # See http://www.braintreepaymentsolutions.com/docs/ruby/credit_cards/search
def self.expired(options = {})
- response = Http.post("/payment_methods/all/expired_ids")
- ResourceCollection.new(response) { |ids| _fetch_expired(ids) }
+ Configuration.gateway.credit_card.expired(options)
end
- # Returns a ResourceCollection of credit cards expiring between +start_date+ and +end_date+ inclusive.
- # Only the month and year of the start and end dates are used.
+ # See http://www.braintreepaymentsolutions.com/docs/ruby/credit_cards/search
def self.expiring_between(start_date, end_date, options = {})
- formatted_start_date = start_date.strftime('%m%Y')
- formatted_end_date = end_date.strftime('%m%Y')
- response = Http.post("/payment_methods/all/expiring_ids?start=#{formatted_start_date}&end=#{formatted_end_date}")
- ResourceCollection.new(response) { |ids| _fetch_expiring_between(formatted_start_date, formatted_end_date, ids) }
+ Configuration.gateway.credit_card.expiring_between(start_date, end_date, options)
end
- # Finds the credit card with the given +token+. Raises a NotFoundError if it cannot be found.
+ # See http://www.braintreepaymentsolutions.com/docs/ruby/credit_cards/search
def self.find(token)
- response = Http.get "/payment_methods/#{token}"
- new(response[:credit_card])
- rescue NotFoundError
- raise NotFoundError, "payment method with token #{token.inspect} not found"
+ Configuration.gateway.credit_card.find(token)
end
+ # See http://www.braintreepaymentsolutions.com/docs/ruby/transactions/create_from_vault
def self.sale(token, transaction_attributes)
- Transaction.sale(transaction_attributes.merge(
- :payment_method_token => token
- ))
+ Configuration.gateway.transaction.sale(transaction_attributes.merge(:payment_method_token => token))
end
+ # See http://www.braintreepaymentsolutions.com/docs/ruby/transactions/create_from_vault
def self.sale!(token, transaction_attributes)
return_object_or_raise(:transaction) { sale(token, transaction_attributes) }
end
+ # See http://www.braintreepaymentsolutions.com/docs/ruby/credit_cards/update
def self.update(token, attributes)
- Util.verify_keys(_update_signature, attributes)
- _do_update(:put, "/payment_methods/#{token}", :credit_card => attributes)
+ Configuration.gateway.credit_card.update(token, attributes)
end
+ # See http://www.braintreepaymentsolutions.com/docs/ruby/credit_cards/update
def self.update!(token, attributes)
return_object_or_raise(:credit_card) { update(token, attributes) }
end
+ # Deprecated. Use Braintree::TransparentRedirect.confirm
+ #
+ # See http://www.braintreepaymentsolutions.com/docs/ruby/credit_cards/update_tr
def self.update_from_transparent_redirect(query_string)
warn "[DEPRECATED] CreditCard.update_via_transparent_redirect_request is deprecated. Please use TransparentRedirect.confirm"
- params = TransparentRedirect.parse_and_validate_query_string query_string
- _do_update(:post, "/payment_methods/all/confirm_transparent_redirect_request", :id => params[:id])
+ Configuration.gateway.credit_card.update_from_transparent_redirect(query_string)
end
- # The transparent redirect URL to use to update a credit card.
+ # Deprecated. Use Braintree::TransparentRedirect.url
+ #
+ # See http://www.braintreepaymentsolutions.com/docs/ruby/credit_cards/update_tr
def self.update_credit_card_url
warn "[DEPRECATED] CreditCard.update_credit_card_url is deprecated. Please use TransparentRedirect.url"
- "#{Braintree::Configuration.base_merchant_url}/payment_methods/all/update_via_transparent_redirect_request"
- end
-
- def self._fetch_expired(ids)
- response = Http.post("/payment_methods/all/expired", :search => {:ids => ids})
- attributes = response[:payment_methods]
- Util.extract_attribute_as_array(attributes, :credit_card).map { |attrs| _new(attrs) }
+ Configuration.gateway.credit_card.update_credit_card_url
end
- def self._fetch_expiring_between(formatted_start_date, formatted_end_date, ids)
- response = Http.post(
- "/payment_methods/all/expiring?start=#{formatted_start_date}&end=#{formatted_end_date}",
- :search => {:ids => ids}
- )
- attributes = response[:payment_methods]
- Util.extract_attribute_as_array(attributes, :credit_card).map { |attrs| _new(attrs) }
- end
-
- def initialize(attributes) # :nodoc:
- _init attributes
- @subscriptions = (@subscriptions || []).map { |subscription_hash| Subscription._new(subscription_hash) }
+ def initialize(gateway, attributes) # :nodoc:
+ @gateway = gateway
+ set_instance_variables_from_hash(attributes)
+ @billing_address = attributes[:billing_address] ? Address._new(@gateway, attributes[:billing_address]) : nil
+ @subscriptions = (@subscriptions || []).map { |subscription_hash| Subscription._new(@gateway, subscription_hash) }
end
- # Creates a credit transaction for this credit card.
+ # Deprecated. Use Braintree::CreditCard.credit
+ #
+ # See http://www.braintreepaymentsolutions.com/docs/ruby/transactions/create_from_vault
def credit(transaction_attributes)
- Transaction.credit(transaction_attributes.merge(
- :payment_method_token => self.token
- ))
+ warn "[DEPRECATED] credit as an instance method is deprecated. Please use CreditCard.credit"
+ @gateway.transaction.credit(transaction_attributes.merge(:payment_method_token => token))
end
+ # Deprecated. Use Braintree::CreditCard.credit!
+ #
+ # See http://www.braintreepaymentsolutions.com/docs/ruby/transactions/create_from_vault
def credit!(transaction_attributes)
+ warn "[DEPRECATED] credit! as an instance method is deprecated. Please use CreditCard.credit!"
return_object_or_raise(:transaction) { credit(transaction_attributes) }
end
+ # Deprecated. Use Braintree::CreditCard.delete
+ #
+ # http://www.braintreepaymentsolutions.com/docs/ruby/credit_cards/delete
def delete
- CreditCard.delete(token)
+ warn "[DEPRECATED] delete as an instance method is deprecated. Please use CreditCard.delete"
+ @gateway.credit_card.delete(token)
end
# Returns true if this credit card is the customer's default.
@@ -187,29 +178,39 @@ def masked_number
"#{bin}******#{last_4}"
end
- # Creates a sale transaction for this credit card.
+ # Deprecated. Use Braintree::CreditCard.sale
+ #
+ # See http://www.braintreepaymentsolutions.com/docs/ruby/transactions/create_from_vault
def sale(transaction_attributes)
- CreditCard.sale(self.token, transaction_attributes)
+ warn "[DEPRECATED] sale as an instance method is deprecated. Please use CreditCard.sale"
+ @gateway.transaction.sale(transaction_attributes.merge(:payment_method_token => token))
end
+ # Deprecated. Use Braintree::CreditCard.sale!
+ #
+ # See http://www.braintreepaymentsolutions.com/docs/ruby/transactions/create_from_vault
def sale!(transaction_attributes)
+ warn "[DEPRECATED] sale! as an instance method is deprecated. Please use CreditCard.sale!"
return_object_or_raise(:transaction) { sale(transaction_attributes) }
end
+ # Deprecated. Use Braintree::CreditCard.update
+ #
+ # See http://www.braintreepaymentsolutions.com/docs/ruby/credit_cards/update
def update(attributes)
- Util.verify_keys(self.class._update_signature, attributes)
- response = Http.put "/payment_methods/#{token}", :credit_card => attributes
- if response[:credit_card]
- _init response[:credit_card]
- SuccessfulResult.new(:credit_card => self)
- elsif response[:api_error_response]
- ErrorResult.new(response[:api_error_response])
- else
- raise UnexpectedError, "expected :credit_card or :api_error_response"
+ warn "[DEPRECATED] update as an instance method is deprecated. Please use CreditCard.update"
+ result = @gateway.credit_card.update(token, attributes)
+ if result.success?
+ copy_instance_variables_from_object result.credit_card
end
+ result
end
+ # Deprecated. Use Braintree::CreditCard.update!
+ #
+ # See http://www.braintreepaymentsolutions.com/docs/ruby/credit_cards/update
def update!(attributes)
+ warn "[DEPRECATED] update! as an instance method is deprecated. Please use CreditCard.update!"
return_object_or_raise(:credit_card) { update(attributes) }
end
@@ -230,63 +231,8 @@ def self._attributes # :nodoc:
]
end
- def self._create_signature # :nodoc:
- _signature(:create)
- end
-
def self._new(*args) # :nodoc:
self.new *args
end
-
- def self._do_create(url, params=nil) # :nodoc:
- response = Http.post url, params
- if response[:credit_card]
- SuccessfulResult.new(:credit_card => new(response[:credit_card]))
- elsif response[:api_error_response]
- ErrorResult.new(response[:api_error_response])
- else
- raise UnexpectedError, "expected :credit_card or :api_error_response"
- end
- end
-
- def self._do_update(http_verb, url, params) # :nodoc:
- response = Http.send http_verb, url, params
- if response[:credit_card]
- SuccessfulResult.new(:credit_card => new(response[:credit_card]))
- elsif response[:api_error_response]
- ErrorResult.new(response[:api_error_response])
- else
- raise UnexpectedError, "expected :credit_card or :api_error_response"
- end
- end
-
- def self._update_signature # :nodoc:
- _signature(:update)
- end
-
- def self._signature(type) # :nodoc:
- billing_address_params = Address._shared_signature
- signature = [
- :cardholder_name, :cvv, :expiration_date, :expiration_month, :expiration_year, :number, :token,
- {:options => [:make_default, :verification_merchant_account_id, :verify_card]},
- {:billing_address => billing_address_params}
- ]
-
- case type
- when :create
- signature << :customer_id
- when :update
- billing_address_params << {:options => [:update_existing]}
- else
- raise ArgumentError
- end
-
- return signature
- end
-
- def _init(attributes) # :nodoc:
- set_instance_variables_from_hash(attributes)
- @billing_address = attributes[:billing_address] ? Address._new(attributes[:billing_address]) : nil
- end
end
end
133 lib/braintree/credit_card_gateway.rb
View
@@ -0,0 +1,133 @@
+module Braintree
+ class CreditCardGateway # :nodoc:
+ def initialize(gateway)
+ @gateway = gateway
+ @config = gateway.config
+ end
+
+ def create(attributes)
+ if attributes.has_key?(:expiration_date) && (attributes.has_key?(:expiration_month) || attributes.has_key?(:expiration_year))
+ raise ArgumentError.new("create with both expiration_month and expiration_year or only expiration_date")
+ end
+ Util.verify_keys(CreditCardGateway._create_signature, attributes)
+ _do_create("/payment_methods", :credit_card => attributes)
+ end
+
+ # Deprecated
+ def create_credit_card_url
+ "#{@config.base_merchant_url}/payment_methods/all/create_via_transparent_redirect_request"
+ end
+
+ # Deprecated
+ def create_from_transparent_redirect(query_string)
+ params = @gateway.transparent_redirect.parse_and_validate_query_string query_string
+ _do_create("/payment_methods/all/confirm_transparent_redirect_request", :id => params[:id])
+ end
+
+ def delete(token)
+ @config.http.delete("/payment_methods/#{token}")
+ end
+
+ def expired(options = {})
+ response = @config.http.post("/payment_methods/all/expired_ids")
+ ResourceCollection.new(response) { |ids| _fetch_expired(ids) }
+ end
+
+ def expiring_between(start_date, end_date, options = {})
+ formatted_start_date = start_date.strftime('%m%Y')
+ formatted_end_date = end_date.strftime('%m%Y')
+ response = @config.http.post("/payment_methods/all/expiring_ids?start=#{formatted_start_date}&end=#{formatted_end_date}")
+ ResourceCollection.new(response) { |ids| _fetch_expiring_between(formatted_start_date, formatted_end_date, ids) }
+ end
+
+ def find(token)
+ response = @config.http.get "/payment_methods