예제 #1
0
def providers(request):
    donation = json.loads(request.body)
    _, contribution = save_donor_and_contribution(donation)

    stamp = uuid.uuid1().hex
    body = payments_request_body(stamp, contribution.sum,
                                 contribution.donor.email)
    body_json = json.dumps(body)
    payment_providers_response = requests.post(
        f"{PAYTRAIL_URL}/payments",
        headers={
            **signed_paytrail_headers(PAYTRAIL_ACCOUNT_ID, PAYTRAIL_ACCOUNT_SECRET, body_json),
            **{
                "Content-Type": "application/json; charset=utf-8"
            }
        },
        data=body_json)
    verify_response_headers(payment_providers_response.headers,
                            PAYTRAIL_ACCOUNT_SECRET,
                            payment_providers_response.text)

    payment_providers = json.loads(payment_providers_response.text)
    payment = Transaction(
        checkout_transaction_id=payment_providers["transactionId"],
        checkout_reference=payment_providers["reference"],
        status="new",
        contribution=contribution)
    logger.info("Creating new payment %", payment)
    payment.save()

    response = HttpResponse(content_type="application/json")
    response.write(payment_providers_response.text)
    return response
예제 #2
0
def make_payment(payment: Payment):
    transaction = Transaction(payment=payment, waiting=True)
    transaction.save()
    response = None

    try:
        if payment.payment_method == 'M':

            # save transaction phone number
            transaction_phone = TransactionPhone(
                transaction=transaction,
                phone_number=payment.order.billing_address.phone_number)
            transaction_phone.save()

            response = mobile_payments(
                phone_number=transaction_phone.phone_number,
                amount=payment.amount,
                transaction_id=str(transaction.id))

        elif payment.payment_method == 'C':
            # TODO
            pass
        else:
            raise Exception('Incorrect payment method')
    except Exception as e:
        transaction_failed(transaction, e)
        raise Exception(e)
    else:
        return save_transaction(transaction=transaction,
                                transaction_resp=response)
예제 #3
0
 def checkout(self, user, address, payment_method):
     order = self.user_cart(user)
     transaction = Transaction()
     transaction.transaction_status = 1
     transaction.transaction_id = str(uuid.uuid1())
     transaction.price = order.total_prices()
     transaction.order = order
     transaction.payment_method = payment_method
     transaction.save()
     order.status = PLACED_ORDER
     order.process_status = PENDING
     order.address = Address.objects.get(id=address)
     order.save()
     return order
예제 #4
0
def transaction_failed(transaction: Transaction, error_message=None):
    if error_message:
        if type(error_message) != str:
            try:
                error_message = str(error_message)
            except:
                print(error_message)
                error_message = None
    transaction.paid = False
    transaction.waiting = False
    transaction.failed = True
    transaction.error_message = error_message
    transaction.save()

    payment_failed(transaction.payment)
예제 #5
0
def transaction_failed(transaction: Transaction, error_message=None):
    """
    Save a failed Transaction
    :param transaction: Transaction object(model)
    :param error_message: Error message to be recorded
    """
    if error_message:
        if type(error_message) != str:
            try:
                error_message = str(error_message)
            except:
                error_message = None
    transaction.paid = False
    transaction.waiting = False
    transaction.failed = True
    transaction.error_message = error_message
    transaction.save()

    payment_failed(transaction.payment)
