bootpay 1.1.0 → 3.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.
- checksums.yaml +4 -4
- data/.gitignore +9 -2
- data/.rspec +2 -0
- data/CHANGELOG.md +64 -14
- data/CODE_OF_CONDUCT.md +1 -1
- data/Gemfile +2 -4
- data/LICENSE.txt +1 -1
- data/README.md +309 -171
- data/Rakefile +3 -3
- data/bin/console +1 -1
- data/bootpay.gemspec +27 -24
- data/lib/bootpay/bootpay-rest-client.rb +51 -0
- data/lib/bootpay/concern/authenticate.rb +69 -0
- data/lib/bootpay/concern/cash_receipt.rb +83 -0
- data/lib/bootpay/concern/easy.rb +18 -0
- data/lib/bootpay/concern/escrow.rb +25 -0
- data/lib/bootpay/concern/payment.rb +126 -0
- data/lib/bootpay/concern/reseller.rb +97 -0
- data/lib/bootpay/concern/rest.rb +56 -0
- data/lib/bootpay/concern/sdk.rb +52 -0
- data/lib/bootpay/concern/seller.rb +15 -0
- data/lib/bootpay/concern/service.rb +15 -0
- data/lib/bootpay/concern/subscription.rb +211 -0
- data/lib/bootpay/concern/token.rb +33 -0
- data/lib/bootpay/concern/user_token.rb +23 -0
- data/lib/bootpay/concern/wallet.rb +20 -0
- data/lib/bootpay/concern/webhook.rb +18 -0
- data/lib/bootpay/concern.rb +35 -0
- data/lib/bootpay-backend-ruby.rb +6 -0
- data/lib/bootpay.rb +9 -49
- data/lib/bootpay_storage/bootpay-storage-rest-client.rb +46 -0
- data/lib/bootpay_storage/concern/csv.rb +18 -0
- data/lib/bootpay_storage/concern/image.rb +30 -0
- data/lib/bootpay_storage/concern/rest.rb +176 -0
- data/lib/bootpay_storage/concern/token.rb +9 -0
- data/lib/bootpay_storage/concern.rb +12 -0
- data/lib/bootpay_storage/response.rb +14 -0
- data/lib/bootpay_store/bootpay-store-rest-client.rb +47 -0
- data/lib/bootpay_store/concern/alimtalk_message.rb +67 -0
- data/lib/bootpay_store/concern/alimtalk_official.rb +63 -0
- data/lib/bootpay_store/concern/alimtalk_optout.rb +72 -0
- data/lib/bootpay_store/concern/alimtalk_send.rb +83 -0
- data/lib/bootpay_store/concern/alimtalk_sender.rb +105 -0
- data/lib/bootpay_store/concern/alimtalk_template.rb +215 -0
- data/lib/bootpay_store/concern/alimtalk_webhook.rb +84 -0
- data/lib/bootpay_store/concern/invoice.rb +102 -0
- data/lib/bootpay_store/concern/mall_setting.rb +385 -0
- data/lib/bootpay_store/concern/order.rb +74 -0
- data/lib/bootpay_store/concern/order_subscription.rb +391 -0
- data/lib/bootpay_store/concern/payment.rb +119 -0
- data/lib/bootpay_store/concern/product.rb +175 -0
- data/lib/bootpay_store/concern/rest.rb +128 -0
- data/lib/bootpay_store/concern/store.rb +31 -0
- data/lib/bootpay_store/concern/supervisor.rb +211 -0
- data/lib/bootpay_store/concern/token.rb +24 -0
- data/lib/bootpay_store/concern/user.rb +325 -0
- data/lib/bootpay_store/concern/user_group.rb +221 -0
- data/lib/bootpay_store/concern/webhook.rb +17 -0
- data/lib/bootpay_store/concern.rb +45 -0
- data/lib/bootpay_store/response.rb +14 -0
- data/lib/version.rb +9 -0
- metadata +81 -31
- data/.DS_Store +0 -0
- data/lib/.DS_Store +0 -0
- data/lib/bootpay/.DS_Store +0 -0
- data/lib/bootpay/billing.rb +0 -133
- data/lib/bootpay/cancel.rb +0 -29
- data/lib/bootpay/easy.rb +0 -25
- data/lib/bootpay/escrow.rb +0 -24
- data/lib/bootpay/link.rb +0 -60
- data/lib/bootpay/naverpay.rb +0 -17
- data/lib/bootpay/payment_resource.rb +0 -31
- data/lib/bootpay/reseller.rb +0 -12
- data/lib/bootpay/rest.rb +0 -38
- data/lib/bootpay/submit.rb +0 -20
- data/lib/bootpay/token.rb +0 -20
- data/lib/bootpay/verification.rb +0 -55
- data/lib/bootpay/version.rb +0 -25
- /data/lib/{response.rb → bootpay/response.rb} +0 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
module Bootpay::Concern::Subscription
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
included do
|
|
5
|
+
# 헤당 결제건의 빌링키 가져오기
|
|
6
|
+
# Comment by Gosomi
|
|
7
|
+
# Date: 2021-11-01
|
|
8
|
+
def lookup_subscribe_billing_key(receipt_id)
|
|
9
|
+
request(
|
|
10
|
+
method: :get,
|
|
11
|
+
uri: "subscribe/billing_key/#{receipt_id}"
|
|
12
|
+
)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# 빌링키로 결제 요청하기
|
|
16
|
+
# Comment by ehowlsla
|
|
17
|
+
# Date: 2024-05-29
|
|
18
|
+
def request_subscribe_payment(wallet_key: nil, billing_key: nil, order_name:, price:, tax_free: 0, card_quota: '00', feedback_url: nil, content_type: nil,
|
|
19
|
+
card_interest: nil, order_id:, items: [], user: {}, extra: {}, metadata: {})
|
|
20
|
+
request(
|
|
21
|
+
uri: 'subscribe/payment',
|
|
22
|
+
payload: {
|
|
23
|
+
wallet_key: wallet_key,
|
|
24
|
+
billing_key: billing_key,
|
|
25
|
+
metadata: metadata,
|
|
26
|
+
order_name: order_name,
|
|
27
|
+
price: price,
|
|
28
|
+
tax_free: tax_free,
|
|
29
|
+
card_quota: card_quota,
|
|
30
|
+
card_interest: card_interest,
|
|
31
|
+
order_id: order_id,
|
|
32
|
+
items: items,
|
|
33
|
+
user: user,
|
|
34
|
+
extra: extra,
|
|
35
|
+
feedback_url: feedback_url,
|
|
36
|
+
content_type: content_type
|
|
37
|
+
}
|
|
38
|
+
)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# 자동결제 예약
|
|
42
|
+
# Comment by Gosomi
|
|
43
|
+
# Date: 2022-04-21
|
|
44
|
+
def subscribe_payment_reserve(billing_key:, reserve_execute_at:, order_name:, price:, tax_free: 0, items: nil, order_id:,
|
|
45
|
+
metadata: {}, user: nil, feedback_url: nil, content_type: nil)
|
|
46
|
+
request(
|
|
47
|
+
uri: 'subscribe/payment/reserve',
|
|
48
|
+
payload: {
|
|
49
|
+
billing_key: billing_key,
|
|
50
|
+
reserve_execute_at: reserve_execute_at,
|
|
51
|
+
order_name: order_name,
|
|
52
|
+
order_id: order_id,
|
|
53
|
+
metadata: metadata,
|
|
54
|
+
price: price,
|
|
55
|
+
tax_free: tax_free,
|
|
56
|
+
items: items,
|
|
57
|
+
user: user,
|
|
58
|
+
feedback_url: feedback_url,
|
|
59
|
+
content_type: content_type
|
|
60
|
+
}
|
|
61
|
+
)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# 예약결제 조회 기능
|
|
65
|
+
# Comment by Gosomi
|
|
66
|
+
# Date: 2023-03-08
|
|
67
|
+
def subscribe_payment_reserve_lookup(reserve_id)
|
|
68
|
+
request(
|
|
69
|
+
method: :get,
|
|
70
|
+
uri: "subscribe/payment/reserve/#{reserve_id}"
|
|
71
|
+
)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# 자동결제 조회하기
|
|
75
|
+
# Comment by Gosomi
|
|
76
|
+
# Date: 2023-02-24
|
|
77
|
+
def subscribe_lookup(reserve_id)
|
|
78
|
+
request(
|
|
79
|
+
method: :get,
|
|
80
|
+
uri: "subscribe/payment/reserve/#{reserve_id}"
|
|
81
|
+
)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# 자동결제 예약 취소
|
|
85
|
+
# Comment by Gosomi
|
|
86
|
+
# Date: 2022-04-21
|
|
87
|
+
def cancel_subscribe_reserve(reserve_id)
|
|
88
|
+
request(
|
|
89
|
+
method: :delete,
|
|
90
|
+
uri: "subscribe/payment/reserve/#{reserve_id}"
|
|
91
|
+
)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# 빌링키를 강제로 만료한다
|
|
95
|
+
# Comment by Gosomi
|
|
96
|
+
# Date: 2021-11-04
|
|
97
|
+
def destroy_billing_key(billing_key)
|
|
98
|
+
request(
|
|
99
|
+
method: :delete,
|
|
100
|
+
uri: "subscribe/billing_key/#{billing_key}"
|
|
101
|
+
)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# 빌링키 발급받기
|
|
105
|
+
# Comment by Gosomi
|
|
106
|
+
# Date: 2021-11-04
|
|
107
|
+
def request_subscribe_billing_key(pg:, order_name:, price: nil, tax_free: nil, subscription_id:, card_no:, card_pw:,
|
|
108
|
+
card_identity_no:, card_expire_year:, card_expire_month:, extra: {}, user: {}, metadata: {})
|
|
109
|
+
request(
|
|
110
|
+
uri: 'request/subscribe',
|
|
111
|
+
payload: {
|
|
112
|
+
pg: pg,
|
|
113
|
+
order_name: order_name,
|
|
114
|
+
subscription_id: subscription_id,
|
|
115
|
+
price: price,
|
|
116
|
+
tax_free: tax_free,
|
|
117
|
+
card_no: card_no,
|
|
118
|
+
card_pw: card_pw,
|
|
119
|
+
card_identity_no: card_identity_no,
|
|
120
|
+
card_expire_year: card_expire_year,
|
|
121
|
+
card_expire_month: card_expire_month,
|
|
122
|
+
extra: extra,
|
|
123
|
+
user: user,
|
|
124
|
+
metadata: metadata
|
|
125
|
+
}
|
|
126
|
+
)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# 빌링키 발급 요청하기
|
|
130
|
+
# Comment by GOSOMI
|
|
131
|
+
# @date: 2024-01-26
|
|
132
|
+
def request_subscribe_automatic_transfer_billing_key(pg:, order_name:, price: nil, tax_free: nil, subscription_id:,
|
|
133
|
+
extra: {}, user: {}, metadata: {}, auth_type: 'ARS', username:,
|
|
134
|
+
bank_name:, bank_account:, identity_no:, cash_receipt_type: 1,
|
|
135
|
+
cash_receipt_identity_no: nil, phone:)
|
|
136
|
+
request(
|
|
137
|
+
uri: 'request/subscribe/automatic-transfer',
|
|
138
|
+
payload: {
|
|
139
|
+
pg: pg,
|
|
140
|
+
order_name: order_name,
|
|
141
|
+
subscription_id: subscription_id,
|
|
142
|
+
price: price,
|
|
143
|
+
tax_free: tax_free,
|
|
144
|
+
extra: extra,
|
|
145
|
+
user: user,
|
|
146
|
+
metadata: metadata,
|
|
147
|
+
auth_type: auth_type,
|
|
148
|
+
username: username,
|
|
149
|
+
bank_name: bank_name,
|
|
150
|
+
bank_account: bank_account,
|
|
151
|
+
identity_no: identity_no,
|
|
152
|
+
cash_receipt_type: cash_receipt_type,
|
|
153
|
+
cash_receipt_identity_no: cash_receipt_identity_no,
|
|
154
|
+
phone: phone
|
|
155
|
+
}
|
|
156
|
+
)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
alias_method :request_subscribe_card_payment, :request_subscribe_payment
|
|
160
|
+
|
|
161
|
+
# ARS나 본인인증 이후 빌링키 발급
|
|
162
|
+
# Comment by GOSOMI
|
|
163
|
+
# @date: 2024-01-26
|
|
164
|
+
def publish_automatic_transfer_billing_key(receipt_id:)
|
|
165
|
+
request(
|
|
166
|
+
method: :post,
|
|
167
|
+
uri: "request/subscribe/automatic-transfer/publish",
|
|
168
|
+
payload: {
|
|
169
|
+
receipt_id: receipt_id
|
|
170
|
+
}
|
|
171
|
+
)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# 정기결제를 계속해서 진행한다
|
|
175
|
+
# Comment by Gosomi
|
|
176
|
+
# Date: 2022-01-18
|
|
177
|
+
def request_subscribe_on_continue(receipt_id)
|
|
178
|
+
request(
|
|
179
|
+
method: :put,
|
|
180
|
+
uri: "request/subscribe/#{receipt_id}"
|
|
181
|
+
)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def request_subscribe_automatic_transfer_on_continue(receipt_id)
|
|
185
|
+
request(
|
|
186
|
+
method: :put,
|
|
187
|
+
uri: "request/subscribe/automatic-transfer/#{receipt_id}"
|
|
188
|
+
)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# 빌링키로 조회하는 기능을 만든다
|
|
192
|
+
# Comment by GOSOMI
|
|
193
|
+
# @date: 2023-09-14
|
|
194
|
+
def lookup_billing_key(billing_key)
|
|
195
|
+
request(
|
|
196
|
+
method: :get,
|
|
197
|
+
uri: "billing_key/#{billing_key}"
|
|
198
|
+
)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# 우선순위 빌링키 조회기능 추가
|
|
202
|
+
# Comment by GOSOMI
|
|
203
|
+
# @date: 2026-07-03
|
|
204
|
+
def lookup_sequential_billing_key(widget_key:, billing_key:, user_id:)
|
|
205
|
+
request(
|
|
206
|
+
method: :get,
|
|
207
|
+
uri: "subscribe/sequential_billing_key/#{billing_key}?widget_key=#{widget_key}&user_id=#{user_id}"
|
|
208
|
+
)
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Bootpay::Concern::Token
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
included do
|
|
5
|
+
# Access Token을 요청한다
|
|
6
|
+
# Comment by Gosomi
|
|
7
|
+
# Date: 2021-05-21
|
|
8
|
+
def request_access_token
|
|
9
|
+
response = request(
|
|
10
|
+
uri: 'request/token',
|
|
11
|
+
payload: {
|
|
12
|
+
application_id: @application_id,
|
|
13
|
+
private_key: @private_key
|
|
14
|
+
}
|
|
15
|
+
)
|
|
16
|
+
@token = response.data[:access_token] if response.success?
|
|
17
|
+
response
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# 둘다 겸하는 경우 우회함수
|
|
21
|
+
# Comment by GOSOMI
|
|
22
|
+
# @date: 2026-03-11
|
|
23
|
+
def basic_or_request_access_token
|
|
24
|
+
if @use_client_key
|
|
25
|
+
Object.new.tap do |o|
|
|
26
|
+
o.define_singleton_method(:success?) { true }
|
|
27
|
+
end
|
|
28
|
+
else
|
|
29
|
+
request_access_token
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Bootpay::Concern::UserToken
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
included do
|
|
5
|
+
# User Token 정보를 가져온다
|
|
6
|
+
# Comment by Gosomi
|
|
7
|
+
# Date: 2022-02-03
|
|
8
|
+
def request_user_token(user_id:, email: nil, username: nil, gender: -1, birth: nil, phone: nil)
|
|
9
|
+
request(
|
|
10
|
+
method: :post,
|
|
11
|
+
uri: 'request/user/token',
|
|
12
|
+
payload: {
|
|
13
|
+
user_id: user_id,
|
|
14
|
+
email: email,
|
|
15
|
+
username: username,
|
|
16
|
+
gender: gender,
|
|
17
|
+
birth: birth,
|
|
18
|
+
phone: phone
|
|
19
|
+
}
|
|
20
|
+
)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Bootpay::Concern::Wallet
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
included do
|
|
5
|
+
# 등록된 회원의 지갑 정보를 가져온다
|
|
6
|
+
# Comment by GOSOMI
|
|
7
|
+
# @date: 2025-02-13
|
|
8
|
+
def user_wallets(user_id:, widget_key: nil, sandbox: false)
|
|
9
|
+
request(
|
|
10
|
+
uri: 'wallet',
|
|
11
|
+
method: :get,
|
|
12
|
+
params: {
|
|
13
|
+
user_id: user_id,
|
|
14
|
+
widget_key: widget_key,
|
|
15
|
+
sandbox: sandbox
|
|
16
|
+
}
|
|
17
|
+
)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Bootpay::Concern::Webhook
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
included do
|
|
5
|
+
# Access Token을 요청한다
|
|
6
|
+
# Comment by Gosomi
|
|
7
|
+
# Date: 2021-05-21
|
|
8
|
+
def request_webhook(receipt_id:, webhook_url:)
|
|
9
|
+
request(
|
|
10
|
+
uri: 'request/webhook',
|
|
11
|
+
payload: {
|
|
12
|
+
receipt_id: receipt_id,
|
|
13
|
+
webhook_url: webhook_url
|
|
14
|
+
}
|
|
15
|
+
)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Bootpay
|
|
2
|
+
module Concern
|
|
3
|
+
require_relative 'concern/authenticate'
|
|
4
|
+
require_relative 'concern/cash_receipt'
|
|
5
|
+
require_relative 'concern/easy'
|
|
6
|
+
require_relative 'concern/escrow'
|
|
7
|
+
require_relative 'concern/payment'
|
|
8
|
+
require_relative 'concern/reseller'
|
|
9
|
+
require_relative 'concern/rest'
|
|
10
|
+
require_relative 'concern/sdk'
|
|
11
|
+
require_relative 'concern/seller'
|
|
12
|
+
require_relative 'concern/service'
|
|
13
|
+
require_relative 'concern/subscription'
|
|
14
|
+
require_relative 'concern/token'
|
|
15
|
+
require_relative 'concern/user_token'
|
|
16
|
+
require_relative 'concern/wallet'
|
|
17
|
+
require_relative 'concern/webhook'
|
|
18
|
+
|
|
19
|
+
include Authenticate
|
|
20
|
+
include CashReceipt
|
|
21
|
+
include Easy
|
|
22
|
+
include Escrow
|
|
23
|
+
include Payment
|
|
24
|
+
include Reseller
|
|
25
|
+
include Rest
|
|
26
|
+
include Sdk
|
|
27
|
+
include Seller
|
|
28
|
+
include Service
|
|
29
|
+
include Subscription
|
|
30
|
+
include Token
|
|
31
|
+
include UserToken
|
|
32
|
+
include Wallet
|
|
33
|
+
include Webhook
|
|
34
|
+
end
|
|
35
|
+
end
|
data/lib/bootpay.rb
CHANGED
|
@@ -1,50 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
require 'http'
|
|
3
|
-
require_relative 'response'
|
|
4
|
-
require_relative 'bootpay/billing'
|
|
5
|
-
require_relative 'bootpay/cancel'
|
|
6
|
-
require_relative 'bootpay/easy'
|
|
7
|
-
require_relative 'bootpay/escrow'
|
|
8
|
-
require_relative 'bootpay/link'
|
|
9
|
-
require_relative 'bootpay/naverpay'
|
|
10
|
-
require_relative 'bootpay/payment_resource'
|
|
11
|
-
require_relative 'bootpay/reseller'
|
|
12
|
-
require_relative 'bootpay/rest'
|
|
13
|
-
require_relative 'bootpay/submit'
|
|
14
|
-
require_relative 'bootpay/token'
|
|
15
|
-
require_relative 'bootpay/verification'
|
|
16
|
-
require_relative "bootpay/version"
|
|
1
|
+
# frozen_string_literal: true
|
|
17
2
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
include PaymentResource
|
|
27
|
-
include Reseller
|
|
28
|
-
include Rest
|
|
29
|
-
include Submit
|
|
30
|
-
include Token
|
|
31
|
-
include Verification
|
|
32
|
-
|
|
33
|
-
API =
|
|
34
|
-
{
|
|
35
|
-
development: 'https://dev-api.bootpay.co.kr',
|
|
36
|
-
stage: 'https://stage-api.bootpay.co.kr',
|
|
37
|
-
production: 'https://api.bootpay.co.kr',
|
|
38
|
-
ehowlsla: 'https://ehowlsla.bootpay.co.kr/api/v2'
|
|
39
|
-
}.freeze
|
|
40
|
-
|
|
41
|
-
def initialize(application_id:, private_key:, mode: 'production')
|
|
42
|
-
|
|
43
|
-
@application_id = application_id
|
|
44
|
-
@private_key = private_key
|
|
45
|
-
@mode = mode.presence || 'production'
|
|
46
|
-
@token = nil
|
|
47
|
-
raise ArgumentError, "개발환경 mode는 development, stage, production 중에서 선택이 가능합니다." if API[@mode.to_sym].blank?
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
end
|
|
3
|
+
# `gem 'bootpay'` 의 기본 진입점.
|
|
4
|
+
# Bundler 는 gem 이름과 같은 파일을 자동으로 require 하므로 이 파일이 없으면 부팅에서 LoadError 가 난다.
|
|
5
|
+
#
|
|
6
|
+
# 구 이름 `bootpay-backend-ruby` 로 require 하던 코드도 그대로 동작한다
|
|
7
|
+
# (lib/bootpay-backend-ruby.rb 가 이 파일과 같은 내용을 로드한다).
|
|
8
|
+
require_relative "bootpay/bootpay-rest-client"
|
|
9
|
+
require_relative "bootpay_storage/bootpay-storage-rest-client"
|
|
10
|
+
require_relative "bootpay_store/bootpay-store-rest-client"
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support/all'
|
|
4
|
+
require 'http'
|
|
5
|
+
require_relative 'response'
|
|
6
|
+
require_relative '../version'
|
|
7
|
+
require_relative 'concern'
|
|
8
|
+
|
|
9
|
+
module BootpayStorage
|
|
10
|
+
class RestClient
|
|
11
|
+
include Concern
|
|
12
|
+
|
|
13
|
+
API =
|
|
14
|
+
{
|
|
15
|
+
development: 'https://dev-s.bootapi.com/api/v1',
|
|
16
|
+
stage: 'https://stage-s.bootapi.com/api/v1',
|
|
17
|
+
production: 'https://s.bootapi.com/api/v1',
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
SDK_VERSION = '5.0.0'
|
|
21
|
+
|
|
22
|
+
def initialize(server_key:, private_key:, mode: 'production')
|
|
23
|
+
@server_key = server_key
|
|
24
|
+
@private_key = private_key
|
|
25
|
+
@mode = mode.presence || 'production'
|
|
26
|
+
@token = nil
|
|
27
|
+
@api_version = SDK_VERSION
|
|
28
|
+
raise ArgumentError, "개발환경 mode는 development, stage, production 중에서 선택이 가능합니다." if API[@mode.to_sym].blank?
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# API URL을 변경
|
|
32
|
+
# Comment by GOSOMI
|
|
33
|
+
# @date: 2023-05-26
|
|
34
|
+
def set_api_url(url)
|
|
35
|
+
API[@mode.to_sym] = url
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# API 버전을 설정한다
|
|
39
|
+
# Comment by Gosomi
|
|
40
|
+
# Date: 2022-07-29
|
|
41
|
+
def set_api_version(version)
|
|
42
|
+
raise ArgumentError, 'API Version은 4.0.0 이상만 설정이 가능합니다.' if version < '4.0.0'
|
|
43
|
+
@api_version = version
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module BootpayStorage::Concern::Csv
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
included do
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# csv 파일 업로드 - 마이그레이션 할 때 사용
|
|
8
|
+
# Comment by ehowlsla
|
|
9
|
+
# Date: 2025-07-17
|
|
10
|
+
def csv_file_upload(files:)
|
|
11
|
+
csv_upload(
|
|
12
|
+
uri: 'csvs',
|
|
13
|
+
files: files
|
|
14
|
+
)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module BootpayStorage::Concern::Image
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
included do
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# REST API로 본인인증 요청하기
|
|
8
|
+
# Comment by Gosomi
|
|
9
|
+
# Date: 2022-11-02
|
|
10
|
+
def image_upload(images:)
|
|
11
|
+
upload(
|
|
12
|
+
uri: 'images',
|
|
13
|
+
images: images
|
|
14
|
+
)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# 업로드한 이미지를 URL 로 삭제한다.
|
|
18
|
+
# 업로드 응답이 URL 만 돌려주므로(내부 식별자 미노출) 삭제도 URL 을 키로 받는다.
|
|
19
|
+
# Comment by Claude (alfred)
|
|
20
|
+
# @date: 2026-07-28
|
|
21
|
+
def image_destroy(url:)
|
|
22
|
+
request(
|
|
23
|
+
method: :delete,
|
|
24
|
+
uri: 'images/by_url',
|
|
25
|
+
payload: { url: url }
|
|
26
|
+
)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
module BootpayStorage::Concern::Rest
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
included do
|
|
5
|
+
private
|
|
6
|
+
|
|
7
|
+
# HTTP Request 기본 Method
|
|
8
|
+
# Comment by Gosomi
|
|
9
|
+
# Date: 2021-05-21
|
|
10
|
+
def request(method: :post, uri:, payload: {}, headers: {}, params: nil)
|
|
11
|
+
response = HTTP.headers(
|
|
12
|
+
{
|
|
13
|
+
Authorization: "Bearer #{@token}",
|
|
14
|
+
content_type: 'application/json',
|
|
15
|
+
accept: 'application/json',
|
|
16
|
+
bootpay_api_version: @api_version,
|
|
17
|
+
bootpay_sdk_version: Bootpay::V2_VERSION,
|
|
18
|
+
bootpay_sdk_type: '300'
|
|
19
|
+
}.merge!(headers).compact
|
|
20
|
+
).send(
|
|
21
|
+
method.to_sym,
|
|
22
|
+
[BootpayStorage::RestClient::API[@mode.to_sym], uri].join('/'),
|
|
23
|
+
json: payload,
|
|
24
|
+
params: params
|
|
25
|
+
)
|
|
26
|
+
BootpayStorage::Response.new(
|
|
27
|
+
response.status.to_i == 200,
|
|
28
|
+
JSON.parse(response.body.to_s, symbolize_names: true)
|
|
29
|
+
)
|
|
30
|
+
rescue Exception => e
|
|
31
|
+
BootpayStorage::Response.new(
|
|
32
|
+
false,
|
|
33
|
+
message: "부트페이 API 서버와의 통신이 실패하였습니다. 오류 메세지: #{e.message}",
|
|
34
|
+
backtrace: e.backtrace.join("\n")
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Multipart 파일 전송 Method
|
|
39
|
+
# Comment by Gosomi
|
|
40
|
+
# Date: 2025-03-25
|
|
41
|
+
def upload(uri:, images:, headers: {}, params: nil)
|
|
42
|
+
# 이미지 데이터를 배열로 받음
|
|
43
|
+
files = images.each_with_index.map do |data, index|
|
|
44
|
+
filename = "image_#{Time.now.to_i}_#{index}.jpg"
|
|
45
|
+
HTTP::FormData::File.new(data, filename: filename)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# HTTP 요청
|
|
49
|
+
response = HTTP.headers(
|
|
50
|
+
{
|
|
51
|
+
Authorization: "Bearer #{@token}",
|
|
52
|
+
accept: 'application/json',
|
|
53
|
+
bootpay_api_version: @api_version,
|
|
54
|
+
bootpay_sdk_version: Bootpay::V2_VERSION,
|
|
55
|
+
bootpay_sdk_type: '300'
|
|
56
|
+
}.merge!(headers).compact
|
|
57
|
+
).post(
|
|
58
|
+
[BootpayStorage::RestClient::API[@mode.to_sym], uri].join('/'),
|
|
59
|
+
form: { images: files },
|
|
60
|
+
params: params
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
# JSON 파싱 시도
|
|
64
|
+
parsed_response = begin
|
|
65
|
+
JSON.parse(response.body.to_s, symbolize_names: true)
|
|
66
|
+
rescue JSON::ParserError => e
|
|
67
|
+
{ error: "응답 파싱 실패: #{e.message}", body: response.body.to_s }
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# 응답 처리
|
|
71
|
+
BootpayStorage::Response.new(
|
|
72
|
+
response.status.to_i == 200,
|
|
73
|
+
parsed_response
|
|
74
|
+
)
|
|
75
|
+
rescue Exception => e
|
|
76
|
+
BootpayStorage::Response.new(
|
|
77
|
+
false,
|
|
78
|
+
message: "파일 업로드 실패: #{e.message}",
|
|
79
|
+
backtrace: e.backtrace.join("\n")
|
|
80
|
+
)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# csv Multipart 파일 전송 Method
|
|
84
|
+
# Comment by ehowlsla
|
|
85
|
+
# Date: 2025-07-17
|
|
86
|
+
def csv_upload(uri:, files:, headers: {}, params: nil)
|
|
87
|
+
# 이미지 데이터를 배열로 받음
|
|
88
|
+
files = files.each_with_index.map do |data, index|
|
|
89
|
+
filename = "csv_#{Time.now.to_i}_#{index}.csv"
|
|
90
|
+
HTTP::FormData::File.new(data, filename: filename)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# HTTP 요청
|
|
94
|
+
response = HTTP.headers(
|
|
95
|
+
{
|
|
96
|
+
Authorization: "Bearer #{@token}",
|
|
97
|
+
accept: 'application/json',
|
|
98
|
+
bootpay_api_version: @api_version,
|
|
99
|
+
bootpay_sdk_version: Bootpay::V2_VERSION,
|
|
100
|
+
bootpay_sdk_type: '300'
|
|
101
|
+
}.merge!(headers).compact
|
|
102
|
+
).post(
|
|
103
|
+
[BootpayStorage::RestClient::API[@mode.to_sym], uri].join('/'),
|
|
104
|
+
form: { images: files },
|
|
105
|
+
params: params
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
# JSON 파싱 시도
|
|
109
|
+
parsed_response = begin
|
|
110
|
+
JSON.parse(response.body.to_s, symbolize_names: true)
|
|
111
|
+
rescue JSON::ParserError => e
|
|
112
|
+
{ error: "응답 파싱 실패: #{e.message}", body: response.body.to_s }
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# 응답 처리
|
|
116
|
+
BootpayStorage::Response.new(
|
|
117
|
+
response.status.to_i == 200,
|
|
118
|
+
parsed_response
|
|
119
|
+
)
|
|
120
|
+
rescue Exception => e
|
|
121
|
+
BootpayStorage::Response.new(
|
|
122
|
+
false,
|
|
123
|
+
message: "파일 업로드 실패: #{e.message}",
|
|
124
|
+
backtrace: e.backtrace.join("\n")
|
|
125
|
+
)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
# def upload(uri:, image_data:, image_name:, headers: {}, params: nil)
|
|
130
|
+
#
|
|
131
|
+
# # puts [BootpayStorage::RestClient::API[@mode.to_sym], uri].join('/')
|
|
132
|
+
#
|
|
133
|
+
# # 파일 객체 생성
|
|
134
|
+
# file = HTTP::FormData::File.new(image_data, filename: image_name)
|
|
135
|
+
#
|
|
136
|
+
# # HTTP 요청
|
|
137
|
+
# response = HTTP.headers(
|
|
138
|
+
# {
|
|
139
|
+
# Authorization: "Bearer #{@token}",
|
|
140
|
+
# accept: 'application/json',
|
|
141
|
+
# bootpay_api_version: @api_version,
|
|
142
|
+
# bootpay_sdk_version: Bootpay::V2_VERSION,
|
|
143
|
+
# bootpay_sdk_type: '300'
|
|
144
|
+
# }.merge!(headers).compact
|
|
145
|
+
# ).post(
|
|
146
|
+
# [BootpayStorage::RestClient::API[@mode.to_sym], uri].join('/'),
|
|
147
|
+
# form: { images: [file] },
|
|
148
|
+
# params: params
|
|
149
|
+
# )
|
|
150
|
+
#
|
|
151
|
+
# # 응답 상태와 바디 출력
|
|
152
|
+
# puts "Response Status: #{response.status}"
|
|
153
|
+
# puts "Response Body: #{response.body.to_s}"
|
|
154
|
+
#
|
|
155
|
+
# # JSON 파싱 시도
|
|
156
|
+
# parsed_response = begin
|
|
157
|
+
# JSON.parse(response.body.to_s, symbolize_names: true)
|
|
158
|
+
# rescue JSON::ParserError => e
|
|
159
|
+
# { error: "응답 파싱 실패: #{e.message}", body: response.body.to_s }
|
|
160
|
+
# end
|
|
161
|
+
#
|
|
162
|
+
# # 응답 처리
|
|
163
|
+
# BootpayStorage::Response.new(
|
|
164
|
+
# response.status.to_i == 200,
|
|
165
|
+
# parsed_response
|
|
166
|
+
# )
|
|
167
|
+
# rescue Exception => e
|
|
168
|
+
# BootpayStorage::Response.new(
|
|
169
|
+
# false,
|
|
170
|
+
# message: "파일 업로드 실패: #{e.message}",
|
|
171
|
+
# backtrace: e.backtrace.join("\n")
|
|
172
|
+
# )
|
|
173
|
+
# end
|
|
174
|
+
|
|
175
|
+
end
|
|
176
|
+
end
|