프로젝트/hyper-V 웹서비스

[hyper-V 웹 서비스]7.결제 API 구현하기[RESTFUL API!]

김칠복 2022. 3. 17. 13:06

해야 할 일

1.html로 결제실행 페이지와 결제 완료페이지를 만들기.

2.백엔드 구현

1.결제 페이지

간단하게 결제 버튼만 구현했다.

유저친화적인 설계덕분에 유저가 할 일은 결제버튼을 누르는 일 뿐이다.

결제 준비단계에 필요한 유저 식별 정보와 상품 정보, 할인율(이 또한 어드민 전용 DB에서 조정할 수 있다.)등을

세션과 DB를 유기적으로 조작해 request 해주면 된다.

결제부분의 서버는 Flask의 BluePrint를 활용하여 개발했다.

pay.py:

@bp.route('/point', methods=['GET','POST'])  
def point():
    user_id = session.get('login',None)
    if user_id == None:
        return redirect(url_for("login"))
    if request.method == 'GET':
        return render_template('point.html',user_info = user.find_one({"user_id":user_id}), price = admin.find_one({"lable":"price"}))
    else:
        dc_col = admin.find_one({"lable":"DC"}) #할인율콜렉션
        DC_num = request.form.get('DC_num') 
        bprice = float(request.form.get('pay_price'))#가격 가져오기
        dc = float(dc_col[DC_num])


        aprice = int(bprice*(1-0.01*dc)) #할인된 가격
        
        URL = 'https://kapi.kakao.com/v1/payment/ready'
        headers = {
            'Authorization': "KakaoAK " + "47505261b90a9bd874b965a27a6abc3e",
            "Content-type": "application/x-www-form-urlencoded;charset=utf-8",
        }
        params = {
            "cid": "TC0ONETIME", #가맹점 코드
            "partner_order_id": "1001",  #가맹점 주문코드
            "partner_user_id": user_id,  #가맹점 회원
            "item_name": "포인트)옵션:"+DC_num,  #상품명
            "quantity": 1, #상품 수량
            "total_amount": aprice, #상품총액 
            "tax_free_amount": 0,  #비과세 금액(그냥 0)
            "approval_url": "http://localhost:5000/kakaopay/success",
            "cancel_url": "http://localhost:5000/kakaopay/cancel",
            "fail_url": "http://localhost:5000/kakaopay/fail",
        }
        res = requests.post(URL, headers=headers, params=params)
        print(res)
        session["tid"] = res.json()['tid']
        session['user_id'] = user_id
        return redirect(res.json()['next_redirect_pc_url'])

여기서 유의할 점은 request를 하고나면 session 이 초기화 된다는 점이다. request이후 세션을 다시 넣어주는 코드를 입력했다.

2.결제 완료페이지

유저가 pg토큰을 들고 등장할 페이지 이다. pg토큰을 get인자로 받아와서 tid와 함께 승인여부를 확인한다. 

pay.py:

@bp.route("/kakaopay/success", methods=['POST', 'GET'])
def sucess():
    tid = session.get("tid")
    user_id = session.get("user_id")

    URL = 'https://kapi.kakao.com/v1/payment/approve'
    headers = {
        "Authorization": "KakaoAK " + "47505261b90a9bd874b965a27a6abc3e",
        "Content-type": "application/x-www-form-urlencoded;charset=utf-8",
    }
    params = {
        "cid": "TC0ONETIME",  # 테스트용 코드
        "tid": tid,  # 결제 요청시 세션에 저장한 tid
        "partner_order_id": "1001",  # 주문번호
        "partner_user_id": user_id,  # 유저 아이디
        "pg_token": request.args.get("pg_token"),  # 쿼리 스트링으로 받은 pg토큰
    }
    res = requests.post(URL, headers=headers, params=params)
    print(res.text)
    print(res.json())
    print(res.json()['amount'])
    print(res.json()['amount']['total'])
    amount = res.json()['amount']['total']
    res = res.json()
    context = {
        'res': res,
        'amount': amount,
    }
    item = res['item_name'][7:]
    added_point= admin.find_one({"lable":"default_cash"})[item]
    #결제된 포인트 반영해주기
    session['user_id'] = user_id
    point = user.find_one({"user_id":user_id})["point"]
    point = point + added_point
    user.update_one({"user_id":user_id},{"$set":{"point":point}})
    
    return render_template('success.html', context=context, res=res)

다시 한번 적지만 세션이 초기화 되었음을 잊지 말자.

결제 페이지까지 성공적으로 구현이 완료되었다.