braintree-rails 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <address>
3
3
  <id>address_id</id>
4
- <customer-id>8404776</customer-id>
4
+ <customer-id>customer_id</customer-id>
5
5
  <first-name>Brain</first-name>
6
6
  <last-name>Tree</last-name>
7
7
  <company>Braintree</company>
@@ -51,7 +51,7 @@
51
51
  </credit-cards>
52
52
  <addresses type="array">
53
53
  <address>
54
- <id>wx</id>
54
+ <id>address_id</id>
55
55
  <customer-id>customer_id</customer-id>
56
56
  <first-name>Brain</first-name>
57
57
  <last-name>Tree</last-name>
@@ -0,0 +1,100 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <transaction>
3
+ <id>transactionid</id>
4
+ <status>authorized</status>
5
+ <type>sale</type>
6
+ <currency-iso-code>USD</currency-iso-code>
7
+ <amount>10.00</amount>
8
+ <merchant-account-id>merchant_id</merchant-account-id>
9
+ <order-id nil="true"></order-id>
10
+ <created-at type="datetime">2012-09-15T01:07:58Z</created-at>
11
+ <updated-at type="datetime">2012-09-15T01:07:58Z</updated-at>
12
+ <customer>
13
+ <id>customer_id</id>
14
+ <first-name>Brain</first-name>
15
+ <last-name>Tree</last-name>
16
+ <company>Braintree</company>
17
+ <email>braintree@example.com</email>
18
+ <website>www.braintreepayments.com</website>
19
+ <phone>877.434.2894</phone>
20
+ <fax>888.781.6495</fax>
21
+ </customer>
22
+ <billing>
23
+ <id>address_id</id>
24
+ <first-name>Brain</first-name>
25
+ <last-name>Tree</last-name>
26
+ <company>Braintree</company>
27
+ <street-address>1134 Crane Avenue</street-address>
28
+ <extended-address>Suite 200</extended-address>
29
+ <locality>Menlo Park</locality>
30
+ <region>California</region>
31
+ <postal-code>94025</postal-code>
32
+ <country-name>United States of America</country-name>
33
+ <country-code-alpha2>US</country-code-alpha2>
34
+ <country-code-alpha3>USA</country-code-alpha3>
35
+ <country-code-numeric>840</country-code-numeric>
36
+ </billing>
37
+ <refund-id nil="true"></refund-id>
38
+ <refund-ids type="array"/>
39
+ <refunded-transaction-id nil="true"></refunded-transaction-id>
40
+ <settlement-batch-id nil="true"></settlement-batch-id>
41
+ <shipping>
42
+ <id nil="true"></id>
43
+ <first-name nil="true"></first-name>
44
+ <last-name nil="true"></last-name>
45
+ <company nil="true"></company>
46
+ <street-address nil="true"></street-address>
47
+ <extended-address nil="true"></extended-address>
48
+ <locality nil="true"></locality>
49
+ <region nil="true"></region>
50
+ <postal-code nil="true"></postal-code>
51
+ <country-name nil="true"></country-name>
52
+ <country-code-alpha2 nil="true"></country-code-alpha2>
53
+ <country-code-alpha3 nil="true"></country-code-alpha3>
54
+ <country-code-numeric nil="true"></country-code-numeric>
55
+ </shipping>
56
+ <custom-fields>
57
+ </custom-fields>
58
+ <avs-error-response-code nil="true"></avs-error-response-code>
59
+ <avs-postal-code-response-code>M</avs-postal-code-response-code>
60
+ <avs-street-address-response-code>M</avs-street-address-response-code>
61
+ <cvv-response-code>I</cvv-response-code>
62
+ <gateway-rejection-reason nil="true"></gateway-rejection-reason>
63
+ <processor-authorization-code>796RN2</processor-authorization-code>
64
+ <processor-response-code>1000</processor-response-code>
65
+ <processor-response-text>Approved</processor-response-text>
66
+ <purchase-order-number nil="true"></purchase-order-number>
67
+ <tax-amount nil="true"></tax-amount>
68
+ <tax-exempt type="boolean">false</tax-exempt>
69
+ <credit-card>
70
+ <token>credit_card_id</token>
71
+ <cardholder-name>Brain Tree</cardholder-name>
72
+ <customer-location>US</customer-location>
73
+ <card-type>MasterCard</card-type>
74
+ <bin>555555</bin>
75
+ <last-4>4444</last-4>
76
+ <expiration-month>05</expiration-month>
77
+ <expiration-year>2037</expiration-year>
78
+ </credit-card>
79
+ <status-history type="array">
80
+ <status-event>
81
+ <timestamp type="datetime">2012-09-15T01:07:58Z</timestamp>
82
+ <status>authorized</status>
83
+ <amount>10.00</amount>
84
+ <user>linyang84</user>
85
+ <transaction-source>API</transaction-source>
86
+ </status-event>
87
+ </status-history>
88
+ <plan-id nil="true"></plan-id>
89
+ <subscription-id nil="true"></subscription-id>
90
+ <subscription>
91
+ <billing-period-end-date nil="true"></billing-period-end-date>
92
+ <billing-period-start-date nil="true"></billing-period-start-date>
93
+ </subscription>
94
+ <add-ons type="array"/>
95
+ <discounts type="array"/>
96
+ <descriptor>
97
+ <name nil="true"></name>
98
+ <phone nil="true"></phone>
99
+ </descriptor>
100
+ </transaction>
@@ -0,0 +1,25 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <api-error-response>
3
+ <message>Cannot submit for settlement unless status is authorized.</message>
4
+ <errors>
5
+ <transaction>
6
+ <errors type="array">
7
+ <error>
8
+ <code>91507</code>
9
+ <message>Cannot submit for settlement unless status is authorized.</message>
10
+ <attribute type="symbol">base</attribute>
11
+ </error>
12
+ </errors>
13
+ </transaction>
14
+ <errors type="array"/>
15
+ </errors>
16
+ <params>
17
+ <merchant-id>merchant_id</merchant-id>
18
+ <action>submit_for_settlement</action>
19
+ <id>transactionid</id>
20
+ <transaction>
21
+ <amount nil="true"></amount>
22
+ </transaction>
23
+ <controller>transactions</controller>
24
+ </params>
25
+ </api-error-response>
@@ -7,17 +7,6 @@ describe 'Address Integration' do
7
7
 
