Skip to content

Commit

Permalink
Merge pull request #51 from internetee/add-oneoff-endpoint-for-payment
Browse files Browse the repository at this point in the history
added oneoff feature for payment
  • Loading branch information
vohmar authored Sep 2, 2022
2 parents d0d1b66 + 81a0bfc commit bfa1392
Show file tree
Hide file tree
Showing 15 changed files with 249 additions and 8 deletions.
10 changes: 5 additions & 5 deletions Dockerfile.dev
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ RUN apt-get update && apt-get install -y --no-install-recommends \

RUN npm install -g yarn@latest

COPY package.json ./
RUN yarn install --check-files

WORKDIR /opt/webapps/app

ENTRYPOINT ["./entrypoint.sh"]
COPY Rakefile Gemfile Gemfile.lock ./
RUN gem install bundler && bundle install --jobs 20 --retry 5

COPY package.json ./
RUN yarn install --check-files && yarn sass-migrator division **/*.scss

EXPOSE 3000

CMD ["bundle", "exec", "rails", "s", "-b", "0.0.0.0"]

3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,6 @@ group :test do
gem 'webdrivers'
gem 'webmock'
end

# token
gem 'jwt'
2 changes: 2 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ GEM
activesupport (>= 4.2)
aes_key_wrap
bindata
jwt (2.4.1)
launchy (2.5.0)
addressable (~> 2.7)
loofah (2.18.0)
Expand Down Expand Up @@ -348,6 +349,7 @@ DEPENDENCIES
fuubar
jbuilder
jsbundling-rails
jwt
omniauth (>= 2.0.0)
omniauth-rails_csrf_protection
omniauth-tara!
Expand Down
21 changes: 21 additions & 0 deletions app/controllers/invoices_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,27 @@ def add_credit
redirect_to invoice_path(@response.invoice[:id])
end

def pay
invoice_number = params[:invoice_number]
reference_no = params[:reference_no]
response = Billing::Oneoff.send_invoice(invoice_number: invoice_number.to_s,
customer_url: callback_url,
reference_number: reference_no)

if response['error'].present?
flash.alert = response['error']['message']
redirect_to invoices_path and return
end

redirect_to response['oneoff_redirect_link'], allow_other_host: true
end

def callback
Billing::SendCallback.send(reference_number: params['payment_reference'])

redirect_to invoices_path
end

private

def invoice_params
Expand Down
36 changes: 36 additions & 0 deletions app/services/billing/connection.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
module Billing
module Connection
BASE_URL = Rails.configuration.customization[:eis_billing_system_base_url]
INITIATOR = 'registry'.freeze

def connection
Faraday.new(options) do |faraday|
faraday.adapter Faraday.default_adapter
end
end

private

def options
{
headers: {
'Authorization' => "Bearer #{generate_token}",
'Content-Type' => 'application/json',
},
url: BASE_URL,
}
end

def generate_token
JWT.encode(payload, billing_secret)
end

def payload
{ initiator: INITIATOR }
end

def billing_secret
Rails.configuration.customization[:billing_secret]
end
end
end
31 changes: 31 additions & 0 deletions app/services/billing/oneoff.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module Billing
class Oneoff
include Billing::Request
attr_reader :invoice_number, :customer_url, :reference_number

def initialize(invoice_number:, customer_url:, reference_number:)
@invoice_number = invoice_number
@customer_url = customer_url
@reference_number = reference_number
end

def self.send_invoice(invoice_number:, customer_url:, reference_number:)
fetcher = new(invoice_number: invoice_number, customer_url: customer_url, reference_number: reference_number)
fetcher.send_it
end

def send_it
post invoice_oneoff_url, params
end

def params
{ invoice_number: invoice_number,
customer_url: customer_url,
reference_number: reference_number }
end

def invoice_oneoff_url
'/api/v1/invoice_generator/oneoff'
end
end
end
23 changes: 23 additions & 0 deletions app/services/billing/request.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module Billing
module Request
include Billing::Connection

def get(path, params = {})
respond_with(
connection.get(path, params)
)
end

def post(path, params = {})
respond_with(
connection.post(path, JSON.dump(params))
)
end

private

def respond_with(response)
JSON.parse response.body
end
end
end
23 changes: 23 additions & 0 deletions app/services/billing/send_callback.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module Billing
class SendCallback
include Billing::Request
attr_reader :reference_number

def initialize(reference_number:)
@reference_number = reference_number
end

def self.send(reference_number:)
fetcher = new(reference_number: reference_number)
fetcher.send_it
end

def send_it
get billing_callback_url
end

def billing_callback_url
"/api/v1/callback_handler/callback?payment_reference=#{reference_number}"
end
end
end
2 changes: 1 addition & 1 deletion app/views/invoices/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
</div>
<% if @invoice[:payable] && @invoice[:payment_link].present? %>
<div class="col-xs-auto">
<%= link_to t(:pay), @invoice[:payment_link], target: :_blank, class: 'button button--secondary' %>
<%= button_to t(:pay), pay_path(invoice_number: @invoice[:number], reference_no: @invoice[:reference_no]), method: :post, class: 'button button--secondary' %>
</div>
<% end %>
<% if @invoice[:cancellable] && !@invoice[:monthly_invoice] %>
Expand Down
4 changes: 4 additions & 0 deletions config/application.yml.sample
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ shared:
# Custom legal document types. Changing this requires updating EPP extension schema for allowed legalDocEnumType values.
# System default for legal document types is: pdf,asice,sce,asics,scs,adoc,edoc,bdoc,ddoc,zip,rar,gz,tar,7z,odt,doc,docx
legal_document_types: "pdf,asice,sce,asics,scs,adoc,edoc,bdoc,ddoc,zip,rar,gz,tar,7z,odt,doc,docx"

eis_billing_system_base_url: 'http://eis_billing_system:3000'
billing_secret: ''

tara:
scheme: 'https'
host: 'test-auth.eeid.ee'
Expand Down
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@
get 'invoices/:id/download', to: 'invoices#download', as: :download_invoice
post 'invoices/cancel', to: 'invoices#cancel', as: :cancel_invoice
post 'invoices/add_credit', to: 'invoices#add_credit', as: :add_credit
post 'invoices/pay', to: 'invoices#pay', as: :pay
get 'invoices/callback', to: 'invoices#callback', as: :callback
post 'invoices/send_to_recipient', to: 'invoices#send_to_recipient', as: :send_invoice
resources :invoices, only: %i[index show]

Expand Down
65 changes: 63 additions & 2 deletions spec/controllers/invoices_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,69 @@
description: Faker::Lorem.sentence,
},
},
},
}
]

it_behaves_like 'Base controller with auth', options
end

describe 'billing connection' do
before(:each) do
allow_any_instance_of(BaseController).to receive(:check_auth_info).and_return(true)
end

describe 'successful oneoff redirection' do
redirect_link = "http://everypay.ee/go"
oneoff_payload = {
oneoff_redirect_link: redirect_link
}

subject do
stub_request(:post, "#{Billing::Connection::BASE_URL}/api/v1/invoice_generator/oneoff")
.to_return(status: 200, body: oneoff_payload.to_json, headers: {})

post :pay, params: { invoice_number: '2332434 '}
end

it 'should redirect to everypay payment dialog if oneoff link has been received' do
expect(subject).to redirect_to(redirect_link)
end
end

describe 'oneoff response with error' do
error_message = {
error: {
message: "Something goes wrong"
}
}

subject do
stub_request(:post, "#{Billing::Connection::BASE_URL}/api/v1/invoice_generator/oneoff")
.to_return(status: 200, body: error_message.to_json, headers: {})

post :pay, params: { invoice_number: '2332434 '}
end

it 'should redirect to invoices_path if comes error from billing' do
expect(subject).to redirect_to(invoices_path)
end
end

describe 'callback from everypay' do
payment_reference = '223344abc'
message = {
message: true
}

subject do
stub_request(:get, "#{Billing::Connection::BASE_URL}/api/v1/callback_handler/callback?payment_reference=#{payment_reference}")
.to_return(status: 200, body: message.to_json, headers: {})

get :callback, params: { payment_reference: payment_reference }
end

it 'should redirect everypay callback to billing callback handler and redirected to invoices list' do
expect(subject).to redirect_to(invoices_path)
end
end
end
end
16 changes: 16 additions & 0 deletions spec/services/oneoff_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
require 'webmock/rspec'

RSpec.describe Billing::Oneoff do
before(:each) do
VCR.eject_cassette
end

specify "#send invoice" do
stub_request(:post, "#{Billing::Connection::BASE_URL}/api/v1/invoice_generator/oneoff")
.to_return(status: 200, body: "{\"oneoff_redirect_link\": \"everypay/go\"}", headers: {})

response = described_class.send_invoice(invoice_number: '332211', customer_url: 'http://fake.ee', reference_number: '33322')

expect(response["oneoff_redirect_link"].to_s).to eq("everypay/go")
end
end
16 changes: 16 additions & 0 deletions spec/services/send_callback_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
require 'webmock/rspec'

RSpec.describe Billing::SendCallback do
before(:each) do
VCR.eject_cassette
end

specify "#send callback" do
stub_request(:get, "#{Billing::Connection::BASE_URL}/api/v1/callback_handler/callback?payment_reference=3434sdfsdfsdf2234234")
.to_return(status: 200, body: "{\"message\": \"received\"}", headers: {})

response = described_class.send(reference_number: '3434sdfsdfsdf2234234')

expect(response["message"].to_s).to eq("received")
end
end
3 changes: 3 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@

require 'vcr'
require 'uri'
require 'webmock/rspec'

WebMock.disable_net_connect!(allow_localhost: true)

# This module is used for avoiding VCR cassettes host conflicts
# during testing on staging environment
Expand Down

0 comments on commit bfa1392

Please sign in to comment.