예제 #6
0
    def pay_bill(self, request, **kwargs):
        if request.user.is_authenticated():
            data = self.deserialize(request, request.body, format=request.META.get('CONTENT_TYPE', 'application/json'))
            bill = Bill.objects.get(id=data.get('bill_id'))
            bill.sender = request.user
            bill.save()

            transcation = Transaction()
            transcation.sender = request.user
            transcation.receiver = bill.store.vendor.user
            transcation.transaction_type = 2
            transcation.amount = bill.total_amount
            transcation.bill = bill
            transcation.store = bill.store
            transcation.transaction_state = 1

            mobile = Mobile()
            mobile.transaction = transcation
            try:
                bank = BankAccountDetails.objects.get(user=request.user, account_state=1)
                mobile.sender_account = bank
            except BankAccountDetails.DoesNotExist:

                return self.create_response(request, {"success":False,
                                                      "status_code":101,
                                                      "details": "No active bank accounts or please link atleast one bank account"})
            if int(bill.total_amount) > int(bank.balance):
                return self.create_response(request, {"success":False,
                                                      "status_code":201,
                                                      "details":"Insufficient Funds"})
            else:
                bank.balance = int(bank.balance)-int(bill.total_amount)
                bank1 = BankAccountDetails.objects.get(user=transcation.receiver, account_state=1)
                bank.save()
                bank1.balance = int(bank1.balance)+int(bill.total_amount)
                bank1.save()
            transcation.save()
            bank = BankAccountDetails.objects.get(user=transcation.receiver, account_state=1)
            mobile.receiver_account = bank
            mobile.save()
            bundle = TransactionResource().build_bundle(obj=transcation)
            bundle = TransactionResource().full_dehydrate(bundle=bundle)
            return self.create_response(request, {'success': True,
                                                  "status_code": 100,
                                                  'transaction': bundle})

        else:
            return self.create_response(request, {'success':False,
                                                  "details":"user not authenticated please login",
                                                  "status_code": 111})
예제 #7
0
    def send_money(self, request, **kwargs):
        if request.user.is_authenticated():
            data = self.deserialize(request, request.body, format=request.META.get('CONTENT_TYPE', 'application/json'))
            if data.get('send_money_type') == 0:
                mobile_number = data.get('mobile')
                amount = data.get('amount')
                message = data.get('message')
                transaction = Transaction()
                transaction.sender = request.user
                try:
                    receiver = User.objects.get(mobile=mobile_number)
                except User.DoesNotExist:
                    return self.create_response(request, {"success": False,
                                                          "status_code": 102,
                                                          'details':"given mobile number is not associated with any account"})
                transaction.receiver = receiver
                transaction.amount = amount
                transaction.text = message
                transaction.transaction_type = 2
                transaction.transaction_state = 1

                mobile = Mobile()
                mobile.transaction = transaction
                try:
                    bank = BankAccountDetails.objects.get(user=request.user, account_state=1)
                    mobile.sender_account = bank
                    a=transaction.amount
                    aa=bank.balance
                    s=int(aa)-int(a)
                    if s<0:
                        print(transaction.amount)
                        print(bank.balance)
                        return self.create_response(request, {"success": False,
                                                              "status_code": 201,
                                                              "details": "Insufficient Funds"})
                    else:
                        bank.balance = int(bank.balance)-int(transaction.amount)
                        bank.save()
                    bank = BankAccountDetails.objects.get(user=transaction.receiver, account_state=1)
                    mobile.receiver_account = bank
                    bank.balance = int(bank.balance)+int(transaction.amount)
                    bank.save()
                except BankAccountDetails.DoesNotExist:
                    return self.create_response(request, {"success": False,
                                                          "status_code": 101,
                                                          "details": "No active bank accounts or please link atleast one bank account"})
                transaction.save()
                mobile.save()
                bundle = TransactionResource().build_bundle(obj=transaction)
                bundle = TransactionResource().full_dehydrate(bundle=bundle)
                return self.create_response(request, {'success': True,
                                                      "status_code": 100,
                                                      'transaction': bundle})
            elif data.get('send_money_type') == 1:
                account_no = data.get('account_no')
                holder_name = data.get('holder_name')
                ifsc_code = data.get('ifsc_code')
                amount = data.get('amount')
                transaction = Transaction()
                transaction.sender = request.user
                transaction.amount = amount
                transaction.transaction_type = 0
                transaction.text = data.get('message')
                transaction.transaction_state = 1
                transaction.save()
                account_details = AccountDetails()
                account_details.transaction = transaction
                try:
                    account_details.sender_bank = BankAccountDetails.objects.get(user=request.user,account_state=BankAccountDetails.ACTIVE)
                    account_details.sender_bank.balance = int(account_details.sender_bank.balance)-int(amount)

                except BankAccountDetails.DoesNotExist:
                    return self.create_response(request, {"success": False,
                                                          "status_code": 101,
                                                          "details": "No active bank accounts or please link atleast one bank account"})
                account_details.holder_name = holder_name
                account_details.account_no = account_no
                account_details.ifsc_code = ifsc_code
                account_details.save()

                account_details.save()
                bundle = TransactionResource().build_bundle(obj=transaction)
                bundle = TransactionResource().full_dehydrate(bundle=bundle)
                return self.create_response(request, {'success': True,
                                                      "status_code": 100,
                                                      'transaction': bundle})
            else:
                return self.create_response(request, {'success': False,
                                                      "details": "service not found",
                                                      "error_code": 404})
        else:
            return self.create_response(request, {'success': False,
                                                  "details": "user not authenticated please login",
                                                  "error_code": 111})
