Skip to content

Latest commit

ย 

History

87 Commits

Folders and files

NameName
Last commit message
Last commit date
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

CODEF API - Python

Python sample for CODEF API

Documentation

๋ณธ ์ƒ˜ํ”Œ์€ CODEF API์˜ ์—ฐ๋™์„ ์œ„ํ•œ ๊ณตํ†ต ์ฝ”๋“œ๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, ์ง€์›ํ•˜๋Š” ๋ชจ๋“  API์˜ ์—”๋“œํฌ์ธํŠธ(์€ํ–‰, ์นด๋“œ, ๋ณดํ—˜, ์ฆ๊ถŒ, ๊ณต๊ณต, ๊ธฐํƒ€)๋Š” https://developer.codef.io ๋ฅผ ํ†ตํ•ด ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

CODEF API Env

CODEF API๋Š” ์›ํ™œํ•œ ๊ฐœ๋ฐœ์„ ์œ„ํ•ด ์ƒŒ๋“œ๋ฐ•์Šค, ๊ฐœ๋ฐœ, ์šด์˜ ํ™˜๊ฒฝ์„ ๊ฐ๊ฐ ์ œ๊ณตํ•œ๋‹ค.

Getting Started

OAuth2.0

CODEF API๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” 'access_token' ๋ฐœํ–‰์ด ์„ ํ–‰๋˜์–ด์•ผ ํ•˜๋ฉฐ, ๊ฑฐ๋ž˜ ์‹œ Header ์— ํฌํ•จํ•˜์—ฌ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.
'access_token'์„ ๋ฐœ๊ธ‰ ๋ฐ›๊ธฐ ์œ„ํ•œ 'client_id' ๋ฐ 'client_secret'์€ https://codef.io/#/account/keys ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋ฐœ๊ธ‰๋ฐ›์€ access_token์€ ๋ชจ๋“  CODEF API ํ˜ธ์ถœ ์‹œ Headers ์— ์ถ”๊ฐ€๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ('Authorization': 'Bearer ' + access_token)

  • access_token์€ ์ผ์ฃผ์ผ๊ฐ„ ์œ ํšจํ•ฉ๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋‚˜ ๊ธ€๋กœ๋ฒŒ ๋ณ€์ˆ˜์— ์ €์žฅํ•˜์—ฌ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.
  • CODEF API๋ฅผ ํ˜ธ์ถœ ํ•  ๋•Œ๋งˆ๋‹ค access_token์„ ์š”์ฒญํ•˜๋Š” ๊ฒƒ์€ ํผํฌ๋จผ์Šค์— ๋ถ€์ •์ ์ž…๋‹ˆ๋‹ค.
  • ๊ถŒ์žฅํ•˜๋Š” ํ๋ฆ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. [1.ํ† ํฐ ๋ฐœ๊ธ‰ -> 2.ํ† ํฐ ์ €์žฅ -> 3.์ €์žฅ๋œ ํ† ํฐ์„ ์ด์šฉํ•˜์—ฌ API ํ˜ธ์ถœ -> 4.ํ† ํฐ์ด ์œ ํšจํ•˜์ง€ ์•Š์„๊ฒฝ์šฐ ํ† ํฐ ์žฌ๋ฐœ๊ธ‰ -> 5.API ์žฌ์‹œ๋„]
token_url = 'https://oauth.codef.io/oauth/token'
response_oauth = request_token(token_url, 'CODEF๋กœ๋ถ€ํ„ฐ ๋ฐœ๊ธ‰๋ฐ›์€ ํด๋ผ์ด์–ธํŠธ ์•„์ด๋””', 'CODEF๋กœ๋ถ€ํ„ฐ ๋ฐœ๊ธ‰๋ฐ›์€ ์‹œํฌ๋ฆฟ ํ‚ค')
if response_oauth.status_code == 200:
    dict = json.loads(response_oauth.text)
    # reissue_token
    token = dict['access_token']

    print('access_token = ' + token)
