Skip to content

Commit d86027e

Browse files
committed
add advanced invoive
1 parent 397d6ad commit d86027e

File tree

9 files changed

+195
-9
lines changed

9 files changed

+195
-9
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## [1.1.0] - 2024-08-12
2+
- add ability make payments' requests more advanced by adding more params into `MonopayRuby::Invoices::AdvancedInvoice::create` method
3+
- change private methods to protected
4+
- modify `request_body` for additional params
5+
16
## [1.0.0] - 2023-06-27
27

38
### Changed

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ source "https://rubygems.org"
66
gemspec
77

88
gem "rake", "~> 13.0"
9+
gem 'activesupport', '~> 7.0'

Gemfile.lock

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
PATH
22
remote: .
33
specs:
4-
monopay-ruby (1.0.0)
4+
monopay-ruby (1.1.0)
55
base64 (~> 0.1.1)
66
json (~> 2.5)
77
money (~> 6.13)
@@ -10,13 +10,26 @@ PATH
1010
GEM
1111
remote: https://rubygems.org/
1212
specs:
13+
activesupport (7.1.3.4)
14+
base64
15+
bigdecimal
16+
concurrent-ruby (~> 1.0, >= 1.0.2)
17+
connection_pool (>= 2.2.5)
18+
drb
19+
i18n (>= 1.6, < 2)
20+
minitest (>= 5.1)
21+
mutex_m
22+
tzinfo (~> 2.0)
1323
base64 (0.1.1)
24+
bigdecimal (3.1.8)
1425
coderay (1.1.3)
1526
concurrent-ruby (1.2.2)
27+
connection_pool (2.4.1)
1628
diff-lcs (1.5.0)
1729
docile (1.4.0)
1830
domain_name (0.5.20190701)
1931
unf (>= 0.0.5, < 1.0.0)
32+
drb (2.2.1)
2033
http-accept (1.7.0)
2134
http-cookie (1.0.5)
2235
domain_name (~> 0.5)
@@ -27,8 +40,10 @@ GEM
2740
mime-types (3.4.1)
2841
mime-types-data (~> 3.2015)
2942
mime-types-data (3.2023.0218.1)
43+
minitest (5.25.1)
3044
money (6.16.0)
3145
i18n (>= 0.6.4, <= 2)
46+
mutex_m (0.2.0)
3247
netrc (0.11.0)
3348
pry (0.14.2)
3449
coderay (~> 1.1)
@@ -58,6 +73,8 @@ GEM
5873
simplecov_json_formatter (~> 0.1)
5974
simplecov-html (0.12.3)
6075
simplecov_json_formatter (0.1.4)
76+
tzinfo (2.0.6)
77+
concurrent-ruby (~> 1.0)
6178
unf (0.1.4)
6279
unf_ext
6380
unf_ext (0.0.8.2)
@@ -67,6 +84,7 @@ PLATFORMS
6784
x86_64-linux
6885

6986
DEPENDENCIES
87+
activesupport (~> 7.0)
7088
monopay-ruby!
7189
pry (~> 0.14.2)
7290
rake (~> 13.0)

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,29 @@ class PaymentsController < ApplicationController
6969
end
7070
```
7171

72+
## Generate advanced payment request:
73+
74+
```ruby
75+
# app/controllers/payments_controller.rb
76+
class PaymentsController < ApplicationController
77+
def create
78+
payment = MonopayRuby::Invoices::AdvancedInvoice.new(
79+
redirect_url: "https://example.com",
80+
webhook_url: "https://example.com/payments/webhook"
81+
)
82+
83+
if payment.create(amount, additional_params: {})
84+
# your success code processing
85+
else
86+
# your error code processing
87+
# flash[:error] = payment.error_messages
88+
end
89+
end
90+
end
91+
```
92+
93+
`additional_params` - [Read more about params](https://api.monobank.ua/docs/acquiring.html)
94+
7295
### Verify transaction
7396

7497
```ruby
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
require_relative 'simple_invoice'
2+
3+
module MonopayRuby
4+
module Invoices
5+
class AdvancedInvoice < MonopayRuby::Invoices::SimpleInvoice
6+
attr_reader :additional_params, :amount
7+
8+
# Create invoice for Monobank API
9+
#
10+
# This method sets up the required instance variables and then calls the `create`
11+
# method from the parent class with the relevant parameters.
12+
#
13+
# @param amount [Numeric] The amount of the payment.
14+
# @param additional_params [Hash] (optional) Additional parameters for the payment.
15+
# - :merchantPaymInfo [Hash] Information about the merchant payment.
16+
# - :destination [String] The destination of the payment.
17+
# - :reference [String] A reference for the payment.
18+
#
19+
# @return [Boolean] The result of the `create` method in the parent class,
20+
# which returns true if invoice was created successfully, false otherwise
21+
#
22+
# @example Create a payment with amount and additional parameters
23+
# create(100, additional_params: { merchantPaymInfo: { destination: "Happy payment", reference: "ref123" } })
24+
def create(amount, additional_params: {})
25+
@amount = amount
26+
@additional_params = additional_params
27+
@destination = @additional_params&.dig(:merchantPaymInfo, :destination)
28+
@reference = @additional_params&.dig(:merchantPaymInfo, :reference)
29+
30+
super(amount, destination: @destination, reference: @reference)
31+
end
32+
33+
protected
34+
35+
def request_body
36+
current_params = default_params
37+
38+
return current_params.to_json if additional_params.blank?
39+
40+
unless additional_params[:merchantPaymInfo].blank?
41+
current_params[:merchantPaymInfo] = {
42+
reference: @reference,
43+
destination: @destination
44+
}.merge!(additional_params[:merchantPaymInfo].except(:reference, :destination))
45+
end
46+
47+
current_params.merge!(additional_params.except(:merchantPaymInfo))
48+
49+
# TODO: add and modify sum and qty params of merchantPaymInfo[basketOrder] parameters if it is present
50+
# TODO: add and modify sum and qty params of items parameters if it is present
51+
set_sum_and_qty_params(current_params&.dig(:merchantPaymInfo, :basketOrder))
52+
set_sum_and_qty_params(current_params[:items])
53+
54+
current_params.to_json
55+
end
56+
57+
# Set sum and qty params
58+
# @param current_param [Array] The current parameter to set sum and qty
59+
# It sets the converted amount or sum parameter as sum and pasted quantity parameter or default value as qty parameters for the current parameter
60+
# @return [Object] It could be Hash or Array or nil. It depends on the current parameter
61+
def set_sum_and_qty_params(current_param)
62+
return if current_param.blank?
63+
64+
current_param.each do |item|
65+
return if item.blank?
66+
67+
item[:sum] = convert_to_cents(item[:sum] || amount)
68+
item[:qty] = item[:qty] || 1
69+
end
70+
end
71+
end
72+
end
73+
end

