쿠폰 API 연동 가이드

1. 개요

이 가이드는 쿠폰 API 안내 및 쿠폰 API 연동 방법을 기술한 가이드 문서입니다.

2. 쿠폰 API란?

쿠폰 시스템이 없는 게임에 대해 자사의 쿠폰 시스템을 제공하여 개발사의 개발 부담을 줄이고 회원들에게 쿠폰 혜택을 줄 수 있는 장점을 가진 시스템입니다.
※ http 통신, JSON 데이터 처리가 가능할 경우 프로그래밍 언어에 구애받지 않고 구현이 가능합니다.



3. 개발사 처리 사항

1. 쿠폰 API 연동 신청 문서 작성 후 전달 => 4. 쿠폰 API 연동 신청 바로가기
2. 게임내 쿠폰 입력란 추가
3. API 연동 => 5. 쿠폰 사용 API 연동 바로가기
4. 아이템 코드에 따른 아이템 지급 기능 구현 => 6. 안드로이드 API 연동 예제
5. 쿠폰 사용 완료시 안내 메시지 노출 기능 구현 => 6. 안드로이드 API 연동 예제


4. 쿠폰 API 연동 신청

쿠폰 API 신청서 다운로드

위 신청서를 작성해주신 후 아래의 메일 주소로 보내주시면 빠른 시일내에 회신하도록 하겠습니다.

헝그리앱 쿠폰시스템 담당자 신승용 매니저
shinsy@monawa.com


5. 쿠폰 사용 API 연동

쿠폰의 사용 가능 여부 및 쿠폰에 해당되는 아이템 코드를 조회합니다.

- 아래 API 를 필수 파라미터와 함께 호출하여 쿠폰의 사용 가능 여부 또는 쿠폰에 해당되는 아이템 코드를 조회합니다.

URL

방식 URL
GET 또는 POST http://couponsystems.kr/api/UseCoupon.php

파라메터(*=필수항목)

*key - 발급받은 API Key
*coupon - 회원이 사용한 쿠폰 번호
*id - 게임 내에서 사용 중인 게임 아이디(고유값)



- 쿠폰 사용 API 호출에 대한 응답으로 아래와 같이 Json 형태로 응답이 리턴됩니다.

결과

result 처리 결과
- '1' : 성공
- '0' : 실패
benefit 혜택 내용
(ex. "4성 소환권 1장, 루비 100개")
items
(Array)
아이템 코드 목록
- item_code : 아이템 코드
- item_count : 아이템 수량
error_code 처리 실패시 에러코드
- '-100' : 'key'가 전송되지 않았습니다.
- '-101' : 'coupon'이 전송되지 않았습니다.
- '-102' : 'id'가 전송되지 않았습니다.
- '-200' : 존재하지 않는 API KEY입니다.
- '-201' : 존재하지 않는 쿠폰입니다.
- '-300' : 쿠폰 사용 기간이 아닙니다.
- '-301' : 쿠폰 사용 불가 상태입니다.
- '-302' : 쿠폰을 이미 사용했습니다.
- '-303' : 이미 같은 종류의 쿠폰을 사용했습니다.(중복 사용)
error_msg 에러 메시지
(ex."해당 쿠폰은 같은 계정에서 중복 사용하실 수 없습니다.")

예시

URL 요청 http://couponsystems.kr/api/UseCoupon.php?key=5e861eeade38c0ef&coupon=U2B4586E&id=ljh7795
응답 {
  "result": 1,
  "benefit": "수정 200개, 4성 소환권",
  "items": [
    {
      "item_code": "A",
      "item_count": "200"
    },
    {
      "item_code": "B",
      "item_count": "1"
    }
  ]
}



6. 안드로이드 API 연동 예제

안드로이드에서 API 연동을 위한 예제입니다.

예제 apk 다운로드
예제 프로젝트 다운로드
위 예제를 다운로드하시거나 아래의 코드를 참고해서 기능 구현해주시기 바랍니다.

* 개발사에서 코드 확인 후 직접 구현 부탁드립니다.
* 개발사에서 코드 확인 후 수정 필요시 수정하여 구현 부탁드립니다.

