Enhance payment identifier normalization in TributeService
- Updated the TributeService to normalize provider payment identifiers, prioritizing true payment identifiers over subscription IDs for better uniqueness. - Implemented fallback logic to append timestamps to subscription IDs, preventing deduplication of renewals. - Expanded the list of successful charge events to include various payment-related events, improving event handling consistency.
This commit is contained in:
@@ -96,8 +96,44 @@ class TributeService:
|
|||||||
price_rub = price_val / 100
|
price_rub = price_val / 100
|
||||||
|
|
||||||
async with async_session_factory() as session:
|
async with async_session_factory() as session:
|
||||||
if event_name == 'new_subscription':
|
# Normalize provider payment identifier to be unique per successful charge
|
||||||
provider_payment_id = str(data.get('subscription_id'))
|
# Prefer true payment/transaction identifiers over subscription id
|
||||||
|
provider_payment_id = (
|
||||||
|
data.get('payment_id')
|
||||||
|
or data.get('invoice_id')
|
||||||
|
or data.get('order_id')
|
||||||
|
or data.get('transaction_id')
|
||||||
|
or data.get('charge_id')
|
||||||
|
or data.get('subscription_payment_id')
|
||||||
|
)
|
||||||
|
if provider_payment_id is None:
|
||||||
|
# Fallback to subscription_id which may be stable across renewals
|
||||||
|
# To avoid deduplicating different renewals under same subscription,
|
||||||
|
# append a timestamp if available
|
||||||
|
base_sub_id = data.get('subscription_id')
|
||||||
|
paid_at = (
|
||||||
|
data.get('paid_at')
|
||||||
|
or data.get('created_at')
|
||||||
|
or payload.get('timestamp')
|
||||||
|
or payload.get('id')
|
||||||
|
)
|
||||||
|
if base_sub_id is not None and paid_at is not None:
|
||||||
|
provider_payment_id = f"{base_sub_id}:{paid_at}"
|
||||||
|
elif base_sub_id is not None:
|
||||||
|
provider_payment_id = str(base_sub_id)
|
||||||
|
else:
|
||||||
|
provider_payment_id = str(provider_payment_id)
|
||||||
|
|
||||||
|
# Consider multiple Tribute events as successful charge events
|
||||||
|
success_events = {
|
||||||
|
'new_subscription',
|
||||||
|
'payment_succeeded',
|
||||||
|
'subscription_renewed',
|
||||||
|
'subscription_payment_succeeded',
|
||||||
|
'invoice_paid',
|
||||||
|
}
|
||||||
|
|
||||||
|
if event_name in success_events:
|
||||||
existing_payment = await payment_dal.get_payment_by_provider_payment_id(
|
existing_payment = await payment_dal.get_payment_by_provider_payment_id(
|
||||||
session, provider_payment_id)
|
session, provider_payment_id)
|
||||||
if existing_payment:
|
if existing_payment:
|
||||||
|
|||||||
Reference in New Issue
Block a user