else:
    print('ํ† ํฐ๋ฐœ๊ธ‰ ์˜ค๋ฅ˜')
{
  "access_token" : "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzZXJ2aWNlX3R5cGUiOiIwIiwic2NvcGUiOlsicmVhZCJdLCJzZXJ2aWNlX25vIjoiMDAwMDAwMDQyMDAxIiwiZXhwIjoxNTYzOTQ4NDQ2LCJhdXRob3JpdGllcyI6WyJJTlNVUkFOQ0UiLCJQVUJMSUMiLCJCQU5LIiwiRVRDIiwiU1RPQ0siLCJDQVJEIl0sImp0aSI6Ijc4NDUyMjY4LWFkNDctNGVhNS04ZjljLTQ5ZWI5Yjk1YmQxZCIsImNsaWVudF9pZCI6ImNvZGVmX21hc3RlciJ9.ddZ38ARfTIa4_E8by6gITeIadhQKeDDG4YoGQdGiu-n2sJ1iQ7z81dsMJtc9-YYV-ItIcEn5OXqnIZlGaeF8Ya6Jqy6XdrIb8ou5Sq-jYoB6UXyQRzQsV_1oIIXYSeQtQKalSpPbGGOgLaXsm61fBKimFnnCd1anhxtZAIHwCLMbvQCZlwOeTls1F1EEOvQ76qcdUcmsw-LHM_9I68DwjIwAjyOTe4WPMhsK6KD4MryCAfZRAmdRhG6BWVKk_8D1JPFy42qQmILAr9LXOMODqnVaNeGA-izmtfX5KqqdYxAR6XV_7B9muzYPyGnBL_l2pEcLq5kVSL7YGtczwqB-AA",
  "scope" : "read",
  "token_type" : "bearer",
  "expires_in" : 604799
}

Install dependencies

> pip3 install pycrypto
> pip3 install urllib
> pip3 ...

๊ณ„์ • ์ƒ์„ฑ

CODEF API๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์—”๋“œ์œ ์ €๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์ƒ๊ธฐ๊ด€์˜ ์ธ์ฆ์ˆ˜๋‹จ ๋“ฑ๋ก์ด ํ•„์š”ํ•˜๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž๋งˆ๋‹ค ์œ ๋‹ˆํฌํ•œ 'connectedId'๋ฅผ ๋ฐœ๊ธ‰๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ดํ›„์—๋Š” ๋ณ„๋„์˜ ์ธ์ฆ์ˆ˜๋‹จ ์ „์†ก ์—†์ด 'connectedId'๋ฅผ ํ†ตํ•ด์„œ ๋Œ€์ƒ๊ธฐ๊ด€์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์—ฐ๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 'connectedId' ๋ฐœ๊ธ‰์€ ์ตœ์ดˆ ๊ณ„์ • ์ƒ์„ฑ ์š”์ฒญ์‹œ์—๋งŒ ๊ฐ€๋Šฅํ•˜๋ฉฐ ์ดํ›„์— ์—”๋“œ์œ ์ €์˜ ์ธ์ฆ์ˆ˜๋‹จ ๊ด€๋ฆฌ๋Š” ๊ณ„์ • ์ถ”๊ฐ€, ๊ณ„์ • ์ˆ˜์ •, ๊ณ„์ • ์‚ญ์ œ ๊ฑฐ๋ž˜๋ฅผ ์ด์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • ์€ํ–‰/์นด๋“œ ์—…๋ฌด์˜ ๊ฒฝ์šฐ ๋™์ผํ•œ ๊ธฐ๊ด€์— ๋“ฑ๋ก ๊ฐ€๋Šฅํ•œ ์ธ์ฆ์ˆ˜๋‹จ์€ ๊ฐœ์ธ ๊ณ ๊ฐ/๊ธฐ์—… ๊ณ ๊ฐ ๊ฐ๊ฐ 1๊ฑด์ž…๋‹ˆ๋‹ค.
  • API์„œ๋ฒ„๋ฅผ ํ–ฅํ•œ ๋ชจ๋“  ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” URLEncoder๋ฅผ ํ†ตํ•ด UTF-8๋กœ ์ธ์ฝ”๋”ฉ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. (RegisterAccount.py ์ฐธ์กฐ)
  • ๊ณ„์ • ์ƒ์„ฑ ์‹œ ํฌํ•จ๋˜๋Š” ๋ชจ๋“  ๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” API ํ˜ธ์ถœ ์‹œ ๋ฐœ๊ธ‰๋œ publicKey ๋ฅผ ํ†ตํ•ด ์•”ํ˜ธํ™” ํ›„ ์ „์†กํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
