-
Notifications
You must be signed in to change notification settings - Fork 100
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(dunning): Create payment on payment request creation (#2485)
## Context We want to be able to manually request payment of the overdue balance and send emails for reminders. 👉 https://getlago.canny.io/feature-requests/p/send-reminders-for-overdue-invoices ## Description The goal of this PR is to kick off the payment creation for payment requests when customer has a payment provider.
- Loading branch information
Showing
12 changed files
with
215 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# frozen_string_literal: true | ||
|
||
module PaymentRequests | ||
module Payments | ||
class AdyenCreateJob < ApplicationJob | ||
queue_as 'providers' | ||
|
||
unique :until_executed | ||
|
||
retry_on Faraday::ConnectionFailed, wait: :polynomially_longer, attempts: 6 | ||
|
||
def perform(payable) | ||
result = PaymentRequests::Payments::AdyenService.new(payable).create | ||
result.raise_if_error! | ||
end | ||
end | ||
end | ||
end |
16 changes: 16 additions & 0 deletions
16
app/jobs/payment_requests/payments/gocardless_create_job.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# frozen_string_literal: true | ||
|
||
module PaymentRequests | ||
module Payments | ||
class GocardlessCreateJob < ApplicationJob | ||
queue_as 'providers' | ||
|
||
unique :until_executed | ||
|
||
def perform(payable) | ||
result = PaymentRequests::Payments::GocardlessService.new(payable).create | ||
result.raise_if_error! | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# frozen_string_literal: true | ||
|
||
module PaymentRequests | ||
module Payments | ||
class StripeCreateJob < ApplicationJob | ||
queue_as 'providers' | ||
|
||
unique :until_executed, on_conflict: :log | ||
|
||
retry_on Stripe::RateLimitError, wait: :polynomially_longer, attempts: 6 | ||
retry_on Stripe::APIConnectionError, wait: :polynomially_longer, attempts: 6 | ||
|
||
def perform(payable) | ||
result = PaymentRequests::Payments::StripeService.new(payable).create | ||
result.raise_if_error! | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# frozen_string_literal: true | ||
|
||
module PaymentRequests | ||
module Payments | ||
class CreateService < BaseService | ||
def initialize(payable) | ||
@payable = payable | ||
|
||
super | ||
end | ||
|
||
def call | ||
case payment_provider | ||
when :adyen | ||
PaymentRequests::Payments::AdyenCreateJob.perform_later(payable) | ||
when :gocardless | ||
PaymentRequests::Payments::GocardlessCreateJob.perform_later(payable) | ||
when :stripe | ||
PaymentRequests::Payments::StripeCreateJob.perform_later(payable) | ||
end | ||
# TODO: Do something when no payment provider is set | ||
# or leave it to the caller | ||
rescue ActiveJob::Uniqueness::JobNotUnique => e | ||
Sentry.capture_exception(e) | ||
end | ||
|
||
private | ||
|
||
attr_reader :payable | ||
|
||
def payment_provider | ||
payable.customer.payment_provider&.to_sym | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
22 changes: 22 additions & 0 deletions
22
spec/jobs/payment_requests/payments/adyen_create_job_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'rails_helper' | ||
|
||
RSpec.describe PaymentRequests::Payments::AdyenCreateJob, type: :job do | ||
let(:payment_request) { create(:payment_request) } | ||
|
||
let(:adyen_service) { instance_double(PaymentRequests::Payments::AdyenService) } | ||
|
||
it 'calls the stripe create service' do | ||
allow(PaymentRequests::Payments::AdyenService).to receive(:new) | ||
.with(payment_request) | ||
.and_return(adyen_service) | ||
allow(adyen_service).to receive(:create) | ||
.and_return(BaseService::Result.new) | ||
|
||
described_class.perform_now(payment_request) | ||
|
||
expect(PaymentRequests::Payments::AdyenService).to have_received(:new) | ||
expect(adyen_service).to have_received(:create) | ||
end | ||
end |
22 changes: 22 additions & 0 deletions
22
spec/jobs/payment_requests/payments/gocardless_create_job_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'rails_helper' | ||
|
||
RSpec.describe PaymentRequests::Payments::GocardlessCreateJob, type: :job do | ||
let(:payment_request) { create(:payment_request) } | ||
|
||
let(:gocardless_service) { instance_double(PaymentRequests::Payments::GocardlessService) } | ||
|
||
it 'calls the stripe create service' do | ||
allow(PaymentRequests::Payments::GocardlessService).to receive(:new) | ||
.with(payment_request) | ||
.and_return(gocardless_service) | ||
allow(gocardless_service).to receive(:create) | ||
.and_return(BaseService::Result.new) | ||
|
||
described_class.perform_now(payment_request) | ||
|
||
expect(PaymentRequests::Payments::GocardlessService).to have_received(:new) | ||
expect(gocardless_service).to have_received(:create) | ||
end | ||
end |
22 changes: 22 additions & 0 deletions
22
spec/jobs/payment_requests/payments/stripe_create_job_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'rails_helper' | ||
|
||
RSpec.describe PaymentRequests::Payments::StripeCreateJob, type: :job do | ||
let(:payment_request) { create(:payment_request) } | ||
|
||
let(:stripe_service) { instance_double(PaymentRequests::Payments::StripeService) } | ||
|
||
it 'calls the stripe create service' do | ||
allow(PaymentRequests::Payments::StripeService).to receive(:new) | ||
.with(payment_request) | ||
.and_return(stripe_service) | ||
allow(stripe_service).to receive(:create) | ||
.and_return(BaseService::Result.new) | ||
|
||
described_class.perform_now(payment_request) | ||
|
||
expect(PaymentRequests::Payments::StripeService).to have_received(:new) | ||
expect(stripe_service).to have_received(:create) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
44 changes: 44 additions & 0 deletions
44
spec/services/payment_requests/payments/create_service_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# frozen_string_literal: true | ||
|
||
require "rails_helper" | ||
|
||
RSpec.describe PaymentRequests::Payments::CreateService, type: :service do | ||
subject(:create_service) { described_class.new(payment_request) } | ||
|
||
let(:payment_request) do | ||
create(:payment_request, customer:, organization: customer.organization) | ||
end | ||
let(:customer) { create(:customer, payment_provider:) } | ||
|
||
describe "#call" do | ||
context "with adyen payment provider" do | ||
let(:payment_provider) { "adyen" } | ||
|
||
it "enqueues a job to create a adyen payment" do | ||
expect do | ||
create_service.call | ||
end.to have_enqueued_job(PaymentRequests::Payments::AdyenCreateJob) | ||
end | ||
end | ||
|
||
context "with gocardless payment provider" do | ||
let(:payment_provider) { "gocardless" } | ||
|
||
it "enqueues a job to create a gocardless payment" do | ||
expect do | ||
create_service.call | ||
end.to have_enqueued_job(PaymentRequests::Payments::GocardlessCreateJob) | ||
end | ||
end | ||
|
||
context "with strip payment provider" do | ||
let(:payment_provider) { "stripe" } | ||
|
||
it "enqueues a job to create a stripe payment" do | ||
expect do | ||
create_service.call | ||
end.to have_enqueued_job(PaymentRequests::Payments::StripeCreateJob) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters