def payment_callback(request): merchant_uid = request.POST.get('merchant_uid') registration = Registration.objects.filter(merchant_uid=merchant_uid) if not registration.exists(): return HttpResponse(status=404) try: iamport = Iamport(config.IMP_DOM_API_KEY, config.IMP_DOM_API_SECRET) result = iamport.find_by_merchant_uid(merchant_uid) registration = registration.first() if result['status'] == 'paid': registration.confirmed = datetime.datetime.now() elif result['status'] == 'cancelled': registration.canceled = datetime.datetime.now() registration.payment_status = result['status'] registration.save() return HttpResponse() except Iamport.ResponseError as iamport_error: if iamport_error.code == 401 or iamport_error.code == 404: iamport = Iamport(config.IMP_INTL_API_KEY, config.IMP_INTL_API_SECRET) result = iamport.find_by_merchant_uid(merchant_uid) registration = registration.first() if result['status'] == 'paid': registration.confirmed = datetime.datetime.now() elif result['status'] == 'cancelled': registration.canceled = datetime.datetime.now() registration.payment_status = result['status'] registration.save() return HttpResponse() return HttpResponse(status=404)
def payment_process(request): # 비정상적 접근으로 등록 메인 페이지로 이동합니다. if request.method == 'GET': return redirect('registration_index') # 이미 등록된 사용자로 등록 현황 페이지로 이동합니다. if Registration.objects.filter(user=request.user, payment_status__in=['paid', 'ready']).exists(): return redirect('registration_status') payment_logger.debug(request.POST) form = RegistrationAdditionalPriceForm(request.POST) # TODO : more form validation # eg) merchant_uid if not form.is_valid(): form_errors_string = "\n".join( ('%s:%s' % (k, v[0]) for k, v in form.errors.items())) return JsonResponse({ 'success': False, 'message': form_errors_string, }) remain_ticket_count = (config.TOTAL_TICKET - Registration.objects.filter( payment_status__in=['paid', 'ready']).count()) # 매진 상태 if remain_ticket_count <= 0: return JsonResponse({ 'success': False, 'message': '티켓이 매진 되었습니다', }) # 후원 추가 금액이 0원 미만일 때 if form.cleaned_data.get('additional_price', 0) < 0: return JsonResponse({ 'success': False, 'message': u'후원 금액은 0원 이상이어야 합니다.', }) cleaned_form = form.cleaned_data registration = Registration( user=request.user, email=request.user.email, merchant_uid=request.POST.get('merchant_uid'), name=cleaned_form.get('name'), additional_price=cleaned_form.get('additional_price', 0), company=cleaned_form.get('company', ''), top_size=cleaned_form.get('top_size', ''), phone_number=cleaned_form.get('phone_number', ''), option=cleaned_form.get('option'), payment_method=cleaned_form.get('payment_method')) # 다시 한 번 매진 확인 if registration.option.is_sold_out: return JsonResponse({ 'success': False, 'message': '{name} 티켓이 매진 되었습니다'.format(name=registration.option.name), }) try: product = registration.option post_data = request.POST # 한국인용 카드 결제일 때 if registration.payment_method == 'card-korean': iamport = Iamport(config.IMP_DOM_API_KEY, config.IMP_DOM_API_SECRET) # TODO : use validated and cleaned data iamport_params = dict(name=product.name, amount=product.price + registration.additional_price, token=post_data.get('token'), merchant_uid=post_data.get('merchant_uid'), card_number=post_data.get('card_number'), expiry=post_data.get('expiry'), birth=post_data.get('birth'), pwd_2digit=post_data.get('pwd_2digit'), vat=0, buyer_name=post_data.get('name'), buyer_email=post_data.get('email'), buyer_tel=post_data.get('phone_number')) iamport.pay_onetime(**iamport_params) confirm = iamport.find_by_merchant_uid( post_data.get('merchant_uid')) # 결제한 금액과 Form에 입력된 결제 금액들이 다를 때 if confirm[ 'amount'] != product.price + registration.additional_price: # TODO : 결제 취소하는 로직 있어야 함 return render_io_error( "amount is not same as product.price. it will be canceled") registration.transaction_code = confirm.get('pg_tid') registration.payment_method = confirm.get('pay_method') registration.payment_status = confirm.get('status') registration.payment_message = confirm.get('fail_reason') registration.vbank_name = confirm.get('vbank_name', None) registration.vbank_num = confirm.get('vbank_num', None) registration.vbank_date = confirm.get('vbank_date', None) registration.vbank_holder = confirm.get('vbank_holder', None) registration.save() elif registration.payment_method == 'card-foreign': iamport = Iamport(config.IMP_INTL_API_KEY, config.IMP_INTL_API_SECRET) # TODO : use validated and cleaned data iamport_params = dict(name=product.name, amount=product.price + registration.additional_price, token=post_data.get('token'), merchant_uid=post_data.get('merchant_uid'), card_number=post_data.get('card_number'), expiry=post_data.get('expiry'), birth=post_data.get('birth'), pwd_2digit=post_data.get('pwd_2digit'), vat=0, buyer_name=post_data.get('name'), buyer_email=post_data.get('email'), buyer_tel=post_data.get('phone_number')) iamport.pay_foreign(**iamport_params) confirm = iamport.find_by_merchant_uid( post_data.get('merchant_uid')) # 결제한 금액과 Form에 입력된 결제 금액들이 다를 때 if confirm[ 'amount'] != product.price + registration.additional_price: # TODO : 결제 취소하는 로직 있어야 함 return render_io_error( "amount is not same as product.price. it will be canceled") registration.transaction_code = confirm.get('pg_tid') registration.payment_method = confirm.get('pay_method') registration.payment_status = confirm.get('status') registration.payment_message = confirm.get('fail_reason') registration.vbank_name = confirm.get('vbank_name', None) registration.vbank_num = confirm.get('vbank_num', None) registration.vbank_date = confirm.get('vbank_date', None) registration.vbank_holder = confirm.get('vbank_holder', None) registration.save() elif registration.payment_method == 'vbank': registration.transaction_code = post_data.get('pg_tid') registration.payment_method = post_data.get('pay_method') registration.payment_status = post_data.get('status') registration.payment_message = post_data.get('fail_reason') registration.vbank_name = post_data.get('vbank_name', None) registration.vbank_num = post_data.get('vbank_num', None) registration.vbank_date = post_data.get('vbank_date', None) registration.vbank_holder = post_data.get('vbank_holder', None) registration.save() else: raise Exception('Unknown payment method') except IamporterError as e: # TODO : other status code return JsonResponse({ 'success': False, 'code': e.code, 'message': e.message, }) else: return JsonResponse({ 'success': True, })
def manual_payment_process(request): if request.method == 'GET': return redirect('registration_index') payment_logger.debug(request.POST) form = ManualPaymentForm(request.POST) if not form.is_valid(): form_errors_string = "\n".join( ('%s:%s' % (k, v[0]) for k, v in form.errors.items())) return JsonResponse({ 'success': False, 'message': form_errors_string, # TODO : ... }) # check already payment try: mp = ManualPayment.objects.get( pk=request.POST.get('manual_payment_id')) except ManualPayment.DoesNotExist: return JsonResponse({ 'success': False, 'message': '결제할 내역이 존재하지 않습니다. 다시 한번 확인해 주시기 바랍니다.', }) if mp.payment_status == 'paid': return JsonResponse({ 'success': False, 'message': '이미 지불되었습니다. 문의사항은 [email protected] 로 문의주시기 바랍니다.', }) # Only card try: imp_client = Iamport(config.IMP_DOM_API_KEY, config.IMP_DOM_API_SECRET) imp_params = dict(token=request.POST.get('token'), merchant_uid=request.POST.get('merchant_uid'), amount=mp.price, card_number=request.POST.get('card_number'), expiry=request.POST.get('expiry'), birth=request.POST.get('birth'), pwd_2digit=request.POST.get('pwd_2digit'), name=mp.title, buyer_name=request.POST.get('name', ''), buyer_email=request.POST.get('email'), buyer_tel=request.POST.get('phone_number', '')) imp_client.pay_onetime(**imp_params) confirm = imp_client.find_by_merchant_uid( request.POST.get('merchant_uid')) if confirm['amount'] != mp.price: return render_io_error( "amount is not same as product.price. it will be canceled") mp.transaction_code = confirm.get('pg_tid') mp.imp_uid = confirm.get('imp_uid') mp.merchant_uid = confirm.get('merchant_uid') mp.payment_method = confirm.get('pay_method') mp.payment_status = confirm.get('status') mp.payment_message = confirm.get('fail_reason') mp.confirmed = timezone.now() mp.save() except IamporterError as e: return JsonResponse({ 'success': False, 'code': e.code, 'message': e.message, }) else: return JsonResponse({ 'success': True, })