8
8
  it 'should be able to add address' do
9
9
  customer = BraintreeRails::Customer.create!(:first_name => 'Brain', :last_name => 'Tree')
10
- address_hash = {
11
- :first_name => 'Brain',
12
- :last_name => 'Tree',
13
- :company => 'Braintree',
14
- :street_address => '1134 Crane Avenue',
15
- :extended_address => 'Suite 200',
16
- :locality => 'Menlo Park',
17
- :region => 'California',
18
- :postal_code => '94025',
19
- :country_name => 'United States of America'
20
- }
21
10
  customer.addresses.create!(address_hash)
22
11
  braintree_customer = Braintree::Customer.find(customer.id)
23
12
  braintree_address = braintree_customer.addresses.first
@@ -29,17 +18,6 @@ describe 'Address Integration' do
29
18
 
30
19
  it 'should be able to update existing address' do
31
20
  customer = BraintreeRails::Customer.create!(:first_name => 'Brain', :last_name => 'Tree')
32
- address_hash = {
33
- :first_name => 'Brain',
34
- :last_name => 'Tree',
35
- :company => 'Braintree',
36
- :street_address => '1134 Crane Avenue',
37
- :extended_address => 'Suite 200',
38
- :locality => 'Menlo Park',
39
- :region => 'California',
40
- :postal_code => '94025',
41
- :country_name => 'United States of America'
42
- }
43
21
  address = customer.addresses.create!(address_hash)
44
22
  address.update_attributes!(:first_name => 'Foo', :last_name => 'Bar')
45
23
  braintree_customer = Braintree::Customer.find(customer.id)
@@ -51,17 +29,6 @@ describe 'Address Integration' do
51
29
 
52
30
  it 'should be able to destroy existing address' do
53
31
  customer = BraintreeRails::Customer.create!(:first_name => 'Brain', :last_name => 'Tree')
