def _order_requested(sender, order, **kwargs): # Check the status at PSP if status is still locked if order.status == StatusDefinition.LOCKED: order_payment = OrderPayment.get_latest_by_order(order) service = PaymentService(order_payment) service.check_payment_status()
def post_save(self, obj, created=False): try: service = PaymentService(obj) service.start_payment() except PaymentException as error: print error raise ParseError(detail=str(error))
def check_status(self, request, pk=None): order_payment = OrderPayment.objects.get(pk=pk) service = PaymentService(order_payment) service.check_payment_status() order_payment_url = reverse('admin:payments_orderpayment_change', args=(order_payment.id,)) response = HttpResponseRedirect(order_payment_url) return response
def get_redirect_url(self, *args, **kwargs): order_payment = get_object_or_404(OrderPayment, id=kwargs['order_payment_id']) service = PaymentService(order_payment) service.check_payment_status() return "{0}/orders/{1}/success".format(get_current_host(), order_payment.order.id)
def refund_project(tenant, project): with LocalTenant(tenant, clear_tenant=True): for donation in project.donations: service = PaymentService(donation.order.order_payment) try: service.refund_payment() except Exception: # Don't trip if one refund throws an error pass
def test_refund(self): """ User with can_pledge setting enabled is allowed to pledge """ service = PaymentService(order_payment=self.order_payment) service.refund_payment() # Check that the status propagated through to order self.assert_status(self.order_payment, StatusDefinition.REFUNDED)
def perform_update(self, serializer): serializer.save(amount=serializer.validated_data['order'].total) # store integration_data in non-persisted card_data field serializer.instance.card_data = serializer.validated_data[ 'integration_data'] service = PaymentService(serializer.instance) try: service.check_payment_status() except PaymentException as error: raise ParseError(detail=str(error))
def check_payment_statuses(order_payments, tenant): connection.set_tenant(tenant) with LocalTenant(tenant, clear_tenant=True): for order_payment in order_payments: service = PaymentService(order_payment) try: service.check_payment_status() except (PaymentException, TypeError): pass
def post(self, request, *args, **kwargs): payload = json.loads(request.body)['data'] transaction_reference = payload["collection_request"]["id"] payment = get_object_or_404( BeyonicPayment, transaction_reference=transaction_reference) service = PaymentService(payment.order_payment) try: service.check_payment_status() return HttpResponse('success') except PaymentException: return HttpResponse('success')
def setUp(self, mock_client): super(TestPaymentLogger, self).setUp() # Mock response to creating the payment at docdata instance = mock_client.return_value instance.create.return_value = {'order_key': 123, 'order_id': 123} self.order = OrderFactory.create(total=35) self.order_payment = OrderPaymentFactory.create( payment_method='docdataIdeal', order=self.order, integration_data={'default_pm': 'ideal'}) self.service = PaymentService(self.order_payment)
def check_status(self, request, pk=None): order_payment = OrderPayment.objects.get(pk=pk) service = PaymentService(order_payment) try: service.check_payment_status() except PaymentException as e: self.message_user(request, 'Error checking status {}'.format(e), level='WARNING') order_payment_url = reverse('admin:payments_orderpayment_change', args=(order_payment.id, )) response = HttpResponseRedirect(order_payment_url) return response
class TestPaymentLogger(BluebottleTestCase, FsmTestMixin): @patch('bluebottle.payments_docdata.adapters.gateway.DocdataClient') def setUp(self, mock_client): super(TestPaymentLogger, self).setUp() # Mock response to creating the payment at docdata instance = mock_client.return_value instance.create.return_value = {'order_key': 123, 'order_id': 123} self.order = OrderFactory.create(total=35) self.order_payment = OrderPaymentFactory.create( payment_method='docdataIdeal', order=self.order, integration_data={'default_pm': 'ideal'}) self.service = PaymentService(self.order_payment) def test_create_payment_create_log(self): """ This test will start the process of creating a new payment and tests if a log associated has been created """ # Get the number of logs in the table last_log = PaymentLogEntry.objects.all().order_by('-timestamp')[:1][0] # The latest entry should be for the payment associated with this test self.assertEqual(last_log.payment_id, self.order_payment.payment.id) @patch.object(DocdataPaymentAdapter, '_store_payment_transaction') @patch.object(DocdataPaymentAdapter, '_fetch_status') def test_check_authorized_status_logged(self, mock_fetch_status, mock_transaction): # Mock the status check with docdata mock_fetch_status.return_value = self.create_status_response( 'AUTHORIZED', totals={ 'totalAcquirerApproved': '1000', 'totalRegistered': '1000' }) self.service.check_payment_status() last_log = PaymentLogEntry.objects.all().order_by('-timestamp')[:1][0] # Check that the status change was logged self.assertEqual(last_log.payment_id, self.order_payment.payment.id) self.assertEqual( last_log.message, 'DocdataPayment object - a new payment status authorized') self.assertEqual(last_log.level, 'INFO')
def setUp(self, mock_client): super(PaymentsDocdataTestCase, self).setUp() # Mock response to creating the payment at docdata instance = mock_client.return_value instance.create.return_value = {'order_key': 123, 'order_id': 123} # Mock create payment patch.object(DocdataPaymentAdapter, 'create_payment', fake_create_payment) self.order = OrderFactory.create() self.order_payment = OrderPaymentFactory.create( order=self.order, payment_method='docdataIdeal', integration_data={'default_pm': 'ideal'}) self.service = PaymentService(order_payment=self.order_payment)
def test_abnormal_address_data(self, mock_client): # Mock response to creating the payment at docdata instance = mock_client.return_value instance.create.return_value = {'order_key': 123, 'order_id': 123} patch.object(DocdataPaymentAdapter, 'create_payment', fake_create_payment) user = BlueBottleUserFactory() CountryFactory(name='Netherlands', alpha2_code='NL') # Update user address with abnormal line1 user.address.line1 = '1a' user.address.save() self.order = OrderFactory.create(user=user) self.order_payment = OrderPaymentFactory.create( order=self.order, payment_method='docdataIdeal', integration_data={'default_pm': 'ideal'}) self.service = PaymentService(order_payment=self.order_payment) user_data = self.service.adapter.get_user_data() self.assertEqual(user_data['street'], 'Unknown')
def test_incomplete_userdata(self, mock_client): # Mock response to creating the payment at docdata instance = mock_client.return_value instance.create.return_value = {'order_key': 123, 'order_id': 123} patch.object(DocdataPaymentAdapter, 'create_payment', fake_create_payment) user = BlueBottleUserFactory() self.order = OrderFactory.create(user=user) self.order_payment = OrderPaymentFactory.create( order=self.order, payment_method='docdataIdeal', integration_data={'default_pm': 'ideal'}) self.service = PaymentService(order_payment=self.order_payment) user_data = self.service.adapter.get_user_data() self.assertEqual(user_data['id'], user.id) self.assertEqual(user_data['first_name'], user.first_name) self.assertEqual(user_data['last_name'], user.last_name) self.assertEqual(user_data['email'], user.email) self.assertEqual(user_data['street'], 'Unknown') self.assertEqual(user_data['house_number'], 'Unknown') self.assertEqual(user_data['postal_code'], 'Unknown') self.assertEqual(user_data['city'], 'Unknown') self.assertEqual(user_data['country'], 'NL') self.assertEqual(user_data['company'], '') self.assertEqual(user_data['kvk_number'], '') self.assertEqual(user_data['vat_number'], '') self.assertEqual(user_data['house_number_addition'], '') self.assertEqual(user_data['state'], '')
def perform_create(self, serializer): if self.request.user and self.request.user.is_authenticated(): serializer.save(user=self.request.user) if not serializer.instance.order.user: serializer.instance.order.user = self.request.user serializer.instance.order.save() else: serializer.save() try: service = PaymentService(serializer.instance) service.start_payment() except PaymentException as error: raise ParseError(detail=str(error))
def test_order_status_can_pledge(self): """ User with can_pledge setting enabled is allowed to pledge """ PaymentService(order_payment=self.order_payment) # Check that the status propagated through to order self.assert_status(self.order, StatusDefinition.PLEDGED)
def test_fixed_transaction_fee(self): """ Check that the flat 0.75 mockIdeal fee is set """ self.order_payment.payment_method = 'mockIdeal' self.order_payment.save() PaymentService(self.order_payment) self.assertEqual(self.order_payment.transaction_fee, 0.75)
def check_status_psp(self, order): try: order_payment = order.order_payments.all().order_by('-created')[0] except IndexError: raise Http404 service = PaymentService(order_payment) service.adapter.check_payment_status()
def get(self, request, **kwargs): merchant_order_id = kwargs["merchant_order_id"] try: # Try to load new style OrderPayment order_payment_id = merchant_order_id.split("-")[0] order_payment = OrderPayment.objects.get(pk=order_payment_id) except OrderPayment.DoesNotExist: # Try to load old style DocdataPayment. try: payment = DocdataPayment.objects.get(merchant_order_id=merchant_order_id) order_payment = payment.order_payment except DocdataPayment.DoesNotExist: raise Exception("Couldn't find Payment for merchant_order_id: {0}".format(merchant_order_id)) service = PaymentService(order_payment) service.check_payment_status() return HttpResponse("success")
def test_order_status_cannot_pledge(self): """ Normal user can not pledge """ self.user.can_pledge = False self.user.save() with self.assertRaises(PaymentException): self.service = PaymentService(order_payment=self.order_payment)
def setUp(self): super(PaymentsMockTestCase, self).setUp() self.init_projects() self.order = OrderFactory.create(total=35) self.order_payment = OrderPaymentFactory.create(order=self.order, payment_method='mock') self.service = PaymentService(order_payment=self.order_payment)
def setUp(self, mock_client_create): super(TestPaymentLogger, self).setUp() mock_client_create.return_value = {'order_key': 123, 'order_id': 123} self.order = OrderFactory.create(total=35) self.order_payment = OrderPaymentFactory.create(payment_method='docdataIdeal', order=self.order, integration_data={'default_pm': 'ideal'}) self.service = PaymentService(self.order_payment)
def test_relative_transaction_fee(self): """ Check that the 3.25% mockCard fee is calculated """ self.assertEqual(self.order.total.amount, 60) self.order_payment.payment_method = 'mockCard' self.order_payment.save() PaymentService(self.order_payment) self.assertEqual(self.order_payment.transaction_fee, 1.95)
def test_no_success_payment_status_check(self, mock_check_payment_status): self.order = OrderFactory.create(user=self.user1, total=15) self.order_payment = OrderPaymentFactory.create(order=self.order, payment_method='mock') self.service = PaymentService(order_payment=self.order_payment) self.client.get(reverse('order-manage-detail', kwargs={'pk': self.order.id}), token=self.user1_token) self.assertEqual(mock_check_payment_status.called, True)
def post(self, request, *args, **kwargs): payload = json.loads(request.body) try: payment = FlutterwaveMpesaPayment.objects.get( account_number=payload['billrefnumber']) except FlutterwaveMpesaPayment.DoesNotExist: raise Http404('No payment found with this billrefnumber.') service = PaymentService(payment.order_payment) service.adapter.update_mpesa(**payload) return HttpResponse(status=200, content={'success': 1})
def refund(self, request, pk=None): if not request.user.has_perm('payments.refund_orderpayment' ) or not properties.ENABLE_REFUNDS: return HttpResponseForbidden( 'Missing permission: payments.refund_orderpayment') order_payment = OrderPayment.objects.get(pk=pk) service = PaymentService(order_payment) service.refund_payment() self.message_user(request, 'Refund is requested.') order_payment_url = reverse('admin:payments_orderpayment_change', args=(order_payment.id, )) response = HttpResponseRedirect(order_payment_url) return response
class TestPaymentLogger(BluebottleTestCase, FsmTestMixin): @patch.object(DocdataClient, 'create') def setUp(self, mock_client_create): super(TestPaymentLogger, self).setUp() mock_client_create.return_value = {'order_key': 123, 'order_id': 123} self.order = OrderFactory.create(total=35) self.order_payment = OrderPaymentFactory.create( payment_method='docdataIdeal', order=self.order, integration_data={'default_pm': 'ideal'}) self.service = PaymentService(self.order_payment) def test_create_payment_create_log(self): """ This test will start the process of creating a new payment and tests if a log associated has been created """ # Get the number of logs in the table last_log = PaymentLogEntry.objects.all().order_by('-timestamp')[:1][0] # The latest entry should be for the payment associated with this test self.assertEqual(last_log.payment_id, self.order_payment.payment.id) @patch.object(DocdataPaymentAdapter, '_store_payment_transaction') @patch.object(DocdataPaymentAdapter, '_fetch_status') def test_check_authorized_status_logged(self, mock_fetch_status, mock_transaction): # Mock the status check with docdata mock_fetch_status.return_value = self.create_status_response( 'AUTHORIZED', totals={'totalAcquirerApproved': '1000', 'totalRegistered': '1000'} ) self.service.check_payment_status() last_log = PaymentLogEntry.objects.all().order_by('-timestamp')[:1][0] # Check that the status change was logged self.assertEqual(last_log.payment_id, self.order_payment.payment.id) self.assertEqual(last_log.message, 'DocdataPayment object - a new payment status authorized') self.assertEqual(last_log.level, 'INFO')
def setUp(self, mock_client_create): # Mock response to creating the payment at docdata mock_client_create.return_value = {'order_key': 123, 'order_id': 123} # Mock create payment mock_create_payment = patch.object(DocdataPaymentAdapter, 'create_payment', fake_create_payment) self.order = OrderFactory.create() self.order_payment = OrderPaymentFactory.create(order=self.order, payment_method='docdataIdeal', integration_data={'default_pm': 'ideal'}) self.service = PaymentService(order_payment=self.order_payment)
def test_changing_fee_when_changing_payment_method(self): """ Check that the fee changes when we change payment method """ self.order_payment.payment_method = 'mockIdeal' self.order_payment.save() PaymentService(self.order_payment) self.assertEqual(self.order_payment.transaction_fee, 0.75) self.order_payment.payment_method = 'mockCard' self.order_payment.save() self.assertEqual(self.order_payment.transaction_fee, 1.95)
def get(self, request, **kwargs): merchant_order_id = kwargs['merchant_order_id'] try: # Try to load new style OrderPayment order_payment_id = merchant_order_id.split('-')[0] order_payment = OrderPayment.objects.get(pk=order_payment_id) except OrderPayment.DoesNotExist: # Try to load old style DocdataPayment. try: payment = DocdataPayment.objects.get( merchant_order_id=merchant_order_id) order_payment = payment.order_payment except DocdataPayment.DoesNotExist: raise Exception( "Couldn't find Payment for merchant_order_id: {0}".format( merchant_order_id)) service = PaymentService(order_payment) service.check_payment_status() return HttpResponse('success')
def post(self, request, *args, **kwargs): status = request.POST.get('status', None) order_payment_id = request.POST.get('order_payment_id') try: order_payment = OrderPayment.objects.get(id=order_payment_id) except OrderPayment.DoesNotExist: raise Http404 service = PaymentService(order_payment) # We pass the MockPayment status and get back the status name of our OrderStatus definition service.adapter.set_order_payment_new_status(status) return HttpResponse('success')
def test_normal_userdata(self, mock_client): # Mock response to creating the payment at docdata instance = mock_client.return_value instance.create.return_value = {'order_key': 123, 'order_id': 123} patch.object(DocdataPaymentAdapter, 'create_payment', fake_create_payment) user = BlueBottleUserFactory() holland = CountryFactory(name='Netherlands', alpha2_code='NL') # Update user address user.address.line1 = 'Dam 1a' user.address.line2 = 'Bovenste bel' user.address.city = 'Amsterdam' user.address.postal_code = '1000AA' user.address.country = holland user.address.save() self.order = OrderFactory.create(user=user) self.order_payment = OrderPaymentFactory.create( order=self.order, payment_method='docdataIdeal', integration_data={'default_pm': 'ideal'}) self.service = PaymentService(order_payment=self.order_payment) user_data = self.service.adapter.get_user_data() self.assertEqual(user_data['id'], user.id) self.assertEqual(user_data['first_name'], user.first_name) self.assertEqual(user_data['last_name'], user.last_name) self.assertEqual(user_data['email'], user.email) self.assertEqual(user_data['street'], 'Dam') self.assertEqual(user_data['house_number'], '1a') self.assertEqual(user_data['postal_code'], '1000AA') self.assertEqual(user_data['city'], 'Amsterdam') self.assertEqual(user_data['country'], 'NL') self.assertEqual(user_data['company'], '') self.assertEqual(user_data['kvk_number'], '') self.assertEqual(user_data['vat_number'], '') self.assertEqual(user_data['house_number_addition'], '') self.assertEqual(user_data['state'], '')
def test_refund_pledged_payment(self): user = BlueBottleUserFactory.create(can_pledge=True) order = OrderFactory.create(user=user) order_payment = OrderPaymentFactory.create( order=order, user=user, payment_method='pledgeStandard') DonationFactory.create( project=self.project, order=order, amount=Money(100, 'EUR'), ) PaymentService(order_payment=order_payment) with mock.patch.object(DocdataPaymentAdapter, 'refund_payment', side_effect=self.mock_side_effect): refund_project(connection.tenant, self.project) order = Order.objects.get(pk=order.pk) self.assertEqual(order.status, 'cancelled')
def post(self, request, *args, **kwargs): success = 'success' in request.POST failure = 'failure' in request.POST authenticity = request.POST.get('authenticity') order_id = request.POST.get('order_id') try: payment = VitepayPayment.objects.get(order_id=order_id) order_payment = payment.order_payment except VitepayPayment.DoesNotExist: return HttpResponse('{"status": "0", "message": "Order not found."}') service = PaymentService(order_payment) # We pass the post params to the adapter to do the status update try: service.adapter.status_update(authenticity, success, failure) return HttpResponse('{"status": "1"}') except PaymentException as e: return HttpResponse('{"status": "0", "message": "%s"}' % e)
def reload_status(self, request, queryset): for order in queryset.all(): for order_payment in order.order_payments.all(): service = PaymentService(order_payment) service.check_payment_status()
class PaymentsDocdataTestCase(TestCase, FsmTestMixin): @patch.object(DocdataClient, 'create') def setUp(self, mock_client_create): # Mock response to creating the payment at docdata mock_client_create.return_value = {'order_key': 123, 'order_id': 123} # Mock create payment mock_create_payment = patch.object(DocdataPaymentAdapter, 'create_payment', fake_create_payment) self.order = OrderFactory.create() self.order_payment = OrderPaymentFactory.create(order=self.order, payment_method='docdataIdeal', integration_data={'default_pm': 'ideal'}) self.service = PaymentService(order_payment=self.order_payment) @patch.object(DocdataPaymentAdapter, '_store_payment_transaction') @patch.object(DocdataPaymentAdapter, '_fetch_status') def test_check_authorized_status(self, mock_fetch_status, mock_transaction): # Mock the status check with docdata mock_fetch_status.return_value = self.create_status_response('AUTHORIZED') self.service.check_payment_status() # Check that the status propagated through to order self.assert_status(self.order_payment.payment, StatusDefinition.AUTHORIZED) self.assert_status(self.order_payment, StatusDefinition.AUTHORIZED) self.assert_status(self.order, StatusDefinition.PENDING) @patch.object(DocdataPaymentAdapter, '_store_payment_transaction') @patch.object(DocdataPaymentAdapter, '_fetch_status') def test_no_payment_method_change(self, mock_fetch_status, mock_transaction): self.assertEquals(PaymentLogEntry.objects.count(), 2) # Mock the status check with docdata mock_fetch_status.return_value = self.create_status_response('AUTHORIZED') order = OrderFactory.create() order_payment = OrderPaymentFactory.create(order=order, payment_method='docdataCreditcard') docdata_payment = DocdataPaymentFactory.create(order_payment=order_payment, default_pm='mastercard', payment_cluster_id='1234', total_gross_amount=100) docdata_transaction = DocdataTransactionFactory.create(payment=docdata_payment, payment_method='VISA') c = Client() merchant_order_id = "{0}-1".format(order_payment.id) resp = c.get(reverse('docdata-payment-status-update', kwargs={'merchant_order_id': merchant_order_id})) self.assertEqual(resp.status_code, 200) self.assertEqual(resp.content, 'success') # Reload the order payment order_payment = OrderPayment.objects.get(id=order_payment.id) self.assertEqual(order_payment.payment_method, 'docdataCreditcard') @patch.object(DocdataPaymentAdapter, '_store_payment_transaction') @patch.object(DocdataPaymentAdapter, '_fetch_status') def test_payment_method_change(self, mock_fetch_status, mock_transaction): self.skipTest('Skipping test until we update it.') # Two payment log entries already exist: 2x 'a new payment status "started" ' self.assertEquals(PaymentLogEntry.objects.count(), 2) # Mock the status check with docdata mock_fetch_status.return_value = self.create_status_response('AUTHORIZED') order = OrderFactory.create() # Ensure that we use an existing payment_method or the adapter throws an exception order_payment = OrderPaymentFactory.create(order=order, payment_method='docdataPaypal') docdata_payment = DocdataPaymentFactory.create(order_payment=order_payment, default_pm='paypal', payment_cluster_id='1235', total_gross_amount=100) docdata_transaction = DocdataTransactionFactory.create(payment=docdata_payment, payment_method='VISA') c = Client() merchant_order_id = "{0}-1".format(order_payment.id) resp = c.get(reverse('docdata-payment-status-update', kwargs={'merchant_order_id': merchant_order_id})) self.assertEqual(resp.status_code, 200) self.assertEqual(resp.content, 'success') # # Reload the order payment order_payment = OrderPayment.objects.get(id=order_payment.id) self.assertEqual(order_payment.payment_method, 'docdataPaypal') # Check that all is logged correctly self.assertEquals(PaymentLogEntry.objects.filter(payment=docdata_payment).count(), 5) # The status changes triggers the # creation of more payment log entries log = PaymentLogEntry.objects.all()[0] self.assertEqual(log.message, "{0} - Payment method changed for payment with id {1} and order payment with id {2}.".format(docdata_payment, docdata_payment.id, docdata_payment.order_payment.id)) self.assertEqual(log.payment.id, docdata_payment.id) self.assertEqual(log.level, 'INFO') @patch.object(DocdataPaymentAdapter, '_store_payment_transaction') @patch.object(DocdataPaymentAdapter, '_fetch_status') def test_unknown_payment_method_change(self, mock_fetch_status, mock_transaction): self.skipTest('Skipping test until we update it.') # Two payment log entries already exist: 2x 'a new payment status "started" ' self.assertEquals(PaymentLogEntry.objects.count(), 2) # Mock the status check with docdata mock_fetch_status.return_value = self.create_status_response('AUTHORIZED') order = OrderFactory.create() # Ensure that we use an existing payment_method or the adapter throws an exception order_payment = OrderPaymentFactory.create(order=order, payment_method='docdataPaypal') docdata_payment = DocdataPaymentFactory.create(order_payment=order_payment, default_pm='paypal', payment_cluster_id='1236', total_gross_amount=100) docdata_transaction = DocdataTransactionFactory.create(payment=docdata_payment, payment_method='BLABLABLA') c = Client() merchant_order_id = "{0}-1".format(order_payment.id) resp = c.get(reverse('docdata-payment-status-update', kwargs={'merchant_order_id': merchant_order_id})) self.assertEqual(resp.status_code, 200) self.assertEqual(resp.content, 'success') # Reload the order payment order_payment = OrderPayment.objects.get(id=order_payment.id) self.assertEqual(order_payment.payment_method, 'docdataPaypal') # Check that all is logged correctly self.assertEquals(PaymentLogEntry.objects.filter(payment=docdata_payment).count(), 5) log = PaymentLogEntry.objects.all()[0] self.assertEqual(log.message, "{0} - Payment method '{1}' not found for payment with id {2} and order payment with id {3}.".format( docdata_payment, 'BLABLABLA', docdata_payment.id, docdata_payment.order_payment.id)) self.assertEqual(log.payment.id, docdata_payment.id) self.assertEqual(log.level, 'WARNING')
def batch_check_status(self, request, queryset): for order_payment in queryset: service = PaymentService(order_payment) service.check_payment_status()
class PaymentsDocdataTestCase(BluebottleTestCase, FsmTestMixin): @patch('bluebottle.payments_docdata.adapters.gateway.DocdataClient') def setUp(self, mock_client): super(PaymentsDocdataTestCase, self).setUp() # Mock response to creating the payment at docdata instance = mock_client.return_value instance.create.return_value = {'order_key': 123, 'order_id': 123} # Mock create payment patch.object(DocdataPaymentAdapter, 'create_payment', fake_create_payment) self.order = OrderFactory.create() self.order_payment = OrderPaymentFactory.create(order=self.order, payment_method='docdataIdeal', integration_data={ 'default_pm': 'ideal'}) self.service = PaymentService(order_payment=self.order_payment) @patch.object(DocdataPaymentAdapter, '_store_payment_transaction') @patch.object(DocdataPaymentAdapter, '_fetch_status') def test_check_authorized_status(self, mock_fetch_status, mock_transaction): # Mock the status check with docdata mock_fetch_status.return_value = self.create_status_response( 'AUTHORIZED', totals={'totalAcquirerApproved': '1000', 'totalRegistered': '1000'} ) self.service.check_payment_status() # Check that the status propagated through to order self.assert_status(self.order_payment.payment, StatusDefinition.AUTHORIZED) self.assert_status(self.order_payment, StatusDefinition.AUTHORIZED) self.assert_status(self.order, StatusDefinition.PENDING) mock_transaction.assert_called_once_with( mock_fetch_status.return_value.payment[0]) @patch.object(DocdataPaymentAdapter, '_fetch_status') def test_check_transaction(self, mock_fetch_status): # Mock the status check with docdata mock_fetch_status.return_value = self.create_status_response( 'AUTHORIZED', totals={'totalAcquirerApproved': '1000', 'totalRegistered': '1000'} ) self.service.check_payment_status() # Check that the status propagated through to order self.assert_status(self.order_payment.payment, StatusDefinition.AUTHORIZED) self.assert_status(self.order_payment, StatusDefinition.AUTHORIZED) self.assert_status(self.order, StatusDefinition.PENDING) transaction = Transaction.objects.get() self.assertEqual(transaction.authorization_amount, 1000) self.assertEqual(transaction.raw_response, str(mock_fetch_status.return_value.payment[0])) @patch.object(DocdataPaymentAdapter, '_store_payment_transaction') @patch.object(DocdataPaymentAdapter, '_fetch_status') def test_check_new(self, mock_fetch_status, mock_transaction): # Mock the status check with docdata mock_fetch_status.return_value = self.create_status_response('NEW') self.service.check_payment_status() # Check that the status propagated through to order self.assert_status(self.order_payment.payment, StatusDefinition.STARTED) self.assert_status(self.order_payment, StatusDefinition.STARTED) self.assert_status(self.order, StatusDefinition.LOCKED) @patch.object(DocdataPaymentAdapter, '_store_payment_transaction') @patch.object(DocdataPaymentAdapter, '_fetch_status') def test_check_redirected(self, mock_fetch_status, mock_transaction): # Mock the status check with docdata mock_fetch_status.return_value = self.create_status_response( 'REDIRECTED_FOR_AUTHORIZATION') self.service.check_payment_status() # Check that the status propagated through to order self.assert_status(self.order_payment.payment, StatusDefinition.STARTED) self.assert_status(self.order_payment, StatusDefinition.STARTED) self.assert_status(self.order, StatusDefinition.LOCKED) @patch.object(DocdataPaymentAdapter, '_store_payment_transaction') @patch.object(DocdataPaymentAdapter, '_fetch_status') def test_check_authenticated(self, mock_fetch_status, mock_transaction): # Mock the status check with docdata mock_fetch_status.return_value = self.create_status_response( 'AUTHENTICATED') self.service.check_payment_status() # Check that the status propagated through to order self.assert_status(self.order_payment.payment, StatusDefinition.STARTED) self.assert_status(self.order_payment, StatusDefinition.STARTED) self.assert_status(self.order, StatusDefinition.LOCKED) @patch.object(DocdataPaymentAdapter, '_store_payment_transaction') @patch.object(DocdataPaymentAdapter, '_fetch_status') def test_check_error(self, mock_fetch_status, mock_transaction): # Mock the status check with docdata mock_fetch_status.return_value = self.create_status_response( 'AUTHORIZATION_FAILED') self.service.check_payment_status() # Check that the status propagated through to order self.assert_status(self.order_payment.payment, StatusDefinition.FAILED) self.assert_status(self.order_payment, StatusDefinition.FAILED) self.assert_status(self.order, StatusDefinition.FAILED) @patch.object(DocdataPaymentAdapter, '_store_payment_transaction') @patch.object(DocdataPaymentAdapter, '_fetch_status') def test_check_settled(self, mock_fetch_status, mock_transaction): # Mock the status check with docdata mock_fetch_status.return_value = self.create_status_response( 'AUTHORIZED', totals={'totalCaptured': '1000', 'totalRegistered': '1000'} ) self.service.check_payment_status() # Check that the status propagated through to order self.assert_status(self.order_payment.payment, StatusDefinition.SETTLED) self.assert_status(self.order_payment, StatusDefinition.SETTLED) self.assert_status(self.order, StatusDefinition.SUCCESS) @patch.object(DocdataPaymentAdapter, '_store_payment_transaction') @patch.object(DocdataPaymentAdapter, '_fetch_status') def test_check_chargeback(self, mock_fetch_status, mock_transaction): # Mock the status check with docdata mock_fetch_status.return_value = self.create_status_response( 'AUTHORIZED', totals={'totalCaptured': '1000', 'totalRegistered': '1000'} ) self.service.check_payment_status() mock_fetch_status.return_value = self.create_status_response( 'AUTHORIZED', totals={'totalCaptured': '1000', 'totalRegistered': '1000', 'totalChargedback': '1000'} ) self.service.check_payment_status() # Check that the status propagated through to order self.assert_status(self.order_payment.payment, StatusDefinition.CHARGED_BACK) self.assert_status(self.order_payment, StatusDefinition.CHARGED_BACK) self.assert_status(self.order, StatusDefinition.FAILED) @patch.object(DocdataPaymentAdapter, '_store_payment_transaction') @patch.object(DocdataPaymentAdapter, '_fetch_status') def test_check_refund(self, mock_fetch_status, mock_transaction): # Mock the status check with docdata mock_fetch_status.return_value = self.create_status_response( 'AUTHORIZED', totals={'totalCaptured': '1000', 'totalRegistered': '1000'} ) self.service.check_payment_status() mock_fetch_status.return_value = self.create_status_response( 'AUTHORIZED', totals={'totalCaptured': '1000', 'totalRegistered': '1000', 'totalRefunded': '1000'} ) self.service.check_payment_status() # Check that the status propagated through to order self.assert_status(self.order_payment.payment, StatusDefinition.REFUNDED) self.assert_status(self.order_payment, StatusDefinition.REFUNDED) self.assert_status(self.order, StatusDefinition.FAILED) @patch.object(DocdataPaymentAdapter, '_store_payment_transaction') @patch.object(DocdataPaymentAdapter, '_fetch_status') def test_check_chargeback_refund(self, mock_fetch_status, mock_transaction): # Mock the status check with docdata mock_fetch_status.return_value = self.create_status_response( 'AUTHORIZED', totals={'totalCaptured': '1000', 'totalRegistered': '1000'} ) self.service.check_payment_status() mock_fetch_status.return_value = self.create_status_response( 'AUTHORIZED', totals={'totalCaptured': '1000', 'totalRegistered': '1000', 'totalRefunded': '500', 'totalChargedback': '500'} ) self.service.check_payment_status() # Check that the status propagated through to order self.assert_status(self.order_payment.payment, StatusDefinition.REFUNDED) self.assert_status(self.order_payment, StatusDefinition.REFUNDED) self.assert_status(self.order, StatusDefinition.FAILED) @patch.object(DocdataPaymentAdapter, '_store_payment_transaction') @patch.object(DocdataPaymentAdapter, '_fetch_status') def test_check_two_payments(self, mock_fetch_status, mock_transaction): # Mock the status check with docdata mock_fetch_status.return_value = self.create_status_response( 'AUTHORIZED', payments=[{ 'id': '1234', 'status': 'FAILED', 'amount': '1000', 'paymentMethod': 'MASTERCARD' }, { 'id': '12345', 'status': 'AUTHORIZED', 'amount': '1000', 'paymentMethod': 'MASTERCARD' }], totals={'totalCaptured': '1000', 'totalRegistered': '1000'} ) self.service.check_payment_status() # Check that the status propagated through to order self.assert_status(self.order_payment.payment, StatusDefinition.SETTLED) self.assert_status(self.order_payment, StatusDefinition.SETTLED) self.assert_status(self.order, StatusDefinition.SUCCESS) @patch.object(DocdataPaymentAdapter, '_store_payment_transaction') @patch.object(DocdataPaymentAdapter, '_fetch_status') def test_check_partially_settled(self, mock_fetch_status, mock_transaction): # Mock the status check with docdata mock_fetch_status.return_value = self.create_status_response( 'AUTHORIZED', totals={'totalCaptured': '1000', 'totalRegistered': '1000'} ) self.service.check_payment_status() mock_fetch_status.return_value = self.create_status_response( 'AUTHORIZED', totals={'totalCaptured': '500', 'totalRegistered': '1000'} ) self.service.check_payment_status() # Check that the status propagated through to order self.assert_status(self.order_payment.payment, StatusDefinition.UNKNOWN) self.assert_status(self.order_payment, StatusDefinition.UNKNOWN) self.assert_status(self.order, StatusDefinition.FAILED) @patch.object(DocdataPaymentAdapter, '_store_payment_transaction') @patch.object(DocdataPaymentAdapter, '_fetch_status') def test_check_failed_success_status(self, mock_fetch_status, mock_transaction): # Check the order can go from failed to success when the payment goes from # cancelled to paid. # Mock the status check with docdata mock_fetch_status.return_value = self.create_status_response('CANCELED') self.service.check_payment_status() # Check that the status propagated through to order self.assert_status(self.order_payment.payment, StatusDefinition.CANCELLED) self.assert_status(self.order_payment, StatusDefinition.CANCELLED) self.assert_status(self.order, StatusDefinition.FAILED) # Check that the status propagated through to order mock_fetch_status.return_value = self.create_status_response( 'AUTHORIZED', totals={'totalCaptured': '1000', 'totalRegistered': '1000'} ) self.service.check_payment_status() self.assert_status(self.order_payment, StatusDefinition.SETTLED) self.assert_status(self.order, StatusDefinition.SUCCESS) @patch.object(DocdataPaymentAdapter, '_store_payment_transaction') @patch.object(DocdataPaymentAdapter, '_fetch_status') def test_no_payment_method_change(self, mock_fetch_status, mock_transaction): self.assertEquals(PaymentLogEntry.objects.count(), 1) # Mock the status check with docdata mock_fetch_status.return_value = self.create_status_response( 'AUTHORIZED') order = OrderFactory.create() order_payment = OrderPaymentFactory.create( order=order, payment_method='docdataCreditcard') docdata_payment = DocdataPaymentFactory.create( order_payment=order_payment, default_pm='mastercard', payment_cluster_id='1234', total_gross_amount=100) DocdataTransactionFactory.create(payment=docdata_payment, payment_method='VISA') c = Client() merchant_order_id = "{0}-1".format(order_payment.id) resp = c.get(reverse('docdata-payment-status-update', kwargs={'merchant_order_id': merchant_order_id})) self.assertEqual(resp.status_code, 200) self.assertEqual(resp.content, 'success') # Reload the order payment order_payment = OrderPayment.objects.get(id=order_payment.id) self.assertEqual(order_payment.payment_method, 'docdataCreditcard') @patch.object(DocdataPaymentAdapter, '_store_payment_transaction') @patch.object(DocdataPaymentAdapter, '_fetch_status') def test_payment_method_change(self, mock_fetch_status, mock_transaction): self.skipTest('Skipping test until we update it.') # Two payment log entries already exist: 2x 'a new payment status "started" ' self.assertEquals(PaymentLogEntry.objects.count(), 2) # Mock the status check with docdata mock_fetch_status.return_value = self.create_status_response( 'AUTHORIZED') order = OrderFactory.create() # Ensure that we use an existing payment_method or the adapter throws an exception order_payment = OrderPaymentFactory.create( order=order, payment_method='docdataPaypal') docdata_payment = DocdataPaymentFactory.create( order_payment=order_payment, default_pm='paypal', payment_cluster_id='1235', total_gross_amount=100) DocdataTransactionFactory.create(payment=docdata_payment, payment_method='VISA') c = Client() merchant_order_id = "{0}-1".format(order_payment.id) resp = c.get(reverse('docdata-payment-status-update', kwargs={'merchant_order_id': merchant_order_id})) self.assertEqual(resp.status_code, 200) self.assertEqual(resp.content, 'success') # # Reload the order payment order_payment = OrderPayment.objects.get(id=order_payment.id) self.assertEqual(order_payment.payment_method, 'docdataPaypal') # Check that all is logged correctly self.assertEquals( PaymentLogEntry.objects.filter(payment=docdata_payment).count(), 5) # The status changes triggers the # creation of more payment log entries log = PaymentLogEntry.objects.all()[0] self.assertEqual(log.message, "{0} - Payment method changed for payment with id {1}" " and order payment with id {2}.".format( docdata_payment, docdata_payment.id, docdata_payment.order_payment.id)) self.assertEqual(log.payment.id, docdata_payment.id) self.assertEqual(log.level, 'INFO') @patch.object(DocdataPaymentAdapter, '_store_payment_transaction') @patch.object(DocdataPaymentAdapter, '_fetch_status') def test_unknown_payment_method_change(self, mock_fetch_status, mock_transaction): self.skipTest('Skipping test until we update it.') # Two payment log entries already exist: 2x 'a new payment status "started" ' self.assertEquals(PaymentLogEntry.objects.count(), 2) # Mock the status check with docdata mock_fetch_status.return_value = self.create_status_response( 'AUTHORIZED') order = OrderFactory.create() # Ensure that we use an existing payment_method or the adapter throws an exception order_payment = OrderPaymentFactory.create(order=order, payment_method='docdataPaypal') docdata_payment = DocdataPaymentFactory.create( order_payment=order_payment, default_pm='paypal', payment_cluster_id='1236', total_gross_amount=100) DocdataTransactionFactory.create(payment=docdata_payment, payment_method='BLABLABLA') c = Client() merchant_order_id = "{0}-1".format(order_payment.id) resp = c.get(reverse('docdata-payment-status-update', kwargs={'merchant_order_id': merchant_order_id})) self.assertEqual(resp.status_code, 200) self.assertEqual(resp.content, 'success') # Reload the order payment order_payment = OrderPayment.objects.get(id=order_payment.id) self.assertEqual(order_payment.payment_method, 'docdataPaypal') # Check that all is logged correctly self.assertEquals( PaymentLogEntry.objects.filter(payment=docdata_payment).count(), 5) log = PaymentLogEntry.objects.all()[0] self.assertEqual(log.message, "{0} - Payment method '{1}' not found for payment " "with id {2} and order payment with id {3}.".format( docdata_payment, 'BLABLABLA', docdata_payment.id, docdata_payment.order_payment.id)) self.assertEqual(log.payment.id, docdata_payment.id) self.assertEqual(log.level, 'WARNING')
def _process_monthly_order(monthly_order, send_email=False): if monthly_order.processed: logger.info( "Order for {0} already processed".format(monthly_order.user)) return False ten_days_ago = timezone.now() + timezone.timedelta(days=-10) recent_orders = Order.objects.filter(user=monthly_order.user, order_type='recurring', updated__gt=ten_days_ago) if recent_orders.count() > 0: message = "Skipping '{0}' recently processed a recurring order for {1}:".format( monthly_order, monthly_order.user) logger.warn(message) for closed_order in recent_orders.all(): logger.warn("Recent Order Number: {0}".format(closed_order.id)) # Set an error on this monthly order monthly_order.error = message monthly_order.save() return False order = Order.objects.create(status=StatusDefinition.LOCKED, user=monthly_order.user, order_type='recurring') order.save() logger.info( "Creating Order for {0} with {1} donations".format(monthly_order.user, monthly_order.donations.count())) for monthly_donation in monthly_order.donations.all(): donation = Donation.objects.create(amount=monthly_donation.amount, project=monthly_donation.project, order=order) donation.save() integration_data = {'account_name': monthly_order.name, 'account_city': monthly_order.city, 'iban': monthly_order.iban, 'bic': monthly_order.bic, 'agree': True} order_payment = OrderPayment(order=order, user=monthly_order.user, payment_method=PAYMENT_METHOD, integration_data=integration_data) order_payment.save() try: service = PaymentService(order_payment) service.start_payment() except PaymentException as e: error_message = "Problem starting payment. {0}".format(e) monthly_order.error = "{0}".format(e.message) monthly_order.save() logger.error(error_message) order_payment.delete() order.delete() return False logger.debug("Payment for '{0}' started.".format(monthly_order)) monthly_order.processed = True monthly_order.error = '' monthly_order.save() # Try to update status service.check_payment_status() # Send an email to the user. if send_email: mail_monthly_donation_processed_notification(monthly_order) return True