forked from stripe-ruby-mock/stripe-ruby-mock
-
Notifications
You must be signed in to change notification settings - Fork 0
/
checkout_session.rb
179 lines (162 loc) · 7.23 KB
/
checkout_session.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
module StripeMock
module RequestHandlers
module Checkout
module Session
def Session.included(klass)
klass.add_handler 'post /v1/checkout/sessions', :new_session
klass.add_handler 'get /v1/checkout/sessions', :list_checkout_sessions
klass.add_handler 'get /v1/checkout/sessions/([^/]*)', :get_checkout_session
klass.add_handler 'get /v1/checkout/sessions/([^/]*)/line_items', :list_line_items
end
def new_session(route, method_url, params, headers)
id = params[:id] || new_id('cs')
[:cancel_url, :success_url].each do |p|
require_param(p) if params[p].nil? || params[p].empty?
end
line_items = nil
if params[:line_items]
line_items = params[:line_items].each_with_index.map do |line_item, i|
throw Stripe::InvalidRequestError("Quantity is required. Add `quantity` to `line_items[#{i}]`") unless line_item[:quantity]
unless line_item[:price] || line_item[:price_data] || (line_item[:amount] && line_item[:currency] && line_item[:name])
throw Stripe::InvalidRequestError("Price or amount and currency is required. Add `price`, `price_data`, or `amount`, `currency` and `name` to `line_items[#{i}]`")
end
{
id: new_id("li"),
price: if line_item[:price]
line_item[:price]
elsif line_item[:price_data]
new_price(nil, nil, line_item[:price_data], nil)[:id]
else
new_price(nil, nil, {
unit_amount: line_item[:amount],
currency: line_item[:currency],
product_data: {
name: line_item[:name]
}
}, nil)[:id]
end,
quantity: line_item[:quantity]
}
end
end
amount = nil
currency = nil
if line_items
amount = 0
line_items.each do |line_item|
price = prices[line_item[:price]]
if price.nil?
raise StripeMock::StripeMockError.new("Price not found for ID: #{line_item[:price]}")
end
amount += (price[:unit_amount] * line_item[:quantity])
end
currency = prices[line_items.first[:price]][:currency]
end
payment_status = "unpaid"
payment_intent = nil
setup_intent = nil
case params[:mode]
when nil, "payment"
params[:customer] ||= new_customer(nil, nil, {email: params[:customer_email]}, nil)[:id]
require_param(:line_items) if params[:line_items].nil? || params[:line_items].empty?
payment_intent = new_payment_intent(nil, nil, {
amount: amount,
currency: currency,
customer: params[:customer],
payment_method_options: params[:payment_method_options],
payment_method_types: params[:payment_method_types]
}.merge(params[:payment_intent_data] || {}), nil)[:id]
checkout_session_line_items[id] = line_items
when "setup"
if !params[:line_items].nil? && !params[:line_items].empty?
throw Stripe::InvalidRequestError.new("You cannot pass `line_items` in `setup` mode", :line_items, http_status: 400)
end
setup_intent = new_setup_intent(nil, nil, {
customer: params[:customer],
payment_method_options: params[:payment_method_options],
payment_method_types: params[:payment_method_types]
}.merge(params[:setup_intent_data] || {}), nil)[:id]
payment_status = "no_payment_required"
when "subscription"
params[:customer] ||= new_customer(nil, nil, {email: params[:customer_email]}, nil)[:id]
require_param(:line_items) if params[:line_items].nil? || params[:line_items].empty?
checkout_session_line_items[id] = line_items
else
throw Stripe::InvalidRequestError.new("Invalid mode: must be one of payment, setup, or subscription", :mode, http_status: 400)
end
checkout_sessions[id] = {
id: id,
object: "checkout.session",
allow_promotion_codes: nil,
amount_subtotal: amount,
amount_total: amount,
automatic_tax: {
enabled: false,
status: nil
},
billing_address_collection: nil,
cancel_url: params[:cancel_url],
client_reference_id: nil,
currency: currency,
customer: params[:customer],
customer_details: nil,
customer_email: params[:customer_email],
livemode: false,
locale: nil,
metadata: params[:metadata],
mode: params[:mode],
payment_intent: payment_intent,
payment_method_options: params[:payment_method_options],
payment_method_types: params[:payment_method_types],
payment_status: payment_status,
setup_intent: setup_intent,
shipping: nil,
shipping_address_collection: nil,
submit_type: nil,
subscription: nil,
success_url: params[:success_url],
total_details: nil,
url: URI.join(StripeMock.checkout_base, id).to_s
}
end
def list_checkout_sessions(route, method_url, params, headers)
Data.mock_list_object(checkout_sessions.values)
end
def get_checkout_session(route, method_url, params, headers)
route =~ method_url
checkout_session = assert_existence :checkout_session, $1, checkout_sessions[$1]
checkout_session = checkout_session.clone
if params[:expand]&.include?('setup_intent') && checkout_session[:setup_intent]
checkout_session[:setup_intent] = setup_intents[checkout_session[:setup_intent]]
end
checkout_session
end
def list_line_items(route, method_url, params, headers)
route =~ method_url
checkout_session = assert_existence :checkout_session, $1, checkout_sessions[$1]
case checkout_session[:mode]
when "payment", "subscription"
line_items = assert_existence :checkout_session_line_items, $1, checkout_session_line_items[$1]
line_items.map do |line_item|
price = prices[line_item[:price]].clone
if price.nil?
raise StripeMock::StripeMockError.new("Price not found for ID: #{line_item[:price]}")
end
{
id: line_item[:id],
object: "item",
amount_subtotal: price[:unit_amount] * line_item[:quantity],
amount_total: price[:unit_amount] * line_item[:quantity],
currency: price[:currency],
price: price.clone,
quantity: line_item[:quantity]
}
end
else
throw Stripe::InvalidRequestError("Only payment and subscription sessions have line items")
end
end
end
end
end
end