-
Notifications
You must be signed in to change notification settings - Fork 99
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Create customer on stripe (#268)
- Loading branch information
1 parent
de4dc92
commit e6cabb8
Showing
12 changed files
with
322 additions
and
13 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
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,16 @@ | ||
# frozen_string_literal: true | ||
|
||
module PaymentProviderCustomers | ||
class StripeCreateJob < ApplicationJob | ||
queue_as :providers | ||
|
||
retry_on Stripe::APIConnectionError, wait: :exponentially_longer, attempts: 6 | ||
retry_on Stripe::APIError, wait: :exponentially_longer, attempts: 6 | ||
retry_on Stripe::RateLimitError, wait: :exponentially_longer, attempts: 6 | ||
|
||
def perform(stripe_customer) | ||
result = PaymentProviderCustomers::StripeService.new(stripe_customer).create | ||
result.throw_error | ||
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
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,62 @@ | ||
# frozen_string_literal: true | ||
|
||
module PaymentProviderCustomers | ||
class StripeService < BaseService | ||
def initialize(stripe_customer) | ||
@stripe_customer = stripe_customer | ||
|
||
super(nil) | ||
end | ||
|
||
def create | ||
result.stripe_customer = stripe_customer | ||
return result if stripe_customer.provider_customer_id? | ||
|
||
stripe_result = Stripe::Customer.create( | ||
stripe_create_payload, | ||
{ api_key: api_key }, | ||
) | ||
|
||
stripe_customer.update!( | ||
provider_customer_id: stripe_result.id, | ||
) | ||
|
||
result.stripe_customer = stripe_customer | ||
result | ||
end | ||
|
||
private | ||
|
||
attr_accessor :stripe_customer | ||
|
||
delegate :customer, to: :stripe_customer | ||
|
||
def organization | ||
customer.organization | ||
end | ||
|
||
def api_key | ||
organization.stripe_payment_provider.secret_key | ||
end | ||
|
||
def stripe_create_payload | ||
{ | ||
address: { | ||
city: customer.city, | ||
country: customer.country, | ||
line1: customer.address_line1, | ||
line2: customer.address_line2, | ||
postal_code: customer.zipcode, | ||
state: customer.state, | ||
}, | ||
email: customer.email, | ||
name: customer.name, | ||
metadata: { | ||
lago_customer_id: customer.id, | ||
customer_id: customer.customer_id, | ||
}, | ||
phone: customer.phone, | ||
} | ||
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 |
---|---|---|
|
@@ -4,6 +4,7 @@ retry: 1 | |
queues: | ||
- default | ||
- clock | ||
- providers | ||
- billing | ||
- webhook | ||
|
||
|
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 |
---|---|---|
@@ -1,9 +1,9 @@ | ||
# frozen_string_literal: true | ||
|
||
FactoryBot.define do | ||
factory :payment_provider_customer do | ||
factory :stripe_customer, class: 'PaymentProviderCustomers::StripeCustomer' do | ||
customer | ||
|
||
external_customer_id { SecureRandom.uuid } | ||
provider_customer_id { SecureRandom.uuid } | ||
end | ||
end |
22 changes: 22 additions & 0 deletions
22
spec/jobs/payment_provider_customers/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 PaymentProviderCustomers::StripeCreateJob, type: :job do | ||
let(:stripe_customer) { create(:stripe_customer) } | ||
|
||
let(:stripe_service) { instance_double(PaymentProviderCustomers::StripeService) } | ||
|
||
it 'calls the stripe create service' do | ||
allow(PaymentProviderCustomers::StripeService).to receive(:new) | ||
.with(stripe_customer) | ||
.and_return(stripe_service) | ||
allow(stripe_service).to receive(:create) | ||
.and_return(BaseService::Result.new) | ||
|
||
described_class.perform_now(stripe_customer) | ||
|
||
expect(PaymentProviderCustomers::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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -149,6 +149,59 @@ | |
end | ||
end | ||
end | ||
|
||
context 'when forcing customer creation on stripe' do | ||
before do | ||
create( | ||
:stripe_provider, | ||
organization: organization, | ||
create_customers: true, | ||
) | ||
end | ||
|
||
it 'creates a payment provider customer' do | ||
result = customers_service.create_from_api( | ||
organization: organization, | ||
params: create_args, | ||
) | ||
|
||
aggregate_failures do | ||
expect(result).to be_success | ||
|
||
customer = result.customer | ||
expect(customer.id).to be_present | ||
expect(customer.payment_provider).to eq('stripe') | ||
expect(customer.stripe_customer).to be_present | ||
end | ||
end | ||
|
||
context 'when customer is updated' do | ||
before do | ||
create( | ||
:customer, | ||
organization: organization, | ||
customer_id: create_args[:customer_id], | ||
email: '[email protected]', | ||
) | ||
end | ||
|
||
it 'does not create a payment provider customer' do | ||
result = customers_service.create_from_api( | ||
organization: organization, | ||
params: create_args, | ||
) | ||
|
||
aggregate_failures do | ||
expect(result).to be_success | ||
|
||
customer = result.customer | ||
expect(customer.id).to be_present | ||
expect(customer.payment_provider).to be_nil | ||
expect(customer.stripe_customer).not_to be_present | ||
end | ||
end | ||
end | ||
end | ||
end | ||
|
||
describe 'create' do | ||
|
@@ -201,6 +254,29 @@ | |
expect(result).not_to be_success | ||
end | ||
end | ||
|
||
context 'with payment provider' do | ||
before do | ||
create( | ||
:stripe_provider, | ||
organization: organization, | ||
create_customers: true, | ||
) | ||
end | ||
|
||
it 'creates a payment provider customer' do | ||
result = customers_service.create(**create_args) | ||
|
||
aggregate_failures do | ||
expect(result).to be_success | ||
|
||
customer = result.customer | ||
expect(customer.id).to be_present | ||
expect(customer.payment_provider).to eq('stripe') | ||
expect(customer.stripe_customer).to be_present | ||
end | ||
end | ||
end | ||
end | ||
|
||
describe 'update' do | ||
|
@@ -252,6 +328,29 @@ | |
end | ||
end | ||
end | ||
|
||
context 'when updating payment provider' do | ||
let(:update_args) do | ||
{ | ||
id: customer.id, | ||
name: 'Updated customer name', | ||
customer_id: customer_id, | ||
payment_provider: 'stripe', | ||
} | ||
end | ||
|
||
it 'creates a payment provider customer' do | ||
result = customers_service.update(**update_args) | ||
|
||
expect(result).to be_success | ||
|
||
updated_customer = result.customer | ||
aggregate_failures do | ||
expect(updated_customer.payment_provider).to eq('stripe') | ||
expect(updated_customer.stripe_customer).to be_present | ||
end | ||
end | ||
end | ||
end | ||
|
||
describe 'destroy' do | ||
|
Oops, something went wrong.