codef_account_create_url = 'https://api.codef.io/v1/account/create'
codef_account_create_body = {
            'accountList':[                    # ๊ณ„์ •๋ชฉ๋ก
                {
                    'countryCode':'KR',        # ๊ตญ๊ฐ€์ฝ”๋“œ
                    'businessType':'BK',       # ๋น„์ฆˆ๋‹ˆ์Šค ๊ตฌ๋ถ„
                    'clientType':'P',          # ๊ณ ๊ฐ๊ตฌ๋ถ„(P: ๊ฐœ์ธ, B: ๊ธฐ์—…)
                    'organization':'0003',     # ๊ธฐ๊ด€์ฝ”๋“œ
                    'loginType':'0',           # ๋กœ๊ทธ์ธํƒ€์ž… (0: ์ธ์ฆ์„œ, 1: ID/PW)
                    'password':publicEncRSA(pubKey, '1234'),    # ์—”๋“œ์œ ์ €์˜ ์ธ์ฆ์„œ ๋น„๋ฐ€๋ฒˆํ˜ธ ์ž…๋ ฅ
                    'derFile':'MIIF...',                        # ์—”๋“œ์œ ์ €์˜ ์ธ์ฆ์„œ ์ธ์ฆ์„œ DerFile
                    'keyFile':'MIIF...'                         # ์—”๋“œ์œ ์ €์˜ ์ธ์ฆ์„œ ์ธ์ฆ์„œ KeyFile
                },
                {
                    'countryCode':'KR',        # ๊ตญ๊ฐ€์ฝ”๋“œ
                    'businessType':'BK',       # ๋น„์ฆˆ๋‹ˆ์Šค ๊ตฌ๋ถ„
                    'clientType':'P',          # ๊ณ ๊ฐ๊ตฌ๋ถ„(P: ๊ฐœ์ธ, B: ๊ธฐ์—…)
                    'organization':'0004',     # ๊ธฐ๊ด€์ฝ”๋“œ
                    'loginType':'0',           # ๋กœ๊ทธ์ธํƒ€์ž… (0: ์ธ์ฆ์„œ, 1: ID/PW)
                    'password':publicEncRSA(pubKey, '1234'),    # ์—”๋“œ์œ ์ €์˜ ์ธ์ฆ์„œ ๋น„๋ฐ€๋ฒˆํ˜ธ ์ž…๋ ฅ
                    'derFile':'MIIF...',                        # ์—”๋“œ์œ ์ €์˜ ์ธ์ฆ์„œ ์ธ์ฆ์„œ DerFile
                    'keyFile':'MIIF...'                         # ์—”๋“œ์œ ์ €์˜ ์ธ์ฆ์„œ ์ธ์ฆ์„œ KeyFile
                }
            ]
}

# CODEF API ํ˜ธ์ถœ
response_account_create = http_sender(codef_account_create_url, token, codef_account_create_body)
import base64

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5 as Cipher_PKCS1_v1_5

def publicEncRSA(publicKey, data):
    keyDER = base64.b64decode(pubKey)
    keyPub = RSA.importKey(keyDER)
    cipher = Cipher_PKCS1_v1_5.new(keyPub)
    cipher_text = cipher.encrypt(data.encode())

    encryptedData = base64.b64encode(cipher_text)
    print('encryptedData = ' + encryptedData)

    return encryptedData
{
  "result" : {
    "code" : "CF-00000",
    "extraMessage" : "",
    "message" : "์ •์ƒ"
  },
  "data" : {
    "successList" : [ {
      "clientType" : "P",
      "code" : "CF-00000",
      "loginType" : "0",
      "countryCode" : "KR",
      "organization" : "0003",
      "businessType" : "BK",
      "message" : "์„ฑ๊ณต"
    }, {
      "clientType" : "P",
      "code" : "CF-00000",
      "loginType" : "1",
      "countryCode" : "KR",
      "organization" : "0004",
      "businessType" : "BK",
      "message" : "์„ฑ๊ณต"
    } ],
    "errorList" : [ ],
    "connectedId" : "45t4DJOD44M9uwH7zxSgBg"
  }
}

๊ณ„์ • ์ถ”๊ฐ€