54
- address_hash = {
55
- :first_name => 'Brain',
56
- :last_name => 'Tree',
57
- :company => 'Braintree',
58
- :street_address => '1134 Crane Avenue',
59
- :extended_address => 'Suite 200',
60
- :locality => 'Menlo Park',
61
- :region => 'California',
62
- :postal_code => '94025',
63
- :country_name => 'United States of America'
64
- }
65
32
  address = customer.addresses.create!(address_hash)
66
33
  address.destroy!
67
34
  lambda{ Braintree::Address.find(customer.id, address.id) }.must_raise Braintree::NotFoundError
@@ -6,28 +6,6 @@ describe 'Credit Card Integration' do
6
6
  end
7
7
 
8
8
  it 'should be able to fetch from Braintree for given token' do
9
- address_hash = {
10
- :first_name => 'Brain',
11
- :last_name => 'Tree',
12
- :company => 'Braintree',
13
- :street_address => '1134 Crane Avenue',
14
- :extended_address => 'Suite 200',
15
- :locality => 'Menlo Park',
16
- :region => 'California',
17
- :postal_code => '94025',
18
- :country_name => 'United States of America'
19
- }
20
-
21
- credit_card_hash = {
22
- :token => 'credit_card_id',
23
- :number => '4111111111111111',
24
- :cvv => '123',
25
- :cardholder_name => 'Brain Tree',
26
- :expiration_month => '05',
27
- :expiration_year => '2037',
28
- :billing_address => address_hash,
29
- }
30
-
31
9
  braintree_customer = Braintree::Customer.create!(:id => 'customer_id', :first_name => 'Brain', :last_name => 'Tree', :credit_card => credit_card_hash)
32
10
 
33
11
  credit_card = BraintreeRails::CreditCard.new(braintree_customer.credit_cards.first.token)
@@ -43,30 +21,6 @@ describe 'Credit Card Integration' do
43
21
 
44
22
  it 'should be able to add credit card' do
45
23
  customer = BraintreeRails::Customer.create!(:id => 'customer_id', :first_name => 'Brain', :last_name => 'Tree')
46
-
47
- address_hash = {
48
- :first_name => 'Brain',
49
- :last_name => 'Tree',
50
- :company => 'Braintree',
51
- :street_address => '1134 Crane Avenue',
52
- :extended_address => 'Suite 200',
53
- :locality => 'Menlo Park',
54
- :region => 'California',
55
- :postal_code => '94025',
56
- :country_name => 'United States of America'
57
- }
58
-
59
- credit_card_hash = {
60
- :token => 'credit_card_id',
61
- :number => '4111111111111111',
62
- :cvv => '123',
63
- :customer_id => 'customer_id',
64
- :cardholder_name => 'Brain Tree',
65
- :expiration_month => '05',
66
- :expiration_year => '2037',
67
- :billing_address => address_hash,
68
- }
69
-
70
24
  credit_card = customer.credit_cards.create!(credit_card_hash)
71
25
 
72
26
  braintree_credit_card = Braintree::CreditCard.find(credit_card.id)
@@ -82,30 +36,6 @@ describe 'Credit Card Integration' do
82
36
 
83
37
  it 'should be able to update existing credit card' do
84
38
  customer = BraintreeRails::Customer.create!(:id => 'customer_id', :first_name => 'Brain', :last_name => 'Tree')
85
-
86
- address_hash = {
87
- :first_name => 'Brain',
88
- :last_name => 'Tree',
89
- :company => 'Braintree',
90
- :street_address => '1134 Crane Avenue',
91
- :extended_address => 'Suite 200',
92
- :locality => 'Menlo Park',
93
- :region => 'California',
94
- :postal_code => '94025',
95
- :country_name => 'United States of America'
96
- }
97
-
98
- credit_card_hash = {
99
- :token => 'credit_card_id',
100
- :number => '4111111111111111',
101
- :cvv => '123',
102
- :customer_id => 'customer_id',
103
- :cardholder_name => 'Brain Tree',
104
- :expiration_month => '05',
105
- :expiration_year => '2037',
106
- :billing_address => address_hash,
107
- }
108
-
109
39
  credit_card = customer.credit_cards.create!(credit_card_hash)
