示例#1
0
 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)
示例#2
0
 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)
示例#3
0
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
示例#4
0
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)
示例#5
0
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()
示例#6
0
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
示例#7
0
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
示例#8
0
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
示例#9
0
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
示例#10
0
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)
示例#11
0
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
示例#12
0
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()
示例#13
0
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
示例#14
0
    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)
示例#15
0
    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)
示例#16
0
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