๊ณ„์ • ์ƒ์„ฑ์„ ํ†ตํ•ด ๋ฐœ๊ธ‰๋ฐ›์€ 'connectedId'์— ์ถ”๊ฐ€ ๊ธฐ๊ด€์˜ ์ธ์ฆ์ˆ˜๋‹จ์„ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ถ”๊ฐ€ ๋“ฑ๋กํ•œ ๊ธฐ๊ด€์„ ํฌํ•จํ•˜์—ฌ ์ดํ›„์—๋Š” ๋ณ„๋„์˜ ์ธ์ฆ์ˆ˜๋‹จ ์ „์†ก์—†์ด 'connectedId'๋ฅผ ํ†ตํ•ด์„œ ๋Œ€์ƒ๊ธฐ๊ด€์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์—ฐ๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์€ํ–‰/์นด๋“œ ์—…๋ฌด์˜ ๊ฒฝ์šฐ ๋™์ผํ•œ ๊ธฐ๊ด€์— ๋“ฑ๋ก ๊ฐ€๋Šฅํ•œ ์ธ์ฆ์ˆ˜๋‹จ์€ ๊ฐœ์ธ ๊ณ ๊ฐ/๊ธฐ์—… ๊ณ ๊ฐ ๊ฐ๊ฐ 1๊ฑด์ž…๋‹ˆ๋‹ค.
  • API์„œ๋ฒ„๋ฅผ ํ–ฅํ•œ ๋ชจ๋“  ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” URLEncoder๋ฅผ ํ†ตํ•ด UTF-8๋กœ ์ธ์ฝ”๋”ฉ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. (RegisterAccount.py ์ฐธ์กฐ)
codef_account_add_url = 'https://api.codef.io/v1/account/add'
codef_account_add_body = {
            'connectedId': '์—”๋“œ์œ ์ €์˜ ์€ํ–‰/์นด๋“œ์‚ฌ ๊ณ„์ • ๋“ฑ๋ก ํ›„ ๋ฐœ๊ธ‰๋ฐ›์€ ์ปค๋„ฅํ‹ฐ๋“œ์•„์ด๋”” ์ž…๋ ฅ',    # connectedId
            'accountList':[                  # ๊ณ„์ •๋ชฉ๋ก
              {
                  'countryCode':'KR',        # ๊ตญ๊ฐ€์ฝ”๋“œ
                  'businessType':'BK',       # ๋น„์ฆˆ๋‹ˆ์Šค ๊ตฌ๋ถ„
                  'clientType':'P',          # ๊ณ ๊ฐ๊ตฌ๋ถ„(P: ๊ฐœ์ธ, B: ๊ธฐ์—…)
                  'organization':'0020',     # ๊ธฐ๊ด€์ฝ”๋“œ
                  'loginType':'0',           # ๋กœ๊ทธ์ธํƒ€์ž… (0: ์ธ์ฆ์„œ, 1: ID/PW)
                  'password':publicEncRSA(pubKey, '1234'),    # ์—”๋“œ์œ ์ €์˜ ์ธ์ฆ์„œ ๋น„๋ฐ€๋ฒˆํ˜ธ ์ž…๋ ฅ
                  'derFile':'MIIF...',                        # ์—”๋“œ์œ ์ €์˜ ์ธ์ฆ์„œ ์ธ์ฆ์„œ DerFile
                  'keyFile':'MIIF...'                         # ์—”๋“œ์œ ์ €์˜ ์ธ์ฆ์„œ ์ธ์ฆ์„œ KeyFile
              }
            ]
}

# CODEF API ํ˜ธ์ถœ
response_account_add = http_sender(codef_account_add_url, token, codef_account_add_body)
{
  "result" : {
    "code" : "CF-00000",
    "extraMessage" : "",
    "message" : "์ •์ƒ"
  },
  "data" : {
    "successList" : [ {
      "clientType" : "P",
      "code" : "CF-00000",
      "loginType" : "0",
      "countryCode" : "KR",
      "organization" : "0020",
      "businessType" : "BK",
      "message" : "์„ฑ๊ณต"
    } ],
    "errorList" : [ ],
    "connectedId" : "45t4DJOD44M9uwH7zxSgBg"
  }
}

๊ณ„์ • ์ˆ˜์ •