110
40
 
111
41
  credit_card.update_attributes!(:cardholder_name => 'Foo Bar')
@@ -114,31 +44,9 @@ describe 'Credit Card Integration' do
114
44
  end
115
45
 
116
46
  it 'should be able to destroy existing credit card' do
117
- address_hash = {
118
- :first_name => 'Brain',
119
- :last_name => 'Tree',
120
- :company => 'Braintree',
121
- :street_address => '1134 Crane Avenue',
122
- :extended_address => 'Suite 200',
123
- :locality => 'Menlo Park',
124
- :region => 'California',
125
- :postal_code => '94025',
126
- :country_name => 'United States of America'
127
- }
128
-
129
- credit_card_hash = {
130
- :token => 'credit_card_id',
131
- :number => '4111111111111111',
132
- :cvv => '123',
133
- :cardholder_name => 'Brain Tree',
134
- :expiration_month => '05',
135
- :expiration_year => '2037',
136
- :billing_address => address_hash,
137
- }
138
-
139
47
  braintree_customer = Braintree::Customer.create!(:id => 'customer_id', :first_name => 'Brain', :last_name => 'Tree', :credit_card => credit_card_hash)
140
-
141
48
  credit_card = BraintreeRails::CreditCard.new(braintree_customer.credit_cards.first.token)
49
+
142
50
  credit_card.destroy!
143
51
  lambda{ Braintree::CreditCard.find(credit_card.token) }.must_raise Braintree::NotFoundError
144
52
  credit_card.persisted?.must_equal false
@@ -0,0 +1,50 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../integration_test_helper'))
2
+
3
+ describe 'Transaction Integration' do
4
+ before do
5
+ Braintree::Customer.all.each { |c| Braintree::Customer.delete c.id }
6
+ end
7
+
8
+ it 'should be able to create, submit, void transactions for a customer' do
9
+
10
+ braintree_customer = Braintree::Customer.create!(:id => 'customer_id', :first_name => 'Brain', :last_name => 'Tree', :credit_card => credit_card_hash)
11
+ customer = BraintreeRails::Customer.new(braintree_customer)
12
+ credit_card = customer.credit_cards.first
13
+
14
+ [{:amount => rand(1..10), :customer => customer}, {:amount => rand(1..10), :customer => customer, :credit_card => credit_card}].each do |params|
15
+ transaction = BraintreeRails::Transaction.create!(params)
16
+ transaction.persisted?.must_equal true
17
+ transaction.amount.must_equal params[:amount]
18
+ transaction.status.must_equal Braintree::Transaction::Status::Authorized
19
+
20
+ transaction.submit_for_settlement!
21
+ transaction.status.must_equal Braintree::Transaction::Status::SubmittedForSettlement
22
+
23
+ transaction.void!
24
+ transaction.status.must_equal Braintree::Transaction::Status::Voided
25
+ end
26
+ end
27
+
28
+ it "should be able to load transactions for given customer and credit_card" do
29
+ braintree_customer = Braintree::Customer.create!(:id => 'customer_id', :first_name => 'Brain', :last_name => 'Tree', :credit_card => credit_card_hash)
30
+ customer = BraintreeRails::Customer.new(braintree_customer)
31
+ credit_card = customer.credit_cards.first
32
+ transaction = BraintreeRails::Transaction.create!(:amount => rand(1..10), :customer => customer)
33
+
34
+ customer.transactions.count.must_equal 1
35
+ credit_card.transactions.count.must_equal 1
36
+ end
37
+
38
+ it 'should be able to capture braintree api errors' do
39
+ braintree_customer = Braintree::Customer.create!(:id => 'customer_id', :first_name => 'Brain', :last_name => 'Tree', :credit_card => credit_card_hash)
40
+ customer = BraintreeRails::Customer.new(braintree_customer)
41
+ credit_card = customer.credit_cards.first
42
+ transaction = BraintreeRails::Transaction.create!(:amount => rand(1..10), :customer => customer)
43
+
44
+ transaction.void!
45
+ transaction.submit_for_settlement.must_equal false
46
+ transaction.errors[:base].wont_be :blank?
47
+
48
+ lambda{transaction.submit_for_settlement!}.must_raise Braintree::ValidationsFailed
49
+ end
50
+ end
@@ -19,6 +19,32 @@ MiniTest::Unit::TestCase.class_eval do
19
19
  response = response.reverse_merge(:headers => {'Content-Type' => ['application/xml', 'charset=utf-8'], 'Content-Encoding' => 'gzip'})
