Client for Comgate payment gateway
https://help.comgate.cz/docs/api-protokol
Install the gem and add to the application's Gemfile by executing:
$ bundle add comgate_ruby
If bundler is not being used to manage dependencies, install the gem by executing:
$ gem install comgate_ruby
As singleton on app init or for each transaction:
gateway = Comgate::Gateway.new(merchant_gateway_id: ":comgate_id",
test_calls: false,
client_secret: ":comgate_secret")
# or with proxy
gateway = Comgate::Gateway.new(merchant_gateway_id: ":comgate_id",
test_calls: false,
client_secret: ":comgate_secret",
proxy_uri: "http://pxuser:[email protected]:123") # or just "http://proxy.me:123"
Comgate sends POST requests to your app about transactions updates. The URL of it needs to be setup in Comgate Client portal. At endpoint, just call gateway.process_callback(params)
, which will return
{state: :paid, transaction_id: ":transID"}
(at least). See bullets 4) and 5) in Single payment process bellow.
(see bellow)
- Start transaction by
gateway.start_transaction(payment_data)
. Response isImportant part is#<Comgate::Response:0x00007f56800295a8 @array=nil, @errors=nil, @hash={:code=>0, :message=>"OK", :transaction_id=>"AB12-CD34-EF56", :redirect_to=>"https://payments.comgate.cz/client/instructions/index?id=AB12-CD34-EF56"}, @http_code=200, @params_conversion_hash= { .... } @redirect_to="https://payments.comgate.cz/client/instructions/index?id=AB12-CD34-EF56">
response.hash
:{ code: 0, message: "OK", transaction_id: "AB12-CD34-EF56" redirect_to: "https://payments.comgate.cz/client/instructions/index?id=AB12-CD34-EF56", }
- Redirect user to
response.redirect_to
page (=> display Comgate form). - Client will (not) pay.
- Comgate will send request to your defined endpoint about status change of transaction. Call
gateway.process_state_change(payload)
, which will return{state: :paid, transaction_id: ":transID"}
(and maybe some more informations). - Now is Your time to handle payment (or other state like
cancelled
,authorized
).
- Use
gateway.start_recurring_transaction(payment_data)
and storetransaction_id
. - Create following payments
gateway.repeat_recurring_transaction(payment_data: new_payment_data)
, wherenew_payment_data
includes{payment: {reccurrence: { init_transaction_id: transaction_id } } }
. No redirection here. Price can change in each payment. - Handle status change like bullets 4) and 5) in single payment
- Use
gateway.start_preauthorized_transaction(payment_data)
and storetransaction_id
. 2a) Confirm payment bygateway.confirm_preauthorized_transaction(payment_data.merge({transaction_id: ":transID"}))
(price cannot exceed preauthorized amount) 2b) Cancel payment bygateway.cancel_preauthorized_transaction(transaction_id: ":transID")
- Handle status change like bullets 4) and 5) in single payment
- Use
gateway.start_verification_transaction(payment_data)
and storetransaction_id
. - If payment is succesfull, bank will refund payment immediatelly.
- Then you can create (repeat) payments like reccuring payments.
- Call
gateway.refund_transaction(payment_data.merge({transaction_id: ":transID"}))
(refunded value cannot exceed paid amount) - Handle status change like bullets 4) and 5) in single payment
- Call
gateway.cancel_transaction(transaction_id: ":transID")
- Handle status change like bullets 4) and 5) in single payment
- The endpoint must be always implemented, this is just additional way to check payment state
- Call
gateway.check_transaction(transaction_id: ":transID")
. It will return{state: :paid, transaction_id: ":transID"}
and some more infos. - Handle status change like bullet 5) in single payment
- Call
gateway.allowed_payment_methods(params)
. It will return array of allowed payment methods inresponse.array
.[ { id: "BANK_CZ_CS_P", name: "Česká spořitelna - PLATBA 24", description: "On-line platba pro majitele účtu u České spořitelny.", logo_url: "https://payments.comgate.cz/assets/images/logos/BANK_CZ_CS_P.png" }, { id: "BANK_CZ_FB_P", name: "Fio banka - PayMyway", description: "On-line platba pro majitele účtu u Fio banky.", logo_url: "https://payments.comgate.cz/assets/images/logos/BANK_CZ_FB.png" } ]
- Call
gateway.transfers_from(date)
. Array of transfers will be returned inresponse.array
.[ { transfer_id: 1234567, transfer_date: date, account_counter_party: "0/0000", account_outgoing: "123456789/0000", variable_symbol: "12345678"} ]
- Call
gateway.download_zipped_csvs_of_transfers(date: time_as_date, output_file_path: path_to_download)
. - Unzip (at your own) file at
:path_to_download
. There can be several CSV files. Example file can be found at./test/fixtures/csvs.zip
.
Structure of parameters is unchanged across most of methods, but you can leave out unused keys. You will get error if You do not pass required key.
See test/comgate/test_gateway.rb
for examples.
Also returned hash have consistent structure (very similar to input params)
Maximal mixed version looks like:
{
code: 0, # output
message: "OK", # output
transfer_id: "1234-abcd-45678", # input/output
test: true, # input (handle as test call)/ output (created by test call)
state: :paid, # output (:pending, :paid, :cancelled, :authorized)
merchant: {
gateway_id: "some_id_from_comgate", # output (input is set at gateway init)
target_shop_account: "12345678/1234", # input (change against default)/ output
},
payment: {
amount_in_cents: 12_900, # input/output
currency: "CZK", # input/output
label: "Payment for 2 straws", # input/output
reference_id: "our eshop order #1 reference", # input/output
method: "CARD_CZ_CSOB_2", # input (selected method; or use "ALL") / output
product_name: "product name ABC", # input/output
fee: nil, # output ( if automatic deduction of the payment fee is set at Comgate)
variable_symbol: 739_689_656, # output (so I acctually do not know where it came from)
apple_pay_payload: "raw apple pay payload", # input
dynamic_expiration: false, # input (see https://help.comgate.cz/v1/docs/expirace-plateb )
expiration_time: "10h", # input ( use "m" or "h" or "d", but only one of them; allowed rage "30m".."7d")
description: "Some description",
reccurrence: { init_transaction_id: "12AD-dfsA-4568",
period: 1,
cycle: :month, # :on_demand
valid_to: } },
},
payer: {
email: "payer1@gmail.com", # input/output
phone: "+420778899", # input/output
first_name: "John", # input - not used at Comgate
last_name: "Doe", # input - not used at Comgate
account_number: "account_num", # output
account_name: "payer account name" # output
},
options: {
country_code: "DE", # input (can restrict allowed payment methods)
language_code: "sk", # input
shop_return_url: "https://example.com/return",
callback_url: "https://example.com/callback"
},
# items are not used at Comgate
items: [{ type: "ITEM",
name: "Je to kulatý – Měsíční (6. 6. 2023 – 6. 7. 2023)",
amount_in_cents: 9900,
count: 1,
vat_rate_percent: 21 }],
headers: {} # not actually used now
}
Response returned from gateway
call is Comgate::Response
instance.
You can check redirection response.redirect? ? response.redirect_to : nil
.
Most of the time, the response shoul be hash-like, stored in response.hash
. But for lists there will be array in response.array
.
If there are errors from API call , they will be in response.errors
. But note, that gateway will raise them and not return Comgate::Response
instance.
And you can also check result.http_code
(which is surprisingly 200 from API errors)
Connection errors or API error responses are raised as RuntimeError with message like "{:api=>[\"[Error #1309] incorrect amount\"]}"
.
Error Number and text can be found in lib/comgate/response.rb
.
This may be refactored in future.
This gem extends Hash
with methods deep_symbolize_keys
and deep_merge
(if needed).
Every request to Comgate is logged/printout at :debug
level. You can change the minimal level with ENV variable "COMGATE_MIN_LOG_LEVEL".
After checking out the repo, run bin/setup
to install dependencies. Then, run rake test
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and the created tag, and push the .gem
file to rubygems.org.
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/comgate_ruby.
The gem is available as open source under the terms of the MIT License.