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.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +9 -2
  3. data/.rspec +2 -0
  4. data/CHANGELOG.md +64 -14
  5. data/CODE_OF_CONDUCT.md +1 -1
  6. data/Gemfile +2 -4
  7. data/LICENSE.txt +1 -1
  8. data/README.md +309 -171
  9. data/Rakefile +3 -3
  10. data/bin/console +1 -1
  11. data/bootpay.gemspec +27 -24
  12. data/lib/bootpay/bootpay-rest-client.rb +51 -0
  13. data/lib/bootpay/concern/authenticate.rb +69 -0
  14. data/lib/bootpay/concern/cash_receipt.rb +83 -0
  15. data/lib/bootpay/concern/easy.rb +18 -0
  16. data/lib/bootpay/concern/escrow.rb +25 -0
  17. data/lib/bootpay/concern/payment.rb +126 -0
  18. data/lib/bootpay/concern/reseller.rb +97 -0
  19. data/lib/bootpay/concern/rest.rb +56 -0
  20. data/lib/bootpay/concern/sdk.rb +52 -0
  21. data/lib/bootpay/concern/seller.rb +15 -0
  22. data/lib/bootpay/concern/service.rb +15 -0
  23. data/lib/bootpay/concern/subscription.rb +211 -0
  24. data/lib/bootpay/concern/token.rb +33 -0
  25. data/lib/bootpay/concern/user_token.rb +23 -0
  26. data/lib/bootpay/concern/wallet.rb +20 -0
  27. data/lib/bootpay/concern/webhook.rb +18 -0
  28. data/lib/bootpay/concern.rb +35 -0
  29. data/lib/bootpay-backend-ruby.rb +6 -0
  30. data/lib/bootpay.rb +9 -49
  31. data/lib/bootpay_storage/bootpay-storage-rest-client.rb +46 -0
  32. data/lib/bootpay_storage/concern/csv.rb +18 -0
  33. data/lib/bootpay_storage/concern/image.rb +30 -0
  34. data/lib/bootpay_storage/concern/rest.rb +176 -0
  35. data/lib/bootpay_storage/concern/token.rb +9 -0
  36. data/lib/bootpay_storage/concern.rb +12 -0
  37. data/lib/bootpay_storage/response.rb +14 -0
  38. data/lib/bootpay_store/bootpay-store-rest-client.rb +47 -0
  39. data/lib/bootpay_store/concern/alimtalk_message.rb +67 -0
  40. data/lib/bootpay_store/concern/alimtalk_official.rb +63 -0
  41. data/lib/bootpay_store/concern/alimtalk_optout.rb +72 -0
  42. data/lib/bootpay_store/concern/alimtalk_send.rb +83 -0
  43. data/lib/bootpay_store/concern/alimtalk_sender.rb +105 -0
  44. data/lib/bootpay_store/concern/alimtalk_template.rb +215 -0
  45. data/lib/bootpay_store/concern/alimtalk_webhook.rb +84 -0
  46. data/lib/bootpay_store/concern/invoice.rb +102 -0
  47. data/lib/bootpay_store/concern/mall_setting.rb +385 -0
  48. data/lib/bootpay_store/concern/order.rb +74 -0
  49. data/lib/bootpay_store/concern/order_subscription.rb +391 -0
  50. data/lib/bootpay_store/concern/payment.rb +119 -0
  51. data/lib/bootpay_store/concern/product.rb +175 -0
  52. data/lib/bootpay_store/concern/rest.rb +128 -0
  53. data/lib/bootpay_store/concern/store.rb +31 -0
  54. data/lib/bootpay_store/concern/supervisor.rb +211 -0
  55. data/lib/bootpay_store/concern/token.rb +24 -0
  56. data/lib/bootpay_store/concern/user.rb +325 -0
  57. data/lib/bootpay_store/concern/user_group.rb +221 -0
  58. data/lib/bootpay_store/concern/webhook.rb +17 -0
  59. data/lib/bootpay_store/concern.rb +45 -0
  60. data/lib/bootpay_store/response.rb +14 -0
  61. data/lib/version.rb +9 -0
  62. metadata +81 -31
  63. data/.DS_Store +0 -0
  64. data/lib/.DS_Store +0 -0
  65. data/lib/bootpay/.DS_Store +0 -0
  66. data/lib/bootpay/billing.rb +0 -133
  67. data/lib/bootpay/cancel.rb +0 -29
  68. data/lib/bootpay/easy.rb +0 -25
  69. data/lib/bootpay/escrow.rb +0 -24
  70. data/lib/bootpay/link.rb +0 -60
  71. data/lib/bootpay/naverpay.rb +0 -17
  72. data/lib/bootpay/payment_resource.rb +0 -31
  73. data/lib/bootpay/reseller.rb +0 -12
  74. data/lib/bootpay/rest.rb +0 -38
  75. data/lib/bootpay/submit.rb +0 -20
  76. data/lib/bootpay/token.rb +0 -20
  77. data/lib/bootpay/verification.rb +0 -55
  78. data/lib/bootpay/version.rb +0 -25
  79. /data/lib/{response.rb → bootpay/response.rb} +0 -0
