def confirm_transaction(request):
    if request.method == "POST":
        logger.info("Received callback request from TTT ScratchCard servers")
        # logger.info("Refferer: " + request.META["HTTP_REFERER"])
        # logger.info("Host: " + request.META["REMOTE_HOST"])
        logger.info(request.POST)
        try:
            matching_transaction = Transaction.objects.get(
                transaction_id=request.POST["partner_tran_id"],
                order_id=request.POST["id"]
            )
            logger.info("Found matching transaction:")
            logger.info(matching_transaction)
            matching_transaction.status = 3  # PENDING

            if request.POST["status"] == '4':
                logger.info({'msg': 'Card already used!'})
                matching_transaction.status = 1  # FAILED
                matching_transaction.remark = 'Card already used!'
            if request.POST["status"] == '5':
                logger.info({'msg': 'Wrong PIN'})
                matching_transaction.status = 1  # FAILED
                matching_transaction.remark = 'Wrong PIN'
            if request.POST["status"] == '7':
                logger.info({'msg': 'Wrong Serial'})
                matching_transaction.status = 1  # FAILED
                matching_transaction.remark = 'Wrong Serial'
            if request.POST["status"] == '8':
                logger.info({'msg': 'Wrong Amount'})
                matching_transaction.status = 1  # FAILED
                matching_transaction.remark = 'Wrong Amount'
            if request.POST["status"] == '1':
                logger.info({'msg': 'Confirming Transaction!'})
                matching_transaction.status = 0  # success
                matching_transaction.amount = request.POST["amount"]
                matching_transaction.remark = 'Successfully Deposited!'
                # update user balance after updating matching transaction
                helpers.addOrWithdrawBalance(matching_transaction.user_id, request.POST["amount"], "add")

            matching_transaction.arrive_time = timezone.now()
            matching_transaction.last_updated = timezone.now()
            matching_transaction.save()
            return JsonResponse({
                "success": True,
                "message": "received response"
            })
        except ObjectDoesNotExist as e:
            logger.critical("FATAL__ERROR::ScratchCard::Matching transaction not found", exc_info=1, stack_info=1)
            return JsonResponse({
                "success": False,
                "message": "Could not find matching transaction"
            })
        except Exception as e:
            logger.exception("Exception occurred::"+repr(e))
            return JsonResponse({
                "success": False,
                "message": "There was an exception"
            })
Пример #2
0
    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class(self.get_queryset(), many=True)
        trans_status = request.data.get('Status')
        depositID = request.data.get('ID')
        update_data = Transaction.objects.get(
            transaction_id=request.POST.get('Reference'),
            user_id=CustomUser.objects.get(pk=request.POST.get('Customer'))
        )
        if update_data.order_id != '0':  # attempting to confirm the same transaction twice
            logger.info("Callback was sent twice for Deposit #" + str(request.POST.get('Reference')))
            return JsonResponse({
                "error": "Transaction was already modified from 3rd party callback",
                "message": "Transaction already exists"
            })

        result = "Pending"
        if trans_status == '000':
            update_data.status = 0
            result = "Success"
            can_deposit = helpers.addOrWithdrawBalance(update_data.user_id, request.POST.get('Amount'), 'add')
            if not can_deposit:
                return JsonResponse({
                    'message': 'There was an error with updating the user balance',
                    'success': False
                })
        elif trans_status == '001':
            update_data.status = 1
            result = "Failed"
        elif trans_status == '006':
            update_data.status = 4
            result = "Approved"
        elif trans_status == '007':
            update_data.status = 8
            result = "Rejected"
        elif trans_status == '009':
            update_data.status = 3
            result = "Pending"

        update_data.order_id = depositID
        update_data.arrive_time = timezone.now()
        update_data.last_updated = timezone.now()
        update_data.remark = result
        update_data.save()
        
        return Response({
            'message': 'Received callback from Help2Pay',
            'status': trans_status,
            'result': result
        }, status=status.HTTP_200_OK)