public class MainActivity extends Activity {

    private static final String TAG = "COUPON_API";

    // 발급받은 API KEY 입니다.
    public static final String COUPON_API_KEY = "e9ed0d710bedc095";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final String gameId = getRandomString(8);

        final TextView info = (TextView) findViewById(R.id.info);
        info.setText("API KEY : " + COUPON_API_KEY + "\n게임아이디 : " + gameId + "\n(게임아이디는 재실행시마다 변경됩니다.)"
                + "\n쿠폰 번호를 입력해주세요.");

        final EditText coupon = (EditText) findViewById(R.id.coupon);

        final View button = findViewById(R.id.button);
        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                useCoupon(coupon.getText().toString(), gameId);
            }
        });

    }

    /*************************
     * 테스트용 아이디 랜덤 생성을 위한 메소드입니다.
     ※ 실제 구현 시에는 중복되지 않고, 변경되지 않는 고유한 아이디로 구현해주셔야 합니다.
     *************************/
    private static final String ALLOWED_CHARACTERS = "0123456789qwertyuiopasdfghjklzxcvbnm";

    private static String getRandomString(final int sizeOfRandomString) {
        final Random random = new Random();
        final StringBuilder sb = new StringBuilder(sizeOfRandomString);
        for (int i = 0; i < sizeOfRandomString; ++i)
            sb.append(ALLOWED_CHARACTERS.charAt(random.nextInt(ALLOWED_CHARACTERS.length())));
        return sb.toString();
    }

    /*************************
     * 쿠폰을 사용합니다.
     * coupon : 쿠폰 번호
     * gameId : 게임내 고유 아이디
     * 아래 코드 확인 후 개발사에서 수정이 필요한 부분은 수정하여 사용 부탁드립니다.
     *************************/
    public void useCoupon(final String coupon, final String gameId) {
        /**
         * 네트워크 연결 상태에 따라 처리 시간이 늦어 질수 있으므로 백그라운드로 처리합니다.
         */
        new AsyncTask(){
            Dialog dialog;
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                dialog = ProgressDialog.show(MainActivity.this, getString(R.string.app_name), "처리 중입니다...", true, false);
            }

            @Override
            protected CouponData doInBackground(Void... params) {
                /*
                 * 쿠폰 사용 API URL에 key, coupon, id를 전송한 후 응답을 apiResult에 저장합니다.
                 * http 통신 라이브러리 사용 시 그에 맞게 수정하여 구현 부탁드립니다.
                 */
                String apiResult = executeHttp("http://couponsystems.kr/api/UseCoupon.php?key=" + COUPON_API_KEY + "&coupon=" + coupon + "&id=" + gameId);
                
                //응답을 CouponData로 파싱합니다.
                CouponData data = CouponData.valueOf(apiResult);
                return data;
            }
            
            @Override
            protected void onPostExecute(CouponData result) {
                if(dialog != null)
                    if(dialog.isShowing())
                        dialog.dismiss();
                
                super.onPostExecute(result);
                
                //아이템을 지급합니다.
                provideItem(result);
                
                //결과를 회원에게 노출합니다.
                showResult(result);
            }
            
        }.execute();
    }
    
    /*************************
     * CouponData 값에 따라 아이템을 지급처리합니다.
     * 아래 코드 참고하여 개발사에서 직접 구현 부탁드립니다.
     *************************/
    private void provideItem(CouponData data){
        if(data == null)
            return;
        
        if(data.items == null)
            return;
        
        for(CouponItem item : data.items){
            if(TextUtils.isEmpty(item.itemCode))
                continue;
            
            
            ///////////개발사 구현 부분입니다.///////////
            if(item.itemCode.equals("weapon")){
                Log.e(TAG, "무기 소환권 " + item.itemCount + "장 지급");
            }else if(item.itemCode.equals("armor")){
                Log.e(TAG, "방어구 소환권 " + item.itemCount + "장 지급");
            }
            ///////////개발사 구현 부분입니다.///////////
        }
    }
    
    
    /*************************
     * CouponData 값에 따라 결과를 사용자에게 노출합니다.
     * 아래 코드 참고하여 개발사에서 직접 구현 부탁드립니다.
     *************************/
    private void showResult(CouponData data){
        ///////////개발사 구현 부분입니다.///////////
        //쿠폰 사용 완료 후 결과를 Dialog로 노출합니다.
        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
        if (data != null && data.items != null && data.items.size() > 0) {
            dialogBuilder.setMessage("아이템이 발급되었습니다!\n[" + data.benefit + "]");
        } else {
            dialogBuilder.setMessage(data.errorMsg + "\n에러코드 : " + data.errorCode);
        }
        dialogBuilder.setNeutralButton("확인", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // TODO Auto-generated method stub
                dialog.dismiss();
            }
        });
        Dialog dialog = dialogBuilder.create();
        dialog.setCanceledOnTouchOutside(true);
        dialog.show();
        ///////////개발사 구현 부분입니다.///////////
    }

    /***************
     * http 통신으로 URL에 데이터를 전송하는 메소드입니다.
     ***************/
    private String executeHttp(String url) {
        HttpUriRequest request = new HttpGet(url);
        HttpParams params = new BasicHttpParams();
        params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
        params.setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);
        HttpConnectionParams.setConnectionTimeout(params, 15000);
        HttpConnectionParams.setSoTimeout(params, 15000);
        HttpConnectionParams.setTcpNoDelay(params, true);

        HttpClient client = new DefaultHttpClient(params);

        HttpResponse response = null;
        try {
            response = client.execute(request);
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        if (response == null)
            return "";

        StatusLine statusLine = response.getStatusLine();
        int responseCode = statusLine.getStatusCode();

        HttpEntity entity = response.getEntity();
        InputStream content = null;
        try {
            content = entity.getContent();
        } catch (IllegalStateException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        if (content == null)
            return "";

        BufferedReader reader = new BufferedReader(new InputStreamReader(content));
        String line;
        StringBuilder builder = new StringBuilder();
        try {
            while ((line = reader.readLine()) != null) {
                builder.append(line);
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        if (reader != null)
            try {
                reader.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        if (response.getEntity() != null)
            try {
                response.getEntity().consumeContent();
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }

        return builder.toString();
    }
    
    
    /*************************
     * 응답받은 JSON 데이터를 사용하기 쉽도록 CouponData로 파싱하는 클래스입니다.
     *************************/
    public static class CouponData{
        public boolean result;
        public int errorCode;
        public String errorMsg;
        public String benefit;
        public ArrayList items;
        
        public static CouponData valueOf(String jsonStr){
            
            if(TextUtils.isEmpty(jsonStr))
                return null;
            
            JSONObject json = null;
            
            try {
                json = new JSONObject(jsonStr);
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            if(json == null)
                return null;
            
            CouponData data =new CouponData();
            data.result = json.optInt("result", 0) == 1;
            data.errorCode = json.optInt("error_code", 0);
            data.errorMsg = json.optString("error_msg", "알 수 없는 오류가 발생했습니다.");
            data.benefit = json.optString("benefit");
            JSONArray itemArr = json.optJSONArray("items");
            if(itemArr != null){
                data.items = new ArrayList();
                CouponItem item = null;
                for(int i = 0 ; i < itemArr.length() ; i++){
                    item = CouponItem.valueOf(itemArr.optString(i));
                    if(item != null)
                        data.items.add(item);
                }
            }
            return data;
        }
        
        public static class CouponItem{
            public String itemCode;
            public int itemCount;
            
            public static CouponItem valueOf(String jsonStr){
                
                if(TextUtils.isEmpty(jsonStr))
                    return null;
                
                JSONObject json = null;
                
                try {
                    json = new JSONObject(jsonStr);
                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                
                if(json == null)
                    return null;
                
                CouponItem data = new CouponItem();
                data.itemCode = json.optString("item_code");
                data.itemCount = json.optInt("item_count", 0);
                
                return data;
            }
        }
    }
}