Skip to content

Commit

Permalink
🎨 1. part: invoice expiration fix (🗃️) (#5532)
Browse files Browse the repository at this point in the history
  • Loading branch information
matusdrobuliak66 authored Mar 22, 2024
1 parent 9e9bbb2 commit 2a7ece2
Show file tree
Hide file tree
Showing 14 changed files with 52 additions and 57 deletions.
4 changes: 3 additions & 1 deletion packages/models-library/src/models_library/payments.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
from decimal import Decimal
from typing import Any, ClassVar
from typing import Any, ClassVar, TypeAlias

from models_library.emails import LowerCaseEmailStr
from pydantic import BaseModel, Field, validator

from .products import StripePriceID, StripeTaxRateID

StripeInvoiceID: TypeAlias = str


class UserInvoiceAddress(BaseModel):
line1: str | None = None
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"""add invoice id column
Revision ID: 4a0f4efe8c86
Revises: 5b37c3bc99af
Create Date: 2024-03-21 10:27:45.493789+00:00
"""
import sqlalchemy as sa
from alembic import op

# revision identifiers, used by Alembic.
revision = "4a0f4efe8c86"
down_revision = "5b37c3bc99af"
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column(
"payments_transactions",
sa.Column("stripe_invoice_id", sa.String(), nullable=True),
)
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column("payments_transactions", "stripe_invoice_id")
# ### end Alembic commands ###
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ def is_acknowledged(self) -> bool:
nullable=True,
doc="Link to invoice of this transaction. Available when completed",
),
sa.Column(
"stripe_invoice_id",
sa.String,
nullable=True,
doc="Invoice ID of invoice of this transaction. Available when completed",
),
#
# States
#
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
from servicelib.logging_utils import get_log_record_extra, log_context
from servicelib.rabbitmq import RPCRouter

from ...core.settings import ApplicationSettings
from ...db.payments_transactions_repo import PaymentsTransactionsRepo
from ...services import payments
from ...services.payments_gateway import PaymentsGatewayApi
Expand Down Expand Up @@ -47,9 +46,6 @@ async def init_payment( # pylint: disable=too-many-arguments
stripe_tax_rate_id: StripeTaxRateID,
comment: str | None = None,
) -> WalletPaymentInitiated:

settings: ApplicationSettings = app.state.settings