๊ณ„์ • ์ƒ์„ฑ์„ ํ†ตํ•ด ๋ฐœ๊ธ‰๋ฐ›์€ 'connectedId'์— ๋“ฑ๋ก๋œ ๊ธฐ๊ด€์˜ ์ธ์ฆ์ˆ˜๋‹จ์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ณ€๊ฒฝ ์š”์ฒญํ•œ ๊ธฐ๊ด€์˜ ์ธ์ฆ ์ˆ˜๋‹จ์€ ํ˜ธ์ถœ ์ฆ‰์‹œ ๋ณ€๊ฒฝ๋˜๋ฉฐ, ์ด ํ›„ 'connectedId'๋ฅผ ํ†ตํ•ด์„œ ๋Œ€์ƒ๊ธฐ๊ด€์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์—ฐ๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • API์„œ๋ฒ„๋ฅผ ํ–ฅํ•œ ๋ชจ๋“  ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” URLEncoder๋ฅผ ํ†ตํ•ด UTF-8๋กœ ์ธ์ฝ”๋”ฉ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. (RegisterAccount.py ์ฐธ์กฐ)
codef_account_update_url = 'https://api.codef.io/v1/account/update'
codef_account_update_body = {
            'connectedId': '๊ณ„์ •์ƒ์„ฑ ์‹œ ๋ฐœ๊ธ‰๋ฐ›์€ ์•„์ด๋””',    # connectedId
            'accountList':[                    # ๊ณ„์ •๋ชฉ๋ก
                {
                    'countryCode':'KR',        # ๊ตญ๊ฐ€์ฝ”๋“œ
                    'businessType':'BK',       # ๋น„์ฆˆ๋‹ˆ์Šค ๊ตฌ๋ถ„
                    'clientType':'P',          # ๊ณ ๊ฐ๊ตฌ๋ถ„(P: ๊ฐœ์ธ, B: ๊ธฐ์—…)
                    'organization':'0020',     # ๊ธฐ๊ด€์ฝ”๋“œ
                    'loginType':'0',           # ๋กœ๊ทธ์ธํƒ€์ž… (0: ์ธ์ฆ์„œ, 1: ID/PW)
                    'password':publicEncRSA(pubKey, '1234'),    # ์—”๋“œ์œ ์ €์˜ ์ธ์ฆ์„œ ๋น„๋ฐ€๋ฒˆํ˜ธ ์ž…๋ ฅ   
                    'derFile':'์ธ์ฆ์„œ DerFile',  # Base64String
                    'keyFile':'์ธ์ฆ์„œ KeyFile'   # Base64String
                }
            ]
}

# CODEF API ํ˜ธ์ถœ
response_account_update = http_sender(codef_account_update_url, token, codef_account_update_body)
{
  "result" : {
    "code" : "CF-00000",
    "extraMessage" : "",
    "message" : "์ •์ƒ"
  },
  "data" : {
    "successList" : [ {
      "clientType" : "P",
      "code" : "CF-00000",
      "loginType" : "0",
      "countryCode" : "KR",
      "organization" : "0020",
      "businessType" : "BK",
      "message" : "์„ฑ๊ณต"
    } ],
    "errorList" : [ ],
    "connectedId" : "45t4DJOD44M9uwH7zxSgBg"
  }
}

๊ณ„์ • ์‚ญ์ œ

์—”๋“œ์œ ์ €๊ฐ€ ๋“ฑ๋ก๋œ ๊ณ„์ •์˜ ์‚ญ์ œ๋ฅผ ์š”์ฒญ ์‹œ 'connectedId'์— ๋“ฑ๋ก๋œ ๊ธฐ๊ด€์˜ ์ธ์ฆ์ˆ˜๋‹จ์„ ์ฆ‰์‹œ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์š”์ฒญํ•œ ๊ธฐ๊ด€์˜ ์ธ์ฆ ์ˆ˜๋‹จ์€ ํ˜ธ์ถœ ์ฆ‰์‹œ ์‚ญ์ œ๋˜๋ฉฐ, ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋Š” ๋ณต๊ตฌํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

  • API์„œ๋ฒ„๋ฅผ ํ–ฅํ•œ ๋ชจ๋“  ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” URLEncoder๋ฅผ ํ†ตํ•ด UTF-8๋กœ ์ธ์ฝ”๋”ฉ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. (RegisterAccount.py ์ฐธ์กฐ)
codef_account_delete_url = 'https://api.codef.io/v1/account/delete'
codef_account_delete_body = {
            'connectedId': '๊ณ„์ •์ƒ์„ฑ ์‹œ ๋ฐœ๊ธ‰๋ฐ›์€ ์•„์ด๋””',    # connectedId
            'accountList':[                    # ๊ณ„์ •๋ชฉ๋ก
                {
                    'countryCode':'KR',        # ๊ตญ๊ฐ€์ฝ”๋“œ
                    'businessType':'BK',       # ๋น„์ฆˆ๋‹ˆ์Šค ๊ตฌ๋ถ„
                    'clientType':'P',          # ๊ณ ๊ฐ๊ตฌ๋ถ„(P: ๊ฐœ์ธ, B: ๊ธฐ์—…)
                    'organization':'0020',     # ๊ธฐ๊ด€์ฝ”๋“œ
                    'loginType':'0',           # ๋กœ๊ทธ์ธํƒ€์ž… (0: ์ธ์ฆ์„œ, 1: ID/PW)
                }
            ]
}

# CODEF API ํ˜ธ์ถœ
response_account_delete = http_sender(codef_account_delete_url, token, codef_account_delete_body)
{
  "result" : {
    "code" : "CF-00000",
    "extraMessage" : "",
    "message" : "์ •์ƒ"
  },
  "data" : {
    "successList" : [ {
      "clientType" : "P",
      "loginType" : "0",
      "countryCode" : "KR",
      "organization" : "0020",
      "businessType" : "BK"
    } ],
    "connectedId" : "45t4DJOD44M9uwH7zxSgBg"
  }
}

๊ณ„์ • ๋ชฉ๋ก ์กฐํšŒ

๊ณ„์ • ๋“ฑ๋ก, ์ถ”๊ฐ€ ๋“ฑ์„ ํ†ตํ•ด CODEF์— ๋“ฑ๋ก๋œ ์—”๋“œ ์œ ์ €์˜ ์ธ์ฆ์ˆ˜๋‹จ ์ •๋ณด ๋ชฉ๋ก์— ๋Œ€ํ•œ ์กฐํšŒ๋ฅผ ์š”์ฒญํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—”๋“œ์œ ์ €์— ๋Œ€ํ•œ ์œ ๋‹ˆํฌํ•œ ์‹๋ณ„๊ฐ’์ธ 'connectedId'๋ฅผ ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์‚ฌ์šฉํ•˜๋ฉฐ ํ•ด๋‹น 'connectedId'์— ์—ฐ๊ฒฐ๋œ ์ธ์ฆ์ˆ˜๋‹จ ์ •๋ณด ๋ชฉ๋ก์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

  • API์„œ๋ฒ„๋ฅผ ํ–ฅํ•œ ๋ชจ๋“  ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” URLEncoder๋ฅผ ํ†ตํ•ด UTF-8๋กœ ์ธ์ฝ”๋”ฉ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. (AccountList.py ์ฐธ์กฐ)
codef_account_list_url = 'https://api.codef.io/v1/account/list'
codef_account_list_body = {
    'connectedId':connectedId          # ์—”๋“œ์œ ์ €์˜ ์€ํ–‰/์นด๋“œ์‚ฌ ๊ณ„์ • ๋“ฑ๋ก ํ›„ ๋ฐœ๊ธ‰๋ฐ›์€ ์ปค๋„ฅํ‹ฐ๋“œ์•„์ด๋”” ์˜ˆ์‹œ
}

# CODEF API ํ˜ธ์ถœ
response_account_list = http_sender(codef_account_list_url, token, codef_account_list_body)
{
  "result" : {
    "code" : "CF-00000",
    "extraMessage" : "",
    "message" : "์„ฑ๊ณต"
  },
  "data" : {
    "accountList" : [ {
      "clientType" : "B",
      "organizationCode" : "0003",
      "loginType" : "0",
      "countryCode" : "KR",
      "businessType" : "BK"
    }, {
      "clientType" : "B",
      "organizationCode" : "0004",
      "loginType" : "0",
      "countryCode" : "KR",
      "businessType" : "BK"
    }, {
      "clientType" : "P",
      "organizationCode" : "0004",
      "loginType" : "0",
      "countryCode" : "KR",
      "businessType" : "BK"
    }, {
      "clientType" : "B",
      "organizationCode" : "0011",
      "loginType" : "0",
      "countryCode" : "KR",
      "businessType" : "BK"
    }, {
      "clientType" : "P",
      "organizationCode" : "0020",
      "loginType" : "1",
      "countryCode" : "KR",
      "businessType" : "BK"
    }, {
      "clientType" : "B",
      "organizationCode" : "0301",
      "loginType" : "0",
      "countryCode" : "KR",
      "businessType" : "CD"
    }, {
      "clientType" : "P",
      "organizationCode" : "0302",
      "loginType" : "0",
      "countryCode" : "KR",
      "businessType" : "CD"
    }, {
      "clientType" : "B",
      "organizationCode" : "0309",
      "loginType" : "0",
      "countryCode" : "KR",
      "businessType" : "CD"
    }, {
      "clientType" : "P",
      "organizationCode" : "0309",
      "loginType" : "0",
      "countryCode" : "KR",
      "businessType" : "CD"
    } ],
    "connectedId" : "bybF-S85kX998Trh23JUVb"
  }
}

'connectedId' ๋ชฉ๋ก ์กฐํšŒ

CODEF๋กœ๋ถ€ํ„ฐ ๋ฐœ๊ธ‰๋œ 'connectedId'์˜ ๋ชฉ๋ก์— ๋Œ€ํ•œ ์กฐํšŒ๋ฅผ ์š”์ฒญํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์š”์ฒญ ๊ฒฐ๊ณผ๋Š” ํŽ˜์ด์ง•(5๋งŒ๊ฑด) ๋‹จ์œ„๋กœ ์ „์†ก๋˜๋ฉฐ ๊ฒฐ๊ณผ ๊ฐ’(hasNext == true)์— ๋”ฐ๋ผ ๋‹ค์Œ ํŽ˜์ด์ง€(nextPageNo)์— ๋Œ€ํ•œ ์š”์ฒญ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

  • API์„œ๋ฒ„๋ฅผ ํ–ฅํ•œ ๋ชจ๋“  ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” URLEncoder๋ฅผ ํ†ตํ•ด UTF-8๋กœ ์ธ์ฝ”๋”ฉ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. (ConnectedIdList.py ์ฐธ์กฐ)
codef_connectedId_list_url = 'https://api.codef.io/v1/account/connectedId-list'
codef_connectedId_list_body = {
    'pageNo':'5'            # ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ(์ƒ๋žต ๊ฐ€๋Šฅ) ์ƒ๋žต์‹œ 1ํŽ˜์ด์ง€ ๊ฐ’(0) ์ž๋™ ์„ค์ •
}

# CODEF API ํ˜ธ์ถœ
response_connectedId_list = http_sender(codef_connectedId_list_url, token, codef_connectedId_list_body)
{
  "result" : {
    "code" : "CF-00000",
    "extraMessage" : "",
    "message" : "์„ฑ๊ณต"
  },
  "data" : {
    "connectedIdList" : [ "6OOOZ58zAU.aX0pRRgzEBk", "bybF-S85kX998Trh23JUVb" ],
    "pageNo" : 0,
    "hasNext" : true,
    "nextPageNo" : 1
  }
}

CODEF API(๋ฒ•์ธ ๋ณด์œ ๊ณ„์ขŒ์กฐํšŒ)

๋ฐœ๊ธ‰๋ฐ›์€ 'connectedId' ๋ฅผ ํ†ตํ•ด ๋“ฑ๋ก๋œ ๊ธฐ๊ด€์˜ ๋ณด์œ ๊ณ„์ขŒ๋ฅผ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • API์„œ๋ฒ„๋ฅผ ํ–ฅํ•œ ๋ชจ๋“  ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” URLEncoder๋ฅผ ํ†ตํ•ด UTF-8๋กœ ์ธ์ฝ”๋”ฉ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. (TestKR_BK_1_B_001.py ์ฐธ์กฐ)

TestKR_BK_1_B_001.py

# CodefURL
codef_url = 'https://api.codef.io'
token_url = 'https://api.codef.io/oauth/token'

# ์€ํ–‰ ๋ฒ•์ธ ๋ณด์œ ๊ณ„์ขŒ
account_list_path = '/v1/kr/bank/b/account/list'

# ๊ธฐ ๋ฐœ๊ธ‰๋œ ํ† ํฐ
token =''     #access_token

# BodyData
body = {
    'connectedId':'9LUm.uhVQbzaangazwI0tr',
    'organization':'0011'
}

# CODEF API ์š”์ฒญ
response_codef_api = http_sender(codef_url + account_list_path, token, body)

# token error
if response_codef_api.status_code == 401:
    dict = json.loads(response_codef_api.text)
    # invalid_token
    print('error = ' + dict['error'])
    # Cannot convert access token to JSON
    print('error_description = ' + dict['error_description'])

    # reissue token
    response_oauth = request_token(token_url, 'CODEF๋กœ๋ถ€ํ„ฐ ๋ฐœ๊ธ‰๋ฐ›์€ ํด๋ผ์ด์–ธํŠธ ์•„์ด๋””', 'CODEF๋กœ๋ถ€ํ„ฐ ๋ฐœ๊ธ‰๋ฐ›์€ ์‹œํฌ๋ฆฟ ํ‚ค');
    if response_oauth.status_code == 200:
        dict = json.loads(response_oauth.text)
        # reissue_token
        token = dict['access_token']
        print('access_token = ' + token)

        # request codef_api
        response = http_sender(codef_url + account_list_path, token, body)

        # codef_api ์‘๋‹ต ๊ฒฐ๊ณผ
        print(response.status_code)
        print(response.text)
    else:
        print('ํ† ํฐ๋ฐœ๊ธ‰ ์˜ค๋ฅ˜')