예제 #8
0
def save_transaction(transaction: Transaction, transaction_resp):

    if type(transaction_resp) == dict and transaction_resp['status']:

        if transaction_resp['description']:
            transaction.description = transaction_resp['description']

        if transaction_resp['transactionId']:
            transaction.transaction_id = transaction_resp['transactionId']

        if transaction_resp['providerChannel']:
            transaction.provider_channel = transaction_resp['providerChannel']

        if transaction_resp['status'] == 'InvalidRequest':
            transaction.save()
            transaction_failed(
                transaction=transaction,
                error_message=
                'InvalidRequest: The request could not be accepted as one of the fields '
                'was invalid. The description field will contain more information.'
            )
            raise Exception('Transaction Failed: InvalidRequest')
        #
        elif transaction_resp['status'] == 'NotSupported':
            transaction.save()
            transaction_failed(
                transaction=transaction,
                error_message=
                'NotSupported: Checkout to the provided phone number is not supported.'
            )
            raise Exception('Transaction Failed: NotSupported')
        #
        elif transaction_resp['status'] == 'Failed':
            transaction.save()
            transaction_failed(transaction=transaction, error_message='Failed')
            raise Exception('Transaction Failed: Failed')
        #
        elif transaction_resp['status'] == 'PendingConfirmation':
            transaction.save()
            pass
        else:
            transaction.save()
            transaction_failed(transaction=transaction)
    else:
        transaction_failed(transaction=transaction,
                           error_message='No response')
        raise Exception('Transaction Failed')
예제 #9
0
def save_transaction(transaction: Transaction, transaction_resp):
    """
    Save the transaction response as a Transaction object to the db
    :param transaction: Transaction model object
    :param transaction_resp: Transaction respsonse from africastalking API
    """

    if type(transaction_resp) == dict and transaction_resp['status']:

        if transaction_resp['description']:
            transaction.description = transaction_resp['description']

        if transaction_resp['transactionId']:
            transaction.transaction_id = transaction_resp['transactionId']

        if transaction_resp['providerChannel']:
            transaction.provider_channel = transaction_resp['providerChannel']

        if transaction_resp['status'] == 'InvalidRequest':
            transaction.save()
            transaction_failed(
                transaction=transaction,
                error_message=
                'InvalidRequest: The request could not be accepted as one of the fields '
                'was invalid. The description field will contain more information.'
            )
            raise Exception('Transaction Failed: InvalidRequest')

        # Handle phone number not supported
        elif transaction_resp['status'] == 'NotSupported':
            # TODO: mark transaction phone number as invalid
            transaction.save()
            transaction_failed(
                transaction=transaction,
                error_message=
                'NotSupported: Checkout to the provided phone number is not supported.'
            )
            raise Exception('Transaction Failed: NotSupported')
        # Handle unknown fail
        elif transaction_resp['status'] == 'Failed':
            transaction.save()
            transaction_failed(transaction=transaction, error_message='Failed')
            raise Exception('Transaction Failed: Failed')
        # Successful transaction. Awaiting confirmation from user
        elif transaction_resp['status'] == 'PendingConfirmation':
            transaction.save()
            return
        else:
            transaction.save()
            transaction_failed(transaction=transaction)
    else:
        transaction_failed(transaction=transaction,
                           error_message='No response')
        raise Exception('Transaction Failed')