defra_ruby_mocks 1.1.0 → 1.5.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 +5 -5
- data/README.md +52 -2
- data/Rakefile +0 -2
- data/app/controllers/defra_ruby_mocks/company_controller.rb +1 -1
- data/app/controllers/defra_ruby_mocks/worldpay_controller.rb +33 -12
- data/app/services/defra_ruby_mocks/{worldpay_request_service.rb → worldpay_payment_service.rb} +3 -9
- data/app/services/defra_ruby_mocks/worldpay_refund_service.rb +37 -0
- data/app/services/defra_ruby_mocks/worldpay_request_handler_service.rb +40 -0
- data/app/services/defra_ruby_mocks/worldpay_resource_service.rb +55 -0
- data/app/services/defra_ruby_mocks/worldpay_response_service.rb +71 -52
- data/app/views/defra_ruby_mocks/worldpay/payment_request.xml.erb +4 -0
- data/app/views/defra_ruby_mocks/worldpay/refund_request.xml.erb +4 -0
- data/app/views/defra_ruby_mocks/worldpay/stuck.html.erb +37 -0
- data/lib/defra_ruby_mocks/engine.rb +2 -1
- data/lib/defra_ruby_mocks/missing_resource_error.rb +9 -0
- data/lib/defra_ruby_mocks/unrecognised_worldpay_request_error.rb +5 -0
- data/lib/defra_ruby_mocks/version.rb +1 -1
- data/spec/dummy/log/development.log +180 -0
- data/spec/dummy/log/test.log +1287 -323
- data/spec/examples.txt +99 -56
- data/spec/fixtures/{worldpay_request_invalid.xml → payment_request_invalid.xml} +0 -0
- data/spec/fixtures/{worldpay_request_valid.xml → payment_request_valid.xml} +0 -0
- data/spec/fixtures/refund_request_invalid.xml +6 -0
- data/spec/fixtures/refund_request_valid.xml +11 -0
- data/spec/fixtures/unrecognised_request.xml +6 -0
- data/spec/requests/worldpay_spec.rb +87 -26
- data/spec/services/{worldpay_request_service_spec.rb → worldpay_payment_service_spec.rb} +25 -22
- data/spec/services/worldpay_refund_service_spec.rb +68 -0
- data/spec/services/worldpay_request_handler_service_spec.rb +79 -0
- data/spec/services/worldpay_resource_service_spec.rb +112 -0
- data/spec/services/worldpay_response_service_spec.rb +185 -58
- data/spec/support/helpers/xml_matchers.rb +19 -0
- metadata +50 -17
- data/app/views/defra_ruby_mocks/worldpay/payments_service.xml.erb +0 -4
- data/lib/defra_ruby_mocks/missing_registration_error.rb +0 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 49581eea82699de82215ca95ff2dab0ff58b782e9c322003859bf211669ae717
|
|
4
|
+
data.tar.gz: 9ee91cdb992f56c2fee2a71be9c4c19d2289b19ea03c29e61076e23f064b19a6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ceeb708b2dd35c00eca628e935edc3e6db111cb731a6cb2721885f00dc7618d1778ff0ad4487b1f9b131e1db9c193ed222b74a148623dcfc84e1de2e55fc842b
|
|
7
|
+
data.tar.gz: 2db7ba1c4d5c1c484b414949e04622809fcd906767c8af69990d19709e6e210f968fbc6657af3f2adfa561e938398e79211b95c4a3cca95224c380ed377b7660
|
data/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Defra Ruby Mocks
|
|
2
2
|
|
|
3
3
|
[](https://travis-ci.com/DEFRA/defra-ruby-mocks)
|
|
4
|
-
[](https://sonarcloud.io/dashboard?id=DEFRA_defra-ruby-mocks)
|
|
5
|
+
[](https://sonarcloud.io/dashboard?id=DEFRA_defra-ruby-mocks)
|
|
6
6
|
[](https://hakiri.io/github/DEFRA/defra-ruby-mocks/master)
|
|
7
7
|
[](http://www.nationalarchives.gov.uk/doc/open-government-licence/version/3)
|
|
8
8
|
|
|
@@ -108,6 +108,8 @@ The list of possible statuses was taken from
|
|
|
108
108
|
|
|
109
109
|
When mounted into an app you can simulate interacting with the Worldpay hosted pages service.
|
|
110
110
|
|
|
111
|
+
#### Payments
|
|
112
|
+
|
|
111
113
|
Making a payment with Worldpay essentially comes in 2 stages
|
|
112
114
|
|
|
113
115
|
1. The app sends an XML request to Worldpay asking it to prepare for a new payment. Worldpay responds with a reference and a URL to redirect the user to
|
|
@@ -120,6 +122,54 @@ This Worldpay mock replicates those 2 interactions with the following urls
|
|
|
120
122
|
- `../worldpay/payments-service`
|
|
121
123
|
- `../worldpay/dispatcher`
|
|
122
124
|
|
|
125
|
+
##### Cancelled payments
|
|
126
|
+
|
|
127
|
+
The engine has the ability to mock a user cancelling a payment when on the Worldpay site. To have the mock return a cancelled payment response just ensure the registration's company name includes the word `cancel` (case doesn't matter).
|
|
128
|
+
|
|
129
|
+
If it does the engine will redirect back to the cancelled url instead of the success url provided, plus set the payment status to `CANCELLED`.
|
|
130
|
+
|
|
131
|
+
This allows us to test how the application handles Worldpay responding with a cancelled payment response.
|
|
132
|
+
|
|
133
|
+
##### Errored payments
|
|
134
|
+
|
|
135
|
+
The engine has the ability to Worldpay erroring during a payment. To have the mock return an errored payment response just ensure the registration's company name includes the word `error` (case doesn't matter).
|
|
136
|
+
|
|
137
|
+
If it does the engine will redirect back to the error url instead of the success url provided, plus set the payment status to `ERROR`.
|
|
138
|
+
|
|
139
|
+
This allows us to test how the application handles Worldpay responding with an errored payment response.
|
|
140
|
+
|
|
141
|
+
##### Pending payments
|
|
142
|
+
|
|
143
|
+
The engine has the ability to also mock Worldpay marking a payment as pending. To have the mock return a payment pending response just ensure the registration's company name includes the word `pending` (case doesn't matter).
|
|
144
|
+
|
|
145
|
+
If it does the engine will redirect back to the pending url instead of the success url provided, plus set the payment status to `SENT_FOR_AUTHORISATION`.
|
|
146
|
+
|
|
147
|
+
This allows us to test how the application handles Worldpay responding with a payment pending response.
|
|
148
|
+
|
|
149
|
+
##### Refused payments
|
|
150
|
+
|
|
151
|
+
The engine has the ability to also mock Worldpay refusing a payment. To have the mock refuse payment just ensure the registration's company name includes the word `reject` (case doesn't matter).
|
|
152
|
+
|
|
153
|
+
If it does the engine will redirect back to the failure url instead of the success url provided, plus set the payment status to `REFUSED`.
|
|
154
|
+
|
|
155
|
+
This allows us to test how the application handles both successful and unsucessful Worldpay payments.
|
|
156
|
+
|
|
157
|
+
##### Stuck payments
|
|
158
|
+
|
|
159
|
+
The engine has the ability to also mock Worldpay not redirecting back to the service. This is the equivalent of a registration getting 'stuck at Worldpay'. To have the mock not respond just ensure the registration's company name includes the word `stuck` (case doesn't matter).
|
|
160
|
+
|
|
161
|
+
If it does the engine will not redirect back to the service, but instead render a 'You're stuck!' page.
|
|
162
|
+
|
|
163
|
+
This allows us to test how the application handles Worldpay not returning after we redirect a user to them.
|
|
164
|
+
|
|
165
|
+
#### Refunds
|
|
166
|
+
|
|
167
|
+
Requesting a refund from Worldpay is a single step process.
|
|
168
|
+
|
|
169
|
+
1. The app sends an XML request to Worldpay with details of the order to be refunded and the amount. Worldpay returns an XML response confirming the request has been received
|
|
170
|
+
|
|
171
|
+
Like payments, refund requests are also sent to the same url `../worldpay/payments-service`. The mock handles determining what request is being made and returns the appropriate response.
|
|
172
|
+
|
|
123
173
|
#### Configuration
|
|
124
174
|
|
|
125
175
|
In order to use the Worldpay mock you'll need to provide additional configuration details
|
data/Rakefile
CHANGED
|
@@ -25,7 +25,6 @@ Bundler::GemHelper.install_tasks
|
|
|
25
25
|
# This is wrapped to prevent an error when rake is called in environments where
|
|
26
26
|
# rspec may not be available, e.g. production. As such we don't need to handle
|
|
27
27
|
# the error.
|
|
28
|
-
# rubocop:disable Lint/HandleExceptions
|
|
29
28
|
begin
|
|
30
29
|
require "rspec/core/rake_task"
|
|
31
30
|
|
|
@@ -35,4 +34,3 @@ begin
|
|
|
35
34
|
rescue LoadError
|
|
36
35
|
# no rspec available
|
|
37
36
|
end
|
|
38
|
-
# rubocop:enable Lint/HandleExceptions
|
|
@@ -1,27 +1,36 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module DefraRubyMocks
|
|
4
|
-
class WorldpayController < ApplicationController
|
|
4
|
+
class WorldpayController < ::DefraRubyMocks::ApplicationController
|
|
5
5
|
|
|
6
6
|
before_action :set_default_response_format
|
|
7
7
|
|
|
8
8
|
def payments_service
|
|
9
|
-
|
|
9
|
+
@values = WorldpayRequestHandlerService.run(convert_request_body_to_xml)
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
respond_to :xml
|
|
17
|
-
rescue StandardError
|
|
11
|
+
render_payment_response if @values[:request_type] == :payment
|
|
12
|
+
render_refund_response if @values[:request_type] == :refund
|
|
13
|
+
rescue StandardError => e
|
|
14
|
+
Rails.logger.error("MOCKS: Worldpay payments service error: #{e.message}")
|
|
18
15
|
head 500
|
|
19
16
|
end
|
|
20
17
|
|
|
21
18
|
def dispatcher
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
@response = WorldpayResponseService.run(
|
|
20
|
+
success_url: params[:successURL],
|
|
21
|
+
failure_url: params[:failureURL],
|
|
22
|
+
pending_url: params[:pendingURL],
|
|
23
|
+
cancel_url: params[:cancelURL],
|
|
24
|
+
error_url: params[:errorURL]
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
if @response.status == :STUCK
|
|
28
|
+
render formats: :html, action: "stuck", layout: false
|
|
29
|
+
else
|
|
30
|
+
redirect_to @response.url
|
|
31
|
+
end
|
|
32
|
+
rescue StandardError => e
|
|
33
|
+
Rails.logger.error("MOCKS: Worldpay dispatcher error: #{e.message}")
|
|
25
34
|
head 500
|
|
26
35
|
end
|
|
27
36
|
|
|
@@ -31,5 +40,17 @@ module DefraRubyMocks
|
|
|
31
40
|
request.format = :xml
|
|
32
41
|
end
|
|
33
42
|
|
|
43
|
+
def convert_request_body_to_xml
|
|
44
|
+
Nokogiri::XML(request.body.read)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def render_payment_response
|
|
48
|
+
render "defra_ruby_mocks/worldpay/payment_request"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def render_refund_response
|
|
52
|
+
render "defra_ruby_mocks/worldpay/refund_request"
|
|
53
|
+
end
|
|
54
|
+
|
|
34
55
|
end
|
|
35
56
|
end
|
data/app/services/defra_ruby_mocks/{worldpay_request_service.rb → worldpay_payment_service.rb}
RENAMED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module DefraRubyMocks
|
|
4
|
-
class
|
|
5
|
-
def run(
|
|
4
|
+
class WorldpayPaymentService < BaseService
|
|
5
|
+
def run(merchant_code:, xml:)
|
|
6
6
|
check_config
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
@merchant_code = extract_merchant_code(xml)
|
|
8
|
+
@merchant_code = merchant_code
|
|
10
9
|
@order_code = extract_order_code(xml)
|
|
11
10
|
|
|
12
11
|
{
|
|
@@ -25,11 +24,6 @@ module DefraRubyMocks
|
|
|
25
24
|
raise InvalidConfigError, :worldpay_domain if domain.blank?
|
|
26
25
|
end
|
|
27
26
|
|
|
28
|
-
def extract_merchant_code(xml)
|
|
29
|
-
payment_service = xml.at_xpath("//paymentService")
|
|
30
|
-
payment_service.attribute("merchantCode").text
|
|
31
|
-
end
|
|
32
|
-
|
|
33
27
|
def extract_order_code(xml)
|
|
34
28
|
order = xml.at_xpath("//order")
|
|
35
29
|
order.attribute("orderCode").text
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module DefraRubyMocks
|
|
4
|
+
class WorldpayRefundService < BaseService
|
|
5
|
+
def run(merchant_code:, xml:)
|
|
6
|
+
{
|
|
7
|
+
merchant_code: merchant_code,
|
|
8
|
+
order_code: extract_order_code(xml),
|
|
9
|
+
refund_value: extract_refund_value(xml),
|
|
10
|
+
currency_code: extract_currency_code(xml),
|
|
11
|
+
exponent: extract_exponent(xml)
|
|
12
|
+
}
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def extract_order_code(xml)
|
|
18
|
+
order_modification = xml.at_xpath("//orderModification")
|
|
19
|
+
order_modification.attribute("orderCode").text
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def extract_refund_value(xml)
|
|
23
|
+
amount = xml.at_xpath("//amount")
|
|
24
|
+
amount.attribute("value").text
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def extract_currency_code(xml)
|
|
28
|
+
amount = xml.at_xpath("//amount")
|
|
29
|
+
amount.attribute("currencyCode").text
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def extract_exponent(xml)
|
|
33
|
+
amount = xml.at_xpath("//amount")
|
|
34
|
+
amount.attribute("exponent").text
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module DefraRubyMocks
|
|
4
|
+
class WorldpayRequestHandlerService < BaseService
|
|
5
|
+
def run(xml)
|
|
6
|
+
arguments = {
|
|
7
|
+
merchant_code: extract_merchant_code(xml),
|
|
8
|
+
xml: xml
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
generate_response(arguments)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def extract_merchant_code(xml)
|
|
17
|
+
payment_service = xml.at_xpath("//paymentService")
|
|
18
|
+
payment_service.attribute("merchantCode").text
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def generate_response(arguments)
|
|
22
|
+
return WorldpayPaymentService.run(arguments).merge(request_type: :payment) if payment_request?(arguments[:xml])
|
|
23
|
+
return WorldpayRefundService.run(arguments).merge(request_type: :refund) if refund_request?(arguments[:xml])
|
|
24
|
+
|
|
25
|
+
raise UnrecognisedWorldpayRequestError
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def payment_request?(xml)
|
|
29
|
+
submit = xml.at_xpath("//submit")
|
|
30
|
+
|
|
31
|
+
!submit.nil?
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def refund_request?(xml)
|
|
35
|
+
modify = xml.at_xpath("//modify")
|
|
36
|
+
|
|
37
|
+
!modify.nil?
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module DefraRubyMocks
|
|
4
|
+
class WorldpayResourceService < BaseService
|
|
5
|
+
|
|
6
|
+
def run(reference:)
|
|
7
|
+
@reference = reference
|
|
8
|
+
|
|
9
|
+
raise(MissingResourceError, @reference) if resource.nil?
|
|
10
|
+
|
|
11
|
+
WorldpayResource.new(resource, order, company_name)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
WorldpayResource = Struct.new(:resource, :order, :company_name)
|
|
17
|
+
|
|
18
|
+
def resource
|
|
19
|
+
@_resource ||= locate_transient_registration || locate_completed_registration
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def locate_transient_registration
|
|
23
|
+
"WasteCarriersEngine::TransientRegistration"
|
|
24
|
+
.constantize
|
|
25
|
+
.where(token: @reference)
|
|
26
|
+
.first
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def locate_completed_registration
|
|
30
|
+
"WasteCarriersEngine::Registration"
|
|
31
|
+
.constantize
|
|
32
|
+
.where(reg_uuid: @reference)
|
|
33
|
+
.first
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def locate_original_registration(reg_identifier)
|
|
37
|
+
"WasteCarriersEngine::Registration"
|
|
38
|
+
.constantize
|
|
39
|
+
.where(reg_identifier: reg_identifier)
|
|
40
|
+
.first
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def order
|
|
44
|
+
@_order ||= resource.finance_details&.orders&.order_by(dateCreated: :desc)&.first
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def company_name
|
|
48
|
+
if resource.class.to_s == "WasteCarriersEngine::OrderCopyCardsRegistration"
|
|
49
|
+
locate_original_registration(resource.reg_identifier).company_name.downcase
|
|
50
|
+
else
|
|
51
|
+
resource.company_name.downcase
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -3,16 +3,40 @@
|
|
|
3
3
|
module DefraRubyMocks
|
|
4
4
|
class WorldpayResponseService < BaseService
|
|
5
5
|
|
|
6
|
-
def run(success_url)
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
def run(success_url:, failure_url:, pending_url:, cancel_url:, error_url:)
|
|
7
|
+
urls = {
|
|
8
|
+
success: success_url,
|
|
9
|
+
failure: failure_url,
|
|
10
|
+
pending: pending_url,
|
|
11
|
+
cancel: cancel_url,
|
|
12
|
+
error: error_url
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
parse_reference(urls[:success])
|
|
16
|
+
@resource = WorldpayResourceService.run(reference: @reference)
|
|
17
|
+
|
|
18
|
+
generate_response(urls)
|
|
12
19
|
end
|
|
13
20
|
|
|
14
21
|
private
|
|
15
22
|
|
|
23
|
+
WorldpayResponse = Struct.new(:supplied_url, :separator, :order_key, :mac, :value, :status, :reference) do
|
|
24
|
+
def url
|
|
25
|
+
[supplied_url, separator, params].join
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def params
|
|
29
|
+
[
|
|
30
|
+
"orderKey=#{order_key}",
|
|
31
|
+
"paymentStatus=#{status}",
|
|
32
|
+
"paymentAmount=#{value}",
|
|
33
|
+
"paymentCurrency=GBP",
|
|
34
|
+
"mac=#{mac}",
|
|
35
|
+
"source=WP"
|
|
36
|
+
].join("&")
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
16
40
|
def parse_reference(url)
|
|
17
41
|
path = URI.parse(url).path
|
|
18
42
|
parts = path.split("/")
|
|
@@ -28,71 +52,66 @@ module DefraRubyMocks
|
|
|
28
52
|
end
|
|
29
53
|
end
|
|
30
54
|
|
|
31
|
-
def locate_registration
|
|
32
|
-
@registration = locate_transient_registration || locate_completed_registration
|
|
33
|
-
|
|
34
|
-
raise(MissingRegistrationError, @reference) if @registration.nil?
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def locate_transient_registration
|
|
38
|
-
"WasteCarriersEngine::TransientRegistration"
|
|
39
|
-
.constantize
|
|
40
|
-
.where(token: @reference)
|
|
41
|
-
.first
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def locate_completed_registration
|
|
45
|
-
"WasteCarriersEngine::Registration"
|
|
46
|
-
.constantize
|
|
47
|
-
.where(reg_uuid: @reference)
|
|
48
|
-
.first
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def last_order
|
|
52
|
-
@registration.finance_details&.orders&.order_by(dateCreated: :desc)&.first
|
|
53
|
-
end
|
|
54
|
-
|
|
55
55
|
def order_key
|
|
56
56
|
[
|
|
57
57
|
DefraRubyMocks.configuration.worldpay_admin_code,
|
|
58
58
|
DefraRubyMocks.configuration.worldpay_merchant_code,
|
|
59
|
-
@order.order_code
|
|
59
|
+
@resource.order.order_code
|
|
60
60
|
].join("^")
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
def order_value
|
|
64
|
-
@order.total_amount.to_s
|
|
64
|
+
@resource.order.total_amount.to_s
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def payment_status
|
|
68
|
+
return :REFUSED if @resource.company_name.include?("reject")
|
|
69
|
+
return :STUCK if @resource.company_name.include?("stuck")
|
|
70
|
+
return :SENT_FOR_AUTHORISATION if @resource.company_name.include?("pending")
|
|
71
|
+
return :CANCELLED if @resource.company_name.include?("cancel")
|
|
72
|
+
return :ERROR if @resource.company_name.include?("error")
|
|
73
|
+
|
|
74
|
+
:AUTHORISED
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def url(payment_status, urls)
|
|
78
|
+
return urls[:failure] if %i[REFUSED STUCK].include?(payment_status)
|
|
79
|
+
return urls[:pending] if payment_status == :SENT_FOR_AUTHORISATION
|
|
80
|
+
return urls[:cancel] if payment_status == :CANCELLED
|
|
81
|
+
return urls[:error] if payment_status == :ERROR
|
|
82
|
+
|
|
83
|
+
urls[:success]
|
|
65
84
|
end
|
|
66
85
|
|
|
67
|
-
|
|
86
|
+
# Generate a mac that matches what Worldpay would generate
|
|
87
|
+
#
|
|
88
|
+
# For whatever reason, if the payment is cancelled by the user Worldpay does
|
|
89
|
+
# not include the payment status in the mac it generates. Plus the order of
|
|
90
|
+
# things in the array is important.
|
|
91
|
+
def generate_mac(status)
|
|
68
92
|
data = [
|
|
69
93
|
order_key,
|
|
70
94
|
order_value,
|
|
71
|
-
"GBP"
|
|
72
|
-
"AUTHORISED",
|
|
73
|
-
DefraRubyMocks.configuration.worldpay_mac_secret
|
|
95
|
+
"GBP"
|
|
74
96
|
]
|
|
97
|
+
data << status unless status == :CANCELLED
|
|
98
|
+
data << DefraRubyMocks.configuration.worldpay_mac_secret
|
|
75
99
|
|
|
76
100
|
Digest::MD5.hexdigest(data.join).to_s
|
|
77
101
|
end
|
|
78
102
|
|
|
79
|
-
def
|
|
80
|
-
|
|
81
|
-
"orderKey=#{order_key}",
|
|
82
|
-
"paymentStatus=AUTHORISED",
|
|
83
|
-
"paymentAmount=#{order_value}",
|
|
84
|
-
"paymentCurrency=GBP",
|
|
85
|
-
"mac=#{generate_mac}",
|
|
86
|
-
"source=WP"
|
|
87
|
-
].join("&")
|
|
88
|
-
end
|
|
103
|
+
def generate_response(urls)
|
|
104
|
+
status = payment_status
|
|
89
105
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
"
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
106
|
+
WorldpayResponse.new(
|
|
107
|
+
url(status, urls),
|
|
108
|
+
@url_format == :new ? "?" : "&",
|
|
109
|
+
order_key,
|
|
110
|
+
generate_mac(status),
|
|
111
|
+
order_value,
|
|
112
|
+
status,
|
|
113
|
+
@reference
|
|
114
|
+
)
|
|
96
115
|
end
|
|
97
116
|
end
|
|
98
117
|
end
|