else:
    print('์ •์ƒ์ฒ˜๋ฆฌ')
{
	"result": {
		"code": "CF-00000",
		"extraMessage": "",
		"message": "์„ฑ๊ณต",
		"transactionId": "aedb0cade44f44e48a5f3181c2fe9a96"
	},
	"data": {
		"resAccountEndDate": "",
		"resLoanLimitAmt": "",
		"resWithdrawalAmt": "19615",
		"resAccount": "05300000004040",
		"resAccountStatus": "ํ™œ๋™",
		"resLoanEndDate": "",
		"commEndDate": "20190630",
		"resInterestRate": "",
		"resAccountName": "OO๊ธฐ์—…์ž์œ ์˜ˆ๊ธˆ",
		"resAccountStartDate": "20130605",
		"resAccountCurrency": "KRW",
		"resAccountBalance": "19615",
		"commStartDate": "20190401",
		"resTrHistoryList": [
			{
				"resAccountTrTime": "095900",
				"resAccountDesc4": "",
				"resAccountDesc3": "๏ฝ’๏ฝŽ๏ฝ„๏ผฟ์˜ค์ „",
				"resAccountDesc2": "์ธํ„ฐ๋„ท",
				"resAccountDesc1": "๏ผˆ์ฃผ๏ผ‰OO",
				"resAccountTrDate": "20190628",
				"resAccountOut": "1",
				"resAfterTranBalance": "13634",
				"resAccountIn": "0"
			},
			{
				"resAccountTrTime": "174603",
				"resAccountDesc4": "",
				"resAccountDesc3": "rnd_์ž…๊ธˆํ‘œ์‹œ1",
				"resAccountDesc2": "ํƒ€ํ–‰์ด์ฒด",
				"resAccountDesc1": "OO๏ผˆ์ฃผ๏ผ‰",
				"resAccountTrDate": "20190627",
				"resAccountOut": "0",
				"resAfterTranBalance": "13635",
				"resAccountIn": "1"
			},
			{
				"resAccountTrTime": "164618",
				"resAccountDesc4": "",
				"resAccountDesc3": "rnd_์ž…๊ธˆํ‘œ์‹œ1",
				"resAccountDesc2": "ํƒ€ํ–‰์ด์ฒด",
				"resAccountDesc1": "OO๏ผˆ์ฃผ๏ผ‰",
				"resAccountTrDate": "20190627",
				"resAccountOut": "0",
				"resAfterTranBalance": "13634",
				"resAccountIn": "1"
			},
			{
				"resAccountTrTime": "092130",
				"resAccountDesc4": "",
				"resAccountDesc3": "๏ฝ’๏ฝŽ๏ฝ„๏ผฟ์˜ค์ „",
				"resAccountDesc2": "์ธํ„ฐ๋„ท",
				"resAccountDesc1": "๏ผˆ์ฃผ๏ผ‰OO",
				"resAccountTrDate": "20190627",
				"resAccountOut": "1",
				"resAfterTranBalance": "13633",
				"resAccountIn": "0"
			}
		],
		"resAccountHolder": "(์ฃผ)OO",
		"resManagementBranch": "(0044)๋ถ์•„ํ˜„๋™",
		"resLastTranDate": "20190711"
	}
}

์˜ค๋ฅ˜

CODEF API ์˜ค๋ฅ˜๋Š” HTTP status code ์™€ CODEF API ErrorCode๋กœ ๋ถ„๋ฅ˜ํ•ฉ๋‹ˆ๋‹ค.

HTTP 401 - OAuth2.0 ํ† ํฐ ๋งŒ๋ฃŒ

{"error":"invalid_token","error_description":"Cannot convert access token to JSON","code":"CF-99997","message":"OAUTH2.0 ํ† ํฐ ์—๋Ÿฌ์ž…๋‹ˆ๋‹ค. ๋ฉ”์‹œ์ง€๋ฅผ ํ™•์ธํ•˜์„ธ์š”."}

๊ทธ ์™ธ ์˜ค๋ฅ˜ HTTP 200 - CODEF ์˜ค๋ฅ˜ ๋ณ€ํ™˜(CF-XXXXX)

{"result":{"code":"CF-94002","extraMessage":"","message":"์‚ฌ์šฉ์ž ๊ณ„์ •์ •๋ณด ์„ค์ •์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค."},"data":{}}

Change Log

CODEF API์˜ ๋ณ€๊ฒฝ๋‚ด์„ CHANGELOG.md ์„ ํ†ตํ•ด ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

License

This project is licensed under the MIT License - see the LICENSE file for details

About

Python bindings for CODEF

Resources

Stars

8 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages