payload-api 0.4.1 → 0.5.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.
@@ -759,4 +759,262 @@ RSpec.describe Payload::ARMRequest do
759
759
  end
760
760
  end
761
761
  end
762
+
763
+ describe "API version header functionality" do
764
+
765
+ # Mock object for testing
766
+ class MockObject < Payload::ARMObject
767
+ @spec = { 'object' => 'mock_object', 'endpoint' => '/mock' }
768
+ end
769
+
770
+ context "when session.api_version is set" do
771
+ it "includes X-API-Version header in GET requests" do
772
+ $test_id = 'mock_' + rand(9000000...9999999).to_s
773
+
774
+ session = Payload::Session.new('test_key', 'https://api.test.com', '2.1')
775
+ instance = Payload::ARMRequest.new(MockObject, session)
776
+
777
+ expect(instance).to receive(:_execute_request) do |http, request|
778
+ expect(request.method).to eq("GET")
779
+ expect(request['X-API-Version']).to eq('2.1')
780
+
781
+ class MockResponse
782
+ def initialize
783
+ end
784
+
785
+ def code
786
+ '200'
787
+ end
788
+
789
+ def body
790
+ '{
791
+ "object": "mock_object",
792
+ "id": "' + $test_id + '"
793
+ }'
794
+ end
795
+ end
796
+
797
+ MockResponse.new
798
+ end
799
+
800
+ instance.get($test_id)
801
+ end
802
+ end
803
+
804
+ context "when session.api_version is nil" do
805
+ it "does not include X-API-Version header" do
806
+ $test_id = 'mock_' + rand(9000000...9999999).to_s
807
+
808
+ session = Payload::Session.new('test_key', 'https://api.test.com', nil)
809
+ instance = Payload::ARMRequest.new(MockObject, session)
810
+
811
+ expect(instance).to receive(:_execute_request) do |http, request|
812
+ expect(request.method).to eq("GET")
813
+ expect(request['X-API-Version']).to be_nil
814
+
815
+ class MockResponse
816
+ def initialize
817
+ end
818
+
819
+ def code
820
+ '200'
821
+ end
822
+
823
+ def body
824
+ '{
825
+ "object": "mock_object",
826
+ "id": "' + $test_id + '"
827
+ }'
828
+ end
829
+ end
830
+
831
+ MockResponse.new
832
+ end
833
+
834
+ instance.get($test_id)
835
+ end
836
+ end
837
+
838
+ context "when no session is provided" do
839
+ it "uses global Payload.api_version" do
840
+ $test_id = 'mock_' + rand(9000000...9999999).to_s
841
+
842
+ # Set global api_version
843
+ original_version = Payload.api_version
844
+ Payload.api_version = '2.2'
845
+
846
+ # Create request without session (will use global Payload module)
847
+ instance = Payload::ARMRequest.new(MockObject, nil)
848
+
849
+ expect(instance).to receive(:_execute_request) do |http, request|
850
+ expect(request.method).to eq("GET")
851
+ expect(request['X-API-Version']).to eq('2.2')
852
+
853
+ class MockResponse
854
+ def initialize
855
+ end
856
+
857
+ def code
858
+ '200'
859
+ end
860
+
861
+ def body
862
+ '{
863
+ "object": "mock_object",
864
+ "id": "' + $test_id + '"
865
+ }'
866
+ end
867
+ end
868
+
869
+ MockResponse.new
870
+ end
871
+
872
+ instance.get($test_id)
873
+
874
+ # Restore original version
875
+ Payload.api_version = original_version
876
+ end
877
+ end
878
+
879
+ context "when making POST requests" do
880
+ it "includes X-API-Version header" do
881
+ $test_id = 'mock_' + rand(9000000...9999999).to_s
882
+
883
+ session = Payload::Session.new('test_key', 'https://api.test.com', '2.3')
884
+ instance = Payload::ARMRequest.new(MockObject, session)
885
+
886
+ expect(instance).to receive(:_execute_request) do |http, request|
887
+ expect(request.method).to eq("POST")
888
+ expect(request['X-API-Version']).to eq('2.3')
889
+
890
+ class MockResponse
891
+ def initialize
892
+ end
893
+
894
+ def code
895
+ '200'
896
+ end
897
+
898
+ def body
899
+ '{
900
+ "object": "mock_object",
901
+ "id": "' + $test_id + '"
902
+ }'
903
+ end
904
+ end
905
+
906
+ MockResponse.new
907
+ end
908
+
909
+ instance.create({ field: 'value' })
910
+ end
911
+ end
912
+
913
+ context "when making PUT requests" do
914
+ it "includes X-API-Version header" do
915
+ $test_id = 'mock_' + rand(9000000...9999999).to_s
916
+
917
+ session = Payload::Session.new('test_key', 'https://api.test.com', '2.4')
918
+ instance = Payload::ARMRequest.new(MockObject, session)
919
+
920
+ expect(instance).to receive(:_execute_request) do |http, request|
921
+ expect(request.method).to eq("PUT")
922
+ expect(request['X-API-Version']).to eq('2.4')
923
+
924
+ class MockResponse
925
+ def initialize
926
+ end
927
+
928
+ def code
929
+ '200'
930
+ end
931
+
932
+ def body
933
+ '{
934
+ "object": "mock_object",
935
+ "id": "' + $test_id + '"
936
+ }'
937
+ end
938
+ end
939
+
940
+ MockResponse.new
941
+ end
942
+
943
+ instance.update(field: 'new_value')
944
+ end
945
+ end
946
+
947
+ context "when making DELETE requests" do
948
+ it "includes X-API-Version header" do
949
+ $test_id = 'mock_' + rand(9000000...9999999).to_s
950
+
951
+ session = Payload::Session.new('test_key', 'https://api.test.com', '2.5')
952
+
953
+ # Create mock object to delete
954
+ mock_obj = MockObject.new({ id: $test_id })
955
+ mock_obj.set_session(session)
956
+
957
+ expect_any_instance_of(Payload::ARMRequest).to receive(:_execute_request) do |inst, http, request|
958
+ expect(request.method).to eq("DELETE")
959
+ expect(request['X-API-Version']).to eq('2.5')
960
+
961
+ class MockResponse
962
+ def initialize
963
+ end
964
+
965
+ def code
966
+ '200'
967
+ end
968
+
969
+ def body
970
+ '{
971
+ "object": "mock_object",
972
+ "id": "' + $test_id + '"
973
+ }'
974
+ end
975
+ end
976
+
977
+ MockResponse.new
978
+ end
979
+
980
+ mock_obj.delete
981
+ end
982
+ end
983
+
984
+ context "when custom headers are provided" do
985
+ it "merges X-API-Version header with existing headers" do
986
+ $test_id = 'mock_' + rand(9000000...9999999).to_s
987
+
988
+ session = Payload::Session.new('test_key', 'https://api.test.com', '2.6')
989
+ instance = Payload::ARMRequest.new(MockObject, session)
990
+
991
+ expect(instance).to receive(:_execute_request) do |http, request|
992
+ expect(request.method).to eq("POST")
993
+ # Verify both Content-Type and X-API-Version headers are present
994
+ expect(request['Content-Type']).to eq('application/json')
995
+ expect(request['X-API-Version']).to eq('2.6')
996
+
997
+ class MockResponse
998
+ def initialize
999
+ end
1000
+
1001
+ def code
1002
+ '200'
1003
+ end
1004
+
1005
+ def body
1006
+ '{
1007
+ "object": "mock_object",
1008
+ "id": "' + $test_id + '"
1009
+ }'
1010
+ end
1011
+ end
1012
+
1013
+ MockResponse.new
1014
+ end
1015
+
1016
+ instance.create({ field: 'value' })
1017
+ end
1018
+ end
1019
+ end
762
1020
  end
@@ -0,0 +1,159 @@
1
+ class V1Helpers
2
+ attr_reader :session
3
+
4
+ def initialize(session)
5
+ @session = session
6
+ end
7
+
8
+ def create_customer_account(name: 'Test', email: 'test@example.com')
9
+ session.Customer.create(name: name, email: email)
10
+ end
11
+
12
+ def create_processing_account
13
+ session.ProcessingAccount.create(
14
+ name: 'Processing Account',
15
+ legal_entity: {
16
+ legal_name: 'Test',
17
+ type: 'INDIVIDUAL_SOLE_PROPRIETORSHIP',
18
+ ein: '23 423 4234',
19
+ street_address: '123 Example Street',
20
+ unit_number: 'Suite 1',
21
+ city: 'New York',
22
+ state_province: 'NY',
23
+ state_incorporated: 'NY',
24
+ postal_code: '11238',
25
+ country: 'US',
26
+ phone_number: '(111) 222-3333',
27
+ website: 'http://www.payload.com',
28
+ start_date: '05/01/2015',
29
+ contact_name: 'Test Person',
30
+ contact_email: 'test.person@example.com',
31
+ contact_title: 'VP',
32
+ owners: [
33
+ {
34
+ full_name: 'Test Person',
35
+ email: 'test.person@example.com',
36
+ ssn: '234 23 4234',
37
+ birth_date: '06/20/1985',
38
+ title: 'CEO',
39
+ ownership: '100',
40
+ street_address: '123 Main Street',
41
+ unit_number: '#1A',
42
+ city: 'New York',
43
+ state_province: 'NY',
44
+ postal_code: '10001',
45
+ phone_number: '(111) 222-3333',
46
+ type: 'owner'
47
+ }
48
+ ]
49
+ },
50
+ payment_methods: [session.PaymentMethod.new(
51
+ type: 'bank_account',
52
+ bank_account: {
53
+ account_number: '123456789',
54
+ routing_number: '036001808',
55
+ account_type: 'checking'
56
+ }
57
+ )]
58
+ )
59
+ end
60
+
61
+ def create_card_payment(processing_id, amount: nil, description: nil, customer_id: nil, invoice_id: nil)
62
+ payment = {
63
+ processing_id: processing_id,
64
+ amount: amount || rand * 100,
65
+ description: description || 'Test Payment',
66
+ payment_method: session.PaymentMethod.new(
67
+ type: 'card',
68
+ card: {
69
+ card_number: '4242 4242 4242 4242',
70
+ expiry: '12/35',
71
+ card_code: '123',
72
+ },
73
+ billing_address: {
74
+ postal_code: '11111'
75
+ }
76
+ )
77
+ }
78
+ if invoice_id
79
+ payment = payment.merge({
80
+ allocations: [{invoice_id: invoice_id}]
81
+ })
82
+ end
83
+ if customer_id
84
+ payment = payment.merge({
85
+ customer_id: customer_id
86
+ })
87
+ end
88
+ session.Payment.create(payment)
89
+ end
90
+
91
+ def create_bank_payment
92
+ session.Payment.create(
93
+ type: 'payment',
94
+ amount: rand * 1000,
95
+ payment_method: session.PaymentMethod.new(
96
+ type: 'bank_account',
97
+ account_holder: 'First Last',
98
+ bank_account: {
99
+ account_number: '1234567890',
100
+ routing_number: '036001808',
101
+ account_type: 'checking'
102
+ },
103
+ billing_address: {
104
+ postal_code: '11111'
105
+ }
106
+ )
107
+ )
108
+ end
109
+
110
+ def create_invoice(processing_account, customer_account)
111
+ session.Invoice.create(
112
+ processing_id: processing_account.id,
113
+ due_date: Date.today.strftime('%Y-%m-%d'),
114
+ customer_id: customer_account.id,
115
+ items: [session.ChargeItem.new(amount: 29.99)]
116
+ )
117
+ end
118
+
119
+ def create_blind_refund(amount, processing_id)
120
+ session.Refund.create(
121
+ amount: amount,
122
+ processing_id: processing_id,
123
+ payment_method: {
124
+ type: 'card',
125
+ card: {
126
+ card_number: '4242 4242 4242 4242',
127
+ expiry: '12/30',
128
+ card_code: '123'
129
+ },
130
+ billing_address: { postal_code: '11111' }
131
+ }
132
+ )
133
+ end
134
+
135
+ def create_refund(payment, amount: nil)
136
+ session.Refund.create(
137
+ amount: amount || payment.amount,
138
+ ledger: [{assoc_transaction_id: payment.id}]
139
+ )
140
+ end
141
+
142
+ def create_payment_link_one_time(processing_account)
143
+ session.PaymentLink.create(
144
+ type: 'one_time',
145
+ description: 'Payment Request',
146
+ amount: 10.00,
147
+ processing_id: processing_account.id
148
+ )
149
+ end
150
+
151
+ def create_payment_link_reusable(processing_account)
152
+ session.PaymentLink.create(
153
+ type: 'reusable',
154
+ description: 'Payment Request',
155
+ amount: 10.00,
156
+ processing_id: processing_account.id
157
+ )
158
+ end
159
+ end
@@ -0,0 +1,205 @@
1
+ class V2Helpers
2
+ attr_reader :session
3
+
4
+ def initialize(session)
5
+ @session = session
6
+ end
7
+
8
+ def create_customer_account(name: 'Test', email: 'test@example.com')
9
+ session.Account.create(
10
+ type: 'customer',
11
+ name: name,
12
+ contact_details: {
13
+ email: email
14
+ }
15
+ )
16
+ end
17
+
18
+ def create_processing_account
19
+ org = session.Profile.all()[0]
20
+ session.Account.create(
21
+ type: 'processing',
22
+ name: 'Processing Account',
23
+ processing: {
24
+ status: { funding: 'pending' },
25
+ settings_id: org.processing_settings_id,
26
+ },
27
+ payment_methods: [session.PaymentMethod.new(
28
+ type: 'bank_account',
29
+ bank_account: {
30
+ account_number: '123456789',
31
+ routing_number: '036001808',
32
+ account_type: 'checking'
33
+ },
34
+ billing_address: {
35
+ postal_code: '11111',
36
+ },
37
+ account_defaults: {
38
+ funding: 'all',
39
+ }
40
+ )],
41
+ entity: {
42
+ type: 'business',
43
+ legal_name: 'Example',
44
+ country: 'US',
45
+ phone_number: '123 123-1234',
46
+ tax_id: { value: '123 12 1234' },
47
+ address: {
48
+ address_line_1: '123 Example St',
49
+ city: 'New York',
50
+ state_province: 'NY',
51
+ postal_code: '11111',
52
+ },
53
+ business: {
54
+ category: 'real_estate',
55
+ structure: 'llc',
56
+ website: 'https://example.com',
57
+ formation: {
58
+ state_province: 'NY',
59
+ date: '2019-10-01',
60
+ },
61
+ primary_contact: {
62
+ name: 'John Smith',
63
+ email: 'johnsmith@gmail.com',
64
+ },
65
+ stakeholders: [
66
+ {
67
+ country: 'US',
68
+ personal_information: {
69
+ full_name: 'John Smith',
70
+ email: 'johnsmith@gmail.com',
71
+ birth_date: '1990-05-10',
72
+ phone_number: '123 123-1234',
73
+ },
74
+ address: {
75
+ address_line_1: '123 Example St',
76
+ city: 'New York',
77
+ state_province: 'NY',
78
+ postal_code: '11111',
79
+ },
80
+ govt_id: {
81
+ tax_id: { value: '123 12 1234' },
82
+ },
83
+ association: {
84
+ ownership: {
85
+ percentage: 100,
86
+ years_owned: 5,
87
+ },
88
+ roles: ['principal_officer'],
89
+ title: 'CEO',
90
+ },
91
+ },
92
+ ],
93
+ },
94
+ },
95
+ )
96
+ end
97
+
98
+ def create_card_payment(processing_id, amount: nil, description: nil, customer_id: nil, invoice_id: nil)
99
+ sender = {
100
+ method: session.PaymentMethod.new(
101
+ type: 'card',
102
+ card: {
103
+ card_number: '4242 4242 4242 4242',
104
+ expiry: '12/35',
105
+ card_code: '123',
106
+ },
107
+ billing_address: {
108
+ postal_code: '11111'
109
+ }
110
+ )
111
+ }
112
+ if customer_id
113
+ sender = sender.merge({
114
+ account_id: customer_id,
115
+ })
116
+ end
117
+ payment = {
118
+ type: 'payment',
119
+ amount: amount || rand * 100,
120
+ description: description || 'Test Payment',
121
+ sender: sender,
122
+ }
123
+ if invoice_id
124
+ payment = payment.merge({
125
+ invoice_allocations: [{invoice_id: invoice_id}]
126
+ })
127
+ end
128
+ if processing_id
129
+ payment = payment.merge({
130
+ receiver: {
131
+ account_id: processing_id,
132
+ }
133
+ })
134
+ end
135
+ session.Transaction.create(payment)
136
+ end
137
+
138
+ def create_bank_payment
139
+ session.Transaction.create(
140
+ type: 'payment',
141
+ amount: rand * 1000,
142
+ sender: {
143
+ method: session.PaymentMethod.new(
144
+ type: 'bank_account',
145
+ account_holder: 'First Last',
146
+ bank_account: {
147
+ account_number: '123456789',
148
+ currency: 'USD',
149
+ routing_number: '036001808',
150
+ account_type: 'checking',
151
+ account_class: 'personal',
152
+ },
153
+ )
154
+ }
155
+ )
156
+ end
157
+
158
+ def create_invoice(processing_account, customer_account)
159
+ session.Invoice.create(
160
+ due_date: Date.today.strftime('%Y-%m-%d'),
161
+ biller: {
162
+ account_id: processing_account.id,
163
+ },
164
+ payer: {
165
+ account_id: customer_account.id,
166
+ },
167
+ items: [
168
+ {
169
+ type: 'line_item',
170
+ line_item: {
171
+ value: 29.99,
172
+ }
173
+ }
174
+ ],
175
+ )
176
+ end
177
+
178
+ def create_blind_refund(amount, processing_id)
179
+ session.Transaction.create(
180
+ type: 'refund',
181
+ amount: amount,
182
+ sender: {
183
+ account_id: processing_id,
184
+ },
185
+ receiver: {
186
+ method: session.PaymentMethod.new(
187
+ type: 'card',
188
+ card: {
189
+ card_number: '4242 4242 4242 4242',
190
+ expiry: '12/30',
191
+ card_code: '123'
192
+ },
193
+ billing_address: { postal_code: '11111' }
194
+ )
195
+ }
196
+ )
197
+ end
198
+
199
+ def create_refund(payment, amount: nil)
200
+ session.Transaction.create(
201
+ type: 'refund',
202
+ transfers: [{assoc_transaction_id: payment.id, amount: amount || payment.amount}]
203
+ )
204
+ end
205
+ end
@@ -0,0 +1,15 @@
1
+ require 'payload'
2
+ require 'date'
3
+
4
+ RSpec.shared_context 'test helpers' do
5
+ before(:all) do
6
+ Payload.api_key = ENV['TEST_SECRET_KEY']
7
+ if ENV['TEST_API_URL']
8
+ Payload.api_url = ENV['TEST_API_URL']
9
+ end
10
+ end
11
+ end
12
+
13
+ # Load version-specific helpers
14
+ require_relative 'helpers/v1_helpers'
15
+ require_relative 'helpers/v2_helpers'
@@ -0,0 +1,21 @@
1
+ require 'payload'
2
+ require_relative 'helpers'
3
+
4
+ RSpec.describe 'Test helpers API versions' do
5
+ include_context 'test helpers'
6
+
7
+ describe '#create_processing_account' do
8
+ [1, 2].each do |api_version|
9
+ context "api_version=#{api_version}" do
10
+ let(:session) { Payload::Session.new(Payload.api_key, Payload.api_url, api_version) }
11
+ let(:h) { Object.const_get("V#{api_version}Helpers").new(session) }
12
+
13
+ it 'returns a processing account' do
14
+ account = h.create_processing_account
15
+ expect(account).to respond_to(:id)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+