with log_context(
_logger,
logging.INFO,
Expand All @@ -60,7 +56,6 @@ async def init_payment( # pylint: disable=too-many-arguments
return await payments.init_one_time_payment(
gateway=PaymentsGatewayApi.get_from_app_state(app),
repo=PaymentsTransactionsRepo(db_engine=app.state.engine),
settings=settings,
amount_dollars=amount_dollars,
target_credits=target_credits,
product_name=product_name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
from servicelib.logging_utils import get_log_record_extra, log_context
from servicelib.rabbitmq import RPCRouter

from ...core.settings import ApplicationSettings
from ...db.payments_methods_repo import PaymentsMethodsRepo
from ...db.payments_transactions_repo import PaymentsTransactionsRepo
from ...services import payments, payments_methods
Expand Down Expand Up @@ -170,8 +169,6 @@ async def pay_with_payment_method( # noqa: PLR0913 # pylint: disable=too-many-a
stripe_tax_rate_id: StripeTaxRateID,
comment: str | None = None,
):
settings: ApplicationSettings = app.state.settings

with log_context(
_logger,
logging.INFO,
Expand All @@ -186,7 +183,6 @@ async def pay_with_payment_method( # noqa: PLR0913 # pylint: disable=too-many-a
repo_transactions=PaymentsTransactionsRepo(db_engine=app.state.engine),
repo_methods=PaymentsMethodsRepo(db_engine=app.state.engine),
notifier=NotifierService.get_from_app_state(app),
settings=settings,
payment_method_id=payment_method_id,
amount_dollars=amount_dollars,
target_credits=target_credits,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
PaymentNotFoundError,
)
from models_library.api_schemas_webserver.wallets import PaymentID
from models_library.payments import StripeInvoiceID
from models_library.products import ProductName
from models_library.users import UserID
from models_library.wallets import WalletID
Expand Down Expand Up @@ -66,6 +67,7 @@ async def update_ack_payment_transaction(
completion_state: PaymentTransactionState,
state_message: str | None,
invoice_url: HttpUrl | None,
stripe_invoice_id: StripeInvoiceID | None,
) -> PaymentsTransactionsDB:
"""
- ACKs payment by updating state with SUCCESS, CANCEL, etc
Expand Down Expand Up @@ -112,6 +114,7 @@ async def update_ack_payment_transaction(
completed_at=sa.func.now(),
state=completion_state,
invoice_url=invoice_url,
stripe_invoice_id=stripe_invoice_id,
**optional,
)
.where(payments_transactions.c.payment_id == f"{payment_id}")
Expand Down
3 changes: 3 additions & 0 deletions services/payments/src/simcore_service_payments/models/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from models_library.api_schemas_webserver.wallets import PaymentID, PaymentMethodID
from models_library.emails import LowerCaseEmailStr
from models_library.payments import StripeInvoiceID
from models_library.products import ProductName
from models_library.users import UserID
from models_library.wallets import WalletID
Expand All @@ -23,6 +24,7 @@
"wallet_id": 123,
"comment": "This is a test comment.",
"invoice_url": None,
"stripe_invoice_id": None,
"initiated_at": "2023-09-27T10:00:00",
"state": PaymentTransactionState.PENDING,
}
Expand All @@ -38,6 +40,7 @@ class PaymentsTransactionsDB(BaseModel):
wallet_id: WalletID
comment: str | None
invoice_url: HttpUrl | None
stripe_invoice_id: StripeInvoiceID | None
initiated_at: datetime.datetime
completed_at: datetime.datetime | None
state: PaymentTransactionState
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,6 @@ async def _perform_auto_recharge(
payment_method_db: PaymentsMethodsDB,
wallet_auto_recharge: GetWalletAutoRecharge,
):
settings: ApplicationSettings = app.state.settings

rabbitmq_rpc_client = get_rabbitmq_rpc_client(app)

result = await rabbitmq_rpc_client.request(
Expand All @@ -157,7 +155,6 @@ async def _perform_auto_recharge(
repo_transactions=PaymentsTransactionsRepo(db_engine=app.state.engine),
repo_methods=PaymentsMethodsRepo(db_engine=app.state.engine),
notifier=NotifierService.get_from_app_state(app),
settings=settings,
#
payment_method_id=cast(PaymentMethodID, wallet_auto_recharge.payment_method_id),
amount_dollars=wallet_auto_recharge.top_up_amount_in_usd,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
from tenacity.stop import stop_after_attempt

from .._constants import RUT
from ..core.settings import ApplicationSettings
from ..db.payments_transactions_repo import PaymentsTransactionsRepo
from ..models.db import PaymentsTransactionsDB
from ..models.db_to_api import to_payments_api_model
Expand All @@ -58,7 +57,6 @@
async def init_one_time_payment(
gateway: PaymentsGatewayApi,
repo: PaymentsTransactionsRepo,
settings: ApplicationSettings,
*,
amount_dollars: Decimal,
target_credits: Decimal,
Expand Down Expand Up @@ -91,7 +89,6 @@ async def init_one_time_payment(
else StripeTaxExempt.reverse
),
),
payment_gateway_tax_feature_enabled=settings.PAYMENTS_GATEWAY_TAX_FEATURE_ENABLED,
)

submission_link = gateway.get_form_payment_url(init.payment_id)
Expand Down Expand Up @@ -146,6 +143,7 @@ async def cancel_one_time_payment(
completion_state=PaymentTransactionState.CANCELED,
state_message=payment_cancelled.message,
invoice_url=None,
stripe_invoice_id=None,
)


Expand All @@ -164,6 +162,7 @@ async def acknowledge_one_time_payment(
),
state_message=ack.message,
invoice_url=ack.invoice_url,
stripe_invoice_id=ack.stripe_invoice_id,
)


Expand Down Expand Up @@ -217,7 +216,6 @@ async def pay_with_payment_method( # noqa: PLR0913
repo_transactions: PaymentsTransactionsRepo,
repo_methods: PaymentsMethodsRepo,
notifier: NotifierService,
settings: ApplicationSettings,
*,
payment_method_id: PaymentMethodID,
amount_dollars: Decimal,
Expand Down Expand Up @@ -256,7 +254,6 @@ async def pay_with_payment_method( # noqa: PLR0913
else StripeTaxExempt.reverse
),
),
payment_gateway_tax_feature_enabled=settings.PAYMENTS_GATEWAY_TAX_FEATURE_ENABLED,
)

payment_id = ack.payment_id
Expand Down Expand Up @@ -290,6 +287,7 @@ async def pay_with_payment_method( # noqa: PLR0913
),
state_message=ack.message,
invoice_url=ack.invoice_url,
stripe_invoice_id=ack.stripe_invoice_id,
)

# NOTE: notifications here are done as background-task after responding `POST /wallets/{wallet_id}/payments-methods/{payment_method_id}:pay`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,25 +121,10 @@ class PaymentsGatewayApi(
#

@_handle_status_errors
async def init_payment(
self, payment: InitPayment, payment_gateway_tax_feature_enabled: bool
) -> PaymentInitiated:
_payment_json = payment.dict(
exclude_none=True,
by_alias=True,
exclude={
"user_address",
"stripe_price_id",
"stripe_tax_rate_id",
"stripe_tax_exempt_value",
},
)
if payment_gateway_tax_feature_enabled:
_payment_json = payment.dict(exclude_none=True, by_alias=True)

async def init_payment(self, payment: InitPayment) -> PaymentInitiated:
response = await self.client.post(
"/init",
json=jsonable_encoder(_payment_json),
json=jsonable_encoder(payment.dict(exclude_none=True, by_alias=True)),
)
response.raise_for_status()
return PaymentInitiated.parse_obj(response.json())
Expand Down Expand Up @@ -210,24 +195,10 @@ async def pay_with_payment_method(
self,
id_: PaymentMethodID,
payment: InitPayment,
payment_gateway_tax_feature_enabled: bool, # noqa: FBT001
) -> AckPaymentWithPaymentMethod:
_payment_json = payment.dict(
exclude_none=True,
by_alias=True,
exclude={
"user_address",
"stripe_price_id",
"stripe_tax_rate_id",
"stripe_tax_exempt_value",
},
)
if payment_gateway_tax_feature_enabled:
_payment_json = payment.dict(exclude_none=True, by_alias=True)

response = await self.client.post(
f"/payment-methods/{id_}:pay",
json=jsonable_encoder(_payment_json),
json=jsonable_encoder(payment.dict(exclude_none=True, by_alias=True)),
)
response.raise_for_status()
return AckPaymentWithPaymentMethod.parse_obj(response.json())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ async def test_one_time_payment_annotations_workflow(app: FastAPI):
payment_id=fake.payment_id,
completion_state=PaymentTransactionState.SUCCESS,
invoice_url=fake.invoice_url,
stripe_invoice_id=fake.stripe_invoice_id,
state_message="DONE",
)

Expand Down
3 changes: 0 additions & 3 deletions services/payments/tests/unit/test_services_payments.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,15 +113,12 @@ async def test_fails_to_pay_with_payment_method_without_funds(
# Mocker providers
notifier = NotifierService(mock_email_provider, mock_ws_provider)

settings = app.state.settings

payment = await payments.pay_with_payment_method(
gateway=PaymentsGatewayApi.get_from_app_state(app),
rut=rut,
repo_transactions=PaymentsTransactionsRepo(db_engine=app.state.engine),
repo_methods=PaymentsMethodsRepo(db_engine=app.state.engine),
notifier=notifier,
settings=settings,
#
payment_method_id=payment_method_without_funds.payment_method_id,
amount_dollars=100,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ async def test_one_time_payment_workflow(
stripe_tax_rate_id=faker.word(),
stripe_tax_exempt_value=StripeTaxExempt.none,
),
payment_gateway_tax_feature_enabled=True,
)

# form url
Expand Down Expand Up @@ -192,7 +191,6 @@ async def test_payment_methods_workflow(
stripe_tax_rate_id=faker.word(),
stripe_tax_exempt_value=StripeTaxExempt.none,
),
payment_gateway_tax_feature_enabled=True,
)
assert payment_with_payment_method.success

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,6 @@ async def test_payment_methods_workflow_with_tax_feature_disabled(
stripe_tax_rate_id=faker.word(),
stripe_tax_exempt_value=StripeTaxExempt.none,
),
payment_gateway_tax_feature_enabled=settings.PAYMENTS_GATEWAY_TAX_FEATURE_ENABLED,
)
assert payment_with_payment_method.success

Expand Down Expand Up @@ -365,7 +364,6 @@ async def test_one_time_payment_workflow_with_tax_feature_disabled(
stripe_tax_rate_id=faker.word(),
stripe_tax_exempt_value=StripeTaxExempt.none,
),
payment_gateway_tax_feature_enabled=settings.PAYMENTS_GATEWAY_TAX_FEATURE_ENABLED,
)

# form url
Expand Down

0 comments on commit 2a7ece2

Please sign in to comment.