bambora-client 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/linter.yml +13 -0
- data/.github/workflows/ruby.yml +34 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.rubocop.yml +108 -0
- data/.ruby-version +1 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +93 -0
- data/LICENSE.txt +21 -0
- data/README.md +198 -0
- data/Rakefile +8 -0
- data/bambora-client.gemspec +55 -0
- data/bin/console +12 -0
- data/bin/setup +8 -0
- data/lib/bambora/adapters/json_response.rb +7 -0
- data/lib/bambora/adapters/multipart_mixed_request.rb +23 -0
- data/lib/bambora/adapters/query_string_response.rb +20 -0
- data/lib/bambora/adapters/response.rb +44 -0
- data/lib/bambora/bank/adapters/payment_profile_response.rb +36 -0
- data/lib/bambora/bank/batch_report_messages.rb +81 -0
- data/lib/bambora/bank/batch_report_resource.rb +79 -0
- data/lib/bambora/bank/builders/payment_profile_params.rb +39 -0
- data/lib/bambora/bank/payment_profile_resource.rb +81 -0
- data/lib/bambora/builders/batch_payment_csv.rb +41 -0
- data/lib/bambora/builders/headers.rb +43 -0
- data/lib/bambora/builders/www_form_parameters.rb +33 -0
- data/lib/bambora/builders/xml_request_body.rb +19 -0
- data/lib/bambora/client.rb +215 -0
- data/lib/bambora/client/version.rb +7 -0
- data/lib/bambora/factories/response_adapter_factory.rb +21 -0
- data/lib/bambora/rest/batch_payment_file_upload_client.rb +58 -0
- data/lib/bambora/rest/client.rb +63 -0
- data/lib/bambora/rest/json_client.rb +109 -0
- data/lib/bambora/rest/www_form_client.rb +38 -0
- data/lib/bambora/rest/xml_client.rb +35 -0
- data/lib/bambora/v1/batch_payment_resource.rb +52 -0
- data/lib/bambora/v1/payment_resource.rb +82 -0
- data/lib/bambora/v1/profile_resource.rb +85 -0
- metadata +256 -0
data/Rakefile
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
lib = File.expand_path('lib', __dir__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'bambora/client/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'bambora-client'
|
8
|
+
spec.version = Bambora::Client::VERSION
|
9
|
+
spec.authors = ['Cassidy K']
|
10
|
+
spec.email = ['hello@cassidy.codes', 'tech@himama.com']
|
11
|
+
|
12
|
+
spec.summary = 'A thread-safe client for the Bambora/Beanstream API.'
|
13
|
+
spec.description = 'The official beanstream-ruby gem is not thread-safe. This thread-safe client works in '\
|
14
|
+
'environments like Sidekiq and Puma.'
|
15
|
+
spec.homepage = 'https://github.com/HiMamaInc/bambora-client'
|
16
|
+
spec.license = 'MIT'
|
17
|
+
|
18
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
19
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
20
|
+
if spec.respond_to?(:metadata)
|
21
|
+
spec.metadata['allowed_push_host'] = "https://rubygems.org"
|
22
|
+
|
23
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
24
|
+
spec.metadata['source_code_uri'] = 'https://github.com/HiMamaInc/bambora-client'
|
25
|
+
spec.metadata['changelog_uri'] = 'https://github.com/HiMamaInc/bambora-client/releases'
|
26
|
+
else
|
27
|
+
raise 'RubyGems 2.0 or newer is required to protect against ' \
|
28
|
+
'public gem pushes.'
|
29
|
+
end
|
30
|
+
|
31
|
+
# Specify which files should be added to the gem when it is released.
|
32
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
33
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
34
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
35
|
+
end
|
36
|
+
spec.bindir = 'exe'
|
37
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
38
|
+
spec.require_paths = ['lib']
|
39
|
+
|
40
|
+
spec.required_ruby_version = '>= 2.4.6'
|
41
|
+
|
42
|
+
spec.add_dependency 'excon', '< 1.0'
|
43
|
+
spec.add_dependency 'faraday', '< 1.0'
|
44
|
+
spec.add_dependency 'gyoku', '~> 1.0'
|
45
|
+
spec.add_dependency 'multiparty', '~> 0'
|
46
|
+
|
47
|
+
spec.add_development_dependency 'bundler', '~> 2'
|
48
|
+
spec.add_development_dependency 'pry', '~> 0.12.0'
|
49
|
+
spec.add_development_dependency 'pry-byebug', '~> 3.7'
|
50
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
51
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
52
|
+
spec.add_development_dependency 'rspec_junit_formatter', '~> 0.4.1'
|
53
|
+
spec.add_development_dependency 'rubocop', '~> 0.74.0'
|
54
|
+
spec.add_development_dependency 'webmock', '~> 3.7'
|
55
|
+
end
|
data/bin/console
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'bambora/client'
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
require 'pry'
|
12
|
+
Pry.start
|
data/bin/setup
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bambora
|
4
|
+
module Adapters
|
5
|
+
##
|
6
|
+
# Creates headers and a body for a multipart/mixed request with a file and a JSON body.
|
7
|
+
class MultipartMixedRequest
|
8
|
+
attr_reader :multiparty
|
9
|
+
|
10
|
+
def initialize(options = {})
|
11
|
+
@multiparty = Multiparty.new { |party| party.parts = options[:multipart_args] }
|
12
|
+
end
|
13
|
+
|
14
|
+
def content_type
|
15
|
+
multiparty.header.sub(/^Content-Type: /, '').strip
|
16
|
+
end
|
17
|
+
|
18
|
+
def body
|
19
|
+
"#{multiparty.body}\r\n"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bambora
|
4
|
+
##
|
5
|
+
# Parses a query string response into a Hash
|
6
|
+
class QueryStringResponse < Response
|
7
|
+
def to_h
|
8
|
+
parsed_response = super
|
9
|
+
return error_response if parsed_response.values.flatten.empty? # We didn't get a query string back.
|
10
|
+
|
11
|
+
parsed_response.each_with_object({}) { |(key, val), obj| obj[key] = val.length == 1 ? val.first : val }
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def parser
|
17
|
+
CGI
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bambora
|
4
|
+
##
|
5
|
+
# Parses a response into a Hash. Uses JSON to parse by default.
|
6
|
+
class Response
|
7
|
+
DEFAULT_PARSER = JSON
|
8
|
+
|
9
|
+
attr_reader :response
|
10
|
+
|
11
|
+
def initialize(response)
|
12
|
+
@response = response
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_h
|
16
|
+
deep_transform_keys_in_object(parser.parse(response.body), &:to_sym)
|
17
|
+
rescue JSON::ParserError
|
18
|
+
error_response
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def deep_transform_keys_in_object(object, &block)
|
24
|
+
case object
|
25
|
+
when Hash
|
26
|
+
object.each_with_object({}) do |(key, value), result|
|
27
|
+
result[yield(key)] = deep_transform_keys_in_object(value, &block)
|
28
|
+
end
|
29
|
+
when Array
|
30
|
+
object.map { |e| deep_transform_keys_in_object(e, &block) }
|
31
|
+
else
|
32
|
+
object
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def error_response
|
37
|
+
{ status: response.status, body: response.body }
|
38
|
+
end
|
39
|
+
|
40
|
+
def parser
|
41
|
+
DEFAULT_PARSER
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bambora
|
4
|
+
module Bank
|
5
|
+
module Adapters
|
6
|
+
##
|
7
|
+
# Transforms hash keys from camelCase to snake_case and strips vendor-specific prefixes.
|
8
|
+
class PaymentProfileResponse
|
9
|
+
attr_reader :response
|
10
|
+
|
11
|
+
def initialize(response)
|
12
|
+
@response = response
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_h
|
16
|
+
parsed_query_string.each_with_object({}) do |(key, val), obj|
|
17
|
+
obj[transform(key)] = val
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def parsed_query_string
|
24
|
+
Bambora::QueryStringResponse.new(response).to_h
|
25
|
+
end
|
26
|
+
|
27
|
+
def transform(camel_case_word)
|
28
|
+
word = camel_case_word.to_s
|
29
|
+
word.gsub!(/([a-z])([A-Z\d])/, '\1_\2')
|
30
|
+
word.downcase!
|
31
|
+
word.sub(/^ord_/, '').to_sym
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bambora
|
4
|
+
module Bank
|
5
|
+
module BatchReportMessages
|
6
|
+
##
|
7
|
+
# Adds message text to the response as per the Bambora Docs:
|
8
|
+
# https://help.na.bambora.com/hc/en-us/articles/115010510248-Batch-reporting
|
9
|
+
MESSAGES = {
|
10
|
+
'1' => 'Invalid bank number',
|
11
|
+
'2' => 'Invalid branch number',
|
12
|
+
'3' => 'Invalid account number',
|
13
|
+
'4' => 'Invalid transaction amount',
|
14
|
+
'5' => 'Reference number too long',
|
15
|
+
'6' => 'Invalid due date',
|
16
|
+
'7' => 'Due date out of valid date range',
|
17
|
+
'8' => 'Customer name truncated to 32 characters',
|
18
|
+
'9' => 'Customer name missing',
|
19
|
+
'10' => 'Duplicate transaction matching bank account',
|
20
|
+
'11' => 'Zero, negative or non-numeric amount',
|
21
|
+
'12' => 'Invalid bank and/or branch number',
|
22
|
+
'13' => 'Payee/drawee name cannot be spaces',
|
23
|
+
'14' => 'Invalid payment code',
|
24
|
+
'15' => 'Invalid transaction type',
|
25
|
+
'16' => 'Account Closed',
|
26
|
+
'17' => 'NSF – Debit declined due to insufficient funds.',
|
27
|
+
'18' => 'Transaction rejected by Bank',
|
28
|
+
'19' => 'Invalid bank, branch, or account number',
|
29
|
+
'20' => 'Refused by payor',
|
30
|
+
'21' => 'Funds not cleared',
|
31
|
+
'22' => 'Account Frozen',
|
32
|
+
'23' => 'Payment Stopped',
|
33
|
+
'24' => 'Transaction Cancelled',
|
34
|
+
'25' => 'Cannot Trace',
|
35
|
+
'26' => 'Incorrect Payor/Payee Name',
|
36
|
+
'27' => 'Payor/Payee Deceased',
|
37
|
+
'28' => 'Invalid transit routing number',
|
38
|
+
'29' => 'Invalid Account Type',
|
39
|
+
'30' => 'Transaction type not permitted',
|
40
|
+
'31' => 'No Checking Privileges',
|
41
|
+
'33' => 'Edit Reject',
|
42
|
+
'35' => 'Reserved Return Code',
|
43
|
+
'36' => 'Payment Recalled',
|
44
|
+
'38' => 'Not in accordance with agreement – Personal',
|
45
|
+
'39' => 'Agreement revoked – Personal',
|
46
|
+
'40' => 'No pre-notification – Personal',
|
47
|
+
'41' => 'Not in accordance with agreement – Business',
|
48
|
+
'42' => 'Agreement revoked – Business',
|
49
|
+
'43' => 'No pre-notification – Business',
|
50
|
+
'44' => 'Customer Initiated Return Credit Only',
|
51
|
+
'45' => 'Currency/Account Mismatch',
|
52
|
+
'46' => 'No Debit Allowed',
|
53
|
+
'47' => 'Interbank – Returned Item',
|
54
|
+
'48' => 'Routing as entered, account modified',
|
55
|
+
'49' => 'Routing as entered, repair of account unknown',
|
56
|
+
'50' => 'Routing as entered, account unknown',
|
57
|
+
'51' => 'Routing number modified, account as entered',
|
58
|
+
'52' => 'Routing number modified, account modified',
|
59
|
+
'53' => 'Routing number modified, repair of account unknown',
|
60
|
+
'54' => 'Routing number modified, account unknown',
|
61
|
+
'55' => 'ACH Unavailable for account',
|
62
|
+
'56' => 'Customer code invalid/missing payment info',
|
63
|
+
'58' => 'Profile status is closed or disabled',
|
64
|
+
'59' => 'Invalid SEC code',
|
65
|
+
'60' => 'Invalid Account Identifier',
|
66
|
+
'61' => 'Invalid Account Identifier',
|
67
|
+
'62' => 'Reference Number is Missing',
|
68
|
+
'63' => 'Invalid Customer Country Code',
|
69
|
+
'64' => 'Invalid Bank Country Code',
|
70
|
+
'65' => 'Invalid Bank Name',
|
71
|
+
'66' => 'Bank Name is Missing',
|
72
|
+
'67' => 'Addendum not allowed, too long, or has invalid characters',
|
73
|
+
'68' => 'Invalid Bank Descriptor',
|
74
|
+
'69' => 'Invalid Customer Name',
|
75
|
+
'70' => 'Transaction rejected - contact support',
|
76
|
+
'71' => 'Refund Request by End Customer',
|
77
|
+
'72' => 'Blocked due to a Notice of Change',
|
78
|
+
}.freeze
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bambora
|
4
|
+
module Bank
|
5
|
+
##
|
6
|
+
# For making requests to the /scripts/reporting/report.aspx endpoint
|
7
|
+
#
|
8
|
+
# @see https://dev.na.bambora.com/docs/guides/batch_payment/report/
|
9
|
+
class BatchReportResource
|
10
|
+
include Bambora::Bank::BatchReportMessages
|
11
|
+
|
12
|
+
DEFAULT_REQUEST_PARAMS = {
|
13
|
+
rpt_format: 'JSON',
|
14
|
+
rpt_version: '2.0',
|
15
|
+
session_source: 'external',
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
attr_reader :client, :api_key, :sub_path, :version
|
19
|
+
|
20
|
+
##
|
21
|
+
# Instantiate an interface to make requests against Bambora's Profiles API.
|
22
|
+
#
|
23
|
+
# @example
|
24
|
+
#
|
25
|
+
# client = Bambora::Rest::XMLClient(base_url: '...', merchant_id: '...')
|
26
|
+
# profiles = Bambora::Bank::BatchReportResource(client: client, api_key: '...')
|
27
|
+
#
|
28
|
+
# # Start making requests ...
|
29
|
+
#
|
30
|
+
# @param client [Bambora::Rest::XMLClient] An instance of Bambora::Rest::XMLClient, used to make network requests.
|
31
|
+
# @param api_key [String] An API key for this endpoint. This is also known as the "Pass Code"
|
32
|
+
# @param version [String] The Service Version you are requesting from the server.
|
33
|
+
def initialize(client:, api_key:)
|
34
|
+
@client = client
|
35
|
+
@api_key = api_key
|
36
|
+
@sub_path = '/scripts/reporting/report.aspx'
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# Create a Bank Payment Profile
|
41
|
+
#
|
42
|
+
# @example
|
43
|
+
# data = {
|
44
|
+
# rpt_filter_by_1: 'batch_id',
|
45
|
+
# rpt_filter_value_1: 1,
|
46
|
+
# rpt_operation_type_1: 'EQ',
|
47
|
+
# rpt_from_date_time: '2019-12-18 00:00:00',
|
48
|
+
# rpt_to_date_time: '2019-12-18 23:59:59',
|
49
|
+
# service_name: 'BatchPaymentsEFT',
|
50
|
+
# }
|
51
|
+
#
|
52
|
+
# payment_profile_resource.show(data)
|
53
|
+
#
|
54
|
+
# @params profile_data [Hash] with values as noted in the example.
|
55
|
+
def show(report_data)
|
56
|
+
add_messages_to_response(
|
57
|
+
client.post(path: sub_path, body: batch_report_body(report_data)),
|
58
|
+
)
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def add_messages_to_response(response)
|
64
|
+
response.dig(:response, :record).map! do |record|
|
65
|
+
record.merge!(messages: record[:messageId].split(',').map { |id| MESSAGES[id] })
|
66
|
+
end
|
67
|
+
response
|
68
|
+
end
|
69
|
+
|
70
|
+
def batch_report_body(request_data)
|
71
|
+
DEFAULT_REQUEST_PARAMS.merge(request_data).merge(
|
72
|
+
merchant_id: client.merchant_id,
|
73
|
+
pass_code: api_key,
|
74
|
+
sub_merchant_id: client.sub_merchant_id,
|
75
|
+
)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bambora
|
4
|
+
module Bank
|
5
|
+
module Builders
|
6
|
+
##
|
7
|
+
# Builds a request body for the Bank Payment Profile endpoint from a Hash
|
8
|
+
class PaymentProfileParams
|
9
|
+
CONTACT_PARAMS =
|
10
|
+
%w[name email_address phone_number address_1 address_2 city postal_code province country].freeze
|
11
|
+
|
12
|
+
class << self
|
13
|
+
##
|
14
|
+
# Converts a snake_case hash to camelCase keys with vendor-specific prefixes.
|
15
|
+
# See tests for examples.
|
16
|
+
#
|
17
|
+
# @params params [Hash]
|
18
|
+
def build(params)
|
19
|
+
params.each_with_object({}) do |(key, value), obj|
|
20
|
+
obj[transform_key(key)] = value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def transform_key(key)
|
27
|
+
key = key.to_s
|
28
|
+
key = "ord_#{key}" if CONTACT_PARAMS.include?(key)
|
29
|
+
|
30
|
+
key.split('_').map.with_index do |word, index|
|
31
|
+
word.capitalize! unless index.zero?
|
32
|
+
word
|
33
|
+
end.join
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bambora
|
4
|
+
module Bank
|
5
|
+
##
|
6
|
+
# For making requests to the /scripts/payment_profile.asp endpoint
|
7
|
+
#
|
8
|
+
# @see https://help.na.bambora.com/hc/en-us/articles/115010346067-Secure-Payment-Profiles-Batch-Payments
|
9
|
+
class PaymentProfileResource
|
10
|
+
DEFAULT_VERSION = 1.0
|
11
|
+
DEFAULT_RESPONSE_FORMAT = 'QS'
|
12
|
+
CREATE_OPERATION_TYPE = 'N'
|
13
|
+
|
14
|
+
attr_reader :client, :api_key, :sub_path, :version
|
15
|
+
|
16
|
+
##
|
17
|
+
# Instantiate an interface to make requests against Bambora's Profiles API.
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
#
|
21
|
+
# client = Bambora::Rest::WWWFormClient(base_url: '...', merchant_id: '...')
|
22
|
+
# profiles = Bambora::Bank::PaymentProfileResource(client: client, api_key: '...')
|
23
|
+
#
|
24
|
+
# # Start making requests ...
|
25
|
+
#
|
26
|
+
# @param client [Bambora::Rest::WWWFormClient] An instance of Bambora::Rest::WWWFormClient, used to make network
|
27
|
+
# requests.
|
28
|
+
# @param api_key [String] An API key for this endpoint. This is also known as the "Pass Code"
|
29
|
+
# @param version [String] The Service Version you are requesting from the server.
|
30
|
+
def initialize(client:, api_key:, version: DEFAULT_VERSION)
|
31
|
+
@client = client
|
32
|
+
@api_key = api_key
|
33
|
+
@version = version
|
34
|
+
@sub_path = '/scripts/payment_profile.asp'
|
35
|
+
end
|
36
|
+
|
37
|
+
##
|
38
|
+
# Create a Bank Payment Profile
|
39
|
+
#
|
40
|
+
# @example
|
41
|
+
# data = {
|
42
|
+
# customer_code: '1234',
|
43
|
+
# bank_account_type: 'CA',
|
44
|
+
# bank_account_holder: 'All-Maudra Mayrin',
|
45
|
+
# institution_number: '123',
|
46
|
+
# branch_number: '12345',
|
47
|
+
# account_number: '123456789',
|
48
|
+
# name: 'Hup Podling',
|
49
|
+
# email_address: 'Brea Princess of Vapra',
|
50
|
+
# phone_number: '1231231234',
|
51
|
+
# address_1: 'The Castle',
|
52
|
+
# city: "Ha'rar",
|
53
|
+
# postal_code: 'H0H 0H0',
|
54
|
+
# province: 'Vapra',
|
55
|
+
# country: 'Thra',
|
56
|
+
# }
|
57
|
+
#
|
58
|
+
# payment_profile_resource.create(data)
|
59
|
+
#
|
60
|
+
# @params profile_data [Hash] with values as noted in the example.
|
61
|
+
def create(profile_data)
|
62
|
+
client.post(path: sub_path, body: payment_profile_body(profile_data))
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def payment_profile_body(profile_data)
|
68
|
+
Bambora::Bank::Builders::PaymentProfileParams.build(
|
69
|
+
profile_data.merge(
|
70
|
+
pass_code: api_key,
|
71
|
+
merchant_id: client.merchant_id,
|
72
|
+
sub_merchant_id: client.sub_merchant_id,
|
73
|
+
service_version: version,
|
74
|
+
response_format: DEFAULT_RESPONSE_FORMAT,
|
75
|
+
operation_type: CREATE_OPERATION_TYPE,
|
76
|
+
),
|
77
|
+
)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|