def update(self, request, reference): purchase = Purchase.objects.get(ref=reference) data = json.loads(request.raw_post_data) try: if data['method'] == 'paypal': charging_engine = ChargingEngine(purchase, payment_method='paypal') elif data['method'] == 'credit_card': # Get the payment info if 'credit_card' in data: credit_card = data['credit_card'] else: if purchase.organization_owned: credit_card = purchase.owner_organization.payment_info else: credit_card = purchase.customer.userprofile.payment_info charging_engine = ChargingEngine(purchase, payment_method='credit_card', credit_card=credit_card) charging_engine.resolve_charging() except: # Refresh the purchase info purchase = Purchase.objects.get(ref=reference) rollback(purchase) return build_response(request, 400, 'Invalid JSON content') return build_response(request, 200, 'OK')
def update(self, request, reference): purchase = Purchase.objects.get(ref=reference) data = json.loads(request.raw_post_data) try: if data['method'] == 'paypal': charging_engine = ChargingEngine(purchase, payment_method='paypal') elif data['method'] == 'credit_card': # Get the payment info if 'credit_card' in data: credit_card = data['credit_card'] else: if purchase.organization_owned: credit_card = purchase.owner_organization.payment_info else: credit_card = purchase.customer.userprofile.payment_info charging_engine = ChargingEngine(purchase, payment_method='credit_card', credit_card=credit_card) charging_engine.resolve_charging() except: # Refresh the purchase info purchase = Purchase.objects.get(ref=reference) rollback(purchase) return build_response(request, 400, 'Invalid JSON content') return build_response(request, 200, 'OK')
def _timeout_handler(self): connection = MongoClient() db = connection[settings.DATABASES['default']['NAME']] # Uses an atomic operation to get and set the _lock value in the purchase # document pre_value = db.wstore_purchase.find_and_modify( query={'_id': ObjectId(self._purchase.pk)}, update={'$set': {'_lock': True}} ) # If _lock not exists or is set to false means that this function has # acquired the resource if not '_lock' in pre_value or not pre_value['_lock']: # Only rollback if the state is pending if pre_value['state'] == 'pending': # Refresh the purchase purchase = Purchase.objects.get(pk=self._purchase.pk) rollback(purchase) db.wstore_purchase.find_and_modify( query={'_id': ObjectId(self._purchase.pk)}, update={'$set': {'_lock': False}} )
def _timeout_handler(self): db = get_database_connection() # Uses an atomic operation to get and set the _lock value in the purchase # document pre_value = db.wstore_purchase.find_and_modify( query={'_id': ObjectId(self._purchase.pk)}, update={'$set': { '_lock': True }}) # If _lock not exists or is set to false means that this function has # acquired the resource if '_lock' not in pre_value or not pre_value['_lock']: # Only rollback if the state is pending if pre_value['state'] == 'pending': # Refresh the purchase purchase = Purchase.objects.get(pk=self._purchase.pk) rollback(purchase) db.wstore_purchase.find_and_modify( query={'_id': ObjectId(self._purchase.pk)}, update={'$set': { '_lock': False }})
def test_rollback_not_paid_renovation(self): user = User.objects.get(pk='51070aba8e05cc2115f022f9') profile = UserProfile.objects.get(user=user) org = Organization.objects.get(pk='91000aba8e06ac2115f022f0') profile.organization = org profile.save() purchase = Purchase.objects.get(pk='61005aba8e05ac2115f02222') rollback(purchase) purchase = Purchase.objects.get(pk='61005aba8e05ac2115f02222') self.assertEqual(purchase.state, 'paid') contract = purchase.contract self.assertEqual(len(contract.charges), 1) self.assertEqual(contract.charges[0]['concept'], 'initial')
def test_rollback_not_paid_renovation(self): user = User.objects.get(pk='51070aba8e05cc2115f022f9') profile = UserProfile.objects.get(user=user) org = Organization.objects.get(pk='91000aba8e06ac2115f022f0') profile.organization = org profile.save() purchase = Purchase.objects.get(pk='61005aba8e05ac2115f02222') purchase_rollback.rollback(purchase) purchase = Purchase.objects.get(pk='61005aba8e05ac2115f02222') self.assertEqual(purchase.state, 'paid') contract = purchase.contract self.assertEqual(len(contract.charges), 1) self.assertEqual(contract.charges[0]['concept'], 'initial')
def test_rollback_not_paid_exeption(self): user = User.objects.get(pk='51070aba8e05cc2115f022f9') profile = UserProfile.objects.get(user=user) org = Organization.objects.get(pk='91000aba8e06ac2115f022f0') profile.organization = org profile.save() purchase = Purchase.objects.get(pk='61005aba8e05ac2115f022f0') rollback(purchase) # Check the final state of the database error = False msg = None try: Purchase.objects.get(pk='61005aba8e05ac2115f022f0') except Exception, e: error = True msg = e.message
def test_rollback_not_paid_exeption(self): user = User.objects.get(pk='51070aba8e05cc2115f022f9') profile = UserProfile.objects.get(user=user) org = Organization.objects.get(pk='91000aba8e06ac2115f022f0') profile.organization = org profile.save() purchase = Purchase.objects.get(pk='61005aba8e05ac2115f022f0') purchase_rollback.rollback(purchase) # Check the final state of the database error = False msg = None try: Purchase.objects.get(pk='61005aba8e05ac2115f022f0') except Exception, e: error = True msg = e.message
def read(self, request, reference): # In case the user cancels the payment is necessary to update # the database in order to avoid an inconsistent state try: purchase = Purchase.objects.get(pk=reference) # Check that the request user is authorized to end the payment if purchase.organization_owned: if request.user.userprofile.current_organization != purchase.owner_organization: raise Exception() else: if request.user != purchase.customer: raise Exception('') rollback(purchase) except: return build_response(request, 400, 'Invalid request') context = { 'title': 'Payment Canceled', 'message': 'Your payment has been canceled. If you want to acquire the offering purchase it again in WStore.' } return render(request, 'err_msg.html', context)
def read(self, request, reference): # In case the user cancels the payment is necessary to update # the database in order to avoid an inconsistent state try: purchase = Purchase.objects.get(pk=reference) # Check that the request user is authorized to end the payment if purchase.organization_owned: if request.user.userprofile.current_organization != purchase.owner_organization: raise Exception() else: if request.user != purchase.customer: raise Exception('') rollback(purchase) except: return build_response(request, 400, 'Invalid request') context = { 'title': 'Payment Canceled', 'message': 'Your payment has been canceled. If you want to acquire the offering purchase it again in WStore.' } return render(request, 'err_msg.html', context)
def read(self, request, reference): purchase = None try: token = request.GET.get('token') payer_id = request.GET.get('PayerID', '') db = get_database_connection() # Uses an atomic operation to get and set the _lock value in the purchase # document pre_value = db.wstore_purchase.find_and_modify( query={'_id': ObjectId(reference)}, update={'$set': {'_lock': True}} ) # If the value of _lock before setting it to true was true, means # that the time out function has acquired it previously so the # view ends if '_lock' in pre_value and pre_value['_lock']: raise Exception('') purchase = Purchase.objects.get(ref=reference) # Check that the request user is authorized to end the payment if request.user.userprofile.current_organization != purchase.owner_organization: raise Exception() # If the purchase state value is different from pending means that # the timeout function has completely ended before acquire the resource # so _lock is set to false and the view ends if purchase.state != 'pending': db.wstore_purchase.find_and_modify( query={'_id': ObjectId(reference)}, update={'$set': {'_lock': False}} ) raise Exception('') pending_info = purchase.contract.pending_payment # Get the payment client # Load payment client cln_str = settings.PAYMENT_CLIENT client_class = cln_str.split('.')[-1] client_package = cln_str.partition('.' + client_class)[0] payment_client = getattr(__import__(client_package, globals(), locals(), [client_class], -1), client_class) # build the payment client client = payment_client(purchase) client.end_redirection_payment(token, payer_id) charging_engine = ChargingEngine(purchase) accounting = None if 'accounting' in pending_info: accounting = pending_info['accounting'] charging_engine.end_charging(pending_info['price'], pending_info['concept'], pending_info['related_model'], accounting) except: # Rollback the purchase if existing if purchase is not None: rollback(purchase) context = { 'title': 'Payment Canceled', 'message': 'Your payment has been canceled. An error occurs or the timeout has finished, if you want to acquire the offering purchase it again in WStore.' } return render(request, 'err_msg.html', context) # Check if is the first payment if len(purchase.contract.charges) == 1: if purchase.organization_owned: org = purchase.owner_organization org.offerings_purchased.append(purchase.offering.pk) org.save() else: # Add the offering to the user profile user_profile = UserProfile.objects.get(user=purchase.customer) user_profile.offerings_purchased.append(purchase.offering.pk) user_profile.save() notify_provider(purchase) # _lock is set to false db.wstore_purchase.find_and_modify( query={'_id': reference}, update={'$set': {'_lock': False}} ) # Return the confirmation web page context = { 'title': 'Payment Confirmed', 'message': 'Your payment has been received. To download the resources and the invoice go to the offering details page.' } return render(request, 'err_msg.html', context)
def read(self, request, reference): purchase = None try: token = request.GET.get('token') payer_id = request.GET.get('PayerID', '') db = get_database_connection() # Uses an atomic operation to get and set the _lock value in the purchase # document pre_value = db.wstore_purchase.find_and_modify( query={'_id': ObjectId(reference)}, update={'$set': { '_lock': True }}) # If the value of _lock before setting it to true was true, means # that the time out function has acquired it previously so the # view ends if '_lock' in pre_value and pre_value['_lock']: raise Exception('') purchase = Purchase.objects.get(ref=reference) # Check that the request user is authorized to end the payment if request.user.userprofile.current_organization != purchase.owner_organization: raise Exception() # If the purchase state value is different from pending means that # the timeout function has completely ended before acquire the resource # so _lock is set to false and the view ends if purchase.state != 'pending': db.wstore_purchase.find_and_modify( query={'_id': ObjectId(reference)}, update={'$set': { '_lock': False }}) raise Exception('') pending_info = purchase.contract.pending_payment # Get the payment client # Load payment client cln_str = settings.PAYMENT_CLIENT client_class = cln_str.split('.')[-1] client_package = cln_str.partition('.' + client_class)[0] payment_client = getattr( __import__(client_package, globals(), locals(), [client_class], -1), client_class) # build the payment client client = payment_client(purchase) client.end_redirection_payment(token, payer_id) charging_engine = ChargingEngine(purchase) accounting = None if 'accounting' in pending_info: accounting = pending_info['accounting'] charging_engine.end_charging(pending_info['price'], pending_info['concept'], pending_info['related_model'], accounting) except: # Rollback the purchase if existing if purchase is not None: rollback(purchase) context = { 'title': 'Payment Canceled', 'message': 'Your payment has been canceled. An error occurs or the timeout has finished, if you want to acquire the offering purchase it again in WStore.' } return render(request, 'err_msg.html', context) # Check if is the first payment if len(purchase.contract.charges) == 1: if purchase.organization_owned: org = purchase.owner_organization org.offerings_purchased.append(purchase.offering.pk) org.save() else: # Add the offering to the user profile user_profile = UserProfile.objects.get(user=purchase.customer) user_profile.offerings_purchased.append(purchase.offering.pk) user_profile.save() notify_provider(purchase) # _lock is set to false db.wstore_purchase.find_and_modify(query={'_id': reference}, update={'$set': { '_lock': False }}) # Return the confirmation web page context = { 'title': 'Payment Confirmed', 'message': 'Your payment has been received. To download the resources and the invoice go to the offering details page.' } return render(request, 'err_msg.html', context)