rails-gp-webpay 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +41 -0
- data/Rakefile +6 -0
- data/app/controllers/gp_webpay/cards_controller.rb +11 -0
- data/app/controllers/gp_webpay/orders_controller.rb +11 -0
- data/app/controllers/gp_webpay_controller.rb +18 -0
- data/changelog.md +4 -0
- data/config/keys/cert.pem +8 -0
- data/config/keys/pkey.pem +13 -0
- data/config/routes.rb +4 -0
- data/config/wsdl/GPwebpayAdditionalInfoResponse_v1.xsd +194 -0
- data/config/wsdl/cws_v1.wsdl +2355 -0
- data/config/wsdl/swaref.xsd +59 -0
- data/lib/gp_webpay.rb +55 -0
- data/lib/gp_webpay/configuration.rb +65 -0
- data/lib/gp_webpay/engine.rb +7 -0
- data/lib/gp_webpay/error.rb +4 -0
- data/lib/gp_webpay/http/base_signed_request.rb +72 -0
- data/lib/gp_webpay/http/create_order.rb +24 -0
- data/lib/gp_webpay/http/external_url.rb +13 -0
- data/lib/gp_webpay/http/http_request.rb +63 -0
- data/lib/gp_webpay/http/http_response.rb +40 -0
- data/lib/gp_webpay/http/validate_result.rb +63 -0
- data/lib/gp_webpay/http/verify_card.rb +18 -0
- data/lib/gp_webpay/openssl_security.rb +16 -0
- data/lib/gp_webpay/response.rb +34 -0
- data/lib/gp_webpay/service.rb +15 -0
- data/lib/gp_webpay/version.rb +3 -0
- data/lib/gp_webpay/ws/base_signed_request.rb +69 -0
- data/lib/gp_webpay/ws/echo.rb +35 -0
- data/lib/gp_webpay/ws/services/get_master_payment_status.rb +32 -0
- data/lib/gp_webpay/ws/services/get_payment_status.rb +19 -0
- data/lib/gp_webpay/ws/services/get_token_status.rb +21 -0
- data/lib/gp_webpay/ws/services/process_cancel_capture.rb +20 -0
- data/lib/gp_webpay/ws/services/process_capture_reverse.rb +20 -0
- data/lib/gp_webpay/ws/services/process_card_on_file_payment.rb +40 -0
- data/lib/gp_webpay/ws/services/process_master_payment_revoke.rb +20 -0
- data/lib/gp_webpay/ws/services/process_recurring_payment.rb +20 -0
- data/lib/gp_webpay/ws/services/process_refund_payment.rb +20 -0
- data/lib/gp_webpay/ws/services/process_token_payment.rb +26 -0
- data/lib/gp_webpay/ws/services/process_token_revoke.rb +20 -0
- data/lib/gp_webpay/ws/services/process_usage_based_payment.rb +21 -0
- data/lib/gp_webpay/ws/validate_result.rb +48 -0
- data/lib/gp_webpay/ws/ws_request.rb +39 -0
- data/lib/gp_webpay/ws/ws_response.rb +54 -0
- metadata +135 -0
@@ -0,0 +1,18 @@
|
|
1
|
+
##
|
2
|
+
# Service object creates request data for GP Webpay CARD_VERIFICATION operation.
|
3
|
+
|
4
|
+
module GpWebpay
|
5
|
+
module Http
|
6
|
+
class VerifyCard < BaseSignedRequest
|
7
|
+
def initialize(attributes, locale, merchant_number: nil, url_attributes: {})
|
8
|
+
super(attributes, locale, 'CARD_VERIFICATION', merchant_number: merchant_number, url_attributes: url_attributes)
|
9
|
+
end
|
10
|
+
|
11
|
+
protected
|
12
|
+
|
13
|
+
def callback_url
|
14
|
+
GpWebpay::Engine.routes.url_helpers.gp_webpay_cards_path({ merchant_number: config.merchant_number, locale: locale }.merge(url_attributes))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module GpWebpay
|
2
|
+
module OpensslSecurity
|
3
|
+
def self.generate_digest(configuration, digest_text)
|
4
|
+
private_pem = OpenSSL::PKey::RSA.new(configuration.merchant_pem, configuration.merchant_password)
|
5
|
+
sign = private_pem.sign(OpenSSL::Digest.new('SHA1'), digest_text)
|
6
|
+
Base64.encode64(sign).gsub("\n", '')
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.validate_digests(configuration, data)
|
10
|
+
public_pem = OpenSSL::X509::Certificate.new(configuration.gpe_pem).public_key
|
11
|
+
data.all? do |received, expected|
|
12
|
+
public_pem.verify(OpenSSL::Digest.new('SHA1'), Base64.decode64(received), expected)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module GpWebpay
|
2
|
+
class Response
|
3
|
+
attr_accessor :original_response,
|
4
|
+
:result_text,
|
5
|
+
:token,
|
6
|
+
:status,
|
7
|
+
:pr_code,
|
8
|
+
:sr_code,
|
9
|
+
:config,
|
10
|
+
:params
|
11
|
+
|
12
|
+
# rubocop:disable Metrics/ParameterLists
|
13
|
+
def initialize(original_response:, result_text:, status:, pr_code:, sr_code:, params:, token: nil, merchant_number: nil)
|
14
|
+
@original_response = original_response
|
15
|
+
@result_text = result_text
|
16
|
+
@token = token
|
17
|
+
@status = status
|
18
|
+
@pr_code = pr_code
|
19
|
+
@sr_code = sr_code
|
20
|
+
@params = params
|
21
|
+
@merchant_number = merchant_number
|
22
|
+
@config = GpWebpay.config[merchant_number] || GpWebpay.config.default
|
23
|
+
end
|
24
|
+
|
25
|
+
# rubocop:enable Metrics/ParameterLists
|
26
|
+
|
27
|
+
def valid?
|
28
|
+
end
|
29
|
+
|
30
|
+
def success?
|
31
|
+
pr_code == '0' && sr_code == '0'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
##
|
2
|
+
# Service object signs request which can be send to GP Webpay payment gateway.
|
3
|
+
#
|
4
|
+
# 1. Use request value object to translate attributes to correct GP Webpay format and order.
|
5
|
+
# 2. Append generated signature to attributes. We expect that XML types are prefixed with 'ins0:' by default.
|
6
|
+
# 3. send XML WS SOAP API request.
|
7
|
+
# 4. generate response object:
|
8
|
+
# - success containing response.
|
9
|
+
# - http error when client-side request fails.
|
10
|
+
# - fail error when external server returns fault.
|
11
|
+
#
|
12
|
+
# @param [Hash] attributes for GP Webpay
|
13
|
+
#
|
14
|
+
# @return [GpwebpayWsResponse] response value object
|
15
|
+
|
16
|
+
module GpWebpay
|
17
|
+
module Ws
|
18
|
+
class BaseSignedRequest < Service
|
19
|
+
attr_reader :attributes, :config
|
20
|
+
|
21
|
+
OPERATION_NAME = 'override_me'.freeze
|
22
|
+
REQUEST_NAME = 'override_me'.freeze
|
23
|
+
RESPONSE_NAME = 'override_me'.freeze
|
24
|
+
RESPONSE_ENTITY_NAME = 'override_me'.freeze
|
25
|
+
SERVICE_EXCEPTION = :service_exception
|
26
|
+
|
27
|
+
def initialize(attributes, merchant_number: :default)
|
28
|
+
@attributes = attributes
|
29
|
+
@merchant_number = merchant_number
|
30
|
+
@config = GpWebpay.config[@merchant_number] || GpWebpay.config.default
|
31
|
+
super()
|
32
|
+
end
|
33
|
+
|
34
|
+
def call
|
35
|
+
attrs = WsRequest.new(attributes.merge(provider: config.provider, merchant_number: config.merchant_number)).to_gpwebpay
|
36
|
+
|
37
|
+
res = client.call(self.class::OPERATION_NAME, message: { self.class::REQUEST_NAME => attributes_with_signature(attrs) })
|
38
|
+
WsResponse.from_success(res.body, self.class::RESPONSE_NAME, self.class::RESPONSE_ENTITY_NAME, config.merchant_number)
|
39
|
+
rescue Savon::HTTPError => e
|
40
|
+
rescue_from_http(e)
|
41
|
+
rescue Savon::SOAPFault => e
|
42
|
+
rescue_from_soap(e)
|
43
|
+
end
|
44
|
+
|
45
|
+
protected
|
46
|
+
|
47
|
+
def digest_text(attrs)
|
48
|
+
attrs.values.join('|')
|
49
|
+
end
|
50
|
+
|
51
|
+
def attributes_with_signature(attrs)
|
52
|
+
digest = OpensslSecurity.generate_digest(config, digest_text(attrs))
|
53
|
+
attrs.merge('ins0:signature' => digest)
|
54
|
+
end
|
55
|
+
|
56
|
+
def client
|
57
|
+
@client ||= Savon.client(wsdl: config.wsdl_file, endpoint: config.ws_url, pretty_print_xml: true)
|
58
|
+
end
|
59
|
+
|
60
|
+
def rescue_from_http(error)
|
61
|
+
WsResponse.from_http_error(error.to_hash, config.merchant_number)
|
62
|
+
end
|
63
|
+
|
64
|
+
def rescue_from_soap(error)
|
65
|
+
WsResponse.from_fault_error(error.to_hash, self.class::SERVICE_EXCEPTION, config.merchant_number)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
##
|
2
|
+
# Service object checks if GP Webpay WS service is available.
|
3
|
+
#
|
4
|
+
# 1. Send request :echo operation to SOUP API.
|
5
|
+
# 2. Receive answer, return true if response is present in desired format.
|
6
|
+
# 3. Return false if
|
7
|
+
# - response is not in valid format.
|
8
|
+
# - request fails client-side.
|
9
|
+
# - request returns failure from server.
|
10
|
+
#
|
11
|
+
# @return [Boolean] GP Webpay is available
|
12
|
+
|
13
|
+
module GpWebpay
|
14
|
+
module Ws
|
15
|
+
class Echo < Service
|
16
|
+
attr_reader :config
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
super
|
20
|
+
@config = GpWebpay.config.default
|
21
|
+
end
|
22
|
+
|
23
|
+
def call
|
24
|
+
res = client.call(:echo)
|
25
|
+
res.body && res.body[:echo_response].present?
|
26
|
+
rescue Savon::HTTPError, Savon::SOAPFault
|
27
|
+
false
|
28
|
+
end
|
29
|
+
|
30
|
+
def client
|
31
|
+
@client ||= Savon.client(wsdl: config.wsdl_file, endpoint: config.ws_url, pretty_print_xml: true)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
##
|
2
|
+
# Service object returns current status of credit card token.
|
3
|
+
# Should be used to keep credit card status up-to date,
|
4
|
+
# should be called before process_token_payment to ensure card is still VERIFIED.
|
5
|
+
#
|
6
|
+
# @param [Hash] attributes for GP Webpay
|
7
|
+
#
|
8
|
+
# @return [GpwebpayWsResponse] response value object
|
9
|
+
|
10
|
+
module GpWebpay
|
11
|
+
module Ws
|
12
|
+
module Services
|
13
|
+
class GetMasterPaymentStatus < BaseSignedRequest
|
14
|
+
OPERATION_NAME = :get_master_payment_status
|
15
|
+
REQUEST_NAME = :master_payment_status_request
|
16
|
+
RESPONSE_NAME = :get_master_payment_status_response
|
17
|
+
RESPONSE_ENTITY_NAME = :master_payment_status_response
|
18
|
+
|
19
|
+
SHORTCUT_TRANSFORMATION = {
|
20
|
+
CR: 'CREATED',
|
21
|
+
PS: 'ISSUED',
|
22
|
+
OK: 'VERIFIED',
|
23
|
+
CM: 'REVOKED',
|
24
|
+
CI: 'DECLINED',
|
25
|
+
CC: 'DECLINED',
|
26
|
+
EC: 'EXPIRED',
|
27
|
+
EP: 'EXPIRED'
|
28
|
+
}.freeze
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
##
|
2
|
+
# Service object returns current status of payment.
|
3
|
+
#
|
4
|
+
# @param [Hash] attributes for GP Webpay
|
5
|
+
#
|
6
|
+
# @return [GpwebpayWsResponse] response value object
|
7
|
+
|
8
|
+
module GpWebpay
|
9
|
+
module Ws
|
10
|
+
module Services
|
11
|
+
class GetPaymentStatus < BaseSignedRequest
|
12
|
+
OPERATION_NAME = :get_payment_status
|
13
|
+
REQUEST_NAME = :payment_status_request
|
14
|
+
RESPONSE_NAME = :get_payment_status_response
|
15
|
+
RESPONSE_ENTITY_NAME = :payment_status_response
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
##
|
2
|
+
# Service object returns current status of credit card token.
|
3
|
+
# Should be used to keep credit card status up-to date,
|
4
|
+
# should be called before process_token_payment to ensure card is still VERIFIED.
|
5
|
+
#
|
6
|
+
# @param [Hash] attributes for GP Webpay
|
7
|
+
#
|
8
|
+
# @return [GpwebpayWsResponse] response value object
|
9
|
+
|
10
|
+
module GpWebpay
|
11
|
+
module Ws
|
12
|
+
module Services
|
13
|
+
class GetTokenStatus < BaseSignedRequest
|
14
|
+
OPERATION_NAME = :get_token_status
|
15
|
+
REQUEST_NAME = :token_status_request
|
16
|
+
RESPONSE_NAME = :get_token_status_response
|
17
|
+
RESPONSE_ENTITY_NAME = :token_status_response
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
##
|
2
|
+
# Service object creates fast payment without need of leaving user from Wilio web / app.
|
3
|
+
# It uses VERIFIED credit card token to skip filling card again and 3D secure step.
|
4
|
+
#
|
5
|
+
# @param [Hash] attributes for GP Webpay
|
6
|
+
#
|
7
|
+
# @return [GpwebpayWsResponse] response value object
|
8
|
+
|
9
|
+
module GpWebpay
|
10
|
+
module Ws
|
11
|
+
module Services
|
12
|
+
class ProcessCancelCapture < BaseSignedRequest
|
13
|
+
OPERATION_NAME = :process_authorization_reverse
|
14
|
+
REQUEST_NAME = :authorization_reverse_request
|
15
|
+
RESPONSE_NAME = :process_authorization_reverse_response
|
16
|
+
RESPONSE_ENTITY_NAME = :authorization_reverse_response
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
##
|
2
|
+
# Service object creates fast payment without need of leaving user from Wilio web / app.
|
3
|
+
# It uses VERIFIED credit card token to skip filling card again and 3D secure step.
|
4
|
+
#
|
5
|
+
# @param [Hash] attributes for GP Webpay
|
6
|
+
#
|
7
|
+
# @return [GpwebpayWsResponse] response value object
|
8
|
+
|
9
|
+
module GpWebpay
|
10
|
+
module Ws
|
11
|
+
module Services
|
12
|
+
class ProcessCaptureReverse < BaseSignedRequest
|
13
|
+
OPERATION_NAME = :process_capture_reverse
|
14
|
+
REQUEST_NAME = :capture_reverse_request
|
15
|
+
RESPONSE_NAME = :process_capture_reverse_response
|
16
|
+
RESPONSE_ENTITY_NAME = :capture_reverse_response
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
##
|
2
|
+
# Service object creates fast payment without need of leaving user from Wilio web / app.
|
3
|
+
# It uses VERIFIED credit card token to skip filling card again and 3D secure step.
|
4
|
+
#
|
5
|
+
# @param [Hash] attributes for GP Webpay
|
6
|
+
#
|
7
|
+
# @return [GpwebpayWsResponse] response value object
|
8
|
+
|
9
|
+
module GpWebpay
|
10
|
+
module Ws
|
11
|
+
module Services
|
12
|
+
class ProcessCardOnFilePayment < BaseSignedRequest
|
13
|
+
OPERATION_NAME = :process_card_on_file_payment
|
14
|
+
REQUEST_NAME = :card_on_file_payment_request
|
15
|
+
RESPONSE_NAME = :process_card_on_file_payment_response
|
16
|
+
RESPONSE_ENTITY_NAME = :card_on_file_payment_response
|
17
|
+
SERVICE_EXCEPTION = :card_on_file_payment_service_exception
|
18
|
+
|
19
|
+
def rescue_from_soap(exception)
|
20
|
+
response = WsResponse.from_fault_error(exception.to_hash, self.class::SERVICE_EXCEPTION, config.merchant_number)
|
21
|
+
|
22
|
+
if response.valid? && response.params[:authentication_link].present?
|
23
|
+
raise GpWebpayConfirmationRequired.new('GP Webpay requires authentication', response.params[:authentication_link])
|
24
|
+
else
|
25
|
+
response
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class GpWebpayConfirmationRequired < GpWebpay::Error
|
30
|
+
attr_reader :authentication_link
|
31
|
+
|
32
|
+
def initialize(msg = nil, authentication_link = nil)
|
33
|
+
super(msg)
|
34
|
+
@authentication_link = authentication_link
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
##
|
2
|
+
# Service object changes credit card token status to "REVOKED".
|
3
|
+
# Should be used when user decides to remove card from system.
|
4
|
+
#
|
5
|
+
# @param [Hash] attributes for GP Webpay
|
6
|
+
#
|
7
|
+
# @return [GpwebpayWsResponse] response value object
|
8
|
+
|
9
|
+
module GpWebpay
|
10
|
+
module Ws
|
11
|
+
module Services
|
12
|
+
class ProcessMasterPaymentRevoke < BaseSignedRequest
|
13
|
+
OPERATION_NAME = :process_master_payment_revoke
|
14
|
+
REQUEST_NAME = :master_payment_revoke_request
|
15
|
+
RESPONSE_NAME = :process_master_payment_revoke_response
|
16
|
+
RESPONSE_ENTITY_NAME = :master_payment_status_response
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
##
|
2
|
+
# Service object creates fast payment without need of leaving user from Wilio web / app.
|
3
|
+
# It uses VERIFIED credit card token to skip filling card again and 3D secure step.
|
4
|
+
#
|
5
|
+
# @param [Hash] attributes for GP Webpay
|
6
|
+
#
|
7
|
+
# @return [GpwebpayWsResponse] response value object
|
8
|
+
|
9
|
+
module GpWebpay
|
10
|
+
module Ws
|
11
|
+
module Services
|
12
|
+
class ProcessRecurringPayment < BaseSignedRequest
|
13
|
+
OPERATION_NAME = :process_recurring_payment
|
14
|
+
REQUEST_NAME = :recurring_payment_request
|
15
|
+
RESPONSE_NAME = :process_recurring_payment_response
|
16
|
+
RESPONSE_ENTITY_NAME = :recurring_payment_response
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
##
|
2
|
+
# Service object creates fast payment without need of leaving user from Wilio web / app.
|
3
|
+
# It uses VERIFIED credit card token to skip filling card again and 3D secure step.
|
4
|
+
#
|
5
|
+
# @param [Hash] attributes for GP Webpay
|
6
|
+
#
|
7
|
+
# @return [GpwebpayWsResponse] response value object
|
8
|
+
|
9
|
+
module GpWebpay
|
10
|
+
module Ws
|
11
|
+
module Services
|
12
|
+
class ProcessRefundPayment < BaseSignedRequest
|
13
|
+
OPERATION_NAME = :process_refund
|
14
|
+
REQUEST_NAME = :refund_request
|
15
|
+
RESPONSE_NAME = :process_refund_response
|
16
|
+
RESPONSE_ENTITY_NAME = :refund_request_response
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
##
|
2
|
+
# Service object creates fast payment without need of leaving user from Wilio web / app.
|
3
|
+
# It uses VERIFIED credit card token to skip filling card again and 3D secure step.
|
4
|
+
#
|
5
|
+
# @param [Hash] attributes for GP Webpay
|
6
|
+
#
|
7
|
+
# @return [GpwebpayWsResponse] response value object
|
8
|
+
|
9
|
+
module GpWebpay
|
10
|
+
module Ws
|
11
|
+
module Services
|
12
|
+
class ProcessTokenPayment < BaseSignedRequest
|
13
|
+
OPERATION_NAME = :process_token_payment
|
14
|
+
REQUEST_NAME = :token_payment_request
|
15
|
+
RESPONSE_NAME = :process_token_payment_response
|
16
|
+
RESPONSE_ENTITY_NAME = :token_payment_response
|
17
|
+
SERVICE_EXCEPTION = :payment_service_exception
|
18
|
+
|
19
|
+
def initialize(attributes)
|
20
|
+
super
|
21
|
+
@attributes = attributes.except(:return_url)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|