20
20
  stub_request(method, BraintreeBaseUri+path).to_return(response)
21
21
  end
22
+
23
+ def address_hash
24
+ {
25
+ :first_name => 'Brain',
26
+ :last_name => 'Tree',
27
+ :company => 'Braintree',
28
+ :street_address => '1134 Crane Avenue',
29
+ :extended_address => 'Suite 200',
30
+ :locality => 'Menlo Park',
31
+ :region => 'California',
32
+ :postal_code => '94025',
33
+ :country_name => 'United States of America'
34
+ }
35
+ end
36
+
37
+ def credit_card_hash
38
+ {
39
+ :token => 'credit_card_id',
40
+ :number => '4111111111111111',
41
+ :cvv => '123',
42
+ :cardholder_name => 'Brain Tree',
43
+ :expiration_month => '05',
44
+ :expiration_year => '2037',
45
+ :billing_address => address_hash,
46
+ }
47
+ end
22
48
  end
23
49
 
24
50
  String.class_eval do
@@ -0,0 +1,132 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../unit_test_helper'))
2
+
3
+ describe BraintreeRails::Transaction do
4
+ before do
5
+ stub_braintree_request(:get, '/customers/customer_id', :body => fixture('customer.xml'))
6
+ stub_braintree_request(:get, '/payment_methods/credit_card_id', :body => fixture('credit_card.xml'))
7
+ stub_braintree_request(:get, '/transactions/transactionid', :body => fixture('transaction.xml'))
8
+ end
9
+
10
+ describe '#initialize' do
11
+ it 'should find transaction from braintree when given a transaction id' do
12
+ braintree_transaction = Braintree::Transaction.find('transactionid')
13
+ transaction = BraintreeRails::Transaction.new('transactionid')
14
+
15
+ transaction.persisted?.must_equal true
16
+ [:amount, :created_at, :updated_at].each do |attribute|
17
+ transaction.send(attribute).must_equal braintree_transaction.send(attribute)
18
+ end
19
+ end
20
+
21
+ it 'should wrap a Braintree::Transaction' do
22
+ braintree_transaction = Braintree::Transaction.find('transactionid')
23
+ transaction = BraintreeRails::Transaction.new(braintree_transaction)
24
+
25
+ transaction.persisted?.must_equal true
26
+ [:amount, :created_at, :updated_at].each do |attribute|
27
+ transaction.send(attribute).must_equal braintree_transaction.send(attribute)
28
+ end
29
+ end
30
+
31
+ it 'should extract values from hash' do
32
+ transaction = BraintreeRails::Transaction.new(:id => 'new_id')
33
+
34
+ transaction.persisted?.must_equal false
35
+ transaction.id.must_equal 'new_id'
36
+ end
37
+
38
+ it 'should try to extract value from other types' do
39
+ transaction = BraintreeRails::Transaction.new(OpenStruct.new(:id => 'foobar', :amount => '10.00', :persisted? => true))
40
+
41
+ transaction.persisted?.must_equal true
42
+ transaction.id.must_equal 'foobar'
43
+ transaction.amount.must_equal '10.00'
44
+
45
+ transaction = BraintreeRails::Transaction.new(Object.new)
46
+ transaction.persisted?.must_equal false
47
+ end
48
+ end
49
+
50
+ [:customer, :credit_card].each do |association|
51
+ describe association do
52
+ it "should load #{association} for persisted transaction" do
53
+ transaction = BraintreeRails::Transaction.new('transactionid')
54
+ transaction.send(association).persisted?.must_equal true
55
+ end
56
+ end
57
+ end
58
+
59
+ describe 'validations' do
60
+ it 'should validate amount' do
61
+ [nil, 'abc', -1].each do |invalid_value|
62
+ transaction = BraintreeRails::Transaction.new(:amount => invalid_value)
63
+ transaction.valid?.must_equal false
64
+ transaction.errors[:amount].wont_be :blank?
65
+ end
66
+ end
67
+ end
68
+
69
+ describe 'persistence' do
70
+ before do
71
+ stub_braintree_request(:post, '/transactions', :body => fixture('transaction.xml'))
72
+ end
73
+
74
+ it 'should create a sale transaction' do
75
+ customer = BraintreeRails::Customer.find('customer_id')
76
+ credit_card = BraintreeRails::CreditCard.find('credit_card_id')
77
+ transaction = BraintreeRails::Transaction.new(:amount => '10.00', :customer => customer, :credit_card => credit_card)
78
+
79
+ transaction.save.must_equal true
80
+ transaction.status.must_equal Braintree::Transaction::Status::Authorized
81
+ end
82
+
83
+ it 'should use default credit card of customer if credit_card is not specified' do
84
+ customer = BraintreeRails::Customer.find('customer_id')
85
+ transaction = BraintreeRails::Transaction.new(:amount => '10.00', :customer => customer)
86
+ transaction.save.must_equal true
87
+ transaction.status.must_equal Braintree::Transaction::Status::Authorized
88
+ end
89
+
90
+ it "should be able to submit_for_settlement a transaction" do
91
+ customer = BraintreeRails::Customer.find('customer_id')
92
+ credit_card = BraintreeRails::CreditCard.find('credit_card_id')
93
+ transaction = BraintreeRails::Transaction.new(:amount => '10.00', :customer => customer, :credit_card => credit_card)
94
+ transaction.save!
95
+ stub_braintree_request(:put, "/transactions/#{transaction.id}/submit_for_settlement", :body => fixture('transaction.xml'))
96
+ transaction.submit_for_settlement.must_equal true
97
+ end
98
+
99
+ it "should be able to refund a transaction" do
100
+ customer = BraintreeRails::Customer.find('customer_id')
101
+ credit_card = BraintreeRails::CreditCard.find('credit_card_id')
102
+ transaction = BraintreeRails::Transaction.new(:amount => '10.00', :customer => customer, :credit_card => credit_card)
103
+ transaction.save!
104
+ stub_braintree_request(:post, "/transactions/#{transaction.id}/refund", :body => fixture('transaction.xml'))
105
+ transaction.refund.must_equal true
106
+ end
107
+
108
+ it "should be able to void a transaction" do
109
+ customer = BraintreeRails::Customer.find('customer_id')
110
+ credit_card = BraintreeRails::CreditCard.find('credit_card_id')
111
+ transaction = BraintreeRails::Transaction.new(:amount => '10.00', :customer => customer, :credit_card => credit_card)
112
+ transaction.save!
113
+ stub_braintree_request(:put, "/transactions/#{transaction.id}/void", :body => fixture('transaction.xml'))
114
+ transaction.void.must_equal true
115
+ end
116
+
117
+ it 'should show errors when trying to submit already voided transaction' do
118
+ customer = BraintreeRails::Customer.find('customer_id')
119
+ credit_card = BraintreeRails::CreditCard.find('credit_card_id')
120
+ transaction = BraintreeRails::Transaction.new(:amount => '10.00', :customer => customer, :credit_card => credit_card)
121
+ transaction.save!
122
+ stub_braintree_request(:put, "/transactions/#{transaction.id}/void", :body => fixture('transaction.xml'))
123
+ transaction.void.must_equal true
124
+
125
+ stub_braintree_request(:put, "/transactions/#{transaction.id}/submit_for_settlement", :status => 422, :body => fixture('transaction_error.xml'))
126
+ transaction.submit_for_settlement.must_equal false
127
+ transaction.errors[:base].wont_be :blank?
128
+
129
+ lambda{transaction.submit_for_settlement!}.must_raise Braintree::ValidationsFailed
130
+ end
131
+ end
132
+ end