@@ -0,0 +1,325 @@
1
+ module BootpayStore::Concern::User
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ # 회원 로그인 (V1 API)
6
+ # Comment by Codex
7
+ # @date: 2026-02-23
8
+ # @date: 26-08-14 uri 'user/login' → 'users/login' 로 정정.
9
+ # v1 에는 단수 user/* 라우트가 없다(bin/rails routes 전수 확인). 로그인은 POST /v1/users/login (v1/users/login#create).
10
+ # ⚠️ POST /v1/users/session 은 resource :session 이 만들어낸 라우트일 뿐 sessions_controller 에 create 액션이 없다.
11
+ # 라우트 존재만 보고 그리로 보내면 안 된다 — show(GET)/destroy(DELETE) 만 정의돼 있다.
12
+ # ⚠️ 서버(LoginService)는 login_id·password 만 읽는다. corporate_type 은 전달돼도 무시된다.
13
+ # /mall/user/login 은 스토어프론트 스코프라 서버사이드 SDK(base=/v1)와 무관하다.
14
+ def user_login(login_id:, password:, corporate_type: 0, idempotency_key: nil)
15
+ request(
16
+ uri: 'users/login',
17
+ method: :post,
18
+ headers: {
19
+ 'Idempotency-Key' => idempotency_key.presence || SecureRandom.uuid
20
+ },
21
+ payload: {
22
+ login_id: login_id,
23
+ password: password,
24
+ corporate_type: corporate_type
25
+ }.compact
26
+ )
27
+ end
28
+
29
+ # 회원 세션 조회 (V1 Mall API)
30
+ # Comment by Codex
31
+ # @date: 2026-02-23
32
+ # @date: 26-08-14 uri 'user/session' → 'users/session' 로 정정 (GET /v1/users/session).
33
+ def user_session(user_jwt: nil, idempotency_key: nil)
34
+ request(
35
+ uri: 'users/session',
36
+ method: :get,
37
+ headers: {
38
+ 'Idempotency-Key' => idempotency_key.presence || SecureRandom.uuid,
39
+ 'Bootpay-User-JWT' => user_jwt
40
+ }.compact
41
+ )
42
+ end
43
+
44
+ # 회원 로그아웃 (V1 Mall API)
45
+ # Comment by Codex
46
+ # @date: 2026-02-23
47
+ # @date: 26-08-14 uri 'user/session' → 'users/session' 로 정정 (DELETE /v1/users/session).
48
+ def user_logout(user_jwt:, idempotency_key: nil)
49
+ request(
50
+ uri: 'users/session',
51
+ method: :delete,
52
+ headers: {
53
+ 'Idempotency-Key' => idempotency_key.presence || SecureRandom.uuid,
54
+ 'Bootpay-User-JWT' => user_jwt
55
+ }
56
+ )
57
+ end
58
+
59
+ # 회원가입 (V1 API) — 일반 회원가입용
60
+ # Comment by Codex
61
+ # @date: 2026-02-23
62
+ # @date: 26-08-14 uri 'user/join' → 'users/join' 로 정정 (POST /v1/users/join).
63
+ # ⚠️ external_user_sign_in 과 같은 엔드포인트를 부른다. 중복이 아니라 용도가 다르다 —
64
+ # 이쪽은 password/corporate_type/group 을 쓰는 일반 회원가입, 저쪽은 uid/login_email/login_pw 를 쓰는 외부 uid 연동 가입이다.
65
+ # 서버가 파라미터 조합으로 분기하므로 둘 다 유지한다(26-08-14 사용자 결정). 매뉴얼 customer/register.md 는 external_user_sign_in 에 대응.
66
+ def user_join(login_id:, password:, name:, email: nil, phone: nil, nickname: nil, gender: nil, birth: nil, corporate_type: 0,
67
+ group: nil, idempotency_key: nil)
68
+ request(
69
+ uri: 'users/join',
70
+ method: :post,
71
+ headers: {
72
+ 'Idempotency-Key' => idempotency_key.presence || SecureRandom.uuid
73
+ },
74
+ payload: {
75
+ login_id: login_id,
76
+ password: password,
77
+ name: name,
78
+ email: email,
79
+ phone: phone,
80
+ nickname: nickname,
81
+ gender: gender,
82
+ birth: birth,
83
+ corporate_type: corporate_type,
84
+ group: group
85
+ }.compact
86
+ )
87
+ end
88
+
89
+ # 회원가입 중복 확인 (V1 API) — key 를 인자로 받는 일반형
90
+ # type: email-exist, id-exist, phone-exist, uid-exist, group-business-number-exist
91
+ # Comment by Codex
92
+ # @date: 2026-02-23
93
+ # @date: 26-08-14 uri 'user/join/#{type}' → 'users/join/#{type}' 로 정정 (GET /v1/users/join/:id).
94
+ # ⚠️ email_exist·id_exist·phone_exist·uid_exist·group_business_number_exist 전용형 5종과 기능이 겹치지만 둘 다 유지한다(26-08-14 사용자 결정).
95
+ # 일반형은 서버에 새 key 가 생겨도 SDK 수정 없이 쓸 수 있고, 매뉴얼 customer/check-exist.md 가 key/value 형태를 안내하므로 이쪽에 대응한다.
96
+ def user_join_check(type:, pk:, idempotency_key: nil)
97
+ request(
98
+ uri: "users/join/#{type}",
99
+ method: :get,
100
+ headers: {
101
+ 'Idempotency-Key' => idempotency_key.presence || SecureRandom.uuid
102
+ },
103
+ params: {
104
+ pk: pk
105
+ }
106
+ )
107
+ end
108
+
109
+ # UserId로 로그인을 시도한다
110
+ # Comment by GOSOMI
111
+ # @date: 2025-04-25
112
+ def login_by_user_id(user_id:, membership_type: 'member', corporate_type: 'individual', idempotency_key: nil)
113
+ request(
114
+ uri: "users/login/token",
115
+ headers: {
116
+ 'Idempotency-Key' => idempotency_key.presence || SecureRandom.uuid,
117
+ 'Bootpay-Role' => 'user'
118
+ },
119
+ payload:
120
+ {
121
+ user_id: user_id,
122
+ membership_type: membership_type,
123
+ corporate_type: corporate_type
124
+ }
125
+ )
126
+ end
127
+
128
+ # 회원 목록 정보를 가져온다
129
+ # Comment by GOSOMI
130
+ # @date: 2025-06-16
131
+ # @date: 26-08-26 회원등급 필터 키 정정. 서버(v1/users_controller#index)가 읽는 이름은
132
+ # membership_type 인데 SDK 는 member_type 을 보내고 있어 등급 필터가 조용히 무시됐다
133
+ # (에러 없이 전체 목록이 돌아온다). 기존 호출 호환을 위해 member_type 인자는 남기고 별칭으로 매핑한다.
134
+ def users(membership_type: nil, member_type: nil, keyword: nil, page: 1, limit: 20, idempotency_key: nil)
135
+ request(
136
+ uri: 'users',
137
+ method: :get,
138
+ headers: {
139
+ 'Idempotency-Key' => idempotency_key.presence || SecureRandom.uuid,
140
+ 'Bootpay-Role' => 'user'
141
+ },
142
+ params:
143
+ {
144
+ membership_type: membership_type.presence || member_type,
145
+ keyword: keyword,
146
+ page: page,
147
+ limit: limit
148
+ }.compact
149
+ )
150
+ end
151
+
152
+ # 회원정보를 조회한다
153
+ # Comment by GOSOMI
154
+ # @date: 2025-06-16
155
+ def lookup_user(user_id:, idempotency_key: nil)
156
+ request(
157
+ uri: "users/#{user_id}",
158
+ method: :get,
159
+ headers: {
160
+ 'Idempotency-Key' => idempotency_key.presence || SecureRandom.uuid,
161
+ }
162
+ )
163
+ end
164
+
165
+ # 회원가입
166
+ # Comment by GOSOMI
167
+ # @date: 2025-06-16
168
+ def external_user_sign_in(idempotency_key: nil, uid:, user_group_id: nil, is_group_admin: false,
169
+ name:, phone:, email:, tel: nil, nickname: nil, comment: nil,
170
+ gender: nil, birth: nil, individual_extension: nil, login_id:, login_email:,
171
+ login_pw: nil, join_at: nil)
172
+ request(
173
+ uri: 'users/join',
174
+ method: :post,
175
+ headers: {
176
+ 'Idempotency-Key' => idempotency_key.presence || SecureRandom.uuid,
177
+ 'Bootpay-Role' => 'user'
178
+ },
179
+ payload:
180
+ {
181
+ uid: uid,
182
+ user_group_id: user_group_id,
183
+ is_group_admin: is_group_admin,
184
+ name: name,
185
+ phone: phone,
186
+ email: email,
187
+ tel: tel,
188
+ nickname: nickname,
189
+ comment: comment,
190
+ gender: gender,
191
+ birth: birth,
192
+ individual_extension: individual_extension,
193
+ login_id: login_id,
194
+ login_email: login_email,
195
+ login_pw: login_pw,
196
+ join_at: join_at
197
+ }.compact
198
+ )
199
+ end
200
+
201
+ # 회원 탈퇴
202
+ # Comment by GOSOMI
203
+ # @date: 2025-06-16
204
+ def withdraw(user_id:, idempotency_key: nil)
205
+ request(
206
+ uri: "users/#{user_id}",
207
+ method: :delete,
208
+ headers: {
209
+ 'Idempotency-Key' => idempotency_key.presence || SecureRandom.uuid,
210
+ 'Bootpay-Role' => 'user'
211
+ }
212
+ )
213
+ end
214
+
215
+ # 이메일 중복검사
216
+ # Comment by GOSOMI
217
+ # @date: 2025-06-18
218
+ def email_exist(email:, idempotency_key: nil)
219
+ request(
220
+ uri: 'users/join/email-exist',
221
+ method: :get,
222
+ headers: {
223
+ 'Idempotency-Key' => idempotency_key.presence || SecureRandom.uuid,
224
+ 'Bootpay-Role' => 'user'
225
+ },
226
+ params: { pk: email }
227
+ )
228
+ end
229
+
230
+ # ID 중복검사
231
+ # Comment by GOSOMI
232
+ # @date: 2025-06-18
233
+ def id_exist(id:, idempotency_key: nil)
234
+ request(
235
+ uri: 'users/join/id-exist',
236
+ method: :get,
237
+ headers: {
238
+ 'Idempotency-Key' => idempotency_key.presence || SecureRandom.uuid,
239
+ 'Bootpay-Role' => 'user'
240
+ },
241
+ params: { pk: id }
242
+ )
243
+ end
244
+
245
+ # 전화번호 중복검사
246
+ # Comment by GOSOMI
247
+ # @date: 2025-06-18
248
+ def phone_exist(phone:, idempotency_key: nil)
249
+ request(
250
+ uri: 'users/join/phone-exist',
251
+ method: :get,
252
+ headers: {
253
+ 'Idempotency-Key' => idempotency_key.presence || SecureRandom.uuid,
254
+ 'Bootpay-Role' => 'user'
255
+ },
256
+ params: { pk: phone }
257
+ )
258
+ end
259
+
260
+ # 그룹 사업자 번호 중복검사
261
+ # Comment by GOSOMI
262
+ # @date: 2025-06-18
263
+ def group_business_number_exist(business_number:, idempotency: nil)
264
+ request(
265
+ uri: 'users/join/group-business-number-exist',
266
+ method: :get,
267
+ headers: {
268
+ 'Idempotency-Key' => idempotency.presence || SecureRandom.uuid,
269
+ 'Bootpay-Role' => 'user'
270
+ },
271
+ params: { pk: business_number }
272
+ )
273
+ end
274
+
275
+ # 외부 uid(ex_uid) 중복검사 (GET /v1/users/join/uid-exist)
276
+ # @comment_by Claude (alfred)
277
+ # @date: 26-08-14
278
+ # email/id/phone/group-business-number 전용형과 같은 패턴. 이걸로 *_exist 계열이 5종 완성된다.
279
+ def uid_exist(uid:, idempotency_key: nil)
280
+ request(
281
+ uri: 'users/join/uid-exist',
282
+ method: :get,
283
+ headers: {
284
+ 'Idempotency-Key' => idempotency_key.presence || SecureRandom.uuid,
285
+ 'Bootpay-Role' => 'user'
286
+ },
287
+ params: { pk: uid }
288
+ )
289
+ end
290
+
291
+ # 회원 정보를 수정한다 (PUT /v1/users/:id)
292
+ # @comment_by Claude (alfred)
293
+ # @date: 26-08-14
294
+ # 컨트롤러 build_user_params 기준. 사업자 정보는 group: { company_name:, business_number:, registration_number: } 로 중첩 전달.
295
+ # 바뀐 값만 보내면 된다.
296
+ def user_update(user_id:, login_id: nil, login_pw: nil, name: nil, phone: nil, email: nil,
297
+ tel: nil, nickname: nil, bank_username: nil, bank_account: nil, bank_code: nil,
298
+ comment: nil, gender: nil, birth: nil, group: nil, idempotency_key: nil, **attrs)
299
+ request(
300
+ uri: "users/#{user_id}",
301
+ method: :put,
302
+ headers: {
303
+ 'Idempotency-Key' => idempotency_key.presence || SecureRandom.uuid,
304
+ 'Bootpay-Role' => 'user'
305
+ },
306
+ payload: {
307
+ login_id: login_id,
308
+ login_pw: login_pw,
309
+ name: name,
310
+ phone: phone,
311
+ email: email,
312
+ tel: tel,
313
+ nickname: nickname,
314
+ bank_username: bank_username,
315
+ bank_account: bank_account,
316
+ bank_code: bank_code,
317
+ comment: comment,
318
+ gender: gender,
319
+ birth: birth,
320
+ group: group
321
+ }.merge(attrs).compact
322
+ )
323
+ end
324
+ end
325
+ end
@@ -0,0 +1,221 @@
1
+ module BootpayStore::Concern::UserGroup
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ # 등록된 User Group 정보를 가져온다
6
+ # Comment by GOSOMI
7
+ # @date: 2025-06-18
8
+ def user_groups(keyword: nil, page: 1, limit: 20, corporate_type: 2, idempotency_key: nil)
9
+ request(
10
+ uri: 'user-groups',
11
+ method: :get,
12
+ headers: {
13
+ 'Idempotency-Key' => idempotency_key.presence || SecureRandom.uuid,
14
+ 'Bootpay-Role' => 'user'
15
+ },
16
+ params:
17
+ {
18
+ keyword: keyword,
19
+ page: page,
20
+ limit: limit,
21
+ corporate_type: corporate_type
22
+ }.compact
23
+ )
24
+ end
25
+
26
+ # user group 정보를 가져온다
27
+ # Comment by GOSOMI
28
+ # @date: 2025-06-18
29
+ def lookup_user_group(user_group_id:, idempotency_key: nil)
30
+ request(
31
+ uri: "user-groups/#{user_group_id}",
32
+ method: :get,
33
+ headers: {
34
+ 'Idempotency-Key' => idempotency_key.presence || SecureRandom.uuid,
35
+ 'Bootpay-Role' => 'user'
36
+ }
37
+ )
38
+ end
39
+
40
+ # 새로운 User Group을 생성한다
41
+ # Comment by GOSOMI
42
+ # @date: 2025-06-18
43
+ def create_user_group(uid: nil, phone: nil, email: nil, address: nil, address_detail: nil, zipcode: nil,
44
+ corporate_type: nil, bank: nil, bank_code: nil, company_name: nil, business_number: nil,
45
+ registration_number: nil, business_type: nil, business_category: nil, ceo_name: nil, auth_company: nil,
46
+ manager_name: nil, manager_phone: nil, manager_email: nil, pccc: nil, use_subscription_aggregate_transaction: nil,
47
+ subscription_month_day: nil, subscription_week_day: nil, purchase_limit: nil, subscribed_limit: nil,
48
+ limit_message: nil, idempotency_key: nil)
49
+ request(
50
+ uri: 'user-groups',
51
+ method: :post,
52
+ headers: {
53
+ 'Idempotency-Key' => idempotency_key.presence || SecureRandom.uuid,
54
+ 'Bootpay-Role' => 'user'
55
+ },
56
+ payload:
57
+ {
58
+ uid: uid,
59
+ phone: phone,
60
+ email: email,
61
+ address: address,
62
+ address_detail: address_detail,
63
+ corporate_type: corporate_type,
64
+ bank: bank,
65
+ bank_code: bank_code,
66
+ zipcode: zipcode,
67
+ company_name: company_name,
68
+ business_number: business_number,
69
+ registration_number: registration_number,
70
+ business_type: business_type,
71
+ business_category: business_category,
72
+ ceo_name: ceo_name,
73
+ auth_company: auth_company,
74
+ manager_name: manager_name,
75
+ manager_phone: manager_phone,
76
+ manager_email: manager_email,
77
+ pccc: pccc,
78
+ use_subscription_aggregate_transaction: use_subscription_aggregate_transaction,
79
+ subscription_month_day: subscription_month_day,
80
+ subscription_week_day: subscription_week_day,
81
+ purchase_limit: purchase_limit,
82
+ subscribed_limit: subscribed_limit,
83
+ limit_message: limit_message
84
+ }.compact
85
+ )
86
+ end
87
+
88
+ # UserGroup 정보를 갱신한다
89
+ # Comment by GOSOMI
90
+ # @date: 2025-06-18
91
+ def update_user_group(user_group_id:, phone: nil, email: nil, address: nil, address_detail: nil, zipcode: nil,
92
+ corporate_type: nil, bank: nil, bank_code: nil, company_name: nil, business_number: nil,
93
+ registration_number: nil, business_type: nil, business_category: nil, ceo_name: nil, auth_company: nil,
94
+ manager_name: nil, manager_phone: nil, manager_email: nil, pccc: nil, use_subscription_aggregate_transaction: nil,
95
+ subscription_month_day: nil, subscription_week_day: nil, purchase_limit: nil, subscribed_limit: nil,
96
+ limit_message: nil, idempotency_key: nil)
97
+ request(
98
+ uri: "user-groups/#{user_group_id}",
99
+ method: :put,
100
+ headers: {
101
+ 'Idempotency-Key' => idempotency_key.presence || SecureRandom.uuid,
102
+ 'Bootpay-Role' => 'user'
103
+ },
104
+ payload:
105
+ {
106
+ phone: phone,
107
+ email: email,
108
+ address: address,
109
+ address_detail: address_detail,
110
+ corporate_type: corporate_type,
111
+ bank: bank,
112
+ bank_code: bank_code,
113
+ zipcode: zipcode,
114
+ company_name: company_name,
115
+ business_number: business_number,
116
+ registration_number: registration_number,
117
+ business_type: business_type,
118
+ business_category: business_category,
119
+ ceo_name: ceo_name,
120
+ auth_company: auth_company,
121
+ manager_name: manager_name,
122
+ manager_phone: manager_phone,
123
+ manager_email: manager_email,
124
+ pccc: pccc,
125
+ use_subscription_aggregate_transaction: use_subscription_aggregate_transaction,
126
+ subscription_month_day: subscription_month_day,
127
+ subscription_week_day: subscription_week_day,
128
+ purchase_limit: purchase_limit,
129
+ subscribed_limit: subscribed_limit,
130
+ limit_message: limit_message
131
+ }.compact
132
+ )
133
+ end
134
+
135
+ # UserGroup 정보를 삭제한다
136
+ # Comment by GOSOMI
137
+ # @date: 2025-06-19
138
+ def delete_user_group(user_group_id:, idempotency_key: nil)
139
+ request(
140
+ uri: "user-groups/#{user_group_id}",
141
+ method: :delete,
142
+ headers: {
143
+ 'Idempotency-Key' => idempotency_key.presence || SecureRandom.uuid,
144
+ 'Bootpay-Role' => 'user'
145
+ }
146
+ )
147
+ end
148
+
149
+ # 사용자 그룹에 사용자를 추가한다
150
+ def add_user_to_group(user_group_id:, user_id:, idempotency_key: nil)
151
+ request(
152
+ uri: "user-groups/#{user_group_id}/user",
153
+ method: :post,
154
+ headers: {
155
+ 'Idempotency-Key' => idempotency_key.presence || SecureRandom.uuid,
156
+ 'Bootpay-Role' => 'manager'
157
+ },
158
+ payload: { user_id: user_id }
159
+ )
160
+ end
161
+
162
+ # 사용자 그룹에서 사용자를 제거한다
163
+ def delete_user_from_group(user_group_id:, user_id:, idempotency_key: nil)
164
+ request(
165
+ uri: "user-groups/#{user_group_id}/user/#{user_id}",
166
+ method: :delete,
167
+ headers: {
168
+ 'Idempotency-Key' => idempotency_key.presence || SecureRandom.uuid,
169
+ 'Bootpay-Role' => 'manager'
170
+ }
171
+ )
172
+ end
173
+
174
+ # 그룹 구매한도를 설정한다 (PUT /v1/user-groups/:id/limit)
175
+ # @comment_by Claude (alfred)
176
+ # @date: 26-08-14
177
+ # ⚠️ update_user_group 으로는 한도가 절대 반영되지 않는다.
178
+ # user_groups_controller#update 가 use_limit/limit_message/limit_month_purchase/limit_week_purchase 를
179
+ # params.except! 로 명시적으로 제거하기 때문 — 한도는 이 전용 라우트로만 바뀐다.
180
+ # 서버 scope: manager:limit
181
+ def user_group_limit(user_group_id:, use_limit: nil, limit_month_purchase: nil,
182
+ limit_week_purchase: nil, limit_message: nil, idempotency_key: nil)
183
+ request(
184
+ uri: "user-groups/#{user_group_id}/limit",
185
+ method: :put,
186
+ headers: {
187
+ 'Idempotency-Key' => idempotency_key.presence || SecureRandom.uuid,
188
+ 'Bootpay-Role' => 'manager'
189
+ },
190
+ payload: {
191
+ use_limit: use_limit,
192
+ limit_month_purchase: limit_month_purchase,
193
+ limit_week_purchase: limit_week_purchase,
194
+ limit_message: limit_message
195
+ }.compact
196
+ )
197
+ end
198
+
199
+ # 그룹 구독 합산청구(정산주기) 설정을 변경한다 (PUT /v1/user-groups/:id/aggregate-transaction)
200
+ # @comment_by Claude (alfred)
201
+ # @date: 26-08-14
202
+ # update_user_group 에도 같은 이름의 인자가 있지만 서버는 이 전용 라우트에서만 처리한다.
203
+ def user_group_aggregate_transaction(user_group_id:, use_subscription_aggregate_transaction: nil,
204
+ subscription_month_day: nil, subscription_week_day: nil,
205
+ idempotency_key: nil)
206
+ request(
207
+ uri: "user-groups/#{user_group_id}/aggregate-transaction",
208
+ method: :put,
209
+ headers: {
210
+ 'Idempotency-Key' => idempotency_key.presence || SecureRandom.uuid,
211
+ 'Bootpay-Role' => 'manager'
212
+ },
213
+ payload: {
214
+ use_subscription_aggregate_transaction: use_subscription_aggregate_transaction,
215
+ subscription_month_day: subscription_month_day,
216
+ subscription_week_day: subscription_week_day
217
+ }.compact
218
+ )
219
+ end
220
+ end
221
+ end
@@ -0,0 +1,17 @@
1
+ module BootpayStore::Concern::Webhook
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ # 테스트 웹훅을 발송한다 (POST /v1/test-webhooks)
6
+ # @comment_by Claude (alfred)
7
+ # @date: 26-03-05
8
+ def send_test_webhook(header_content_type: nil)
9
+ request(
10
+ uri: 'webhook/test',
11
+ payload: {
12
+ header_content_type: header_content_type
13
+ }.compact
14
+ )
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,45 @@
1
+ module BootpayStore
2
+ module Concern
3
+ require_relative 'concern/alimtalk_message'
4
+ require_relative 'concern/alimtalk_official'
5
+ require_relative 'concern/alimtalk_optout'
6
+ require_relative 'concern/alimtalk_send'
7
+ require_relative 'concern/alimtalk_sender'
8
+ require_relative 'concern/alimtalk_template'
9
+ require_relative 'concern/alimtalk_webhook'
10
+ require_relative 'concern/invoice'
11
+ require_relative 'concern/mall_setting'
12
+ require_relative 'concern/order'
13
+ require_relative 'concern/order_subscription'
14
+ require_relative 'concern/payment'
15
+ require_relative 'concern/product'
16
+ require_relative 'concern/rest'
17
+ require_relative 'concern/supervisor'
18
+ require_relative 'concern/token'
19
+ require_relative 'concern/user'
20
+ require_relative 'concern/user_group'
21
+ require_relative 'concern/store'
22
+ require_relative 'concern/webhook'
23
+
24
+ include AlimtalkMessage
25
+ include AlimtalkOfficial
26
+ include AlimtalkOptout
27
+ include AlimtalkSend
28
+ include AlimtalkSender
29
+ include AlimtalkTemplate
30
+ include AlimtalkWebhook
31
+ include Invoice
32
+ include MallSetting
33
+ include Order
34
+ include OrderSubscription
35
+ include Payment
36
+ include Product
37
+ include Rest
38
+ include Supervisor
39
+ include Token
40
+ include User
41
+ include UserGroup
42
+ include Store
43
+ include Webhook
44
+ end
45
+ end
@@ -0,0 +1,14 @@
1
+ module BootpayStore
2
+ class Response
3
+ attr_reader :data
4
+
5
+ def initialize(success = true, data = {})
6
+ @success = success
7
+ @data = data
8
+ end
9
+
10
+ def success?
11
+ @success
12
+ end
13
+ end
14
+ end
data/lib/version.rb ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bootpay
4
+ VERSION = "3.0.0"
5
+
6
+ # 구 이름(`bootpay-backend-ruby`) 시절 gemspec·코드가 참조하던 상수.
7
+ # 값이 갈리지 않도록 VERSION 을 그대로 가리킨다.
8
+ V2_VERSION = VERSION
9
+ end