spreedly 1.4.0 → 2.0.0

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 (87) hide show
  1. data/.gitignore +8 -0
  2. data/Gemfile +4 -0
  3. data/HISTORY.md +5 -0
  4. data/README.md +362 -29
  5. data/Rakefile +32 -0
  6. data/lib/certs/cacert.pem +7815 -0
  7. data/lib/spreedly.rb +24 -282
  8. data/lib/spreedly/common/errors_parser.rb +15 -0
  9. data/lib/spreedly/common/fields.rb +90 -0
  10. data/lib/spreedly/connection.rb +40 -0
  11. data/lib/spreedly/environment.rb +176 -0
  12. data/lib/spreedly/error.rb +50 -0
  13. data/lib/spreedly/gateway.rb +10 -0
  14. data/lib/spreedly/model.rb +17 -0
  15. data/lib/spreedly/payment_methods/credit_card.rb +9 -0
  16. data/lib/spreedly/payment_methods/payment_method.rb +34 -0
  17. data/lib/spreedly/payment_methods/paypal.rb +7 -0
  18. data/lib/spreedly/payment_methods/sprel.rb +7 -0
  19. data/lib/spreedly/ssl_requester.rb +65 -0
  20. data/lib/spreedly/transactions/add_payment_method.rb +16 -0
  21. data/lib/spreedly/transactions/auth_purchase.rb +17 -0
  22. data/lib/spreedly/transactions/authorization.rb +7 -0
  23. data/lib/spreedly/transactions/capture.rb +14 -0
  24. data/lib/spreedly/transactions/gateway_transaction.rb +31 -0
  25. data/lib/spreedly/transactions/purchase.rb +7 -0
  26. data/lib/spreedly/transactions/redact_payment_method.rb +14 -0
  27. data/lib/spreedly/transactions/refund.rb +14 -0
  28. data/lib/spreedly/transactions/retain_payment_method.rb +14 -0
  29. data/lib/spreedly/transactions/transaction.rb +41 -0
  30. data/lib/spreedly/transactions/void.rb +9 -0
  31. data/lib/spreedly/urls.rb +64 -0
  32. data/lib/spreedly/version.rb +1 -1
  33. data/spreedly.gemspec +29 -0
  34. data/test/credentials/credentials.yml +9 -0
  35. data/test/credentials/test_credentials.rb +43 -0
  36. data/test/helpers/assertions.rb +29 -0
  37. data/test/helpers/communication_helper.rb +31 -0
  38. data/test/helpers/creation_helper.rb +26 -0
  39. data/test/helpers/stub_response.rb +18 -0
  40. data/test/remote/remote_add_credit_card_test.rb +62 -0
  41. data/test/remote/remote_add_gateway_test.rb +30 -0
  42. data/test/remote/remote_authorize_test.rb +48 -0
  43. data/test/remote/remote_capture_test.rb +71 -0
  44. data/test/remote/remote_find_gateway_test.rb +31 -0
  45. data/test/remote/remote_find_payment_method_test.rb +29 -0
  46. data/test/remote/remote_find_transaction_test.rb +33 -0
  47. data/test/remote/remote_list_transactions_test.rb +36 -0
  48. data/test/remote/remote_purchase_test.rb +69 -0
  49. data/test/remote/remote_redact_test.rb +38 -0
  50. data/test/remote/remote_refund_test.rb +65 -0
  51. data/test/remote/remote_retain_test.rb +39 -0
  52. data/test/remote/remote_void_test.rb +64 -0
  53. data/test/test_helper.rb +23 -0
  54. data/test/unit/add_credit_card_test.rb +74 -0
  55. data/test/unit/add_gateway_test.rb +26 -0
  56. data/test/unit/authorize_test.rb +87 -0
  57. data/test/unit/capture_test.rb +91 -0
  58. data/test/unit/environment_test.rb +18 -0
  59. data/test/unit/fields_test.rb +75 -0
  60. data/test/unit/find_gateway_test.rb +28 -0
  61. data/test/unit/find_payment_method_test.rb +90 -0
  62. data/test/unit/find_transaction_test.rb +31 -0
  63. data/test/unit/list_transactions_test.rb +46 -0
  64. data/test/unit/purchase_test.rb +95 -0
  65. data/test/unit/redact_payment_method_test.rb +51 -0
  66. data/test/unit/refund_test.rb +91 -0
  67. data/test/unit/response_stubs/add_credit_card_stubs.rb +43 -0
  68. data/test/unit/response_stubs/add_gateway_stubs.rb +39 -0
  69. data/test/unit/response_stubs/authorization_stubs.rb +139 -0
  70. data/test/unit/response_stubs/capture_stubs.rb +87 -0
  71. data/test/unit/response_stubs/find_gateway_stubs.rb +38 -0
  72. data/test/unit/response_stubs/find_payment_method_stubs.rb +108 -0
  73. data/test/unit/response_stubs/find_transaction_stubs.rb +43 -0
  74. data/test/unit/response_stubs/list_transactions_stubs.rb +110 -0
  75. data/test/unit/response_stubs/purchase_stubs.rb +139 -0
  76. data/test/unit/response_stubs/redact_payment_method_stubs.rb +54 -0
  77. data/test/unit/response_stubs/refund_stubs.rb +87 -0
  78. data/test/unit/response_stubs/retain_payment_method_stubs.rb +85 -0
  79. data/test/unit/response_stubs/void_stubs.rb +79 -0
  80. data/test/unit/retain_payment_method_test.rb +44 -0
  81. data/test/unit/timeout_test.rb +20 -0
  82. data/test/unit/void_test.rb +96 -0
  83. metadata +215 -29
  84. checksums.yaml +0 -15
  85. data/lib/spreedly/common.rb +0 -44
  86. data/lib/spreedly/mock.rb +0 -221
  87. data/lib/spreedly/test_hacks.rb +0 -27