lib/monopay-ruby/invoices/simple_invoice.rb

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
require 'active_support/all'
12
require "bigdecimal"
23
require "money"
34

@@ -53,12 +54,11 @@ def create(amount, destination: nil, reference: nil)
5354
end
5455
end
5556

56-
private
57+
protected
5758

58-
# Request body required for Monobank API
59-
#
60-
# @return [Hash] request body
61-
def request_body
59+
# Default params required for request into Monobank
60+
61+
def default_params
6262
# TODO: add "ccy" and another missing params
6363
# TODO: remove nil valued params
6464
{
@@ -69,7 +69,14 @@ def request_body
6969
reference: reference,
7070
destination: destination
7171
}
72-
}.to_json
72+
}
73+
end
74+
75+
# Request body required for Monobank API
76+
#
77+
# @return [Hash] request body
78+
def request_body
79+
default_params.to_json
7380
end
7481

7582
def convert_to_cents(amount)

lib/monopay-ruby/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# frozen_string_literal: true
22

33
module MonopayRuby
4-
VERSION = "1.0.0"
4+
VERSION = "1.1.0"
55
end
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# frozen_string_literal: true
2+
3+
RSpec.describe MonopayRuby::Invoices::AdvancedInvoice do
4+
describe "#new" do
5+
let!(:redirect_url) { "https://redirect.example.com" }
6+
let!(:webhook_url) { "https://webhook.example.com" }
7+
8+
context "with keyword parameters" do
9+
subject { described_class.new(redirect_url: redirect_url, webhook_url: webhook_url) }
10+
11+
it "initializes with correct redirect_url" do
12+
expect(subject.redirect_url).to eq(redirect_url)
13+
end
14+
15+
it "initializes with correct webhook_url" do
16+
expect(subject.webhook_url).to eq(webhook_url)
17+
end
18+
end
19+
20+
context "without keyword parameters" do
21+
subject { described_class.new(redirect_url, webhook_url) }
22+
23+
it "raises an ArgumentError" do
24+
expect { subject }.to raise_error(ArgumentError)
25+
end
26+
end
27+
28+
context "without parameters" do
29+
subject { described_class.new }
30+
31+
it { is_expected.to be_a(described_class) }
32+
end
33+
end
34+
35+
describe "#create" do
36+
context "when request is successful" do
37+
let(:simple_invoice_instance) { described_class.new }
38+
let(:invoice_id) { "p2_9ZgpZVsl3" }
39+
let(:page_url) { "https://pay.mbnk.biz/p2_9ZgpZVsl3" }
40+
let(:basket_order) { { name: "product", qty: 1 } }
41+
let(:additional_params) { { merchantPaymInfo: { basketOrder: [basket_order] }, ccy: 9 } }
42+
let(:response_example) { { "invoiceId": invoice_id, "pageUrl": page_url } }
43+
44+
before do
45+
allow(RestClient).to receive(:post).and_return(double(body: response_example.to_json))
46+
end
47+
48+
it "returns true" do
49+
expect(simple_invoice_instance.create(2000, additional_params: additional_params)).to be_truthy
50+
end
51+
end
52+
end
53+
end

spec/lib/invoices/simple_invoice_spec.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,13 @@
7171
context "when request is failed" do
7272
context "with missing token" do
7373
# move this code to shared example or mb shared context
74-
let(:missing_x_token_server_message) { { "errorDescription" => "Missing required header 'X-Token'" } }
74+
let(:missing_x_token_server_message) {
75+
{
76+
"errCode" => "BAD_REQUEST",
77+
"errText" => "Missing required header 'X-Token'",
78+
"errorDescription" => "Missing required header 'X-Token'"
79+
}
80+
}
7581
let(:error_code) { "400 Bad Request" }
7682
let(:missing_x_token_header_error_message) do
7783
[error_code, missing_x_token_server_message].join(", ")

0 commit comments

Comments
 (0)