Пример #3
0
    def post(self, request):
        # print(request)
        new_amount = request.POST.get("new_amount")
        reason = request.POST.get("reason")
        pk = request.POST.get("txn_id")

        try:
            with transaction.atomic():
                curr_txn = Transaction.objects.get(pk=pk)
                if new_amount:
                    curr_txn.amount = new_amount
                new_status = 0 if curr_txn.status == 1 else 1
                curr_txn.status = new_status
                curr_txn.remark = curr_txn.remark + " -> Result override to " + curr_txn.get_status_display(
                )

                # TODO: implement changelog function to record
                # addToChangelog()

                can_update = helpers.addOrWithdrawBalance(
                    curr_txn.user_id.username, curr_txn.amount, "add")
                if can_update:
                    curr_txn.save()
                    return HttpResponse(
                        "Transaction No. " + pk +
                        " was changed from 'Failed' to 'Successful'")
                else:
                    return HttpResponse(
                        "Was not able to update user's balance")

        except Exception as e:
            logger.error(
                "There was an error with overriding the transaction result",
                exc_info=1)
            logger.error(repr(e))
            return HttpResponse(
                "There was an error when overriding the result")
Пример #4
0
    def post(self, request, *args, **kwargs):
        serializer = approvePayoutSerialize(self.queryset,
                                            context={'request': request},
                                            many=True)

        orderId = self.request.POST['order_id']
        userId = self.request.POST['user_id']
        notes = self.request.POST['remark']
        list = [merchantId, orderId, userId, notes]
        message = '|'.join(str(x) for x in list)
        mymessage = bytes(message, 'utf-8')
        secret = bytes(merchantApiKey, 'utf-8')
        my_hmac = generateHash(secret, mymessage)

        url = api + apiVersion + '/' + merchantId + '/payout/' + orderId + '/reject'
        headers = {
            'Accept': 'application/json',
            'Content-Type': 'application/x-www-form-urlencoded',
        }
        delay = kwargs.get("delay", 5)

        #retry
        success = False
        for x in range(3):
            try:
                r = requests.post(url,
                                  headers=headers,
                                  data={
                                      'rejectedBy': userId,
                                      'notes': notes,
                                      'messageAuthenticationCode': my_hmac,
                                  })
                if r.status_code == 200:
                    success = True
                    break
            except ValueError:
                logger.info(
                    'Request failed {} time(s).wating for %s seconds before retrying again'
                    .format(x + 1))

                sleep(delay)
        if not success:
            logger.critical(
                'Failed to complete a request for rejecting payout transaction'
            )
        # Handle error

        rdata = r.json()
        #print(rdata)

        if r.status_code == 200:

            for x in Transaction._meta.get_field('currency').choices:

                if rdata['currency'] == x[1]:
                    cur_val = x[0]
            for y in Transaction._meta.get_field('status').choices:
                if rdata["status"] == y[1]:
                    cur_status = y[0]
            try:
                with transaction.atomic():
                    user = CustomUser.objects.get(username=rdata['userId'])
                    update_data = Transaction.objects.get(
                        transaction_id=rdata['orderId'])

                    update_data.order_id = rdata['transactionId']
                    update_data.last_updated = rdata["dateUpdated"]
                    update_data.status = TRAN_REJECTED_TYPE
                    update_data.review_status = REVIEW_REJ
                    update_data.remark = notes
                    update_data.release_by = user
                    update_data.save()

                    addOrWithdrawBalance(user.username, update_data.amount,
                                         'add')

                    logger.info('Finish updating the status of withdraw ' +
                                str(rdata['orderId']) + ' to Approve')
                    return Response(rdata)
            except ObjectDoesNotExist as e:

                logger.error(
                    "matching transaction not found / does not exist for qaicash rejecting payout"
                )
                return Response({
                    "error":
                    "Could not find matching transaction for qaicash rejecting payout",
                    "code": ERROR_CODE_NOT_FOUND
                })

            except DatabaseError as e:
                logger.info(
                    "Error update transaction for qaicash rejecting payout" +
                    str(e))
                return Response({
                    "error":
                    "Error updating transaction for qaicash rejecting payout",
                    "code": ERROR_CODE_DATABASE
                })

        else:
            logger.error(
                'The request information is not correct for qaicash rejecting payout, please try again.'
            )
            return Response({
                "error":
                "The request information is not correct for qaicash rejecting payout",
                "code": ERROR_CODE_INVALID_INFO
            })
