defra_ruby_mocks 1.1.0 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Build Status](https://travis-ci.com/DEFRA/defra-ruby-mocks.svg?branch=master)](https://travis-ci.com/DEFRA/defra-ruby-mocks)
|
4
|
-
[![Maintainability](https://
|
5
|
-
[![
|
4
|
+
[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=DEFRA_defra-ruby-mocks&metric=sqale_rating)](https://sonarcloud.io/dashboard?id=DEFRA_defra-ruby-mocks)
|
5
|
+
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=DEFRA_defra-ruby-mocks&metric=coverage)](https://sonarcloud.io/dashboard?id=DEFRA_defra-ruby-mocks)
|
6
6
|
[![security](https://hakiri.io/github/DEFRA/defra-ruby-mocks/master.svg)](https://hakiri.io/github/DEFRA/defra-ruby-mocks/master)
|
7
7
|
[![Licence](https://img.shields.io/badge/Licence-OGLv3-blue.svg)](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
|