콘텐츠로 이동

인증키 사용 방법 샘플

Notice

주의사항

본 API는 GraphQL 공식 문서를 기준으로 제작된 GraphQL API 입니다.
GraphQL에 대한 개념은 Happytalk Embedded 기본 정보에 참고자료를 참고해주시기 바랍니다.

Endpoint

[GQL] API URL 정보

https://patch-gql-gw.happytalk.io/graphql
https://gql-gw.happytalk.io/graphql

Request

Field Name Type Required Description
Content-type String Y application/json
x-mbi-partner-signature String Y Partner Credential을 사용하여 생성 (인증키 사용 방법 샘플)
x-mbi-app-signature String Y App Credential을 사용하여 생성 (인증키 사용 방법 샘플)

Body

Mutation

mutation ($partnerCredentialInput: CredentialInput!, $appCredentialInput: CredentialInput!, $limit: Int!){
  setAccountLimit (partnerCredentialInput: $partnerCredentialInput, appCredentialInput: $appCredentialInput, limit: $limit){
    result
    message
  }
}

Variables

{
    "partnerCredentialInput": {
      "key": "통신을 위한 파트너 키 (header 키와 별개)",
      "expireAt": 1688353665
    },
    "appCredentialInput": {
      "key": "통신을 위한 앱 키 (header 키와 별개)",
      "expireAt": 1688353665
    },
    "limit": 10
  }

Sample Source Code

Issuance of Signature Sample Source Code
Programming Lanuage : node.js v16.20

Use Modules :
    1. dotenv v16.0.3
    2. express v4.18.2
    3. graphql v16.6.0
    4. graphql-playground-middleware-express v1.7.23
    5. graphql-voyager v1.0.0

Command:
    1. npm install
    2. npm start serve
package.json
package.json
{
  "name": "graphql-visualizer",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "serve": "node index.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "dotenv": "^16.0.3",
    "express": "^4.18.2",
    "graphql": "^16.6.0",
    "graphql-playground-middleware-express": "^1.7.23",
    "graphql-voyager": "^1.0.0"
  }
}
package-lock.json
package-lock.json
{
  "name": "make-signature-sample",
  "version": "1.0.0",
  "lockfileVersion": 2,
  "requires": true,
  "packages": {
    "": {
      "name": "make-signature-sample",
      "version": "1.0.0",
      "license": "ISC",
      "dependencies": {
        "axios": "^1.3.4",
        "crypto-js": "^4.1.1",
        "dotenv": "^16.0.3"
      }
    },
    "node_modules/asynckit": {
      "version": "0.4.0",
      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
    },
    "node_modules/axios": {
      "version": "1.3.4",
      "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.4.tgz",
      "integrity": "sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ==",
      "dependencies": {
        "follow-redirects": "^1.15.0",
        "form-data": "^4.0.0",
        "proxy-from-env": "^1.1.0"
      }
    },
    "node_modules/combined-stream": {
      "version": "1.0.8",
      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
      "dependencies": {
        "delayed-stream": "~1.0.0"
      },
      "engines": {
        "node": ">= 0.8"
      }
    },
    "node_modules/crypto-js": {
      "version": "4.1.1",
      "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz",
      "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw=="
    },
    "node_modules/delayed-stream": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
      "engines": {
        "node": ">=0.4.0"
      }
    },
    "node_modules/dotenv": {
      "version": "16.0.3",
      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz",
      "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==",
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/follow-redirects": {
      "version": "1.15.2",
      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
      "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
      "funding": [
        {
          "type": "individual",
          "url": "https://github.com/sponsors/RubenVerborgh"
        }
      ],
      "engines": {
        "node": ">=4.0"
      },
      "peerDependenciesMeta": {
        "debug": {
          "optional": true
        }
      }
    },
    "node_modules/form-data": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
      "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
      "dependencies": {
        "asynckit": "^0.4.0",
        "combined-stream": "^1.0.8",
        "mime-types": "^2.1.12"
      },
      "engines": {
        "node": ">= 6"
      }
    },
    "node_modules/mime-db": {
      "version": "1.52.0",
      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/mime-types": {
      "version": "2.1.35",
      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
      "dependencies": {
        "mime-db": "1.52.0"
      },
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/proxy-from-env": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
    }
  },
  "dependencies": {
    "asynckit": {
      "version": "0.4.0",
      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
    },
    "axios": {
      "version": "1.3.4",
      "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.4.tgz",
      "integrity": "sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ==",
      "requires": {
        "follow-redirects": "^1.15.0",
        "form-data": "^4.0.0",
        "proxy-from-env": "^1.1.0"
      }
    },
    "combined-stream": {
      "version": "1.0.8",
      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
      "requires": {
        "delayed-stream": "~1.0.0"
      }
    },
    "crypto-js": {
      "version": "4.1.1",
      "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz",
      "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw=="
    },
    "delayed-stream": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
    },
    "dotenv": {
      "version": "16.0.3",
      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz",
      "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ=="
    },
    "follow-redirects": {
      "version": "1.15.2",
      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
      "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA=="
    },
    "form-data": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
      "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
      "requires": {
        "asynckit": "^0.4.0",
        "combined-stream": "^1.0.8",
        "mime-types": "^2.1.12"
      }
    },
    "mime-db": {
      "version": "1.52.0",
      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
    },
    "mime-types": {
      "version": "2.1.35",
      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
      "requires": {
        "mime-db": "1.52.0"
      }
    },
    "proxy-from-env": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
    }
  }
}
.env
# replace with your own credentials
APP_KEY="APP_KEY_TEST"
APP_SECRET="APP_SECRET_TEST"
PARTNER_KEY="PARTNER_KEY_TEST"
PARTNER_SECRET="PARTNER_SECRET_TEST"
main.js
require('dotenv').config();
const axios = require('axios');
const HmacSHA512 = require('crypto-js/hmac-sha512');
const Base64 = require('crypto-js/enc-base64');