Пример #5
0
    def post(self, request): # user will need to submit bank acc information
        data = json.loads(request.body)
        username = request.user.username

        try:
            user = CustomUser.objects.get(username=username)
            withdraw_password = data.get("withdrawPassword")
            
            # toBankAccountName = 'orion'
            # toBankAccountNumber = '12345123'
            toBankAccountName = data.get("toBankAccountName")
            toBankAccountNumber = data.get("toBankAccountNumber")

            amount = float(data.get("amount"))
            currency = data.get("currency") or 2 # 2 = THB, 8 = VND
            currency = int(currency)
            trans_id = username+"-"+timezone.datetime.today().isoformat()+"-"+str(random.randint(0, 10000000))
            # trans_id = "orion-"+timezone.datetime.today().isoformat()+"-"+str(random.randint(0, 10000000))
            ip = helpers.get_client_ip(request)
            bank = data.get("bank")

            user_id=user.pk
            
            merchant_code = '123'
            secret_key = '123'
            payoutURL = '123'
            
            if currency == 2:
                merchant_code = HELP2PAY_MERCHANT_THB
                secret_key = HELP2PAY_SECURITY_THB
                payoutURL = H2P_PAYOUT_URL_THB
                
            elif currency == 8:
                merchant_code = HELP2PAY_MERCHANT_VND
                secret_key = HELP2PAY_SECURITY_VND
                payoutURL = H2P_PAYOUT_URL_VND
            
            
            strAmount = str('%.2f' % amount)
            
            utc_datetime = datetime.datetime.utcnow().replace(tzinfo=pytz.utc).astimezone(pytz.timezone('Asia/Shanghai'))
            Datetime = utc_datetime.strftime("%Y-%m-%d %H:%M:%S%p")
            key_time = utc_datetime.strftime("%Y%m%d%H%M%S")
          
            secretMsg = merchant_code+trans_id+str(user_id)+strAmount+currencyConversion[currency]+key_time+toBankAccountNumber+secret_key
            
            checksum = MD5(secretMsg)
       
            if check_password(withdraw_password, user.withdraw_password):
                try:
                    db_currency_code = 7 if currency == 8 else 2
                    withdraw_request = Transaction(
                        transaction_id=trans_id,
                        amount=amount,
                        user_id=user,
                        method='Bank Transfer',
                        currency=currency,
                        transaction_type=TRANSACTION_WITHDRAWAL,
                        channel=0,
                        request_time=timezone.now(),
                        other_data={'checksum': checksum}
                    )
                    withdraw_request.save()
                    logger.info("Withdraw request created: " + str(withdraw_request))

                    can_withdraw = helpers.addOrWithdrawBalance(username, amount, "withdraw")

                    if can_withdraw:
                        data = {
                            "Key": checksum,
                            "ClientIP": ip,
                            "ReturnURI": HELP2PAY_RETURN_URL,
                            "MerchantCode": merchant_code,
                            "TransactionID": str(trans_id),
                            "MemberCode": user_id,
                            "CurrencyCode": currencyConversion[currency],
                            "Amount": amount,
                            "TransactionDateTime": Datetime,
                            "BankCode": bank,
                            "toBankAccountName": toBankAccountName,
                            "toBankAccountNumber": toBankAccountNumber,
                        }

                        r = requests.post(payoutURL, data=data)
                        
                        if r.status_code == 200:
                            return HttpResponse(r.content, content_type="text/xml")
                        else:
                            return JsonResponse({
                                'status_code': ERROR_CODE_FAIL,
                                'message': 'Payment service unavailable'

                            })
                    else:
                        return JsonResponse({
                            'status_code': ERROR_CODE_FAIL,
                            'message': 'Insufficient funds'
                        })
                except (ObjectDoesNotExist, IntegrityError, DatabaseError) as e:
                    logger.critical("FATAL__ERROR::Help2Pay::Exception occured when submitting a payout request", exc_info=1)
                    return HttpResponse(status=500)
            else:
                logger.error("withdraw password is not correct.")    
                return JsonResponse({
                    'status_code': ERROR_CODE_INVALID_INFO,
                    'message': 'Withdraw password is not correct.'
                })
                
        except ObjectDoesNotExist as e:
            logger.error(repr(e))
            return HttpResponse(status=500)
