payload-api 0.4.1 → 0.6.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.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +2 -0
- data/LICENSE +1 -1
- data/README.md +23 -2
- data/lib/payload/arm/attr.rb +169 -0
- data/lib/payload/arm/object.rb +44 -1
- data/lib/payload/arm/request.rb +66 -6
- data/lib/payload/arm/session.rb +13 -9
- data/lib/payload/exceptions.rb +15 -0
- data/lib/payload/objects.rb +81 -18
- data/lib/payload/version.rb +2 -2
- data/lib/payload.rb +15 -5
- data/spec/objects/v1/access_token_spec.rb +19 -0
- data/spec/objects/v1/account_spec.rb +97 -0
- data/spec/objects/v1/billing_spec.rb +54 -0
- data/spec/objects/v1/invoice_spec.rb +53 -0
- data/spec/objects/v1/payment_link_spec.rb +50 -0
- data/spec/objects/v1/payment_method_spec.rb +106 -0
- data/spec/objects/{payment_spec.rb → v1/payment_spec.rb} +5 -6
- data/spec/objects/v1/session_spec.rb +89 -0
- data/spec/objects/v1/transaction_spec.rb +55 -0
- data/spec/objects/v2/account_spec.rb +211 -0
- data/spec/objects/v2/invoice_spec.rb +53 -0
- data/spec/objects/v2/payment_method_spec.rb +106 -0
- data/spec/objects/v2/transaction_spec.rb +48 -0
- data/spec/payload/arm/arm_request_query_spec.rb +226 -0
- data/spec/payload/arm/attr_spec.rb +216 -0
- data/spec/payload/arm/object_spec.rb +114 -0
- data/spec/payload/arm/request_format_integration_spec.rb +166 -0
- data/spec/payload/arm/request_spec.rb +259 -1
- data/spec/payload/arm/session_spec.rb +40 -0
- data/spec/payload/exceptions_spec.rb +82 -0
- data/spec/support/helpers/v1_helpers.rb +159 -0
- data/spec/support/helpers/v2_helpers.rb +205 -0
- data/spec/support/helpers.rb +15 -0
- data/spec/support/helpers_spec.rb +21 -0
- metadata +28 -6
|
@@ -11,7 +11,7 @@ RSpec.describe Payload::ARMRequest do
|
|
|
11
11
|
|
|
12
12
|
context "when the user selects custom fields" do
|
|
13
13
|
it "selects the requested fields" do
|
|
14
|
-
instance.select('
|
|
14
|
+
instance.select('name', 'age')
|
|
15
15
|
expect(instance.instance_variable_get(:@filters)).to eq({ "fields" => "name,age" })
|
|
16
16
|
instance.select('count(id)', 'sum(amount)')
|
|
17
17
|
expect(instance.instance_variable_get(:@filters)).to eq({ "fields" => "count(id),sum(amount)" })
|
|
@@ -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
|
|
@@ -24,6 +24,46 @@ RSpec.describe Payload::Session do
|
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
+
describe "#attr" do
|
|
28
|
+
it "returns an AttrRoot so pl.attr.name returns an Attr (not shadowed by Class#name)" do
|
|
29
|
+
instance = described_class.new("test_key", "https://api.hello.co")
|
|
30
|
+
root = instance.attr
|
|
31
|
+
|
|
32
|
+
expect(root).to be_a(Payload::AttrRoot)
|
|
33
|
+
expect(root.id).to be_a(Payload::Attr)
|
|
34
|
+
expect(root.id.to_s).to eq("id")
|
|
35
|
+
|
|
36
|
+
expect(root.created_at(:year)).to be_a(Payload::Attr)
|
|
37
|
+
expect(root.created_at(:year).to_s).to eq("year(created_at)")
|
|
38
|
+
|
|
39
|
+
expect(root.created_at.year.to_s).to eq("created_at[year]")
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
describe "query chaining with session" do
|
|
44
|
+
it "passes session through query -> select -> order_by -> limit chain" do
|
|
45
|
+
instance = described_class.new("session_key", "https://api.test.com", "v2")
|
|
46
|
+
req = instance.query(Payload::Invoice).select("id", "amount").order_by("created_at").limit(5)
|
|
47
|
+
|
|
48
|
+
expect(req).to be_a(Payload::ARMRequest)
|
|
49
|
+
expect(req.instance_variable_get(:@session)).to eq(instance)
|
|
50
|
+
expect(req.instance_variable_get(:@filters)["fields"]).to eq("id,amount")
|
|
51
|
+
expect(req.instance_variable_get(:@order_by)).to include("created_at")
|
|
52
|
+
expect(req.instance_variable_get(:@limit)).to eq(5)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "filter_by with session.attr uses AttrRoot from same session" do
|
|
56
|
+
instance = described_class.new("test_key", "https://api.test.com", "v2")
|
|
57
|
+
filter_expr = instance.attr.status == "processed"
|
|
58
|
+
req = instance.query(Payload::Transaction).filter_by(filter_expr)
|
|
59
|
+
|
|
60
|
+
expect(req.instance_variable_get(:@session)).to eq(instance)
|
|
61
|
+
expect(req.instance_variable_get(:@filter_objects)).to include(be_a(Payload::ARMEqual))
|
|
62
|
+
params = req.request_params
|
|
63
|
+
expect(params["status"]).to eq("processed")
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
27
67
|
describe "#query" do
|
|
28
68
|
|
|
29
69
|
context "when the user queries an ARMObject with a session" do
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "payload"
|
|
4
|
+
|
|
5
|
+
RSpec.describe Payload::TransactionDeclined do
|
|
6
|
+
def api_error_payload(message:, details: nil)
|
|
7
|
+
{
|
|
8
|
+
"object" => "error",
|
|
9
|
+
"error_type" => "TransactionDeclined",
|
|
10
|
+
"error_description" => message,
|
|
11
|
+
"details" => details,
|
|
12
|
+
}.compact
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "inherits from BadRequest (HTTP 400)" do
|
|
16
|
+
expect(described_class.superclass).to eq(Payload::BadRequest)
|
|
17
|
+
expect(Payload::BadRequest.code).to eq("400")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "sets message from first argument (same as request.rb: data['error_description'])" do
|
|
21
|
+
e = described_class.new("Card declined", nil)
|
|
22
|
+
expect(e.message).to eq("Card declined")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "exposes #transaction as nil when data is nil" do
|
|
26
|
+
e = described_class.new("Declined", nil)
|
|
27
|
+
expect(e.transaction).to be_nil
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "exposes #transaction as nil when details is missing" do
|
|
31
|
+
e = described_class.new("Declined", api_error_payload(message: "Declined"))
|
|
32
|
+
expect(e.transaction).to be_nil
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "exposes #transaction as nil when details is not a Hash" do
|
|
36
|
+
e = described_class.new("Declined", api_error_payload(message: "Declined", details: "string"))
|
|
37
|
+
expect(e.transaction).to be_nil
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "builds a transaction object from data['details'] when present (API-realistic payload)" do
|
|
41
|
+
details = {
|
|
42
|
+
"id" => "txn_123",
|
|
43
|
+
"object" => "transaction",
|
|
44
|
+
"type" => "payment",
|
|
45
|
+
"status" => "declined",
|
|
46
|
+
"status_code" => "do_not_honor",
|
|
47
|
+
"amount" => 100.0,
|
|
48
|
+
}
|
|
49
|
+
data = api_error_payload(message: "Transaction was declined", details: details)
|
|
50
|
+
e = described_class.new(data["error_description"], data)
|
|
51
|
+
|
|
52
|
+
expect(e.transaction).to be_a(Payload::ARMObject)
|
|
53
|
+
expect(e.transaction.id).to eq("txn_123")
|
|
54
|
+
expect(e.transaction["status"]).to eq("declined")
|
|
55
|
+
expect(e.transaction["status_code"]).to eq("do_not_honor")
|
|
56
|
+
expect(e.transaction["amount"]).to eq(100.0)
|
|
57
|
+
expect(e.transaction).to be_a(Payload::Payment)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "uses Transaction when get_cls returns nil for details (minimal details, no object key)" do
|
|
61
|
+
details = { "id" => "txn_456", "status" => "declined" }
|
|
62
|
+
data = api_error_payload(message: "Declined", details: details)
|
|
63
|
+
e = described_class.new(data["error_description"], data)
|
|
64
|
+
|
|
65
|
+
expect(e.transaction).to be_a(Payload::Transaction)
|
|
66
|
+
expect(e.transaction.id).to eq("txn_456")
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it "matches how ARM request raises: message from error_description, data = full response" do
|
|
70
|
+
data = {
|
|
71
|
+
"object" => "error",
|
|
72
|
+
"error_type" => "TransactionDeclined",
|
|
73
|
+
"error_description" => "There was an issue processing the payment",
|
|
74
|
+
"details" => { "id" => "txn_789", "object" => "transaction", "status" => "declined" },
|
|
75
|
+
}
|
|
76
|
+
e = described_class.new(data["error_description"], data)
|
|
77
|
+
|
|
78
|
+
expect(e.message).to eq("There was an issue processing the payment")
|
|
79
|
+
expect(e.transaction).to be_a(Payload::ARMObject)
|
|
80
|
+
expect(e.transaction.id).to eq("txn_789")
|
|
81
|
+
end
|
|
82
|
+
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
|