const env = {
    APP_KEY: process.env?.APP_KEY,
    APP_SECRET: process.env?.APP_SECRET,
    PARTNER_KEY: process.env?.PARTNER_KEY,
    PARTNER_SECRET: process.env?.PARTNER_SECRET,
};

const endpoint = 'https://patch-gql-gw.happytalk.io/graphql';

// set lifetime (10s)
const expireAt = Math.floor(Date.now() / 1000) + 10;

// generate payload
const rawBody = JSON.stringify({
    query: `mutation ($partnerCredentialInput: CredentialInput!, $appCredentialInput: CredentialInput!, $limit: Int!){
  setAccountLimit (partnerCredentialInput: $partnerCredentialInput, appCredentialInput: $appCredentialInput, limit: $limit){
    result
    message
  }
}`,
  variables: {
    "partnerCredentialInput": {
      "key": env.PARTNER_KEY,
      "expireAt": expireAt,
    },
    "appCredentialInput": {
      "key": env.APP_KEY,
      "expireAt": expireAt,
    },
    "limit": 10,
  }
});

// how to generate hmac signature here
const partnerSignature = HmacSHA512(rawBody, env.PARTNER_SECRET).toString(Base64);
const appSignature = HmacSHA512(rawBody, env.APP_SECRET).toString(Base64);

// set header, how to use hmac signature here
const headers = {
    'x-mbi-partner-signature': partnerSignature,
    'x-mbi-app-signature': appSignature,
    'Content-Type': 'application/json',
};

// request to happytalk graphql API server
axios
    .post(endpoint, rawBody, { headers: headers })
    .then(function (response) {
        console.log(`response`, response);
    })
    .catch(function (error) {
        console.log(`error`, error);
    });

Response (Json)

Parameter

Field Name Type Description
data Object
setAccountLimit Object
result Boolean 성공 : true / 실패 : false
message String 에러 메시지

Example

Success
{ 
    data: { 
        setAccountLimit: { 
            result: true, 
            message: null 
        } 
    } 
}

Data Dictionary

Data Dictionary

None

None