@@ -0,0 +1,28 @@
1
+ require 'test_helper'
2
+ require 'unit/response_stubs/find_gateway_stubs'
3
+
4
+ class FindGatewayTest < Test::Unit::TestCase
5
+
6
+ include FindGatewayStubs
7
+
8
+ def setup
9
+ @environment = Spreedly::Environment.new("key", "secret")
10
+ end
11
+
12
+ def test_successful_find_gateway
13
+ g = find_using(successful_get_gateway_response)
14
+
15
+ assert_kind_of(Spreedly::Gateway, g)
16
+ assert_equal("RsVlPgS4dMzeeUpKXxk01rMMRrQ", g.token)
17
+ assert_equal Time.parse("2013-08-07 18:53:30 UTC"), g.created_at
18
+ assert_equal Time.parse("2013-08-07 18:53:30 UTC"), g.updated_at
19
+ assert_equal 'redacted', g.state
20
+ end
21
+
22
+ private
23
+ def find_using(response)
24
+ @environment.stubs(:raw_ssl_request).returns(response)
25
+ @environment.find_gateway("IgnoredTokenSinceResponseIsStubbed")
26
+ end
27
+
28
+ end
@@ -0,0 +1,90 @@
1
+ require 'test_helper'
2
+ require 'unit/response_stubs/find_payment_method_stubs'
3
+
4
+ class FindPaymentMethodTest < Test::Unit::TestCase
5
+
6
+ include FindPaymentMethodStubs
7
+
8
+ def setup
9
+ @environment = Spreedly::Environment.new("key", "secret")
10
+ end
11
+
12
+ def test_successful_find_card
13
+ card = find_using(successful_get_card_response)
14
+
15
+ assert_kind_of(Spreedly::CreditCard, card)
16
+ assert_equal("ROGJFe89QtbJL8QvjaJNMH0UG50", card.token)
17
+ assert_equal("alcatraz@occulators.org", card.email)
18
+ assert_equal("4445", card.last_four_digits)
19
+ assert_equal('XXXX-XXXX-XXXX-4445', card.number)
20
+ assert_equal("<some_attribute>5</some_attribute>", card.data)
21
+ assert_equal(1369504152, card.created_at.to_i)
22
+ assert_equal(1369508044, card.updated_at.to_i)
23
+ assert_equal('master', card.card_type)
24
+ assert_equal('Alcatraz', card.first_name)
25
+ assert_equal('Smedry', card.last_name)
26
+ assert_equal('8', card.month)
27
+ assert_equal('2020', card.year)
28
+ assert_equal('123 Freedom Street', card.address1)
29
+ assert_equal('Apt. 8', card.address2)
30
+ assert_equal('Wanaque', card.city)
31
+ assert_equal('NJ', card.state)
32
+ assert_equal('02124', card.zip)
33
+ assert_equal('USA', card.country)
34
+ assert_equal('201.344.7712', card.phone_number)
35
+ assert_equal('retained', card.storage_state)
36
+ end
37
+
38
+ def test_find_valid_card
39
+ card = find_using(successful_get_card_response)
40
+ assert card.valid?
41
+ assert_equal([], card.errors)
42
+ end
43
+
44
+ def test_find_invalid_card
45
+ card = find_using(successful_get_invalid_card_response)
46
+
47
+ assert !card.valid?
48
+ expected_errors = [
49
+ { attribute: "first_name", key: "errors.blank", message: "First name can't be blank" },
50
+ { attribute: "last_name", key: "errors.blank", message: "Last name can't be blank" },
51
+ { attribute: "year", key: "errors.expired", message: "Year is expired" },
52
+ { attribute: "year", key: "errors.invalid", message: "Year is invalid" },
53
+ { attribute: "number", key: "errors.blank", message: "Number can't be blank" }
54
+ ]
55
+
56
+ assert_equal(expected_errors, card.errors)
57
+ end
58
+
59
+ def test_successfully_find_sprel
60
+ sprel = find_using(successful_get_sprel_response)
61
+
62
+ assert_kind_of(Spreedly::Sprel, sprel)
63
+ assert_equal "RZf8ZQgvmgOfdWaRtAzMLXPSQbk", sprel.token
64
+ assert_equal "neelix@voyager.com", sprel.email
65
+ assert_equal(1366981867, sprel.created_at.to_i)
66
+ assert_equal(1366982301, sprel.updated_at.to_i)
67
+ assert_equal("Some Pretty Data", sprel.data)
68
+ assert_equal("cached", sprel.storage_state)
69
+ end
70
+
71
+ def test_successfully_find_paypal
72
+ paypal = find_using(successful_get_paypal_response)
73
+
74
+ assert_kind_of(Spreedly::Paypal, paypal)
75
+ assert_equal "X7DkJT3NUMNMJ0ZVvRMJBEyUe9B", paypal.token
76
+ assert_equal "shaun@mason.com", paypal.email
77
+ assert_equal(1375288019, paypal.created_at.to_i)
78
+ assert_equal(1375288046, paypal.updated_at.to_i)
79
+ assert_equal("", paypal.data)
80
+ assert_equal("retained", paypal.storage_state)
81
+ end
82
+
83
+ private
84
+ def find_using(response)
85
+ @environment.stubs(:raw_ssl_request).returns(response)
86
+ @environment.find_payment_method("IgnoredTokenSinceResponseIsStubbed")
87
+ end
88
+
89
+
90
+ end
@@ -0,0 +1,31 @@
1
+ require 'test_helper'
2
+ require 'unit/response_stubs/find_transaction_stubs'
3
+
4
+ class FindTransactionTest < Test::Unit::TestCase
5
+
6
+ include FindTransactionStubs
7
+
8
+ def setup
9
+ @environment = Spreedly::Environment.new("key", "secret")
10
+ end
11
+
12
+ def test_successful_find_transaction
13
+ t = find_using(successful_get_transaction_response)
14
+
15
+ assert_kind_of(Spreedly::AddPaymentMethod, t)
16
+ assert_equal("2IFzBBh99rwjXKkZ0hkPVLjCBXL", t.token)
17
+ assert_equal Time.parse("2013-08-05 19:32:49 UTC"), t.created_at
18
+ assert_equal Time.parse("2013-08-05 19:32:49 UTC"), t.updated_at
19
+
20
+ assert t.succeeded?
21
+ assert_equal "Succeeded!", t.message
22
+ assert_equal "7sqmBrh8zS4Mgei6wOyYskFpghF", t.payment_method.token
23
+ end
24
+
25
+ private
26
+ def find_using(response)
27
+ @environment.stubs(:raw_ssl_request).returns(response)
28
+ @environment.find_transaction("IgnoredTokenSinceResponseIsStubbed")
29
+ end
30
+
31
+ end
@@ -0,0 +1,46 @@
1
+ require 'test_helper'
2
+ require 'unit/response_stubs/list_transactions_stubs'
3
+
4
+ class FindPaymentMethodTest < Test::Unit::TestCase
5
+
6
+ include ListTransactionsStubs
7
+
8
+ def setup
9
+ @environment = Spreedly::Environment.new("key", "secret")
10
+ end
11
+
12
+ def test_successful_list_transactions
13
+ list = list_using(successful_list_transactions_response)
14
+
15
+ assert_kind_of(Array, list)
16
+ assert_equal 2, list.size
17
+
18
+ assert_equal 'TpjI3MSmLOSfqpFKP2poZRKc6Ru', list.first.gateway_token
19
+ assert_equal '5Zkgibjs6z5R6XENMtZd8A8ajau', list.last.reference_token
20
+ assert_kind_of Spreedly::Authorization, list.first
21
+ assert_kind_of Spreedly::Capture, list.last
22
+
23
+ assert_equal 'Aybara', list.first.payment_method.last_name
24
+ assert_equal 'Successful capture', list.last.response.message
25
+ end
26
+
27
+ def test_request_url
28
+ url = get_request_url(successful_list_transactions_response) do
29
+ @environment.list_transactions
30
+ end
31
+ assert_equal 'https://core.spreedly.com/v1/transactions.xml', url
32
+
33
+ url = get_request_url(successful_list_transactions_response) do
34
+ @environment.list_transactions("SomeToken")
35
+ end
36
+ assert_equal 'https://core.spreedly.com/v1/transactions.xml?since_token=SomeToken', url
37
+ end
38
+
39
+ private
40
+ def list_using(response)
41
+ @environment.stubs(:raw_ssl_request).returns(response)
42
+ @environment.list_transactions
43
+ end
44
+
45
+
46
+ end
@@ -0,0 +1,95 @@
1
+ require 'test_helper'
2
+ require 'unit/response_stubs/purchase_stubs'
3
+
4
+ class PurchaseTest < Test::Unit::TestCase
5
+
6
+ include PurchaseStubs
7
+
8
+ def setup
9
+ @environment = Spreedly::Environment.new("key", "secret")
10
+ end
11
+
12
+ def test_successful_purchase
13
+ t = purchase_using(successful_purchase_response)
14
+
15
+ assert_kind_of(Spreedly::Purchase, t)
16
+ assert_equal 'Btcyks35m4JLSNOs9ymJoNQLjeX', t.token
17
+ assert_equal 144, t.amount
18
+ assert t.on_test_gateway?
19
+ assert_equal Time.parse("2013-07-31 19:46:26 UTC"), t.created_at
20
+ assert_equal Time.parse("2013-07-31 19:46:32 UTC"), t.updated_at
21
+ assert_equal 'USD', t.currency_code
22
+ assert t.succeeded?
23
+ assert_equal 'succeeded', t.state
24
+ assert_equal '187A', t.order_id
25
+ assert_equal '', t.ip
26
+ assert_equal '4 Shardblades', t.description
27
+ assert_equal '', t.merchant_name_descriptor
28
+ assert_equal '', t.merchant_location_descriptor
29
+ assert_equal 'YOaCn5a9xRaBTGgmGAWbkgWUuqv', t.gateway_token
30
+ assert_equal '8xXXIPGXTaPXysDA5OUpgnjTEjK', t.payment_method.token
31
+
32
+ assert t.response.success
33
+ assert_equal 'Successful purchase', t.response.message
34
+ assert_equal '22', t.response.avs_code
35
+ assert_equal 'I will be back', t.response.avs_message
36
+ assert_equal '31', t.response.cvv_code
37
+ assert_equal 'Rutabaga', t.response.cvv_message
38
+ assert !t.response.pending
39
+ assert_equal '899', t.response.error_code
40
+ assert_equal 'The eagle lives!', t.response.error_detail
41
+ assert !t.response.cancelled
42
+ assert_equal Time.parse('2013-07-31T19:46:26Z'), t.response.created_at
43
+ assert_equal Time.parse('2013-07-31T19:46:27Z'), t.response.updated_at
44
+ end
45
+
46
+ def test_failed_purchase
47
+ t = purchase_using(failed_purchase_response)
48
+
49
+ assert_kind_of(Spreedly::Purchase, t)
50
+ assert_equal 'RxkxK78ZlvDiXRQRnyuJM5ee0Ww', t.token
51
+ assert_equal 5148, t.amount
52
+ assert !t.succeeded?
53
+ assert_equal 'gateway_processing_failed', t.state
54
+
55
+ assert_equal 'The eagle is dead Jim.', t.response.error_detail
56
+ end
57
+
58
+ def test_request_body_params
59
+ body = get_request_body(successful_purchase_response) do
60
+ @environment.purchase_on_gateway("TheGatewayToken", "TheCardToken", 2001, all_possible_options)
61
+ end
62
+
63
+ transaction = body.xpath('./transaction')
64
+ assert_xpaths_in transaction,
65
+ [ './amount', '2001' ],
66
+ [ './currency_code', 'EUR' ],
67
+ [ './payment_method_token', 'TheCardToken' ],
68
+ [ './order_id', '8675' ],
69
+ [ './description', 'SuperDuper' ],
70
+ [ './ip', '183.128.100.103' ],
71
+ [ './merchant_name_descriptor', 'Real Stuff' ],
72
+ [ './merchant_location_descriptor', 'Raleigh' ],
73
+ [ './retain_on_success', 'true' ]
74
+ end
75
+
76
+
77
+ private
78
+ def purchase_using(response)
79
+ @environment.stubs(:raw_ssl_request).returns(response)
80
+ @environment.purchase_on_gateway("IgnoredGatewayTokenSinceResponseIsStubbed", "IgnoredPaymentMethodTokenSinceResponseIsStubbed", 5921)
81
+ end
82
+
83
+ def all_possible_options
84
+ {
85
+ currency_code: "EUR",
86
+ order_id: "8675",
87
+ description: "SuperDuper",
88
+ ip: "183.128.100.103",
89
+ merchant_name_descriptor: "Real Stuff",
90
+ merchant_location_descriptor: "Raleigh",
91
+ retain_on_success: true
92
+ }
93
+ end
94
+
95
+ end
@@ -0,0 +1,51 @@
1
+ require 'test_helper'
2
+ require 'unit/response_stubs/redact_payment_method_stubs'
3
+
4
+ class RedactPaymentMethodTest < Test::Unit::TestCase
5
+
6
+ include RedactPaymentMethodStubs
7
+
8
+ def setup
9
+ @environment = Spreedly::Environment.new("key", "secret")
10
+ end
11
+
12
+ def test_successful_redact
13
+ t = redact_using(successful_redact_response)
14
+
15
+ assert_kind_of(Spreedly::RedactPaymentMethod, t)
16
+ assert_equal '2BSe5T6FHpypph3ensF7m3Nb3qk', t.token
17
+ assert_equal Time.parse('2013-08-05 17:43:41 UTC'), t.created_at
18
+ assert_equal Time.parse('2013-08-05 17:43:41 UTC'), t.updated_at
19
+ assert t.succeeded?
20
+ assert_equal 'Succeeded!', t.message
21
+ assert_equal 'succeeded', t.state
22
+ assert_equal 'redacted', t.payment_method.storage_state
23
+ assert_equal 'RvsxKgbAZBmiZHEPhhTcOQzJeC2', t.payment_method.token
24
+ end
25
+
26
+ def test_empty_request_body_params
27
+ body = get_request_body(successful_redact_response) do
28
+ @environment.redact_payment_method("TransactionToken")
29
+ end
30
+
31
+ assert_nil body.root
32
+ end
33
+
34
+ def test_request_body_params
35
+ body = get_request_body(successful_redact_response) do
36
+ @environment.redact_payment_method("TransactionToken", remove_from_gateway: 'ThePassedGatewayToken')
37
+ end
38
+
39
+ transaction = body.xpath('./transaction')
40
+ assert_xpaths_in transaction,
41
+ [ './remove_from_gateway', 'ThePassedGatewayToken' ]
42
+ end
43
+
44
+ private
45
+ def redact_using(response)
46
+ @environment.stubs(:raw_ssl_request).returns(response)
47
+ @environment.redact_payment_method("IgnoredTokenSinceResponseIsStubbed")
48
+ end
49
+
50
+ end
51
+
@@ -0,0 +1,91 @@
1
+ require 'test_helper'
2
+ require 'unit/response_stubs/refund_stubs'
3
+
4
+ class RefundTest < Test::Unit::TestCase
5
+
6
+ include RefundStubs
7
+
8
+ def setup
9
+ @environment = Spreedly::Environment.new("key", "secret")
10
+ end
11
+
12
+ def test_successful_refund
13
+ t = refund_using(successful_refund_response)
14
+
15
+ assert_kind_of(Spreedly::Refund, t)
16
+ assert_equal 'JyQegcYcIFA2jUg22OYTGiUyXTR', t.token
17
+ assert_equal 944, t.amount
18
+ assert t.on_test_gateway?
19
+ assert_equal Time.parse("2013-08-05 16:37:13 UTC"), t.created_at
20
+ assert_equal Time.parse("2013-08-05 16:37:13 UTC"), t.updated_at
21
+ assert_equal 'USD', t.currency_code
22
+ assert t.succeeded?
23
+ assert_equal 'succeeded', t.state
24
+ assert_equal '99a1', t.order_id
25
+ assert_equal '182.129.106.102', t.ip
26
+ assert_equal 'LotsOCoffee', t.description
27
+ assert_equal 'My Writeoff Inc.', t.merchant_name_descriptor
28
+ assert_equal 'Tax Free Zone', t.merchant_location_descriptor
29
+ assert_equal 'XYI0V2l4KC1cAm6Y3c2kG5loJaA', t.gateway_token
30
+ assert_equal 'RkIAltzr49eXuWc7ajBjLLeKZt8', t.reference_token
31
+
32
+ assert t.response.success
33
+ assert_equal 'Successful credit', t.response.message
34
+ end
35
+
36
+ def test_failed_refund
37
+ t = refund_using(failed_refund_response)
38
+
39
+ assert_kind_of(Spreedly::Refund, t)
40
+ assert_equal 'UWB0L2Q2hwX1qy3Z8UdHd426icC', t.token
41
+ assert_equal 44, t.amount
42
+ assert !t.succeeded?
43
+ assert_equal 'gateway_processing_failed', t.state
44
+
45
+ assert_equal 'The eagle is actually a dead duck.', t.response.error_detail
46
+ end
47
+
48
+ def test_empty_request_body_params
49
+ body = get_request_body(successful_refund_response) do
50
+ @environment.refund_transaction("TheTransactionToken")
51
+ end
52
+
53
+ assert_nil body.root
54
+ end
55
+
56
+ def test_request_body_params
57
+ body = get_request_body(successful_refund_response) do
58
+ @environment.refund_transaction("TheTransactionToken", all_possible_options)
59
+ end
60
+
61
+ transaction = body.xpath('./transaction')
62
+ assert_xpaths_in transaction,
63
+ [ './amount', '29' ],
64
+ [ './currency_code', 'CAD' ],
65
+ [ './order_id', '8668' ],
66
+ [ './description', 'Gold Farmin' ],
67
+ [ './ip', '183.128.100.102' ],
68
+ [ './merchant_name_descriptor', 'TRain' ],
69
+ [ './merchant_location_descriptor', 'British Colombia' ]
70
+ end
71
+
72
+
73
+ private
74
+ def refund_using(response)
75
+ @environment.stubs(:raw_ssl_request).returns(response)
76
+ @environment.refund_transaction("IgnoredTokenSinceResponseIsStubbed")
77
+ end
78
+
79
+ def all_possible_options
80
+ {
81
+ amount: 29,
82
+ currency_code: "CAD",
83
+ order_id: "8668",
84
+ description: "Gold Farmin",
85
+ ip: "183.128.100.102",
86
+ merchant_name_descriptor: "TRain",
87
+ merchant_location_descriptor: "British Colombia"
88
+ }
89
+ end
90
+
91
+ end
@@ -0,0 +1,43 @@
1
+ module AddCreditCardStubs
2
+
3
+ def successful_add_credit_card_response
4
+ StubResponse.succeeded <<-XML
5
+ <transaction>
6
+ <token>6wxjN6HcDik8e3mAhBaaoVGSImH</token>
7
+ <created_at type="datetime">2013-08-02T18:04:45Z</created_at>
8
+ <updated_at type="datetime">2013-08-02T18:04:45Z</updated_at>
9
+ <succeeded type="boolean">true</succeeded>
10
+ <transaction_type>AddPaymentMethod</transaction_type>
11
+ <retained type="boolean">false</retained>
12
+ <message key="messages.transaction_succeeded">Succeeded!</message>
13
+ <payment_method>
14
+ <token>AXaBXfVUqhaGMg8ytf8isiMAAL9</token>
15
+ <created_at type="datetime">2013-08-02T18:04:45Z</created_at>
16
+ <updated_at type="datetime">2013-08-02T18:04:45Z</updated_at>
17
+ <email>ellend@mistborn.com</email>
18
+ <data>Don't test everything here, since find_payment_method tests it all.</data>
19
+ <storage_state>cached</storage_state>
20
+ <last_four_digits>4942</last_four_digits>
21
+ <card_type>master</card_type>
22
+ <first_name>Eland</first_name>
23
+ <last_name>Venture</last_name>
24
+ <month type="integer">1</month>
25
+ <year type="integer">2019</year>
26
+ <address1>3 Main</address1>
27
+ <address2>Suite 7</address2>
28
+ <city>Oakland</city>
29
+ <state>NJ</state>
30
+ <zip>33221</zip>
31
+ <country>UK</country>
32
+ <phone_number>43</phone_number>
33
+ <full_name>Eland Venture</full_name>
34
+ <payment_method_type>credit_card</payment_method_type>
35
+ <errors>
36
+ </errors>
37
+ <verification_value></verification_value>
38
+ <number>XXXX-XXXX-XXXX-4942</number>
39
+ </payment_method>
40
+ </transaction>
41
+ XML
42
+ end
43
+ end