1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-01-29 18:52:22 +01:00

send notifications on payment schedules error/canceled by gateway

This commit is contained in:
Sylvain 2022-01-11 12:37:06 +01:00
parent af62a8446e
commit 051b56b72f
14 changed files with 137 additions and 20 deletions

View File

@ -59,6 +59,10 @@ class NotificationType
notify_member_payment_schedule_failed
notify_admin_payment_schedule_check_deadline
notify_admin_payment_schedule_transfer_deadline
notify_admin_payment_schedule_error
notify_member_payment_schedule_error
notify_admin_payment_schedule_gateway_canceled
notify_member_payment_schedule_gateway_canceled
]
# deprecated:
# - notify_member_subscribed_plan_is_changed

View File

@ -0,0 +1,5 @@
# frozen_string_literal: true
json.title notification.notification_type
json.description t('.schedule_error', DATE: I18n.l(notification.attached_object.due_date.to_date),
REFERENCE: notification.attached_object.payment_schedule.reference)

View File

@ -0,0 +1,4 @@
# frozen_string_literal: true
json.title notification.notification_type
json.description t('.schedule_canceled', REFERENCE: notification.attached_object.payment_schedule.reference)

View File

@ -0,0 +1,5 @@
# frozen_string_literal: true
json.title notification.notification_type
json.description t('.schedule_error', DATE: I18n.l(notification.attached_object.due_date.to_date),
REFERENCE: notification.attached_object.payment_schedule.reference)

View File

@ -0,0 +1,4 @@
# frozen_string_literal: true
json.title notification.notification_type
json.description t('.schedule_canceled', REFERENCE: notification.attached_object.payment_schedule.reference)

View File

@ -0,0 +1,10 @@
<%= render 'notifications_mailer/shared/hello', recipient: @recipient %>
<p>
<%= t('.body.remember',
REFERENCE: @attached_object.payment_schedule.reference,
AMOUNT: number_to_currency(@attached_object.amount / 100.00),
DATE: I18n.l(@attached_object.due_date, format: :long)) %>
<%= t('.body.error', GATEWAY: @attached_object.payment_gateway_object.gateway_object.gateway) %>
</p>
<p><%= t('.body.action') %></p>

View File

@ -0,0 +1,8 @@
<%= render 'notifications_mailer/shared/hello', recipient: @recipient %>
<p>
<%= t('.body.error',
REFERENCE: @attached_object.payment_schedule.reference,
GATEWAY: @attached_object.payment_gateway_object.gateway_object.gateway) %>
</p>
<p><%= t('.body.action') %></p>

View File

@ -0,0 +1,7 @@
<%= render 'notifications_mailer/shared/hello', recipient: @recipient %>
<p>
<%= t('.body.error',
REFERENCE: @attached_object.payment_schedule.reference) %>
</p>
<p><%= t('.body.action') %></p>

View File

@ -0,0 +1,10 @@
<%= render 'notifications_mailer/shared/hello', recipient: @recipient %>
<p>
<%= t('.body.remember',
REFERENCE: @attached_object.payment_schedule.reference,
AMOUNT: number_to_currency(@attached_object.amount / 100.00),
DATE: I18n.l(@attached_object.due_date, format: :long)) %>
<%= t('.body.error') %>
</p>
<p><%= t('.body.action') %></p>

View File

@ -367,10 +367,18 @@ en:
all_objects_sync: "All data were successfully synchronized on Stripe."
notify_user_when_payment_schedule_ready:
your_schedule_is_ready_html: "Your payment schedule #%{REFERENCE}, of %{AMOUNT}, is ready. <a href='api/payment_schedules/%{SCHEDULE_ID}/download' target='_blank'>Click here to download</a>."
notify_admin_payment_schedule_error:
schedule_error: "An error occurred for the card debit of the %{DATE} deadline, for schedule %{REFERENCE}"
notify_member_payment_schedule_error:
schedule_error: "An error occurred for the card debit of the %{DATE} deadline, for your schedule %{REFERENCE}"
notify_admin_payment_schedule_failed:
schedule_failed: "Failed card debit for the %{DATE} deadline, for schedule %{REFERENCE}"
notify_member_payment_schedule_failed:
schedule_failed: "Failed card debit for the %{DATE} deadline, for your schedule %{REFERENCE}"
notify_admin_payment_schedule_gateway_canceled:
schedule_error: "The payment schedule %{REFERENCE} was canceled by the gateway. An action is required."
notify_member_payment_schedule_gateway_canceled:
schedule_error: "Your payment schedule %{REFERENCE} was canceled by the gateway."
notify_admin_payment_schedule_check_deadline:
schedule_deadline: "You must cash the check for the %{DATE} deadline, for schedule %{REFERENCE}"
notify_admin_payment_schedule_transfer_deadline:

