popbill 1.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 +7 -0
- data/lib/cashbill.rb +336 -0
- data/lib/closedown.rb +55 -0
- data/lib/fax.rb +110 -0
- data/lib/htCashbill.rb +123 -0
- data/lib/htTaxinvoice.rb +170 -0
- data/lib/message.rb +272 -0
- data/lib/popbill.rb +389 -0
- data/lib/statement.rb +444 -0
- data/lib/taxinvoice.rb +648 -0
- metadata +66 -0
data/lib/popbill.rb
ADDED
@@ -0,0 +1,389 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'net/http'
|
3
|
+
require 'uri'
|
4
|
+
require 'json'
|
5
|
+
require 'date'
|
6
|
+
require 'linkhub'
|
7
|
+
|
8
|
+
# Popbill API BaseService class
|
9
|
+
class BaseService
|
10
|
+
ServiceID_REAL = "POPBILL";
|
11
|
+
ServiceID_TEST = "POPBILL_TEST"
|
12
|
+
ServiceURL_REAL = "https://popbill.linkhub.co.kr"
|
13
|
+
ServiceURL_TEST = "https://popbill-test.linkhub.co.kr"
|
14
|
+
POPBILL_APIVersion = "1.0"
|
15
|
+
BOUNDARY = "==POPBILL_RUBY_SDK=="
|
16
|
+
|
17
|
+
attr_accessor :token_table, :scopes, :isTest, :linkhub
|
18
|
+
|
19
|
+
# Generate Linkhub Class Singleton Instance
|
20
|
+
class << self
|
21
|
+
def instance(linkID, secretKey)
|
22
|
+
@instance ||= new
|
23
|
+
@instance.token_table = {}
|
24
|
+
@instance.linkhub = Linkhub.instance(linkID, secretKey)
|
25
|
+
@instance.scopes = ["member"]
|
26
|
+
return @instance
|
27
|
+
end
|
28
|
+
private :new
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
# add Service Scope array
|
33
|
+
def addScope(scopeValue)
|
34
|
+
@scopes.push(scopeValue)
|
35
|
+
end
|
36
|
+
|
37
|
+
def setIsTest(testValue)
|
38
|
+
@isTest = testValue
|
39
|
+
end
|
40
|
+
|
41
|
+
def getServiceURL()
|
42
|
+
return @isTest ? BaseService::ServiceURL_TEST : BaseService::ServiceURL_REAL
|
43
|
+
end
|
44
|
+
|
45
|
+
def getServiceID()
|
46
|
+
return @isTest ? BaseService::ServiceID_TEST : BaseService::ServiceID_REAL
|
47
|
+
end
|
48
|
+
|
49
|
+
# Get Session Token by checking token-cached hash or token Request
|
50
|
+
def getSession_Token(corpNum)
|
51
|
+
targetToken = nil
|
52
|
+
refresh = false
|
53
|
+
|
54
|
+
# check already cached CorpNum's SessionToken
|
55
|
+
if @token_table.key?(corpNum.to_sym)
|
56
|
+
targetToken = @token_table[corpNum.to_sym]
|
57
|
+
end
|
58
|
+
|
59
|
+
if targetToken.nil?
|
60
|
+
refresh = true
|
61
|
+
else
|
62
|
+
# Token's expireTime must use parse() because time format is hh:mm:ss.SSSZ
|
63
|
+
expireTime = DateTime.parse(targetToken['expiration'])
|
64
|
+
serverUTCTime = DateTime.strptime(@linkhub.getTime())
|
65
|
+
refresh = expireTime < serverUTCTime
|
66
|
+
end
|
67
|
+
|
68
|
+
if refresh
|
69
|
+
begin
|
70
|
+
# getSessionToken from Linkhub
|
71
|
+
targetToken = @linkhub.getSessionToken(
|
72
|
+
@isTest ? ServiceID_TEST : ServiceID_REAL, corpNum, @scopes)
|
73
|
+
rescue LinkhubException => le
|
74
|
+
raise PopbillException.new(le.code, le.message)
|
75
|
+
end
|
76
|
+
# append token to cache hash
|
77
|
+
@token_table[corpNum.to_sym] = targetToken
|
78
|
+
end
|
79
|
+
|
80
|
+
targetToken['session_token']
|
81
|
+
end # end of getSession_Token
|
82
|
+
|
83
|
+
def gzip_parse (target)
|
84
|
+
sio = StringIO.new(target)
|
85
|
+
gz = Zlib::GzipReader.new(sio)
|
86
|
+
gz.read()
|
87
|
+
end
|
88
|
+
|
89
|
+
# Popbill API http Get Request Func
|
90
|
+
def httpget(url, corpNum, userID = '')
|
91
|
+
headers = {
|
92
|
+
"x-pb-version" => BaseService::POPBILL_APIVersion,
|
93
|
+
"Accept-Encoding" => "gzip,deflate",
|
94
|
+
}
|
95
|
+
|
96
|
+
if corpNum.to_s != ''
|
97
|
+
headers["Authorization"] = "Bearer " + getSession_Token(corpNum)
|
98
|
+
end
|
99
|
+
|
100
|
+
if userID.to_s != ''
|
101
|
+
headers["x-pb-userid"] = userID
|
102
|
+
end
|
103
|
+
|
104
|
+
uri = URI(getServiceURL() + url)
|
105
|
+
request = Net::HTTP.new(uri.host, 443)
|
106
|
+
request.use_ssl = true
|
107
|
+
|
108
|
+
Net::HTTP::Get.new(uri)
|
109
|
+
|
110
|
+
res = request.get(uri.request_uri, headers)
|
111
|
+
|
112
|
+
if res.code == "200"
|
113
|
+
if res.header['Content-Encoding'].eql?('gzip')
|
114
|
+
JSON.parse(gzip_parse(res.body))
|
115
|
+
else
|
116
|
+
JSON.parse(res.body)
|
117
|
+
end
|
118
|
+
else
|
119
|
+
raise PopbillException.new(JSON.parse(res.body)["code"],
|
120
|
+
JSON.parse(res.body)["message"])
|
121
|
+
end
|
122
|
+
end #end of httpget
|
123
|
+
|
124
|
+
# Request HTTP Post
|
125
|
+
def httppost(url, corpNum, postData, action = '', userID = '')
|
126
|
+
headers = {
|
127
|
+
"x-pb-version" => BaseService::POPBILL_APIVersion,
|
128
|
+
"Accept-Encoding" => "gzip,deflate",
|
129
|
+
"Content-Type" => "application/json; charset=utf8",
|
130
|
+
}
|
131
|
+
|
132
|
+
if corpNum.to_s != ''
|
133
|
+
headers["Authorization"] = "Bearer " + getSession_Token(corpNum)
|
134
|
+
end
|
135
|
+
|
136
|
+
if userID.to_s != ''
|
137
|
+
headers["x-pb-userid"] = userID
|
138
|
+
end
|
139
|
+
|
140
|
+
if action.to_s != ''
|
141
|
+
headers["X-HTTP-Method-Override"] = action
|
142
|
+
end
|
143
|
+
|
144
|
+
uri = URI(getServiceURL() + url )
|
145
|
+
|
146
|
+
https = Net::HTTP.new(uri.host, 443)
|
147
|
+
https.use_ssl = true
|
148
|
+
Net::HTTP::Post.new(uri)
|
149
|
+
|
150
|
+
res = https.post(uri.request_uri, postData, headers)
|
151
|
+
|
152
|
+
if res.code == "200"
|
153
|
+
if res.header['Content-Encoding'].eql?('gzip')
|
154
|
+
JSON.parse(gzip_parse(res.body))
|
155
|
+
else
|
156
|
+
JSON.parse(res.body)
|
157
|
+
end
|
158
|
+
else
|
159
|
+
raise PopbillException.new(JSON.parse(res.body)["code"],
|
160
|
+
JSON.parse(res.body)["message"])
|
161
|
+
end
|
162
|
+
end #end of httppost
|
163
|
+
|
164
|
+
|
165
|
+
# Request HTTP Post File
|
166
|
+
def httppostfile(url, corpNum, form, files, userID)
|
167
|
+
headers = {
|
168
|
+
"x-pb-version" => BaseService::POPBILL_APIVersion,
|
169
|
+
"Content-Type" => "multipart/form-data;boundary=" + BaseService::BOUNDARY,
|
170
|
+
"Accept-Encoding" => "gzip,deflate",
|
171
|
+
"Connection" => "Keep-Alive"
|
172
|
+
}
|
173
|
+
|
174
|
+
if corpNum.to_s != ''
|
175
|
+
headers["Authorization"] = "Bearer " + getSession_Token(corpNum)
|
176
|
+
end
|
177
|
+
|
178
|
+
if userID.to_s != ''
|
179
|
+
headers["x-pb-userid"] = userID
|
180
|
+
end
|
181
|
+
|
182
|
+
post_body = []
|
183
|
+
|
184
|
+
if form.to_s != ''
|
185
|
+
post_body << "--#{BaseService::BOUNDARY}\r\n"
|
186
|
+
post_body << "Content-Disposition: form-data; name=\"form\"\r\n"
|
187
|
+
post_body << "Content-Type: Application/json;\r\n\r\n"
|
188
|
+
post_body << form.to_json+"\r\n"
|
189
|
+
end
|
190
|
+
|
191
|
+
files.each do |filePath|
|
192
|
+
begin
|
193
|
+
fileName = File.basename(filePath)
|
194
|
+
post_body << "--#{BaseService::BOUNDARY}\r\n"
|
195
|
+
post_body << "Content-Disposition: form-data; name=\"file\"; filename=\"#{fileName}\"\r\n"
|
196
|
+
post_body << "Content-Type: Application/octet-stream\r\n\r\n"
|
197
|
+
post_body << File.read(filePath)
|
198
|
+
rescue
|
199
|
+
raise PopbillException.new(-99999999,"Failed to reading filedata from filepath")
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
post_body << "\r\n\r\n--#{BaseService::BOUNDARY}--\r\n"
|
204
|
+
# Add the file Data
|
205
|
+
|
206
|
+
uri = URI(getServiceURL() + url)
|
207
|
+
https = Net::HTTP.new(uri.host, 443)
|
208
|
+
https.use_ssl = true
|
209
|
+
Net::HTTP::Post.new(uri)
|
210
|
+
|
211
|
+
res = https.post(uri.request_uri, post_body.join.encode("UTF-8"), headers)
|
212
|
+
|
213
|
+
if res.code == "200"
|
214
|
+
if res.header['Content-Encoding'].eql?('gzip')
|
215
|
+
JSON.parse(gzip_parse(res.body))
|
216
|
+
else
|
217
|
+
JSON.parse(res.body)
|
218
|
+
end
|
219
|
+
else
|
220
|
+
raise PopbillException.new(JSON.parse(res.body)["code"],
|
221
|
+
JSON.parse(res.body)["message"])
|
222
|
+
end
|
223
|
+
|
224
|
+
end
|
225
|
+
|
226
|
+
def httppostfiles(url, corpNum, form, files, userID)
|
227
|
+
headers = {
|
228
|
+
"x-pb-version" => BaseService::POPBILL_APIVersion,
|
229
|
+
"Content-Type" => "multipart/form-data;boundary=" + BaseService::BOUNDARY,
|
230
|
+
"Accept-Encoding" => "gzip,deflate",
|
231
|
+
"Connection" => "Keep-Alive"
|
232
|
+
}
|
233
|
+
|
234
|
+
if corpNum.to_s != ''
|
235
|
+
headers["Authorization"] = "Bearer " + getSession_Token(corpNum)
|
236
|
+
end
|
237
|
+
|
238
|
+
if userID.to_s != ''
|
239
|
+
headers["x-pb-userid"] = userID
|
240
|
+
end
|
241
|
+
|
242
|
+
post_body = []
|
243
|
+
|
244
|
+
if form.to_s != ''
|
245
|
+
post_body << "--#{BaseService::BOUNDARY}\r\n"
|
246
|
+
post_body << "Content-Disposition: form-data; name=\"form\"\r\n"
|
247
|
+
post_body << "Content-Type: Application/json; charset=euc-kr\r\n\r\n"
|
248
|
+
post_body << form.to_json
|
249
|
+
end
|
250
|
+
|
251
|
+
files.each do |filePath|
|
252
|
+
begin
|
253
|
+
fileName = File.basename(filePath)
|
254
|
+
post_body << "--#{BaseService::BOUNDARY}\r\n"
|
255
|
+
post_body << "Content-Disposition: form-data; name=\"Filedata\"; filename=\"#{fileName}\"\r\n"
|
256
|
+
post_body << "Content-Type: Application/octet-stream\r\n\r\n"
|
257
|
+
post_body << File.read(filePath)
|
258
|
+
rescue
|
259
|
+
raise PopbillException.new(-99999999,"Failed to reading filedata from filepath")
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
post_body << "\r\n\r\n--#{BaseService::BOUNDARY}--\r\n"
|
264
|
+
# Add the file Data
|
265
|
+
|
266
|
+
uri = URI(getServiceURL() + url)
|
267
|
+
https = Net::HTTP.new(uri.host, 443)
|
268
|
+
https.use_ssl = true
|
269
|
+
Net::HTTP::Post.new(uri)
|
270
|
+
|
271
|
+
res = https.post(uri.request_uri, post_body.join.encode("UTF-8"), headers)
|
272
|
+
|
273
|
+
if res.code == "200"
|
274
|
+
if res.header['Content-Encoding'].eql?('gzip')
|
275
|
+
JSON.parse(gzip_parse(res.body))
|
276
|
+
else
|
277
|
+
JSON.parse(res.body)
|
278
|
+
end
|
279
|
+
else
|
280
|
+
raise PopbillException.new(JSON.parse(res.body)["code"],
|
281
|
+
JSON.parse(res.body)["message"])
|
282
|
+
end
|
283
|
+
|
284
|
+
end
|
285
|
+
|
286
|
+
# Get Popbill Member's Remain Point
|
287
|
+
def getBalance(corpNum)
|
288
|
+
if corpNum.length != 10
|
289
|
+
raise PopbillException.new('-99999999', '사업자등록번호가 올바르지 않습니다.')
|
290
|
+
end
|
291
|
+
|
292
|
+
begin
|
293
|
+
@linkhub.getBalance(getSession_Token(corpNum), getServiceID())
|
294
|
+
rescue LinkhubException => le
|
295
|
+
raise PopbillException.new(le.code, le.message)
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
# Get Linkhub Partner's Remain Point
|
300
|
+
def getPartnerBalance(corpNum)
|
301
|
+
if corpNum.length != 10
|
302
|
+
raise PopbillException.new('-99999999', '사업자등록번호가 올바르지 않습니다.')
|
303
|
+
end
|
304
|
+
|
305
|
+
begin
|
306
|
+
@linkhub.getPartnerBalance(getSession_Token(corpNum), getServiceID())
|
307
|
+
rescue LinkhubException => le
|
308
|
+
raise PopbillException.new(le.code, le.message)
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
# Join Popbill Member
|
313
|
+
def joinMember(joinInfo)
|
314
|
+
httppost("/Join", "", joinInfo.to_json, "", "")
|
315
|
+
end
|
316
|
+
|
317
|
+
# check Popbill Member ID
|
318
|
+
def checkID(idValue)
|
319
|
+
http_response = httpget("/IDCheck?ID="+idValue,"","")
|
320
|
+
end
|
321
|
+
|
322
|
+
# Get Pobill SSO URL
|
323
|
+
def getPopbillURL(corpNum, togo, userID = "")
|
324
|
+
if corpNum.length != 10
|
325
|
+
raise PopbillException.new('-99999999', '사업자등록번호가 올바르지 않습니다.')
|
326
|
+
end
|
327
|
+
|
328
|
+
response = httpget("/?TG="+togo, corpNum, userID)
|
329
|
+
response['url']
|
330
|
+
end
|
331
|
+
|
332
|
+
# Check is Partner's Popbill Member
|
333
|
+
def checkIsMember(corpNum, linkID)
|
334
|
+
if corpNum.length != 10
|
335
|
+
raise PopbillException.new('-99999999', '사업자등록번호가 올바르지 않습니다.')
|
336
|
+
end
|
337
|
+
http_response = httpget("/Join?CorpNum="+corpNum+"&LID="+linkID, "", "")
|
338
|
+
end
|
339
|
+
|
340
|
+
# Get list Corp Contact
|
341
|
+
def listContact(corpNum, userID = "")
|
342
|
+
if corpNum.length != 10
|
343
|
+
raise PopbillException.new('-99999999', '사업자등록번호가 올바르지 않습니다.')
|
344
|
+
end
|
345
|
+
httpget("/IDs", corpNum, userID)
|
346
|
+
end
|
347
|
+
|
348
|
+
# Update Contact Info
|
349
|
+
def updateContact(corpNum, contactInfo, userID = "")
|
350
|
+
if corpNum.length != 10
|
351
|
+
raise PopbillException.new('-99999999', '사업자등록번호가 올바르지 않습니다.')
|
352
|
+
end
|
353
|
+
|
354
|
+
httppost("/IDs", corpNum, contactInfo.to_json, "", userID)
|
355
|
+
end
|
356
|
+
|
357
|
+
# Regist Contact
|
358
|
+
def registContact(corpNum, contactInfo, userID = "")
|
359
|
+
if corpNum.length != 10
|
360
|
+
raise PopbillException.new('-99999999', '사업자등록번호가 올바르지 않습니다.')
|
361
|
+
end
|
362
|
+
httppost("/IDs/New", corpNum, contactInfo.to_json, "", userID)
|
363
|
+
end
|
364
|
+
|
365
|
+
# Get Corp Info
|
366
|
+
def getCorpInfo(corpNum, userID = "")
|
367
|
+
if corpNum.length != 10
|
368
|
+
raise PopbillException.new('-99999999', '사업자등록번호가 올바르지 않습니다.')
|
369
|
+
end
|
370
|
+
httpget("/CorpInfo", corpNum, userID)
|
371
|
+
end
|
372
|
+
|
373
|
+
# Update Corp Info
|
374
|
+
def updateCorpInfo(corpNum, corpInfo, userID = "")
|
375
|
+
if corpNum.length != 10
|
376
|
+
raise PopbillException.new('-99999999', '사업자등록번호가 올바르지 않습니다.')
|
377
|
+
end
|
378
|
+
httppost("/CorpInfo", corpNum, corpInfo.to_json, "", userID)
|
379
|
+
end
|
380
|
+
end # end of BaseService class
|
381
|
+
|
382
|
+
# Popbill API Exception Handler class
|
383
|
+
class PopbillException < StandardError
|
384
|
+
attr_reader :code, :message
|
385
|
+
def initialize(code, message)
|
386
|
+
@code = code
|
387
|
+
@message = message
|
388
|
+
end
|
389
|
+
end
|