def notify_callback(request): payment_module = config_get_group('PAYMENT_SERMEPA') if payment_module.LIVE.value: log.debug("Live IPN on %s", payment_module.KEY.value) signature_code = payment_module.MERCHANT_SIGNATURE_CODE.value terminal = payment_module.MERCHANT_TERMINAL.value else: log.debug("Test IPN on %s", payment_module.KEY.value) signature_code = payment_module.MERCHANT_TEST_SIGNATURE_CODE.value terminal = payment_module.MERCHANT_TEST_TERMINAL.value data = request.POST log.debug("Transaction data: " + repr(data)) try: sig_data = "%s%s%s%s%s%s" % ( data['Ds_Amount'], data['Ds_Order'], data['Ds_MerchantCode'], data['Ds_Currency'], data['Ds_Response'], signature_code) sig_calc = sha1(sig_data).hexdigest() if sig_calc != data['Ds_Signature'].lower(): log.error("Invalid signature. Received '%s', calculated '%s'." % (data['Ds_Signature'], sig_calc)) return HttpResponseBadRequest("Checksum error") if data['Ds_MerchantCode'] != payment_module.MERCHANT_FUC.value: log.error("Invalid FUC code: %s" % data['Ds_MerchantCode']) return HttpResponseNotFound("Unknown FUC code") if int(data['Ds_Terminal']) != int(terminal): log.error("Invalid terminal number: %s" % data['Ds_Terminal']) return HttpResponseNotFound("Unknown terminal number") # TODO: fields Ds_Currency, Ds_SecurePayment may be worth checking xchg_order_id = data['Ds_Order'] try: order_id = xchg_order_id[:xchg_order_id.index('T')] except ValueError: log.error("Incompatible order ID: '%s'" % xchg_order_id) return HttpResponseNotFound("Order not found") try: order = Order.objects.get(id=order_id) except Order.DoesNotExist: log.error("Received data for nonexistent Order #%s" % order_id) return HttpResponseNotFound("Order not found") amount = Decimal(data['Ds_Amount']) / Decimal( '100') # is in cents, divide it if int(data['Ds_Response']) > 100: log.info("Response code is %s. Payment not accepted." % data['Ds_Response']) return HttpResponse() except KeyError: log.error("Received incomplete SERMEPA transaction data") return HttpResponseBadRequest("Incomplete data") # success order.add_status(status='New', notes=u"Paid through SERMEPA.") processor = get_processor_by_key('PAYMENT_SERMEPA') payment = processor.record_payment( order=order, amount=amount, transaction_id=data['Ds_AuthorisationCode']) # empty customer's carts for cart in Cart.objects.filter(customer=order.contact): cart.empty() return HttpResponse()
def one_step(request): payment_module = config_get_group('PAYMENT_AUTOSUCCESS') #First verify that the customer exists try: contact = Contact.objects.from_request(request, create=False) except Contact.DoesNotExist: url = lookup_url(payment_module, 'satchmo_checkout-step1') return HttpResponseRedirect(url) #Verify we still have items in the cart tempCart = Cart.objects.from_request(request) if tempCart.numItems == 0: template = lookup_template(payment_module, 'shop/checkout/empty_cart.html') return render(request, template) # Create a new order newOrder = Order(contact=contact) pay_ship_save(newOrder, tempCart, contact, shipping="", discount="", notes="") request.session['orderID'] = newOrder.id processor = get_processor_by_key('PAYMENT_AUTOSUCCESS') processor.prepare_data(newOrder) payment = processor.process(newOrder) tempCart.empty() success = lookup_url(payment_module, 'satchmo_checkout-success') return HttpResponseRedirect(success)
def one_step(request): # First verify that the customer exists try: contact = Contact.objects.from_request(request, create=False) except Contact.DoesNotExist: url = lookup_url(payment_config, "satchmo_checkout-step1") return HttpResponseRedirect(url) # Verify we still have items in the cart tempCart = Cart.objects.from_request(request) if tempCart.numItems == 0: template = lookup_template(payment_config, "shop/checkout/empty_cart.html") return render_to_response(template, context_instance=RequestContext(request)) # Create a new order newOrder = Order(contact=contact) pay_ship_save(newOrder, tempCart, contact, shipping="", discount="", notes="") request.session["orderID"] = newOrder.id processor = get_processor_by_key("PAYMENT_REWARD_POINTS") processor.prepare_data(newOrder) processor_result = processor.process(newOrder) if processor_result.success: tempCart.empty() return success(request) else: return failure(request)
def test_authorize_listener(self): """ Test making an authorization using DUMMY, then trigger its capture via the built-in listener, ``capture_on_ship_listener()``. This the lesser twin of ``test_authorize()``. """ order = make_test_order(self.US, '') self.assertEqual(order.balance, order.total) self.assertEqual(order.total, Decimal('125.00')) processor = utils.get_processor_by_key('PAYMENT_DUMMY') processor.create_pending_payment(order=order, amount=order.total) processor.prepare_data(order) result = processor.authorize_payment() self.assertEqual(result.success, True) self.assertEqual(order.authorized_remaining, Decimal('125.00')) # By changing the status, we trigger the satchmo_order_status_changed # signal. Additionally, the use the status 'Shipped', so that # capture_on_ship_listener() completes as expected. order.add_status('Shipped') self.assertEqual(order.authorized_remaining, Decimal('0')) self.assertEqual(order.balance, Decimal('0'))
def notify_neworder(request, data): """ Called when google reports a new order. Looks up the order from the private data and sets the status. Empties the cart. """ # get params from data private_data = data['shopping-cart.merchant-private-data'] order_id = re.search('satchmo-order id="(\d+)"', private_data).group(1) order = Order.objects.get(pk=order_id) payment_module = config_get_group('PAYMENT_GOOGLE') processor = get_processor_by_key('PAYMENT_GOOGLE') # record pending payment amount = data['order-total'] pending_payment = processor.create_pending_payment(order) # save transaction id so we can find this order later pending_payment.capture.transaction_id = data['google-order-number'] pending_payment.capture.save() # delete cart for cart in Cart.objects.filter(customer=order.contact): cart.empty() cart.delete() # set status order.add_status(status='New', notes=_("Received through Google Checkout."))
def test_authorize_multiple(self): """Test making multiple authorization using DUMMY.""" order = make_test_order(self.US, '') self.assertEqual(order.balance, order.total) self.assertEqual(order.total, Decimal('125.00')) processor = utils.get_processor_by_key('PAYMENT_DUMMY') processor.create_pending_payment(order=order, amount=Decimal('25.00')) self.assertEqual(order.pendingpayments.count(), 1) self.assertEqual(order.payments.count(), 1) pending = order.pendingpayments.all()[0] self.assertEqual(pending.amount, Decimal('25.00')) processor.prepare_data(order) result = processor.authorize_payment() self.assertEqual(result.success, True) #self.assertEqual(order.authorized_remaining, Decimal('25.00')) #self.assertEqual(order.balance, Decimal('100.00')) processor.create_pending_payment(order=order, amount=Decimal('100.00')) result = processor.authorize_payment() results = processor.capture_authorized_payments() self.assertEqual(len(results), 2) r1 = results[0] r2 = results[1] self.assertEqual(r1.success, True) self.assertEqual(r2.success, True) self.assertEqual(order.orderstatus_set.latest().status, 'New') self.assertEqual(order.balance, Decimal('0'))
def one_step(request): payment_module = config_get_group('PAYMENT_AUTOSUCCESS') #First verify that the customer exists try: contact = Contact.objects.from_request(request, create=False) except Contact.DoesNotExist: url = lookup_url(payment_module, 'satchmo_checkout-step1') return HttpResponseRedirect(url) #Verify we still have items in the cart tempCart = Cart.objects.from_request(request) if tempCart.numItems == 0: template = lookup_template(payment_module, 'shop/checkout/empty_cart.html') return render_to_response(template, context_instance=RequestContext(request)) # Create a new order newOrder = Order(contact=contact) pay_ship_save(newOrder, tempCart, contact, shipping="", discount="", notes="") request.session['orderID'] = newOrder.id processor = get_processor_by_key('PAYMENT_AUTOSUCCESS') processor.prepare_data(newOrder) payment = processor.process(newOrder) tempCart.empty() success = lookup_url(payment_module, 'satchmo_checkout-success') return HttpResponseRedirect(success)
def notify_callback(request): payment_module = config_get_group("PAYMENT_SERMEPA") if payment_module.LIVE.value: log.debug("Live IPN on %s", payment_module.KEY.value) signature_code = payment_module.MERCHANT_SIGNATURE_CODE.value terminal = payment_module.MERCHANT_TERMINAL.value else: log.debug("Test IPN on %s", payment_module.KEY.value) signature_code = payment_module.MERCHANT_TEST_SIGNATURE_CODE.value terminal = payment_module.MERCHANT_TEST_TERMINAL.value data = request.POST log.debug("Transaction data: " + repr(data)) try: sig_data = "%s%s%s%s%s%s" % ( data["Ds_Amount"], data["Ds_Order"], data["Ds_MerchantCode"], data["Ds_Currency"], data["Ds_Response"], signature_code, ) sig_calc = sha1(sig_data).hexdigest() if sig_calc != data["Ds_Signature"].lower(): log.error("Invalid signature. Received '%s', calculated '%s'." % (data["Ds_Signature"], sig_calc)) return HttpResponseBadRequest("Checksum error") if data["Ds_MerchantCode"] != payment_module.MERCHANT_FUC.value: log.error("Invalid FUC code: %s" % data["Ds_MerchantCode"]) return HttpResponseNotFound("Unknown FUC code") if int(data["Ds_Terminal"]) != int(terminal): log.error("Invalid terminal number: %s" % data["Ds_Terminal"]) return HttpResponseNotFound("Unknown terminal number") # TODO: fields Ds_Currency, Ds_SecurePayment may be worth checking xchg_order_id = data["Ds_Order"] try: order_id = xchg_order_id[: xchg_order_id.index("T")] except ValueError: log.error("Incompatible order ID: '%s'" % xchg_order_id) return HttpResponseNotFound("Order not found") try: order = Order.objects.get(id=order_id) except Order.DoesNotExist: log.error("Received data for nonexistent Order #%s" % order_id) return HttpResponseNotFound("Order not found") amount = Decimal(data["Ds_Amount"]) / Decimal("100") # is in cents, divide it if int(data["Ds_Response"]) > 100: log.info("Response code is %s. Payment not accepted." % data["Ds_Response"]) return HttpResponse() except KeyError: log.error("Received incomplete SERMEPA transaction data") return HttpResponseBadRequest("Incomplete data") # success order.add_status(status="New", notes=u"Paid through SERMEPA.") processor = get_processor_by_key("PAYMENT_SERMEPA") payment = processor.record_payment(order=order, amount=amount, transaction_id=data["Ds_AuthorisationCode"]) # empty customer's carts for cart in Cart.objects.filter(customer=order.contact): cart.empty() return HttpResponse()
def __init__(self, processor): self.payment_module = config_get_group('PAYMENT_%s' \ % processor.upper()) self.processor = get_processor_by_key('PAYMENT_%s' \ % processor.upper()) self.processor_configuration = config_get_group('PAYMENT_%s' \ % processor.upper()) self._postprocess_callables = []
def notify_chargeamount(request, data): """ This gets called when google sends a charge amount """ # find order from google id order = find_order(data) transaction_id = data['google-order-number'] processor = get_processor_by_key('PAYMENT_GOOGLE') processor.record_payment(amount=data['latest-charge-amount'], transaction_id=transaction_id, order=order)
def do_shipped(request, data): """ Called when you use the google checkout console to mark order has been shipped """ # find order from google id order = find_order(data) # process payment processor = get_processor_by_key('PAYMENT_GOOGLE') # setting status to billed (why does paypal set it to new?) order.add_status(status='Shipped', notes=_("Shipped through Google Checkout."))
def test_multiple_pending(self): """Test that creating a second pending payment deletes the first one.""" order = make_test_order(self.US, '') self.assertEqual(order.balance, order.total) self.assertEqual(order.total, Decimal('125.00')) processor = utils.get_processor_by_key('PAYMENT_DUMMY') pend1 = processor.create_pending_payment(order=order, amount=order.total) pend2 = processor.create_pending_payment(order=order, amount=order.total) self.assertEqual(order.pendingpayments.count(), 1) self.assertEqual(order.payments.count(), 1)
def apply_to_order(self, order): """Apply up to the full amount of the balance of this cert to the order. Returns new balance. """ amount = min(order.balance, self.balance) log.info('applying %s from giftcert #%i [%s] to order #%i [%s]', moneyfmt(amount), self.id, moneyfmt(self.balance), order.id, moneyfmt(order.balance)) processor = get_processor_by_key('PAYMENT_GIFTCERTIFICATE') orderpayment = processor.record_payment(order=order, amount=amount) self.orderpayment = orderpayment return self.use(amount, orderpayment=orderpayment)
def success(request): """ The order has been succesfully processed. This can be used to generate a receipt or some other confirmation """ try: order = Order.objects.from_request(request) except Order.DoesNotExist: bad_or_missing_message = 'Your order has already been processed.' return bad_or_missing(request, _(bad_or_missing_message)) amount = order.balance payment_module = config_get_group('PAYMENT_CREDITCARD') processor = get_processor_by_key('PAYMENT_CREDITCARD') account = request.GET.get('a', '') ecripted_string = request.GET.get('b', '') gpc = GestPayCrypt() gpc.SetShopLogin(account) gpc.SetShopTransactionID(str(order.id)) gpc.SetAmount("%.2f" % order.total) gpc.SetEncryptedString(str(ecripted_string)) # if gpc.Decrypt() == 1 --> Transaction is OK if gpc.Decrypt() == 1: processor.record_payment( order = order, amount = amount, transaction_id = gpc.GetBankTransactionID(), reason_code = gpc.GetAuthorizationCode() ) if order.notes is None: order.notes = "" else: order.notes += "\n\n" order.save() order.add_status( status = 'New', notes = "Pagato mediante BANCASELLA" ) # Make cart empty cart = Cart.objects.from_request(request) if cart: cart.empty() return render_to_response('shop/checkout/success_creditcard.html', {'order': order,}, context_instance=RequestContext(request))
def test_creditcard(self): """Test making a capture without authorization using CREDITCARD (Bancasella).""" order = make_test_order(self.IT, '') self.assertEqual(order.balance, order.total) self.assertEqual(order.total, Decimal('72.60')) processor = utils.get_processor_by_key('PAYMENT_CREDITCARD') processor.create_pending_payment(order=order, amount=order.total) self.assertEqual(order.pendingpayments.count(), 1) self.assertEqual(order.payments.count(), 1) pending = order.pendingpayments.all()[0] self.assertEqual(pending.amount, order.total) payment = order.payments.all()[0] self.assertEqual(payment.amount, Decimal('0')) self.assertEqual(pending.capture, payment) self.assertEqual(order.balance_paid, Decimal('0')) self.assertEqual(order.authorized_remaining, Decimal('0')) processor.prepare_data(order) result = processor.authorize_payment() self.assertEqual(result.success, False) processor.record_payment( order = order, amount = order.total, transaction_id = 'ABCDE12345', reason_code = '200' ) if order.notes is None: order.notes = "" else: order.notes += "\n\n" order.save() order.add_status( status = 'New', notes = "Pagato mediante BANCASELLA" ) self.assertEqual(order.authorized_remaining, Decimal('0')) self.assertEqual(order.orderstatus_set.latest().status, 'New') self.assertEqual(order.balance, Decimal('0'))
def success(request): payment_module = config_get_group('PAYMENT_PAYPOINT') live = payment_module.LIVE.value ctx = {} if live: log.debug('Live payment on %s', payment_module.KEY.value) else: log.debug('Test payment on %s', payment_module.KEY.value) try: data = request.GET log.debug('Paypoint callback data: ' + repr(data)) if not 'valid' in data or not data['valid'] == 'true': log.info('Payment failed %s' % data['message'] if 'message' in data else '') return render(request, 'shop/checkout/failure.html') order_id = data['trans_id'].lstrip('0') order = Order.objects.get(pk=order_id) if not OrderPayment.objects.filter(transaction_id=order_id).count(): order.add_status(status='New', notes=_('Paid with Paypoint')) processor = get_processor_by_key('PAYMENT_PAYPOINT') processor.record_payment( order=order, amount=data['amount'], transaction_id=order_id ) for item in order.orderitem_set.all(): product = item.product product.total_sold += item.quantity if config_value('PRODUCT', 'TRACK_INVENTORY'): product.items_in_stock -= item.quantity product.save() for cart in Cart.objects.filter(customer=order.contact): cart.empty() del request.session['orderID'] except: log.exception(''.join(format_exception(*exc_info()))) return render(request, 'shop/checkout/success.html', {'order': order})
def do_charged(request, data): """ Called when google sends a charged status update Note that the charged amount comes in a seperate call """ # find order from google id order = find_order(data) # Added to track total sold for each product for item in order.orderitem_set.all(): product = item.product product.total_sold += item.quantity product.items_in_stock -= item.quantity product.save() # process payment processor = get_processor_by_key('PAYMENT_GOOGLE') # setting status to billed (why does paypal set it to new?) order.add_status(status='Billed', notes=_("Paid through Google Checkout."))
def test_creditcard(self): """Test making a capture without authorization using CREDITCARD (Bancasella).""" order = make_test_order(self.IT, '') self.assertEqual(order.balance, order.total) self.assertEqual(order.total, Decimal('72.60')) processor = utils.get_processor_by_key('PAYMENT_CREDITCARD') processor.create_pending_payment(order=order, amount=order.total) self.assertEqual(order.pendingpayments.count(), 1) self.assertEqual(order.payments.count(), 1) pending = order.pendingpayments.all()[0] self.assertEqual(pending.amount, order.total) payment = order.payments.all()[0] self.assertEqual(payment.amount, Decimal('0')) self.assertEqual(pending.capture, payment) self.assertEqual(order.balance_paid, Decimal('0')) self.assertEqual(order.authorized_remaining, Decimal('0')) processor.prepare_data(order) result = processor.authorize_payment() self.assertEqual(result.success, False) processor.record_payment(order=order, amount=order.total, transaction_id='ABCDE12345', reason_code='200') if order.notes is None: order.notes = "" else: order.notes += "\n\n" order.save() order.add_status(status='New', notes="Pagato mediante BANCASELLA") self.assertEqual(order.authorized_remaining, Decimal('0')) self.assertEqual(order.orderstatus_set.latest().status, 'New') self.assertEqual(order.balance, Decimal('0'))
def test_capture(self): """Test making a capture without authorization using DUMMY.""" order = make_test_order(self.US, '') self.assertEqual(order.balance, order.total) self.assertEqual(order.total, Decimal('125.00')) processor = utils.get_processor_by_key('PAYMENT_DUMMY') processor.create_pending_payment(order=order, amount=order.total) processor.prepare_data(order) result = processor.capture_payment() self.assertEqual(result.success, True) pmt1 = result.payment self.assertEqual(type(pmt1), OrderPayment) self.assertEqual(order.authorized_remaining, Decimal('0.00')) self.assertEqual(result.success, True) payment = result.payment self.assertEqual(pmt1, payment) self.assertEqual(order.orderstatus_set.latest().status, 'New') self.assertEqual(order.balance, Decimal('0'))
def test_authorize(self): """Test making an authorization using DUMMY.""" order = make_test_order(self.US, '') self.assertEqual(order.balance, order.total) self.assertEqual(order.total, Decimal('125.00')) processor = utils.get_processor_by_key('PAYMENT_DUMMY') processor.create_pending_payment(order=order, amount=order.total) self.assertEqual(order.pendingpayments.count(), 1) self.assertEqual(order.payments.count(), 1) pending = order.pendingpayments.all()[0] self.assertEqual(pending.amount, order.total) payment = order.payments.all()[0] self.assertEqual(payment.amount, Decimal('0')) self.assertEqual(pending.capture, payment) self.assertEqual(order.balance_paid, Decimal('0')) self.assertEqual(order.authorized_remaining, Decimal('0')) processor.prepare_data(order) result = processor.authorize_payment() self.assertEqual(result.success, True) auth = result.payment self.assertEqual(type(auth), OrderAuthorization) self.assertEqual(order.authorized_remaining, Decimal('125.00')) result = processor.capture_authorized_payment(auth) self.assertEqual(result.success, True) payment = result.payment self.assertEqual(auth.capture, payment) order = Order.objects.get(pk=order.id) self.assertEqual(order.status, 'New') self.assertEqual(order.balance, Decimal('0'))
def test_authorize(self): """Test making an authorization using DUMMY.""" order = make_test_order(self.US, '') self.assertEqual(order.balance, order.total) self.assertEqual(order.total, Decimal('125.00')) processor = utils.get_processor_by_key('PAYMENT_DUMMY') processor.create_pending_payment(order=order, amount=order.total) self.assertEqual(order.pendingpayments.count(), 1) self.assertEqual(order.payments.count(), 1) pending = order.pendingpayments.all()[0] self.assertEqual(pending.amount, order.total) payment = order.payments.all()[0] self.assertEqual(payment.amount, Decimal('0')) self.assertEqual(pending.capture, payment) self.assertEqual(order.balance_paid, Decimal('0')) self.assertEqual(order.authorized_remaining, Decimal('0')) processor.prepare_data(order) result = processor.authorize_payment() self.assertEqual(result.success, True) auth = result.payment self.assertEqual(type(auth), OrderAuthorization) self.assertEqual(order.authorized_remaining, Decimal('125.00')) result = processor.capture_authorized_payment(auth) self.assertEqual(result.success, True) payment = result.payment self.assertEqual(auth.capture, payment) self.assertEqual(order.orderstatus_set.latest().status, 'New') self.assertEqual(order.balance, Decimal('0'))
def ipn(request): """ PagSeguro IPN (Instant Payment Notification) Cornfirms that payment has been completed and marks invoice as paid. """ payment_module = config_get_group('PAYMENT_PAGSEGURO') if payment_module.LIVE.value: log.debug("Live IPN on %s", payment_module.KEY.value) url = payment_module.IPN_URL.value account = payment_module.BUSINESS.value else: log.debug("Test IPN on %s", payment_module.KEY.value) url = payment_module.IPN_TEST_URL.value account = payment_module.BUSINESS_TEST.value PP_URL = url try: data = request.POST log.debug("PagSeguro IPN data: " + repr(data)) if not confirm_ipn_data(data, PP_URL, payment_module.TOKEN.value): return HttpResponseRedirect(urlresolvers.reverse('satchmo_checkout-success')) #return HttpResponse() if not 'StatusTransacao' in data or not data['StatusTransacao'] in ("Completo","Aprovado"): # We want to respond to anything that isn't a payment - but we won't insert into our database. log.info("Ignoring IPN data for non-completed payment.") return HttpResponse() try: invoice = int(data['Referencia']) except: invoice = -1 txn_id = data['TransacaoID'] if not OrderPayment.objects.filter(transaction_id=txn_id).count(): # If the payment hasn't already been processed: order = Order.objects.get(pk=invoice) # If we are testing set a shipping cost of 5,00 if not payment_module.LIVE.value: order.shipping_cost = Decimal('5.0') else: order.shipping_cost = Decimal(data['ValorFrete'].replace(",", ".")) order.recalculate_total(save=True) #order.save() try: order.ship_addressee = data['CliNome'] order.ship_street1 = data['CliEndereco'] order.ship_city = data['CliCidade'] order.ship_state = data['CliEstado'] order.ship_postal_code = data['CliCEP'] order.save() except Exception, e: log.warn("Error setting ship info: %s", str(e)) order.add_status(status='New', notes="Pago via PagSeguro") processor = get_processor_by_key('PAYMENT_PAGSEGURO') payment = processor.record_payment(order=order, amount=order.total, transaction_id=txn_id) if 'Anotacao' in data: if order.notes: notes = order.notes + "\n" else: notes = "" order.notes = notes + _('---Comment via PagSeguro IPN---') + u'\n' + data['Anotacao'] order.save() log.debug("Saved order notes from PagSeguro") # Run only if subscription products are installed if 'product.modules.subscription' in settings.INSTALLED_APPS: for item in order.orderitem_set.filter(product__subscriptionproduct__recurring=True, completed=False): item.completed = True item.save() for cart in Cart.objects.filter(customer=order.contact): cart.empty() except: log.exception(''.join(format_exception(*exc_info()))) return HttpResponse()
def psb_back_resp(request): """ Cornfirms that payment has been completed and marks invoice as paid.""" # When you debug this function, remember to use satchmo.log; # otherwise, you have no way of knowing whats going on. :) # payment method response codes psb_pay_methods_dict = { '01': 'PAYSBUY Account', '02': 'Credit Card', '03': 'PayPal', '04': 'American Express', '05': 'Online Banking', '06': 'Counter Service' } if not payment_module.LIVE.value or payment_module.EXTRA_LOGGING.value: custom_logger(request, '%s/psb_back_resp.log' % payment_module.PSB_LOGS_DIR) try: psb_back_data = request.POST psb_back_fee = psb_back_data['fee'] psb_back_amt = psb_back_data['amt'] psb_back_result = psb_back_data['result'] psb_back_txn_id = psb_back_data['apCode'] psb_back_method = psb_back_data['method'] try: psb_back_desc = psb_back_data['desc'] except: psb_back_desc = False try: psb_back_confirm_cs = psb_back_data['confirm_cs'] except: psb_back_confirm_cs = False psb_back_x_for = request.META.get('HTTP_X_FORWARDED_FOR') if psb_back_x_for: psb_back_ip = psb_back_x_for else: psb_back_ip = request.META.get('REMOTE_ADDR') success_code = psb_back_result[:2] invoice = psb_back_result[2:] success_code_array = { '00': 'Billed', '02': 'In Process', '99': 'Blocked', } log.debug("Paysbuy response data: " + repr(psb_back_data)) gross = float(psb_back_amt) # Update the order's status in the admin. if psb_back_confirm_cs: order = Order.objects.get(pk=invoice) order.add_status(status=success_code_array[success_code], notes=success_code_array[success_code]) order.save() if success_code == '99': if not psb_back_desc: temp_psb_back_desc = '' payment = processor.record_failure( amount=gross, transaction_id=psb_back_txn_id, reason_code=success_code, order=order, details=temp_psb_back_desc,) if not OrderPayment.objects.filter(transaction_id=psb_back_txn_id).count(): # If the payment hasn't already been processed: order = Order.objects.get(pk=invoice) order.add_status(status=success_code_array[success_code], notes=_("Processing through Paysbuy:")) processor = get_processor_by_key('PAYMENT_PAYSBUY') payment = processor.record_payment(order=order, amount=gross, transaction_id=psb_back_txn_id, reason_code=success_code,) if order.notes: admin_notes = order.notes + u'\n' else: admin_notes = '' if psb_back_desc: desc_placeholder = psb_back_desc + u'\n' else: desc_placeholder = '' order.notes = (admin_notes + _('---Comment via Paysbuy API---') + u'\n' + desc_placeholder + 'Paid by: ' + psb_pay_methods_dict[psb_back_method] + u'\n' + success_code_array[success_code] + u'\n' + u'\n' + 'PAYSBUY FEE: ' + psb_back_fee + u'\n' + u'\n' + 'PAYSBUY IP: ' + psb_back_ip ) order.save() log.debug("Saved order notes from Paysbuy") except: log.exception(''.join(format_exception(*exc_info()))) return HttpResponse()
def notify_callback(request): payment_module = config_get_group('PAYMENT_PAGOSONLINE') signature_code = payment_module.MERCHANT_SIGNATURE_CODE.value if payment_module.LIVE.value: log.debug("Live on %s", payment_module.KEY.value) else: log.debug("Test on %s", payment_module.KEY.value) data = request.POST try: sig_data = '~'.join( map(str,(signature_code, data['usuario_id'], data['ref_venta'], data['valor'], data['moneda'], data['estado_pol'] ))) sig_calc = md5(sig_data).hexdigest() if sig_calc != data['firma'].lower(): log.error("Invalid signature. Received '%s', calculated '%s'. sig_data %s" % (data['firma'], sig_calc, sig_data)) return HttpResponseBadRequest("Checksum error") xchg_order_id = data['ref_venta'] try: order_id = xchg_order_id[:xchg_order_id.index('T')] log.debug("Order ID = %s" % order_id) except ValueError: log.error("Incompatible order ID: '%s'" % xchg_order_id) return HttpResponseNotFound("Order not found") try: order = Order.objects.get(id=order_id) log.debug("Order object status = %s" % order.id ) except Order.DoesNotExist: log.error("Received data for nonexistent Order #%s" % order_id) return HttpResponseNotFound("Order not found") amount = data['valor'] log.debug("Amount Received in POST %s" % amount) trans_id = codigo[data['codigo_respuesta_pol']] except KeyError: log.error("Received incomplete PAGOSONLINE transaction data") return HttpResponseBadRequest("Incomplete data") # success if int(data['codigo_respuesta_pol']) == 1: order.add_status(status='New') processor = get_processor_by_key('PAYMENT_PAGOSONLINE') payment = processor.record_payment( order=order, amount=amount, transaction_id=trans_id) elif int(data['codigo_respuesta_pol']) == 15: order.add_status(status='In Process', notes=u"%s " % codigo[data['codigo_respuesta_pol']]) processor = get_processor_by_key('PAYMENT_PAGOSONLINE') payment = processor.record_payment( order=order, amount=amount, transaction_id=trans_id) elif int(data['codigo_respuesta_pol']) == 26: order.add_status(status='In Process', notes=u"%s " % codigo[data['codigo_respuesta_pol']]) processor = get_processor_by_key('PAYMENT_PAGOSONLINE') payment = processor.record_payment( order=order, amount=amount, transaction_id=trans_id) elif int(data['codigo_respuesta_pol']) == 24: order.add_status(status='Billed', notes=u"%s" % codigo[data['codigo_respuesta_pol']]) processor = get_processor_by_key('PAYMENT_PAGOSONLINE') payment = processor.record_payment( order=order, amount=amount, transaction_id=trans_id) elif int(data['codigo_respuesta_pol']) == 9994: processor = get_processor_by_key('PAYMENT_PAGOSONLINE') payment = processor.record_payment( order=order, amount=amount, transaction_id=trans_id) else: order.add_status(status='Cancelled', notes=u"%s" % trans_id) return HttpResponse()
def ipn(request): """PayPal IPN (Instant Payment Notification) Cornfirms that payment has been completed and marks invoice as paid. Adapted from IPN cgi script provided at http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/456361""" payment_module = config_get_group('PAYMENT_PAYPAL') if payment_module.LIVE.value: log.debug("Live IPN on %s", payment_module.KEY.value) url = payment_module.POST_URL.value account = payment_module.BUSINESS.value else: log.debug("Test IPN on %s", payment_module.KEY.value) url = payment_module.POST_TEST_URL.value account = payment_module.BUSINESS_TEST.value PP_URL = url try: data = request.POST log.debug("PayPal IPN data: " + repr(data)) if not confirm_ipn_data(request.raw_post_data, PP_URL): return HttpResponse() if not 'payment_status' in data or not data['payment_status'] == "Completed": # We want to respond to anything that isn't a payment - but we won't insert into our database. log.info("Ignoring IPN data for non-completed payment.") return HttpResponse() try: invoice = data['invoice'] except: invoice = data['item_number'] gross = data['mc_gross'] txn_id = data['txn_id'] if not OrderPayment.objects.filter(transaction_id=txn_id).count(): # If the payment hasn't already been processed: order = Order.objects.get(pk=invoice) order.add_status(status='New', notes=_("Paid through PayPal.")) processor = get_processor_by_key('PAYMENT_PAYPAL') payment = processor.record_payment(order=order, amount=gross, transaction_id=txn_id) if 'memo' in data: if order.notes: notes = order.notes + "\n" else: notes = "" order.notes = notes + _('---Comment via Paypal IPN---') + u'\n' + data['memo'] order.save() log.debug("Saved order notes from Paypal") # Run only if subscription products are installed if 'product.modules.subscription' in settings.INSTALLED_APPS: for item in order.orderitem_set.filter(product__subscriptionproduct__recurring=True, completed=False): item.completed = True item.save() # We no longer empty the cart here. We do it on checkout success. except: log.exception(''.join(format_exception(*exc_info()))) return HttpResponse()
def ipn(request): """PayPal IPN (Instant Payment Notification) Cornfirms that payment has been completed and marks invoice as paid. Adapted from IPN cgi script provided at http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/456361""" payment_module = config_get_group('PAYMENT_PAYPAL') if payment_module.LIVE.value: log.debug("Live IPN on %s", payment_module.KEY.value) url = payment_module.POST_URL.value account = payment_module.BUSINESS.value else: log.debug("Test IPN on %s", payment_module.KEY.value) url = payment_module.POST_TEST_URL.value account = payment_module.BUSINESS_TEST.value PP_URL = url try: data = request.POST log.debug("PayPal IPN data: " + repr(data)) if not confirm_ipn_data(data, PP_URL): return HttpResponse() if not 'payment_status' in data or not data[ 'payment_status'] == "Completed": # We want to respond to anything that isn't a payment - but we won't insert into our database. log.info("Ignoring IPN data for non-completed payment.") return HttpResponse() try: invoice = data['invoice'] except: invoice = data['item_number'] gross = data['mc_gross'] txn_id = data['txn_id'] if not OrderPayment.objects.filter(transaction_id=txn_id).count(): # If the payment hasn't already been processed: order = Order.objects.get(pk=invoice) order.add_status(status='New', notes=_("Paid through PayPal.")) processor = get_processor_by_key('PAYMENT_PAYPAL') payment = processor.record_payment(order=order, amount=gross, transaction_id=txn_id) if 'memo' in data: if order.notes: notes = order.notes + "\n" else: notes = "" order.notes = notes + _( '---Comment via Paypal IPN---') + u'\n' + data['memo'] order.save() log.debug("Saved order notes from Paypal") # Run only if subscription products are installed if 'product.modules.subscription' in settings.INSTALLED_APPS: for item in order.orderitem_set.filter( product__subscriptionproduct__recurring=True, completed=False): item.completed = True item.save() # We no longer empty the cart here. We do it on checkout success. except: log.exception(''.join(format_exception(*exc_info()))) return HttpResponse()
def psb_back_resp(request): """ Cornfirms that payment has been completed and marks invoice as paid.""" # When you debug this function, remember to use satchmo.log; # otherwise, you have no way of knowing whats going on. :) # payment method response codes psb_pay_methods_dict = { '01': 'PAYSBUY Account', '02': 'Credit Card', '03': 'PayPal', '04': 'American Express', '05': 'Online Banking', '06': 'Counter Service' } if not payment_module.LIVE.value or payment_module.EXTRA_LOGGING.value: custom_logger(request, '%s/psb_back_resp.log' % payment_module.PSB_LOGS_DIR) try: psb_back_data = request.POST psb_back_fee = psb_back_data['fee'] psb_back_amt = psb_back_data['amt'] psb_back_result = psb_back_data['result'] psb_back_txn_id = psb_back_data['apCode'] psb_back_method = psb_back_data['method'] try: psb_back_desc = psb_back_data['desc'] except: psb_back_desc = False try: psb_back_confirm_cs = psb_back_data['confirm_cs'] except: psb_back_confirm_cs = False psb_back_x_for = request.META.get('HTTP_X_FORWARDED_FOR') if psb_back_x_for: psb_back_ip = psb_back_x_for else: psb_back_ip = request.META.get('REMOTE_ADDR') success_code = psb_back_result[:2] invoice = psb_back_result[2:] success_code_array = { '00': 'Billed', '02': 'In Process', '99': 'Blocked', } log.debug("Paysbuy response data: " + repr(psb_back_data)) gross = float(psb_back_amt) # Update the order's status in the admin. if psb_back_confirm_cs: order = Order.objects.get(pk=invoice) order.add_status(status=success_code_array[success_code], notes=success_code_array[success_code]) order.save() if success_code == '99': if not psb_back_desc: temp_psb_back_desc = '' payment = processor.record_failure( amount=gross, transaction_id=psb_back_txn_id, reason_code=success_code, order=order, details=temp_psb_back_desc, ) if not OrderPayment.objects.filter( transaction_id=psb_back_txn_id).count(): # If the payment hasn't already been processed: order = Order.objects.get(pk=invoice) order.add_status(status=success_code_array[success_code], notes=_("Processing through Paysbuy:")) processor = get_processor_by_key('PAYMENT_PAYSBUY') payment = processor.record_payment( order=order, amount=gross, transaction_id=psb_back_txn_id, reason_code=success_code, ) if order.notes: admin_notes = order.notes + u'\n' else: admin_notes = '' if psb_back_desc: desc_placeholder = psb_back_desc + u'\n' else: desc_placeholder = '' order.notes = (admin_notes + _('---Comment via Paysbuy API---') + u'\n' + desc_placeholder + 'Paid by: ' + psb_pay_methods_dict[psb_back_method] + u'\n' + success_code_array[success_code] + u'\n' + u'\n' + 'PAYSBUY FEE: ' + psb_back_fee + u'\n' + u'\n' + 'PAYSBUY IP: ' + psb_back_ip) order.save() log.debug("Saved order notes from Paysbuy") except: log.exception(''.join(format_exception(*exc_info()))) return HttpResponse()
def cb(request): """ Callback view """ payment_module = config_get_group('PAYMENT_PAYBOX') # First thing : log infos given by callback payment_logger.info('Paybox (%s) %s %s'%(request.META['REMOTE_ADDR'], request.META['HTTP_HOST'], request.META['REQUEST_URI'] )) # Check ip source addr is correct if not request.META['REMOTE_ADDR'] in payment_module.PAYBOX_IP_ADDR.value: log.info('Bad source ip for cb') payment_logger.info('%s is not an authorized address !', request.META['REMOTE_ADDR']) return HttpResponse(status=403) data = request.GET # TODO : verifier la signature du message if not 'error' in data: # no return code, cancel ! log.info("Ignoring cb data for non-completed payment.") payment_logger.info("no error code") return HttpResponse(status=404) if not data['error'] == '00000': log.warn('Unsuccesful payment, error %s'%data['error']) payment_logger.warn('Unsuccesful payment, error %s'%data['error']) return HttpResponse(status=200) if not 'autho' in data: # We want to respond to anything that isn't a payment - but we won't insert into our database. log.info("Ignoring cb data for non-completed payment.") payment_logger.info("no authorization number") return HttpResponse(status=404) live=payment_module.LIVE.value if data['autho'] == "XXXXXX" and live: # live autho show wrong autho number ... log.error('Wrong autho number in live mode') payment_logger.error('Wrong autho number in live mode. What is going on ?') return HttpResponse(status=404) if data['autho'] == "XXXXXX": log.debug('Autho is XXXXXX, but we are in test mode') try: orderid=data['ref'] txn_id=data['idtrans'] amount=int(data['amount'])/Decimal(100) log.info("ref %s idtrans %s", orderid, txn_id) if not OrderPayment.objects.filter(transaction_id=txn_id).count(): # If the payment hasn't already been processed: order = Order.objects.get(pk=orderid) try: # set lang back activate(order.additionalorderinformation.lang) except: log.exception("Error while setting back language") order.add_status(status='New', notes="%s"%data['autho']) processor = get_processor_by_key('PAYMENT_PAYBOX') payment = processor.record_payment(order=order, amount=amount, transaction_id=txn_id) for cart in Cart.objects.filter(customer=order.contact): cart.empty() else: log.info("Payment alredy processed") except: traceback.print_exc() log.exception(''.join(format_exception(*exc_info()))) payment_logger.error( 'Exception during cb handler ! ') payment_logger.exception(''.join(format_exception(*exc_info()))) return HttpResponse()
def _verify_feedback(request, order, params): ''' Extract the payment feedback parameters from the request and update the order accordingly Returns a string in case of error, None otherwise ''' # Calculate the sha1 digest to make sure the parameters haven't been # tempered with payment_module = config_get_group('PAYMENT_CONCARDIS') passphrase = payment_module.SHA_OUT_PASSPHRASE.value digest = sha1_sign(params, passphrase) if digest and (digest != request.GET.get('SHASIGN')): log.info('Invalid SHASIGN for order %s, got "%s", expected: "%s"', order, digest, request.GET.get('SHASIGN')) return _('Unexpected parameters when processing request, please ' 'contact [email protected].') pay_id = params['PAYID'] amount = params['AMOUNT'] # If the payment hasn't already been processed: if not OrderPayment.objects.filter(transaction_id=pay_id).count(): processor = get_processor_by_key('PAYMENT_CONCARDIS') status, status_verbose = get_payment_status(params) kwargs = { 'order': order, 'amount': amount, 'transaction_id': pay_id, 'reason_code': status_verbose, } if status.startswith('9'): order.add_status(status='New', notes=_('Paid through Concardis')) processor.record_payment(**kwargs) elif status.startswith('5'): processor.record_authorization(**kwargs) else: processor.record_failure(**kwargs) # Save the payment parameters if order.notes: notes = order.notes + '\n' else: notes = '' notes += '--- Concardis payment parameters ---\n' for key, val in params.items(): notes += '{}: {}\n'.format(key, val) order.notes = notes order.save() # Added to track total sold for each product for item in order.orderitem_set.all(): product = item.product product.total_sold += item.quantity if config_value('PRODUCT', 'TRACK_INVENTORY'): product.items_in_stock -= item.quantity product.save() # Clean up cart now, the rest of the order will be cleaned on paypal IPN for cart in Cart.objects.filter(customer=order.contact): cart.empty()
def notify_callback(request): payment_module = config_get_group('PAYMENT_DOTPAY') if payment_module.LIVE.value: log.debug("Live IPN on %s", payment_module.KEY.value) signature_code = payment_module.MERCHANT_SIGNATURE_CODE.value terminal = payment_module.MERCHANT_TERMINAL.value else: log.debug("Test IPN on %s", payment_module.KEY.value) signature_code = payment_module.MERCHANT_TEST_SIGNATURE_CODE.value terminal = payment_module.MERCHANT_TEST_TERMINAL.value data = request.POST log.debug("Transaction data: " + repr(data)) try: # sig_data = "%s%s%s%s%s%s" % ( # data['Ds_Amount'], # data['Ds_Order'], # data['Ds_MerchantCode'], # data['Ds_Currency'], # data['Ds_Response'], # signature_code # ) # sig_calc = sha1(sig_data).hexdigest() # if sig_calc != data['Ds_Signature'].lower(): # log.error("Invalid signature. Received '%s', calculated '%s'." % (data['Ds_Signature'], sig_calc)) # return HttpResponseBadRequest("Checksum error") # if data['Ds_MerchantCode'] != payment_module.DOTPAY_DOTID.value: # log.error("Invalid FUC code: %s" % data['Ds_MerchantCode']) # return HttpResponseNotFound("Unknown FUC code") if int(data['t_status']) != 2: log.error("Payment not accepted number: %s" % data['t_status']) return HttpResponseNotFound("Platnosc odrzucona") # TODO: fields Ds_Currency, Ds_SecurePayment may be worth checking #xchg_order_id = data['control'] try: #order_id = xchg_order_id[:xchg_order_id.index('T')] order_id = data['control'] except ValueError: log.error("Incompatible order ID: '%s'" % order_id) return HttpResponseNotFound("Order not found") try: order = Order.objects.get(id=order_id) except Order.DoesNotExist: log.error("Received data for nonexistent Order #%s" % order_id) return HttpResponseNotFound("Order not found") amount = Decimal(data['amount']) # if int(data['Ds_Response']) > 100: # log.info("Response code is %s. Payment not accepted." % data['Ds_Response']) # return HttpResponse() except KeyError: log.error("Received incomplete DOTPAY transaction data") return HttpResponseBadRequest("Incomplete data") # success order.add_status(status='New', notes=u"Paid through DOTPAY.") processor = get_processor_by_key('PAYMENT_DOTPAY') payment = processor.record_payment( order=order, amount=amount, transaction_id=data['t_id']) # empty customer's carts for cart in Cart.objects.filter(customer=order.contact): cart.empty() return HttpResponse()
def order_status_update(request, order=None): ''' Updates the order status with ogone data. There are two ways of reaching this flow - payment redirect (user gets redirected through this flow) - ogone server side call (in case of problems ogone will post to our server with an updated version ofo the payment status) ''' log.debug('Attempting to update status information', extra={'request': request}) params = request.GET or request.POST if params.get('orderID', False): # Get Ogone settings from Satchmo ogone = Ogone(params, settings=get_ogone_settings()) # Make sure we check the data, and raise an exception if its wrong ogone.is_valid() # Fetch parsed params parsed_params = ogone.parse_params() log.debug('We have found a valid status feedback message.', extra={'data':{'parsed_params': parsed_params}}) # Get the order payment_id = ogone.get_order_id() try: ogone_payment = OrderPayment.objects.get(pk=payment_id) except OrderPayment.DoesNotExist: log.warning('Payment with payment_id=%d not found.', payment_id) return HttpResponse('') ogone_order = ogone_payment.order assert not order or (ogone_order.pk == order.pk), \ 'Ogone\'s order and my order are different objects.' log.debug('Found order %s for payment %s in processing feedback.', ogone_order, ogone_payment) # Do order processing and status comparisons here processor = get_processor_by_key('PAYMENT_OGONE') status_code = parsed_params['STATUS'] status_num = int(status_code) assert status_num, 'No status number.' log.debug('Recording status: %s (%s)', status_codes.STATUS_DESCRIPTIONS[status_num], status_code) # Prepare parameters for recorder params = {'amount': Decimal(parsed_params['AMOUNT']), 'order': ogone_order, 'transaction_id': parsed_params['PAYID'], 'reason_code': status_code } if status_num in (9, 91): # Payment was captured try: authorization = OrderAuthorization.objects.get(order=ogone_order, \ transaction_id=parsed_params['PAYID'], \ complete=False) params.update({'authorization': authorization}) except OrderAuthorization.DoesNotExist: pass processor.record_payment(**params) # Only change the status when it was empty or 'New' before. def _latest_status(order): try: curr_status = order.orderstatus_set.latest() return curr_status.status except OrderStatus.DoesNotExist: return '' if _latest_status(ogone_order) in ('', 'New'): ogone_order.add_status(status='Billed', notes=_("Payment accepted by Ogone.")) elif status_num in (5, 51): # Record authorization processor.record_authorization(**params) elif status_num in (4, 41): # We're still waiting ogone_order.add_status(status='New', notes=_("Payment is being processed by Ogone.")) else: # Record failure processor.record_failure(**params) if status_num in (1,): # Order cancelled ogone_order.add_status(status='Cancelled', notes=_("Order cancelled through Ogone.")) elif status_num in (2, 93): # Payment declined ogone_order.add_status(status='Blocked', notes=_("Payment declined by Ogone.")) elif status_num in (52, 92): log.warning('Payment of order %s (ID: %d) uncertain. Status: %s (%d)', ogone_order, ogone_order.pk, status_codes.STATUS_DESCRIPTIONS[status_num], status_num) else: log.warning('Uknown status code %d found for order %s.', status_num, ogone_order, exc_info=sys.exc_info() ) else: log.warning('This response does not look valid, orderID not found.', extra={'request': request}) # Return an empty HttpResponse return HttpResponse('')
def ipn(request): """PayPal IPN (Instant Payment Notification) Cornfirms that payment has been completed and marks invoice as paid. Adapted from IPN cgi script provided at http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/456361""" payment_module = config_get_group("PAYMENT_PAYPAL") if payment_module.LIVE.value: log.debug("Live IPN on %s", payment_module.KEY.value) url = payment_module.POST_URL.value account = payment_module.BUSINESS.value else: log.debug("Test IPN on %s", payment_module.KEY.value) url = payment_module.POST_TEST_URL.value account = payment_module.BUSINESS_TEST.value PP_URL = url try: data = request.POST log.debug("PayPal IPN data: " + repr(data)) if not confirm_ipn_data(data, PP_URL): return HttpResponse() if not "payment_status" in data or not data["payment_status"] == "Completed": # We want to respond to anything that isn't a payment - but we won't insert into our database. log.info("Ignoring IPN data for non-completed payment.") return HttpResponse() try: invoice = data["invoice"] except: invoice = data["item_number"] gross = data["mc_gross"] txn_id = data["txn_id"] if not OrderPayment.objects.filter(transaction_id=txn_id).count(): # If the payment hasn't already been processed: order = Order.objects.get(pk=invoice) order.add_status(status="New", notes=_("Paid through PayPal.")) processor = get_processor_by_key("PAYMENT_PAYPAL") payment = processor.record_payment(order=order, amount=gross, transaction_id=txn_id) if "memo" in data: if order.notes: notes = order.notes + "\n" else: notes = "" order.notes = notes + _("---Comment via Paypal IPN---") + u"\n" + data["memo"] order.save() log.debug("Saved order notes from Paypal") for item in order.orderitem_set.filter(product__subscriptionproduct__recurring=True, completed=False): item.completed = True item.save() for cart in Cart.objects.filter(customer=order.contact): cart.empty() except: log.exception("".join(format_exception(*exc_info()))) return HttpResponse()