View File

@ -296,6 +296,18 @@ en:
please_find_attached_html: "Please find attached your payment schedule, issued on {DATE}, with an amount of {AMOUNT} concerning your {TYPE, select, Reservation{reservation} other{subscription}}." #messageFormat interpolation
schedule_in_your_dashboard_html: "You can find this payment schedule at any time from %{DASHBOARD} on the Fab Lab's website."
your_dashboard: "your dashboard"
notify_admin_payment_schedule_error:
subject: "[URGENT] Card debit error"
body:
remember: "In accordance with the %{REFERENCE} payment schedule, a debit by card of %{AMOUNT} was scheduled on %{DATE}."
error: "Unfortunately, an error occurred and this card debit was unable to complete successfully."
action: "Please then consult the %{GATEWAY} dashboard and contact the member as soon as possible to resolve the problem."
notify_member_payment_schedule_error:
subject: "[URGENT] Card debit error"
body:
remember: "In accordance with your %{REFERENCE} payment schedule, a debit by card of %{AMOUNT} was scheduled on %{DATE}."
error: "Unfortunately, an error occurred and this card debit was unable to complete successfully."
action: "Please contact a manager as soon as possible to resolve the problem."
notify_admin_payment_schedule_failed:
subject: "[URGENT] Card debit failure"
body:
@ -309,6 +321,16 @@ en:
error: "Unfortunately, this card debit was unable to complete successfully."
action_html: "Please check %{DASHBOARD} or contact a manager before 24 hours, otherwise your subscription may be interrupted."
your_dashboard: "your dashboard"
notify_admin_payment_schedule_gateway_canceled:
subject: "[URGENT] Payment schedule canceled by the payment gateway"
body:
error: "The payment schedule %{REFERENCE} was canceled by the payment gateway (%{GATEWAY}). No further debits will be made on this payment mean."
action: "Please consult the payment schedule management interface and contact the member as soon as possible to resolve the problem."
notify_member_payment_schedule_gateway_canceled:
subject: "[URGENT] Payment schedule canceled by the payment gateway"
body:
error: "Your payment schedule %{REFERENCE} was canceled by the payment gateway. No further debits will be made on this payment mean."
action: "Please contact a manager as soon as possible to resolve the problem."
notify_admin_payment_schedule_check_deadline:
subject: "Payment deadline"
body:

View File

@ -80,7 +80,8 @@ class PayZen::Service < Payment::Service
def process_payment_schedule_item(payment_schedule_item)
pz_subscription = payment_schedule_item.gateway_subscription.retrieve
if DateTime.parse(pz_subscription['answer']['cancelDate']) < DateTime.current
# the subscription was canceled by the gateway => update the status
# the subscription was canceled by the gateway => notify & update the status
notify_payment_schedule_gateway_canceled(payment_schedule_item)
payment_schedule_item.update_attributes(state: 'gateway_canceled')
return
end
@ -98,20 +99,13 @@ class PayZen::Service < Payment::Service
pgo.gateway_object = PayZen::Item.new('PayZen::Transaction', transaction['uuid'])
pgo.save!
elsif transaction['status'] == 'RUNNING'
if payment_schedule_item.state == 'new'
# notify only for new deadlines, to prevent spamming
NotificationCenter.call type: 'notify_admin_payment_schedule_failed',
receiver: User.admins_and_managers,
attached_object: payment_schedule_item
NotificationCenter.call type: 'notify_member_payment_schedule_failed',
receiver: payment_schedule_item.payment_schedule.user,
attached_object: payment_schedule_item
end
notify_payment_schedule_item_failed(payment_schedule_item)
payment_schedule_item.update_attributes(state: transaction['detailedStatus'])
pgo = PaymentGatewayObject.find_or_initialize_by(item: payment_schedule_item)
pgo.gateway_object = PayZen::Item.new('PayZen::Transaction', transaction['uuid'])
pgo.save!
else
notify_payment_schedule_item_error(payment_schedule_item)
payment_schedule_item.update_attributes(state: 'error')
end
end

View File

@ -21,4 +21,46 @@ class Payment::Service
def process_payment_schedule_item(_payment_schedule_item); end
def pay_payment_schedule_item(_payment_schedule_item); end
protected
# payment has failed but a recovery is still possible
def notify_payment_schedule_item_failed(payment_schedule_item)
# notify only for new deadlines, to prevent spamming
return unless payment_schedule_item.state == 'new'
NotificationCenter.call type: 'notify_admin_payment_schedule_failed',
receiver: User.admins_and_managers,
attached_object: payment_schedule_item
NotificationCenter.call type: 'notify_member_payment_schedule_failed',
receiver: payment_schedule_item.payment_schedule.user,
attached_object: payment_schedule_item
end
# payment has failed and recovery is not possible
def notify_payment_schedule_item_error(payment_schedule_item)
# notify only for new deadlines, to prevent spamming
return unless payment_schedule_item.state == 'new'
NotificationCenter.call type: 'notify_admin_payment_schedule_error',
receiver: User.admins_and_managers,
attached_object: payment_schedule_item
NotificationCenter.call type: 'notify_member_payment_schedule_error',
receiver: payment_schedule_item.payment_schedule.user,
attached_object: payment_schedule_item
end
# payment schedule was cancelled by the gateway
def notify_payment_schedule_gateway_canceled(payment_schedule_item)
# notify only for new deadlines, to prevent spamming
return unless payment_schedule_item.state == 'new'
NotificationCenter.call type: 'notify_admin_payment_schedule_gateway_canceled',
receiver: User.admins_and_managers,
attached_object: payment_schedule_item
NotificationCenter.call type: 'notify_member_payment_schedule_gateway_canceled',
receiver: payment_schedule_item.payment_schedule.user,
attached_object: payment_schedule_item
end
end

View File

@ -95,7 +95,8 @@ class Stripe::Service < Payment::Service
stripe_key = Setting.get('stripe_secret_key')
stp_subscription = payment_schedule_item.payment_schedule.gateway_subscription.retrieve
if stp_subscription.status == 'canceled'
# the subscription was canceled by the gateway => update the status
# the subscription was canceled by the gateway => notify & update the status
notify_payment_schedule_gateway_canceled(payment_schedule_item)
payment_schedule_item.update_attributes(state: 'gateway_canceled')
return
end
@ -112,15 +113,7 @@ class Stripe::Service < Payment::Service
pgo.save!
elsif stp_subscription.status == 'past_due' || stp_invoice.status == 'open'
##### Payment error
if payment_schedule_item.state == 'new'
# notify only for new deadlines, to prevent spamming
NotificationCenter.call type: 'notify_admin_payment_schedule_failed',
receiver: User.admins_and_managers,
attached_object: payment_schedule_item
NotificationCenter.call type: 'notify_member_payment_schedule_failed',
receiver: payment_schedule_item.payment_schedule.user,
attached_object: payment_schedule_item
end
notify_payment_schedule_item_failed(payment_schedule_item)
stp_payment_intent = Stripe::PaymentIntent.retrieve(stp_invoice.payment_intent, api_key: stripe_key)
payment_schedule_item.update_attributes(state: stp_payment_intent.status,
client_secret: stp_payment_intent.client_secret)
@ -128,6 +121,7 @@ class Stripe::Service < Payment::Service
pgo.gateway_object = stp_invoice
pgo.save!
else
notify_payment_schedule_item_error(payment_schedule_item)
payment_schedule_item.update_attributes(state: 'error')
end
end