def cancel(self, amount): ''' Cancel a total or partial amout of this transaction :type: amount: decimal.Decimal ''' cielo_request = self._get_cielo_request() response_transaction = cielo_request.cancelar(tid=self.tid, comercial=self._get_comercial(), valor=decimal_to_int_cents(amount)) self._update_from_transaction(response_transaction)
def cancel(self, amount): ''' Cancel a total or partial amout of this transaction :type: amount: decimal.Decimal ''' cielo_request = self._get_cielo_request() response_transaction = cielo_request.cancelar( tid=self.tid, comercial=self._get_comercial(), valor=decimal_to_int_cents(amount)) self._update_from_transaction(response_transaction)
def test_debit_auto_capture_with_auth(): """ Caso: - Transação com Cartão de Débito - Auto captura HABILITADO - Com URL para autenticação - 1 parcela """ initialize() c = SmartClient() default_product = get_default_product() basket_path = reverse("shuup:basket") add_to_basket_resp = c.post(basket_path, data={ "command": "add", "product_id": default_product.pk, "quantity": 10, "supplier": get_default_supplier().pk }) assert add_to_basket_resp.status_code < 400 ORDER_TOTAL = PRODUCT_PRICE * 10 # Create methods shipping_method = get_default_shipping_method() processor = get_payment_provider() assert isinstance(processor, CieloPaymentProcessor) # aumenta o limite máximo de parcelas para 4 cielo_config = get_cielo_config() cielo_config.max_installments = 4 cielo_config.save() payment_method = processor.create_service( CIELO_SERVICE_CREDIT, identifier="cielo_phase_cc", shop=get_default_shop(), name="credit card", enabled=True, tax_class=get_default_tax_class()) # Resolve paths addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"}) methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"}) payment_path = reverse("shuup:checkout", kwargs={"phase": "payment"}) transaction_path = reverse("shuup:cielo_make_transaction") confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"}) # Phase: Addresses addresses_soup = c.soup(addresses_path) inputs = fill_address_inputs(addresses_soup, with_company=False) response = c.post(addresses_path, data=inputs) assert response.status_code == 302, "Address phase should redirect forth" assert response.url.endswith(methods_path) # Phase: Methods assert Order.objects.filter(payment_method=payment_method).count() == 0 response = c.post(methods_path, data={ "payment_method": payment_method.pk, "shipping_method": shipping_method.pk }) assert response.status_code == 302, "Methods phase should redirect forth" assert response.url.endswith(confirm_path) response = c.get(confirm_path) assert response.status_code == 302, "Confirm should first redirect forth" assert response.url.endswith(payment_path) tid = uuid.uuid4().hex transacao = get_in_progress_transaction(1, decimal_to_int_cents(ORDER_TOTAL), CieloProduct.InstallmentCredit, CieloCardBrand.Visa, CC_VISA_4X_INFO['installments'], tid, return_url=None) transacao = get_approved_transaction(transacao) transacao = get_captured_transaction(transacao) with patch.object(CieloRequest, 'autorizar', return_value=transacao): with patch.object(CieloRequest, 'consultar', return_value=transacao): with patch.object(CieloRequest, 'capturar', return_value=transacao): # Phase: pay response = c.soup(payment_path) response = c.post(transaction_path, CC_VISA_4X_INFO) assert response.status_code == 200 json_content = json.loads(response.content.decode("utf-8")) assert json_content['redirect_url'].endswith( reverse("shuup:cielo_transaction_return", kwargs={"cielo_order_pk": 1})) cielo_transaction = CieloTransaction.objects.get(tid=tid) assert cielo_transaction.cc_brand == CC_VISA_4X_INFO[ 'cc_brand'] assert cielo_transaction.cc_holder == CC_VISA_4X_INFO[ 'cc_holder'] assert cielo_transaction.installments == CC_VISA_4X_INFO[ 'installments'] assert cielo_transaction.cc_product == CieloProduct.InstallmentCredit assert abs(cielo_transaction.total_value - ORDER_TOTAL) < 0.01 assert cielo_transaction.status.value == transacao.status response = c.post(json_content['redirect_url']) assert response.status_code == 302 assert response.url.endswith(confirm_path) # Phase: Confirm assert Order.objects.count() == 0 confirm_soup = c.soup(confirm_path) response = c.post(confirm_path, data=extract_form_fields(confirm_soup)) assert response.status_code == 302, "Confirm should redirect forth" order = Order.objects.filter( payment_method=payment_method).first() process_payment_path = reverse("shuup:order_process_payment", kwargs={ "pk": order.pk, "key": order.key }) process_payment_return_path = reverse( "shuup:order_process_payment_return", kwargs={ "pk": order.pk, "key": order.key }) order_complete_path = reverse("shuup:order_complete", kwargs={ "pk": order.pk, "key": order.key }) response = c.get(process_payment_path) assert response.status_code == 302, "Payment page should redirect forth" assert response.url.endswith(process_payment_return_path) # Check payment return response = c.get(process_payment_return_path) assert response.status_code == 302, "Payment return should redirect forth" assert response.url.endswith(order_complete_path) cielo_transaction = CieloTransaction.objects.get( order_transaction__order=order, tid=tid) assert cielo_transaction.status == CieloTransactionStatus.Captured assert cielo_transaction.authorization_nsu == str( transacao.autorizacao.nsu) assert cielo_transaction.authorization_lr == str( transacao.autorizacao.lr) assert cielo_transaction.authorization_date == iso8601.parse_date( transacao.autorizacao.data_hora) assert cielo_transaction.authentication_eci == transacao.autenticacao.eci assert cielo_transaction.authentication_date == iso8601.parse_date( transacao.autenticacao.data_hora) assert cielo_transaction.total_captured_value == ORDER_TOTAL assert cielo_transaction.total_reversed_value == Decimal() order.refresh_from_db() assert order.payment_data.get(CIELO_TRANSACTION_ID_KEY) assert order.payment_data.get(CIELO_ORDER_TRANSACTION_ID_KEY) assert order.payment_status == PaymentStatus.NOT_PAID
def test_credit_card_fail2(): """ Caso: - Transação com Cartão de Crédito - Auto captura desabilidato - Sem URL para autenticação - 4 parcelas - valor total do parcelado diferente do total do pedido """ initialize() c = SmartClient() default_product = get_default_product() basket_path = reverse("shuup:basket") c.post(basket_path, data={ "command": "add", "product_id": default_product.pk, "quantity": 10, "supplier": get_default_supplier().pk }) ORDER_TOTAL = PRODUCT_PRICE * 10 # Create methods shipping_method = get_default_shipping_method() processor = get_payment_provider() # aumenta o limite máximo de parcelas para 4 cielo_config = get_cielo_config() cielo_config.max_installments = 4 cielo_config.save() payment_method = processor.create_service( CIELO_SERVICE_CREDIT, identifier="cielo_phase_cc", shop=get_default_shop(), name="credit card", enabled=True, tax_class=get_default_tax_class()) # Resolve paths addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"}) methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"}) payment_path = reverse("shuup:checkout", kwargs={"phase": "payment"}) transaction_path = reverse("shuup:cielo_make_transaction") confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"}) # Phase: Addresses addresses_soup = c.soup(addresses_path) inputs = fill_address_inputs(addresses_soup, with_company=False) c.post(addresses_path, data=inputs) c.post(methods_path, data={ "payment_method": payment_method.pk, "shipping_method": shipping_method.pk }) c.get(confirm_path) tid = uuid.uuid4().hex transacao = get_in_progress_transaction(1, decimal_to_int_cents(ORDER_TOTAL), CieloProduct.InstallmentCredit, CieloCardBrand.Visa, CC_VISA_4X_INFO['installments'], tid, return_url=None) transacao = get_approved_transaction(transacao) with patch.object(CieloRequest, 'autorizar', return_value=transacao): with patch.object(CieloRequest, 'consultar', return_value=transacao): # Phase: pay c.soup(payment_path) response = c.post(transaction_path, CC_VISA_4X_INFO) json_content = json.loads(response.content.decode("utf-8")) response = c.post(json_content['redirect_url']) # ok, no redirect response = c.get(confirm_path) assert response.status_code == 200 # sabotagem: adiciona um item ao carrinho c.post(basket_path, data={ "command": "add", "product_id": default_product.pk, "quantity": 10, "supplier": get_default_supplier().pk }) # again, now with redirect response = c.get(confirm_path) assert response.status_code == 302 assert response.url.endswith(payment_path)
def test_credit_card_fail(): """ Caso: - Transação com Cartão de Crédito - Auto captura desabilidato - Sem URL para autenticação - 4 parcelas - dados do pagamento nao existem """ initialize() c = SmartClient() default_product = get_default_product() basket_path = reverse("shuup:basket") c.post(basket_path, data={ "command": "add", "product_id": default_product.pk, "quantity": 10, "supplier": get_default_supplier().pk }) ORDER_TOTAL = PRODUCT_PRICE * 10 # Create methods shipping_method = get_default_shipping_method() processor = get_payment_provider() # aumenta o limite máximo de parcelas para 4 cielo_config = get_cielo_config() cielo_config.max_installments = 4 cielo_config.save() payment_method = processor.create_service( CIELO_SERVICE_CREDIT, identifier="cielo_phase_cc", shop=get_default_shop(), name="credit card", enabled=True, tax_class=get_default_tax_class()) # Resolve paths addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"}) methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"}) payment_path = reverse("shuup:checkout", kwargs={"phase": "payment"}) transaction_path = reverse("shuup:cielo_make_transaction") confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"}) # Phase: Addresses addresses_soup = c.soup(addresses_path) inputs = fill_address_inputs(addresses_soup, with_company=False) c.post(addresses_path, data=inputs) c.post(methods_path, data={ "payment_method": payment_method.pk, "shipping_method": shipping_method.pk }) c.get(confirm_path) tid = uuid.uuid4().hex transacao = get_in_progress_transaction(1, decimal_to_int_cents(ORDER_TOTAL), CieloProduct.InstallmentCredit, CieloCardBrand.Visa, CC_VISA_4X_INFO['installments'], tid, return_url=None) transacao = get_approved_transaction(transacao) with patch.object(CieloRequest, 'autorizar', return_value=transacao): with patch.object(CieloRequest, 'consultar', return_value=transacao): # Phase: pay c.soup(payment_path) response = c.post(transaction_path, CC_VISA_4X_INFO) json_content = json.loads(response.content.decode("utf-8")) response = c.post(json_content['redirect_url']) confirm_soup = c.soup(confirm_path) response = c.post(confirm_path, data=extract_form_fields(confirm_soup)) order = Order.objects.filter(payment_method=payment_method).first() process_payment_path = reverse("shuup:order_process_payment", kwargs={ "pk": order.pk, "key": order.key }) # FORCE CLEAR ORDER PAYMENT DATA order.payment_data = {} order.save() response = c.get(process_payment_path) order.refresh_from_db() assert order.status == OrderStatus.objects.get_default_canceled()
def test_credit_card_success_3(): """ Caso: - Transação com Cartão de Crédito - Auto captura desabilidato - Sem URL para autenticação - 4 parcelas com juros """ initialize() c = SmartClient() default_product = get_default_product() basket_path = reverse("shuup:basket") c.post(basket_path, data={ "command": "add", "product_id": default_product.pk, "quantity": 10, "supplier": get_default_supplier().pk }) ORDER_TOTAL = PRODUCT_PRICE * 10 # Create methods shipping_method = get_default_shipping_method() processor = get_payment_provider() # aumenta o limite máximo de parcelas para 4 cielo_config = get_cielo_config() cielo_config.max_installments = 4 cielo_config.installments_without_interest = 1 cielo_config.interest_rate = Decimal(3.20) cielo_config.save() payment_method = processor.create_service( CIELO_SERVICE_CREDIT, identifier="cielo_phase_cc", shop=get_default_shop(), name="credit card", enabled=True, tax_class=get_default_tax_class()) # Resolve paths addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"}) methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"}) payment_path = reverse("shuup:checkout", kwargs={"phase": "payment"}) transaction_path = reverse("shuup:cielo_make_transaction") confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"}) addresses_soup = c.soup(addresses_path) inputs = fill_address_inputs(addresses_soup, with_company=False) c.post(addresses_path, data=inputs) c.post(methods_path, data={ "payment_method": payment_method.pk, "shipping_method": shipping_method.pk }) c.get(confirm_path) tid = uuid.uuid4().hex transacao = get_in_progress_transaction( numero=1, valor=decimal_to_int_cents(ORDER_TOTAL), produto=CieloProduct.Credit, bandeira=CieloCardBrand.Visa, parcelas=CC_VISA_1X_INFO['installments'], tid=tid, return_url=None) transacao = get_approved_transaction(transacao) with patch.object(CieloRequest, 'autorizar', return_value=transacao): with patch.object(CieloRequest, 'consultar', return_value=transacao): # Phase: pay c.soup(payment_path) response = c.post(transaction_path, CC_VISA_4X_INFO) assert response.status_code == 200 json_content = json.loads(response.content.decode("utf-8")) assert json_content['redirect_url'].endswith( reverse("shuup:cielo_transaction_return", kwargs={"cielo_order_pk": 1})) choices = InstallmentContext( ORDER_TOTAL, cielo_config).get_intallments_choices() cielo_transaction = CieloTransaction.objects.get(tid=tid) assert cielo_transaction.cc_product == CieloProduct.InstallmentCredit assert abs(cielo_transaction.total_value - choices[3][2]) <= Decimal(0.01) assert cielo_transaction.status.value == transacao.status response = c.post(json_content['redirect_url']) confirm_soup = c.soup(confirm_path) response = c.post(confirm_path, data=extract_form_fields(confirm_soup)) order = Order.objects.filter(payment_method=payment_method).first() assert abs(order.taxful_total_price.value - choices[3][2]) <= Decimal(0.01) process_payment_path = reverse("shuup:order_process_payment", kwargs={ "pk": order.pk, "key": order.key }) process_payment_return_path = reverse( "shuup:order_process_payment_return", kwargs={ "pk": order.pk, "key": order.key }) response = c.get(process_payment_path) response = c.get(process_payment_return_path) cielo_transaction = CieloTransaction.objects.get( order_transaction__order=order, tid=tid) order.refresh_from_db() assert order.payment_data.get(CIELO_TRANSACTION_ID_KEY) assert order.payment_data.get(CIELO_ORDER_TRANSACTION_ID_KEY) assert order.payment_status == PaymentStatus.NOT_PAID
def test_decimal_to_int_cents(): assert decimal_to_int_cents(32131) == 3213100 assert decimal_to_int_cents(13.321) == 1332 assert decimal_to_int_cents('32.41312312') == 3241 assert decimal_to_int_cents('0.0001') == 0 assert decimal_to_int_cents('0.01') == 1
def test_refresh_transaction_view(rf, admin_user): initialize() c = SmartClient() default_product = get_default_product() ORDER_TOTAL = PRODUCT_PRICE * 1 basket_path = reverse("shuup:basket") c.post(basket_path, data={ "command": "add", "product_id": default_product.pk, "quantity": 1, "supplier": get_default_supplier().pk }) # Create methods shipping_method = get_default_shipping_method() processor = get_payment_provider() payment_method = processor.create_service( CIELO_SERVICE_CREDIT, identifier="cielo_phase_cc", shop=get_default_shop(), name="credit card", enabled=True, tax_class=get_default_tax_class()) # Resolve paths addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"}) methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"}) payment_path = reverse("shuup:checkout", kwargs={"phase": "payment"}) confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"}) transaction_path = reverse("shuup:cielo_make_transaction") # Phase: Addresses addresses_soup = c.soup(addresses_path) inputs = fill_address_inputs(addresses_soup, with_company=False) c.post(addresses_path, data=inputs) c.post( methods_path, data={ "payment_method": payment_method.pk, "shipping_method": shipping_method.pk } ) c.get(confirm_path) tid = uuid.uuid4().hex transacao = get_in_progress_transaction(numero=1, valor=decimal_to_int_cents(ORDER_TOTAL), produto=CieloProduct.Credit, bandeira=CieloCardBrand.Visa, parcelas=CC_VISA_1X_INFO['installments'], tid=tid) transacao = get_approved_transaction(transacao) with patch.object(CieloRequest, 'autorizar', return_value=transacao): with patch.object(CieloRequest, 'consultar', return_value=transacao): c.soup(payment_path) c.post(transaction_path, CC_VISA_1X_INFO) confirm_soup = c.soup(confirm_path) c.post(confirm_path, data=extract_form_fields(confirm_soup)) order = Order.objects.filter(payment_method=payment_method).first() process_payment_path = reverse("shuup:order_process_payment", kwargs={"pk": order.pk, "key": order.key}) process_payment_return_path = reverse("shuup:order_process_payment_return",kwargs={"pk": order.pk, "key": order.key}) c.get(process_payment_path) c.get(process_payment_return_path) order.refresh_from_db() cielo_transaction = CieloTransaction.objects.get(order_transaction__order=order) # transacao nao capturada assert cielo_transaction.tid == tid assert cielo_transaction.total_captured.value == Decimal() view = load("shuup_cielo.admin.views.RefreshTransactionView").as_view() request = apply_request_middleware(rf.post("/"), user=admin_user) # request sem parametro - bad request response = view(request) assert response.status_code == 500 transacao = get_captured_transaction(transacao) with patch.object(CieloRequest, 'consultar', return_value=transacao): request = apply_request_middleware(rf.post("/", {"id":cielo_transaction.pk}), user=admin_user) response = view(request) assert response.status_code == 200 cielo_transaction.refresh_from_db() assert cielo_transaction.total_captured_value == order.taxful_total_price_value
def test_refresh_transaction_view(rf, admin_user): initialize() c = SmartClient() default_product = get_default_product() ORDER_TOTAL = PRODUCT_PRICE * 1 basket_path = reverse("shuup:basket") c.post(basket_path, data={ "command": "add", "product_id": default_product.pk, "quantity": 1, "supplier": get_default_supplier().pk }) # Create methods shipping_method = get_default_shipping_method() processor = get_payment_provider() payment_method = processor.create_service( CIELO_SERVICE_CREDIT, identifier="cielo_phase_cc", shop=get_default_shop(), name="credit card", enabled=True, tax_class=get_default_tax_class()) # Resolve paths addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"}) methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"}) payment_path = reverse("shuup:checkout", kwargs={"phase": "payment"}) confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"}) transaction_path = reverse("shuup:cielo_make_transaction") # Phase: Addresses addresses_soup = c.soup(addresses_path) inputs = fill_address_inputs(addresses_soup, with_company=False) c.post(addresses_path, data=inputs) c.post(methods_path, data={ "payment_method": payment_method.pk, "shipping_method": shipping_method.pk }) c.get(confirm_path) tid = uuid.uuid4().hex transacao = get_in_progress_transaction( numero=1, valor=decimal_to_int_cents(ORDER_TOTAL), produto=CieloProduct.Credit, bandeira=CieloCardBrand.Visa, parcelas=CC_VISA_1X_INFO['installments'], tid=tid) transacao = get_approved_transaction(transacao) with patch.object(CieloRequest, 'autorizar', return_value=transacao): with patch.object(CieloRequest, 'consultar', return_value=transacao): c.soup(payment_path) c.post(transaction_path, CC_VISA_1X_INFO) confirm_soup = c.soup(confirm_path) c.post(confirm_path, data=extract_form_fields(confirm_soup)) order = Order.objects.filter(payment_method=payment_method).first() process_payment_path = reverse("shuup:order_process_payment", kwargs={ "pk": order.pk, "key": order.key }) process_payment_return_path = reverse( "shuup:order_process_payment_return", kwargs={ "pk": order.pk, "key": order.key }) c.get(process_payment_path) c.get(process_payment_return_path) order.refresh_from_db() cielo_transaction = CieloTransaction.objects.get( order_transaction__order=order) # transacao nao capturada assert cielo_transaction.tid == tid assert cielo_transaction.total_captured.value == Decimal() view = load("shuup_cielo.admin.views.RefreshTransactionView").as_view() request = apply_request_middleware(rf.post("/"), user=admin_user) # request sem parametro - bad request response = view(request) assert response.status_code == 500 transacao = get_captured_transaction(transacao) with patch.object(CieloRequest, 'consultar', return_value=transacao): request = apply_request_middleware(rf.post( "/", {"id": cielo_transaction.pk}), user=admin_user) response = view(request) assert response.status_code == 200 cielo_transaction.refresh_from_db() assert cielo_transaction.total_captured_value == order.taxful_total_price_value
def test_credit_card_fail2(): """ Caso: - Transação com Cartão de Crédito - Auto captura desabilidato - Sem URL para autenticação - 4 parcelas - valor total do parcelado diferente do total do pedido """ initialize() c = SmartClient() default_product = get_default_product() basket_path = reverse("shuup:basket") c.post(basket_path, data={ "command": "add", "product_id": default_product.pk, "quantity": 10, "supplier": get_default_supplier().pk }) ORDER_TOTAL = PRODUCT_PRICE * 10 # Create methods shipping_method = get_default_shipping_method() processor = get_payment_provider() # aumenta o limite máximo de parcelas para 4 cielo_config = get_cielo_config() cielo_config.max_installments = 4 cielo_config.save() payment_method = processor.create_service( CIELO_SERVICE_CREDIT, identifier="cielo_phase_cc", shop=get_default_shop(), name="credit card", enabled=True, tax_class=get_default_tax_class() ) # Resolve paths addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"}) methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"}) payment_path = reverse("shuup:checkout", kwargs={"phase": "payment"}) transaction_path = reverse("shuup:cielo_make_transaction") confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"}) # Phase: Addresses addresses_soup = c.soup(addresses_path) inputs = fill_address_inputs(addresses_soup, with_company=False) c.post(addresses_path, data=inputs) c.post(methods_path, data={"payment_method": payment_method.pk, "shipping_method": shipping_method.pk}) c.get(confirm_path) tid = uuid.uuid4().hex transacao = get_in_progress_transaction(1, decimal_to_int_cents(ORDER_TOTAL), CieloProduct.InstallmentCredit, CieloCardBrand.Visa, CC_VISA_4X_INFO['installments'], tid, return_url=None) transacao = get_approved_transaction(transacao) with patch.object(CieloRequest, 'autorizar', return_value=transacao): with patch.object(CieloRequest, 'consultar', return_value=transacao): # Phase: pay c.soup(payment_path) response = c.post(transaction_path, CC_VISA_4X_INFO) json_content = json.loads(response.content.decode("utf-8")) response = c.post(json_content['redirect_url']) # ok, no redirect response = c.get(confirm_path) assert response.status_code == 200 # sabotagem: adiciona um item ao carrinho c.post(basket_path, data={ "command": "add", "product_id": default_product.pk, "quantity": 10, "supplier": get_default_supplier().pk }) # again, now with redirect response = c.get(confirm_path) assert response.status_code == 302 assert response.url.endswith(payment_path)
def test_order_flow_with_payment_phase_credit_card_success(): """ Caso: - Transação com Cartão de Crédito - Auto captura desabilidato - Com URL para autenticação - 1 parcela sem juros """ initialize() c = SmartClient() default_product = get_default_product() ORDER_TOTAL = PRODUCT_PRICE * 1 basket_path = reverse("shuup:basket") add_to_basket_resp = c.post(basket_path, data={ "command": "add", "product_id": default_product.pk, "quantity": 1, "supplier": get_default_supplier().pk }) assert add_to_basket_resp.status_code < 400 # Create methods shipping_method = get_default_shipping_method() processor = get_payment_provider() assert isinstance(processor, CieloPaymentProcessor) payment_method = processor.create_service( CIELO_SERVICE_CREDIT, identifier="cielo_phase_cc", shop=get_default_shop(), name="credit card", enabled=True, tax_class=get_default_tax_class()) # Resolve paths addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"}) methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"}) payment_path = reverse("shuup:checkout", kwargs={"phase": "payment"}) confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"}) transaction_path = reverse("shuup:cielo_make_transaction") # Phase: Addresses addresses_soup = c.soup(addresses_path) inputs = fill_address_inputs(addresses_soup, with_company=False) response = c.post(addresses_path, data=inputs) assert response.status_code == 302, "Address phase should redirect forth" assert response.url.endswith(methods_path) # Phase: Methods assert Order.objects.filter(payment_method=payment_method).count() == 0 response = c.post( methods_path, data={ "payment_method": payment_method.pk, "shipping_method": shipping_method.pk } ) assert response.status_code == 302, "Methods phase should redirect forth" assert response.url.endswith(confirm_path) response = c.get(confirm_path) assert response.status_code == 302, "Confirm should first redirect forth" assert response.url.endswith(payment_path) tid = uuid.uuid4().hex transacao = get_in_progress_transaction(numero=1, valor=decimal_to_int_cents(ORDER_TOTAL), produto=CieloProduct.Credit, bandeira=CieloCardBrand.Visa, parcelas=CC_VISA_1X_INFO['installments'], tid=tid) with patch.object(CieloRequest, 'autorizar', return_value=transacao): with patch.object(CieloRequest, 'consultar', return_value=transacao): # Phase: Payment response = c.soup(payment_path) response = c.post(transaction_path, CC_VISA_1X_INFO) assert response.status_code == 200 json_content = json.loads(response.content.decode("utf-8")) assert json_content['redirect_url'] == AUTH_URL cielo_transaction = CieloTransaction.objects.get(tid=tid) assert cielo_transaction.status == CieloTransactionStatus.InProgress assert cielo_transaction.cc_brand == CC_VISA_1X_INFO['cc_brand'] assert cielo_transaction.cc_holder == CC_VISA_1X_INFO['cc_holder'] assert cielo_transaction.installments == CC_VISA_1X_INFO['installments'] assert cielo_transaction.cc_product == CieloProduct.Credit assert abs(cielo_transaction.total_value - ORDER_TOTAL) < 0.01 assert cielo_transaction.status.value == transacao.status transacao = get_approved_transaction(transacao) with patch.object(CieloRequest, 'consultar', return_value=transacao): # Phase: Confirm Order assert Order.objects.count() == 0 confirm_soup = c.soup(confirm_path) response = c.post(confirm_path, data=extract_form_fields(confirm_soup)) assert response.status_code == 302, "Confirm should redirect forth" assert Order.objects.count() == 1 order = Order.objects.filter(payment_method=payment_method).first() process_payment_path = reverse("shuup:order_process_payment", kwargs={"pk": order.pk, "key": order.key}) process_payment_return_path = reverse("shuup:order_process_payment_return",kwargs={"pk": order.pk, "key": order.key}) order_complete_path = reverse("shuup:order_complete",kwargs={"pk": order.pk, "key": order.key}) # Visit payment page response = c.get(process_payment_path) assert response.status_code == 302, "Payment page should redirect forth" assert response.url.endswith(process_payment_return_path) # Check payment return response = c.get(process_payment_return_path) assert response.status_code == 302, "Payment return should redirect forth" assert response.url.endswith(order_complete_path) cielo_transaction = CieloTransaction.objects.get(order_transaction__order=order, tid=tid) assert cielo_transaction.status == CieloTransactionStatus.Authorized assert cielo_transaction.authorization_nsu == str(transacao.autorizacao.nsu) assert cielo_transaction.authorization_lr == str(transacao.autorizacao.lr) assert cielo_transaction.authorization_date == iso8601.parse_date(transacao.autorizacao.data_hora) assert cielo_transaction.authentication_eci == transacao.autenticacao.eci assert cielo_transaction.authentication_date == iso8601.parse_date(transacao.autenticacao.data_hora) assert cielo_transaction.total_captured.value == Decimal() assert cielo_transaction.total_reversed.value == Decimal() order.refresh_from_db() assert order.payment_data.get(CIELO_TRANSACTION_ID_KEY) assert order.payment_data.get(CIELO_ORDER_TRANSACTION_ID_KEY) assert order.payment_status == PaymentStatus.NOT_PAID
def test_credit_card_fail(): """ Caso: - Transação com Cartão de Crédito - Auto captura desabilidato - Sem URL para autenticação - 4 parcelas - dados do pagamento nao existem """ initialize() c = SmartClient() default_product = get_default_product() basket_path = reverse("shuup:basket") c.post(basket_path, data={ "command": "add", "product_id": default_product.pk, "quantity": 10, "supplier": get_default_supplier().pk }) ORDER_TOTAL = PRODUCT_PRICE * 10 # Create methods shipping_method = get_default_shipping_method() processor = get_payment_provider() # aumenta o limite máximo de parcelas para 4 cielo_config = get_cielo_config() cielo_config.max_installments = 4 cielo_config.save() payment_method = processor.create_service( CIELO_SERVICE_CREDIT, identifier="cielo_phase_cc", shop=get_default_shop(), name="credit card", enabled=True, tax_class=get_default_tax_class() ) # Resolve paths addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"}) methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"}) payment_path = reverse("shuup:checkout", kwargs={"phase": "payment"}) transaction_path = reverse("shuup:cielo_make_transaction") confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"}) # Phase: Addresses addresses_soup = c.soup(addresses_path) inputs = fill_address_inputs(addresses_soup, with_company=False) c.post(addresses_path, data=inputs) c.post(methods_path, data={"payment_method": payment_method.pk, "shipping_method": shipping_method.pk}) c.get(confirm_path) tid = uuid.uuid4().hex transacao = get_in_progress_transaction(1, decimal_to_int_cents(ORDER_TOTAL), CieloProduct.InstallmentCredit, CieloCardBrand.Visa, CC_VISA_4X_INFO['installments'], tid, return_url=None) transacao = get_approved_transaction(transacao) with patch.object(CieloRequest, 'autorizar', return_value=transacao): with patch.object(CieloRequest, 'consultar', return_value=transacao): # Phase: pay c.soup(payment_path) response = c.post(transaction_path, CC_VISA_4X_INFO) json_content = json.loads(response.content.decode("utf-8")) response = c.post(json_content['redirect_url']) confirm_soup = c.soup(confirm_path) response = c.post(confirm_path, data=extract_form_fields(confirm_soup)) order = Order.objects.filter(payment_method=payment_method).first() process_payment_path = reverse("shuup:order_process_payment", kwargs={"pk": order.pk, "key": order.key}) # FORCE CLEAR ORDER PAYMENT DATA order.payment_data = {} order.save() response = c.get(process_payment_path) order.refresh_from_db() assert order.status == OrderStatus.objects.get_default_canceled()
def test_credit_card_success_3(): """ Caso: - Transação com Cartão de Crédito - Auto captura desabilidato - Sem URL para autenticação - 4 parcelas com juros """ initialize() c = SmartClient() default_product = get_default_product() basket_path = reverse("shuup:basket") c.post(basket_path, data={ "command": "add", "product_id": default_product.pk, "quantity": 10, "supplier": get_default_supplier().pk }) ORDER_TOTAL = PRODUCT_PRICE * 10 # Create methods shipping_method = get_default_shipping_method() processor = get_payment_provider() # aumenta o limite máximo de parcelas para 4 cielo_config = get_cielo_config() cielo_config.max_installments = 4 cielo_config.installments_without_interest = 1 cielo_config.interest_rate = Decimal(3.20) cielo_config.save() payment_method = processor.create_service( CIELO_SERVICE_CREDIT, identifier="cielo_phase_cc", shop=get_default_shop(), name="credit card", enabled=True, tax_class=get_default_tax_class()) # Resolve paths addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"}) methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"}) payment_path = reverse("shuup:checkout", kwargs={"phase": "payment"}) transaction_path = reverse("shuup:cielo_make_transaction") confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"}) addresses_soup = c.soup(addresses_path) inputs = fill_address_inputs(addresses_soup, with_company=False) c.post(addresses_path, data=inputs) c.post(methods_path,data={"payment_method": payment_method.pk,"shipping_method": shipping_method.pk}) c.get(confirm_path) tid = uuid.uuid4().hex transacao = get_in_progress_transaction(numero=1, valor=decimal_to_int_cents(ORDER_TOTAL), produto=CieloProduct.Credit, bandeira=CieloCardBrand.Visa, parcelas=CC_VISA_1X_INFO['installments'], tid=tid, return_url=None) transacao = get_approved_transaction(transacao) with patch.object(CieloRequest, 'autorizar', return_value=transacao): with patch.object(CieloRequest, 'consultar', return_value=transacao): # Phase: pay c.soup(payment_path) response = c.post(transaction_path, CC_VISA_4X_INFO) assert response.status_code == 200 json_content = json.loads(response.content.decode("utf-8")) assert json_content['redirect_url'].endswith(reverse("shuup:cielo_transaction_return", kwargs={"cielo_order_pk": 1})) choices = InstallmentContext(ORDER_TOTAL, cielo_config).get_intallments_choices() cielo_transaction = CieloTransaction.objects.get(tid=tid) assert cielo_transaction.cc_product == CieloProduct.InstallmentCredit assert abs(cielo_transaction.total_value - choices[3][2]) <= Decimal(0.01) assert cielo_transaction.status.value == transacao.status response = c.post(json_content['redirect_url']) confirm_soup = c.soup(confirm_path) response = c.post(confirm_path, data=extract_form_fields(confirm_soup)) order = Order.objects.filter(payment_method=payment_method).first() assert abs(order.taxful_total_price.value - choices[3][2]) <= Decimal(0.01) process_payment_path = reverse("shuup:order_process_payment", kwargs={"pk": order.pk, "key": order.key}) process_payment_return_path = reverse("shuup:order_process_payment_return",kwargs={"pk": order.pk, "key": order.key}) response = c.get(process_payment_path) response = c.get(process_payment_return_path) cielo_transaction = CieloTransaction.objects.get(order_transaction__order=order, tid=tid) order.refresh_from_db() assert order.payment_data.get(CIELO_TRANSACTION_ID_KEY) assert order.payment_data.get(CIELO_ORDER_TRANSACTION_ID_KEY) assert order.payment_status == PaymentStatus.NOT_PAID
def form_valid(self, form): # verifica se existe alguma transação pendente na sessão # se sim, cancela a autorização antiga para fazer uma nova if self.request.cielo.transaction: try: self.request.cielo.transaction.safe_cancel(self.request.cielo.transaction.total_value) except: logger.exception(_("Failed to cancel old Cielo transaction")) # populate the basket with all the checkout stuff _configure_basket(self.request) order_total = self.request.basket.taxful_total_price.value service = self.request.basket.payment_method.choice_identifier cc_info = form.cleaned_data transaction_total = order_total interest_amount = Decimal() installments = safe_int(cc_info['installments']) cielo_config = self.request.shop.cielo_config produto = CieloProduct.Credit if service == CIELO_SERVICE_CREDIT: if installments > 1: installment_choices = InstallmentContext(order_total, cielo_config).get_intallments_choices() # verifica se o número da parcela existe nas opções if installments <= len(installment_choices): produto = CieloProduct.InstallmentCredit # obtém o valor da transação de acordo com a parcela escolhida transaction_total = installment_choices[installments-1][2] interest_amount = installment_choices[installments-1][3] else: installments = 1 else: # debito produto = CieloProduct.Debit installments = 1 cielo_order = CieloOrderTransaction.objects.create() comercial = Comercial(numero=safe_int(cielo_config.ec_num), chave=cielo_config.ec_key) cartao = Cartao(numero=safe_int(cc_info['cc_number']), validade=safe_int("{0}{1}".format(cc_info['cc_valid_year'], cc_info['cc_valid_month'])), indicador=1, # sempre sera necessario o digito verificador codigo_seguranca=safe_int(cc_info['cc_security_code']), nome_portador=cc_info['cc_holder']) pedido = Pedido(numero="{0}".format(cielo_order.pk), valor=decimal_to_int_cents(transaction_total), moeda=986, # Fixo data_hora=now().isoformat()) pagamento = Pagamento(bandeira=cc_info['cc_brand'], produto=produto, parcelas=installments) return_url = self.request.build_absolute_uri( reverse("shuup:cielo_transaction_return", kwargs={"cielo_order_pk": cielo_order.id}) ) transacao = Transacao(comercial=comercial, cartao=cartao, pedido=pedido, pagamento=pagamento, autorizar=cielo_config.authorization_mode, capturar=cielo_config.auto_capture, url_retorno=return_url) cielo_request = CieloRequest(sandbox=cielo_config.sandbox) # base response data response_data = {"success": False} cielo_transaction = None try: response_transaction = cielo_request.autorizar(transacao=transacao) cielo_transaction = CieloTransaction.objects.create(shop=self.request.shop, order_transaction=cielo_order, tid=response_transaction.tid, status=response_transaction.status, total_value=transaction_total, cc_holder=cc_info['cc_holder'], cc_brand=cc_info['cc_brand'], cc_product=produto, installments=installments, interest_value=interest_amount) # se existe uma URL para autenticacao, vamos redirecionar primeiro if response_transaction.url_autenticacao: response_data["success"] = True response_data["redirect_url"] = response_transaction.url_autenticacao # transação autorizada, vamos para a página de retorno para # efetivar elif response_transaction.autorizacao: if response_transaction.autorizacao.lr in CIELO_AUTHORIZED_STATUSES: response_data["success"] = True response_data["redirect_url"] = return_url else: response_data["success"] = False error = _p("Transaction not authorized: {0}").format( CieloAuthorizationCode.get( response_transaction.autorizacao.lr, {} ).get('msg', CIELO_UKNOWN_ERROR_MSG) ) response_data["error"] = error else: response_data["success"] = False response_data["error"] = _p("Transaction not authorized: {0}").format(CIELO_UKNOWN_ERROR_MSG) except CieloRequestError: response_data["success"] = False response_data["error"] = _p("Internal error") logger.exception(_("Cielo transaction error.")) else: self.request.cielo.set_order_transaction(cielo_order) self.request.cielo.set_transaction(cielo_transaction) self.request.cielo.commit() return self.render_to_response(response_data)
def form_valid(self, form): # verifica se existe alguma transação pendente na sessão # se sim, cancela a autorização antiga para fazer uma nova if self.request.cielo.transaction: try: self.request.cielo.transaction.safe_cancel( self.request.cielo.transaction.total_value) except: logger.exception(_("Failed to cancel old Cielo transaction")) # populate the basket with all the checkout stuff _configure_basket(self.request) order_total = self.request.basket.taxful_total_price.value service = self.request.basket.payment_method.choice_identifier cc_info = form.cleaned_data transaction_total = order_total interest_amount = Decimal() installments = safe_int(cc_info['installments']) cielo_config = self.request.shop.cielo_config produto = CieloProduct.Credit if service == CIELO_SERVICE_CREDIT: if installments > 1: installment_choices = InstallmentContext( order_total, cielo_config).get_intallments_choices() # verifica se o número da parcela existe nas opções if installments <= len(installment_choices): produto = CieloProduct.InstallmentCredit # obtém o valor da transação de acordo com a parcela escolhida transaction_total = installment_choices[installments - 1][2] interest_amount = installment_choices[installments - 1][3] else: installments = 1 else: # debito produto = CieloProduct.Debit installments = 1 cielo_order = CieloOrderTransaction.objects.create() comercial = Comercial(numero=safe_int(cielo_config.ec_num), chave=cielo_config.ec_key) cartao = Cartao( numero=safe_int(cc_info['cc_number']), validade=safe_int("{0}{1}".format(cc_info['cc_valid_year'], cc_info['cc_valid_month'])), indicador=1, # sempre sera necessario o digito verificador codigo_seguranca=safe_int(cc_info['cc_security_code']), nome_portador=cc_info['cc_holder']) pedido = Pedido( numero="{0}".format(cielo_order.pk), valor=decimal_to_int_cents(transaction_total), moeda=986, # Fixo data_hora=now().isoformat()) pagamento = Pagamento(bandeira=cc_info['cc_brand'], produto=produto, parcelas=installments) return_url = self.request.build_absolute_uri( reverse("shuup:cielo_transaction_return", kwargs={"cielo_order_pk": cielo_order.id})) transacao = Transacao(comercial=comercial, cartao=cartao, pedido=pedido, pagamento=pagamento, autorizar=cielo_config.authorization_mode, capturar=cielo_config.auto_capture, url_retorno=return_url) cielo_request = CieloRequest(sandbox=cielo_config.sandbox) # base response data response_data = {"success": False} cielo_transaction = None try: response_transaction = cielo_request.autorizar(transacao=transacao) cielo_transaction = CieloTransaction.objects.create( shop=self.request.shop, order_transaction=cielo_order, tid=response_transaction.tid, status=response_transaction.status, total_value=transaction_total, cc_holder=cc_info['cc_holder'], cc_brand=cc_info['cc_brand'], cc_product=produto, installments=installments, interest_value=interest_amount) # se existe uma URL para autenticacao, vamos redirecionar primeiro if response_transaction.url_autenticacao: response_data["success"] = True response_data[ "redirect_url"] = response_transaction.url_autenticacao # transação autorizada, vamos para a página de retorno para # efetivar elif response_transaction.autorizacao: if response_transaction.autorizacao.lr in CIELO_AUTHORIZED_STATUSES: response_data["success"] = True response_data["redirect_url"] = return_url else: response_data["success"] = False error = _p("Transaction not authorized: {0}").format( CieloAuthorizationCode.get( response_transaction.autorizacao.lr, {}).get('msg', CIELO_UKNOWN_ERROR_MSG)) response_data["error"] = error else: response_data["success"] = False response_data["error"] = _p("Transaction not authorized: {0}" ).format(CIELO_UKNOWN_ERROR_MSG) except CieloRequestError: response_data["success"] = False response_data["error"] = _p("Internal error") logger.exception(_("Cielo transaction error.")) else: self.request.cielo.set_order_transaction(cielo_order) self.request.cielo.set_transaction(cielo_transaction) self.request.cielo.commit() return self.render_to_response(response_data)