Пример #6
0
def confirm_payment(request):
    if request.method == "GET":
        logger.info("Hello GET")
        return HttpResponse(status=404)
    if request.method == "POST":
        logger.info("[" + str(datetime.datetime.now()) +
                    "] Received confirm_payment() callback from CirclePay")
        transaction_data = json.loads(request.body)
        logger.info(transaction_data)
        # query for transaction in ibet db
        try:
            matching_transaction = Transaction.objects.get(
                transaction_id=transaction_data["partner_tran_id"],
                amount=transaction_data["amount"],
            )
            logger.info("Found matching transaction!")
            if matching_transaction.order_id != '0':
                return JsonResponse({
                    "code":
                    "888",
                    "message":
                    "Callback rejected: Transaction already processed"
                })

            if transaction_data["status"] == '00':  # deposit successful
                matching_transaction.status = 0
                matching_transaction.remark = "Deposit successful!"
                successful = helpers.addOrWithdrawBalance(
                    matching_transaction.user_id, transaction_data["amount"],
                    "add")
                if not successful:
                    return JsonResponse({
                        "success": False,
                        "message": "Could not modify balance"
                    })

            if transaction_data["status"] == '01' or transaction_data[
                    "status"] == '04':  # deposit pending
                matching_transaction.status = 3
                matching_transaction.remark = "Deposit pending!"
            if transaction_data["status"] == '02':  # deposit canceled
                matching_transaction.status = 5
                matching_transaction.remark = "Deposit canceled!"
            if transaction_data["status"] == '03':  # deposit failed
                matching_transaction.status = 1
                matching_transaction.remark = "Deposit failed!"

            payment_method = matching_transaction.method + "_" + transaction_data[
                "method"]
            matching_transaction.order_id = transaction_data["tran_id"]
            matching_transaction.method = payment_method
            matching_transaction.arrive_time = timezone.datetime.strptime(
                transaction_data["time"], '%Y-%m-%d %H:%M:%S')
            matching_transaction.last_updated = timezone.now()
            matching_transaction.save()

            # update transaction record status
            return JsonResponse({
                "success": True,
                "message": "Received confirmation of payment"
            })
        except ObjectDoesNotExist as e:
            logger.critical(
                "FATAL__ERROR::CirclePay::Unable to confirm payment",
                exc_info=1,
                stack_info=1)
            return JsonResponse({
                "success":
                False,
                "message":
                "Could not find matching transaction"
            })
def confirm_payment(request):
    if request.method == "GET":
        logger.info(request.GET)
        logger.info("Hello, GET request received on payzod confirm_payment()")
        return HttpResponse(
            "You are at the endpoint for Payzod confirm payment")
        # query for transaction in ibet db
        # update transaction record status
    if request.method == "POST":
        logger.info("Hello, POST request received on payzod confirm_payment()")
        logger.info(request.POST)
        req = request.POST
        try:
            matching_transaction = Transaction.objects.get(
                transaction_id=req.get("ref_no"), amount=req.get("amount"))
            logger.info("Found matching transaction!")
            if matching_transaction.order_id != '0':
                return JsonResponse({
                    "responseCode":
                    "202",
                    "responseMesg":
                    "Transaction already exists"
                })

            # success
            if req.get("response_code") == "001":
                matching_transaction.status = 0
                matching_transaction.remark = req.get("response_msg")
                matching_transaction.order_id = req.get("transaction_no")
                matching_transaction.arrive_time = timezone.now()
                matching_transaction.last_updated = timezone.now()
                matching_transaction.save()
                logger.info("Finished updating transaction in DB!")

                logger.info("Updating user balance...")
                helpers.addOrWithdrawBalance(matching_transaction.user_id,
                                             req.get("amount"), "add")

                return JsonResponse({
                    "responseCode": "000",
                    "responseMesg": req.get("response_msg")
                })
            else:  # failure
                matching_transaction.status = 1
                matching_transaction.remark = req.get("response_msg")
                matching_transaction.order_id = req.get("transaction_no")
                matching_transaction.arrive_time = timezone.now()
                matching_transaction.last_updated = timezone.now()
                matching_transaction.save()
                logger.info("Finished updating transaction in DB!")

                return JsonResponse({
                    "responseCode": "888",
                    "responseMesg": req.get("response_msg")
                })

        except ObjectDoesNotExist as e:
            logger.critical(
                "FATAL__ERROR::Payzod::Payment confirmation failed",
                exc_info=1,
                stack_info=1)
            return JsonResponse(
                {"message": "Could not find matching transaction"})

    return HttpResponse("Invalid Request")
def transfer(request):
    """
    This method is called by PaymentIQ after a successfully processed transaction to credit (increase) or debit (decrease)
    a user's account balance. Note: The Operator Platform must always accept a transfer request, even if it results in
    a negative user balance because the payment transaction has already been processed by the payment provider.
    :param request: HTTP request containing user info & transaction data
        Example request:
        {
          "userId": "user_123",
          "txAmount": "100.50",
          "txAmountCy": "SEK",
          "txPspAmount": "12.50",
          "txPspAmountCy": "EUR",
          "fee": "0.50",
          "feeCy": "SEK",
          "txId": "25A0324",
          "txTypeId": "101",
          "txName": "CreditcardDeposit",
          "provider": "Neteller",
          "txRefId": "100019999A26720"
        }
    :return:
    """
    if request.method == "POST":
        post_data = json.loads(request.body)
        user = CustomUser.objects.get(username=post_data["userId"])
        try:
            if "deposit" in post_data["txName"].lower():
                matching_transaction = Transaction.objects.get(
                    user_id=user,
                    order_id=post_data["txId"],
                    amount=float(post_data["txAmount"]),
                    method=post_data["provider"] + ": " + post_data["txName"],
                    currency=cyConversion[post_data["txAmountCy"]],
                    transaction_type=0,  # 0 = DEPOSIT
                    channel=10,  # 10 = PaymentIQ
                )
                if matching_transaction.status != 2:
                    return JsonResponse({
                        "success": False,
                        "errCode": "200",  # custom error code (used internally by ibet)
                        "errMsg": "Transfer failed: duplicate Transfer action"  # message explaining error
                    })
                success = helpers.addOrWithdrawBalance(matching_transaction.user_id, matching_transaction.amount, "add")

                matching_transaction.status = 0
                matching_transaction.arrive_time = timezone.now()
                matching_transaction.last_updated = timezone.now()
                matching_transaction.remark = "Successfully deposited!"
                matching_transaction.save()

                result = {
                    "userId": post_data["userId"],
                    "success": success,
                    "txId": post_data["txId"],
                    "merchantTxId": matching_transaction.transaction_id,
                }
                return JsonResponse(result)

            elif "withdraw" in post_data["txName"].lower():
                matching_transaction = Transaction.objects.get(
                    user_id=user,
                    order_id=post_data["txId"],
                    amount=float(post_data["txAmount"]),
                    method=post_data["provider"] + ": " + post_data["txName"],
                    currency=cyConversion[post_data["txAmountCy"]],
                    transaction_type=0,  # 0 = DEPOSIT
                    channel=10,  # 10 = PaymentIQ
                )
                if matching_transaction.status != 2:
                    return JsonResponse({
                        "success": False,
                        "errCode": "200",  # custom error code (used internally by ibet)
                        "errMsg": "Transfer failed: duplicate Transfer action"  # message explaining error
                    })

                matching_transaction.status = 0
                matching_transaction.arrive_time = timezone.now()
                matching_transaction.last_updated = timezone.now()
                matching_transaction.remark = "Successfully withdrew!"
                matching_transaction.save()

                success = helpers.addOrWithdrawBalance(matching_transaction.user_id, matching_transaction.amount, "withdraw")
                if success:
                    result = {
                        "userId": post_data["userId"],
                        "success": success,
                        "txId": post_data["txId"],
                        "merchantTxId": trans_id,
                    }
                    return JsonResponse(result)
                else:
                    result = {
                        "userId": post_data["userId"],
                        "success": success,
                        "txId": post_data["txId"],
                        "merchantTxId": trans_id,
                        "errCode": "001",
                        "errMsg": "Authorize failed: not enough withdraw balance"
                    }
                    return JsonResponse(result)
        except ObjectDoesNotExist as e:
            logger.info(e)
            return JsonResponse({
                "userId": post_data["userId"],
                "success": False,
                "merchantTxId": trans_id,
                "errCode": "001",  # custom error code (used internally by ibet)
                "errMsg": "Transfer failed: Transaction does not exist"  # message explaining error
            })