Skip to content

Instantly share code, notes, and snippets.

@oivoodoo
Created August 2, 2022 07:51
Show Gist options
  • Save oivoodoo/e462e4e8add7213b6d47d60b166f0386 to your computer and use it in GitHub Desktop.
Save oivoodoo/e462e4e8add7213b6d47d60b166f0386 to your computer and use it in GitHub Desktop.
paytriot.co.uk payment gateway example
require "ostruct"
require 'digest'
require 'faraday'
module Payments
class Paytriots
# Environment variables
#
# Required:
# - PAYTRIOT_SERVICE_URL
# - PAYTRIOT_SECRET
# - PAYTRIOT_KEY
# - PAYTRIOT_DES_KEY
# - PAYTRIOT_ACCOUNT_ID
#
# Optional:
# - PAYTRIOT_CURRENCY
# - PAYTRIOT_PAYMENT_TYPE
#
# Encryption:
# - md5 is primary encryption
ENV_NAMESPACE = 'PAYTRIOT'
DEFAULT_SERVICE_URL = 'https://api.paytriot.co.uk/api/merchant'
DEFAULT_VERSION = '1.0';
DEFAULT_PAYMENT_TYPE = 'creditcard'
DEFAULT_CURRENCY = 'EUR'
DEFAULT_DEPOSIT_CATEGORY = '3'
DEFAULT_NO_EXPIRATION = 0
# Errors happened on missing required configurations
ERROR_SECRET_REQUIRED = 'secret is required'
ERROR_KEY_REQUIRED = 'key is required'
ERROR_DES_KEY_REQUIRED = 'des key is required'
ERROR_ACCOUNT_ID_REQUIRED = 'account id is required'
TEST_MODE_ENABLED = 1
class << self
def create_payment_url(
amount:,
type: nil,
currency: nil,
deposit_category: nil,
url_user_on_success: nil,
url_user_on_fail: nil,
url_api_on_success: nil,
url_api_on_fail: nil,
no_expiration: nil
)
params = {}
# payment arguments
params[:amount] = amount
params[:type] = settings.payment_type || type
params[:currency] = settings.currency || currency
params[:account_id] = settings.account_id
params[:deposit_category] = settings.deposit_category || deposit_category
# callbacks
params[:url_user_on_success] = url_user_on_success
params[:url_user_on_fail] = url_user_on_fail
params[:url_api_on_success] = url_api_on_success
params[:url_api_on_fail] = url_api_on_fail
params[:no_expiration] = no_expiration || DEFAULT_NO_EXPIRATION
request('create_payment_request_link', params)
end
def request(service_name, params)
params[:test] = TEST_MODE_ENABLED if settings.test_mode
# add signature to params
params = sign(params)
url = get_url(service_name)
response = Faraday.post(url, params.to_json, {'Content-Type' => 'application/json; charset=utf-8'})
JSON.parse(response.body, symbolize_names: true)
end
def get_url(service_name)
"#{settings.service_url}/v/#{DEFAULT_VERSION}/function/#{service_name}"
end
def settings
@settings ||= begin
_settings = OpenStruct.new(
{
secret: get_env('secret'),
key: get_env('key'),
des_key: get_env('des_key'),
account_id: get_env('account_id'),
service_url: get_env('service_url', DEFAULT_SERVICE_URL),
payment_type: get_env('type', DEFAULT_PAYMENT_TYPE),
currency: get_env('currency', DEFAULT_CURRENCY),
deposit_category: get_env('deposit_category', DEFAULT_DEPOSIT_CATEGORY),
test_mode: get_env('test_mode')
}
)
raise Exception.new(ERROR_SECRET_REQUIRED) if _settings.secret.blank?
raise Exception.new(ERROR_KEY_REQUIRED) if _settings.key.blank?
raise Exception.new(ERROR_DES_KEY_REQUIRED) if _settings.des_key.blank?
_settings
end
end
def sign(params)
options = params.dup.symbolize_keys.merge(
key: settings.key,
ts: Time.now.to_i
).compact.sort_by(&:first).to_h
# line = options.map { |(k, v)|
# "#{k}:#{v}"
# }.concat([settings.secret])
line = %I[
type
amount
account_id
currency
url_user_on_success
url_user_on_fail
url_api_on_success
url_api_on_fail
no_expiration
deposit_category
key
ts
]
.select { |k| options[k].present? }
.map { |k| "#{k}:#{options[k]}" }
.concat([settings.secret])
line = line.join(':')
options[:sign] = Digest::MD5.hexdigest(line)
options
end
def get_env(key, default = nil)
ENV.fetch("#{ENV_NAMESPACE}_#{key.upcase}", default)
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment