payson_api 0.4.2 → 1.0.1
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/MIT-LICENSE +16 -17
- data/README.md +228 -0
- data/lib/payson_api.rb +55 -22
- data/lib/payson_api/v1/client.rb +80 -0
- data/lib/payson_api/v1/config.rb +63 -0
- data/lib/payson_api/v1/envelope.rb +27 -0
- data/lib/payson_api/v1/errors/unknown_currency_error.rb +13 -0
- data/lib/payson_api/v1/errors/unknown_fees_payer_error.rb +13 -0
- data/lib/payson_api/v1/errors/unknown_funding_constraint_error.rb +13 -0
- data/lib/payson_api/v1/errors/unknown_guarantee_offering_error.rb +13 -0
- data/lib/payson_api/v1/errors/unknown_locale_error.rb +13 -0
- data/lib/payson_api/v1/errors/unknown_payment_action_error.rb +13 -0
- data/lib/payson_api/v1/funding.rb +38 -0
- data/lib/payson_api/v1/order_item.rb +43 -0
- data/lib/payson_api/v1/receiver.rb +46 -0
- data/lib/payson_api/v1/remote_error.rb +36 -0
- data/lib/payson_api/v1/requests/ipn.rb +19 -0
- data/lib/payson_api/v1/requests/payment.rb +68 -0
- data/lib/payson_api/v1/requests/payment_details.rb +19 -0
- data/lib/payson_api/v1/requests/payment_update.rb +27 -0
- data/lib/payson_api/v1/responses/ipn.rb +43 -0
- data/lib/payson_api/v1/responses/payment.rb +25 -0
- data/lib/payson_api/v1/responses/payment_details.rb +50 -0
- data/lib/payson_api/v1/responses/payment_update.rb +20 -0
- data/lib/payson_api/v1/responses/validate.rb +19 -0
- data/lib/payson_api/v1/sender.rb +28 -0
- data/lib/payson_api/v1/shipping_address.rb +34 -0
- data/lib/payson_api/v2/client.rb +67 -0
- data/lib/payson_api/v2/config.rb +51 -0
- data/lib/payson_api/v2/errors/unauthorized_error.rb +10 -0
- data/lib/payson_api/v2/errors/validation_error.rb +16 -0
- data/lib/payson_api/v2/models/account.rb +23 -0
- data/lib/payson_api/v2/models/checkout.rb +28 -0
- data/lib/payson_api/v2/models/customer.rb +27 -0
- data/lib/payson_api/v2/models/merchant.rb +24 -0
- data/lib/payson_api/v2/models/order.rb +32 -0
- data/lib/payson_api/v2/models/order_item.rb +33 -0
- data/lib/payson_api/v2/requests/create_checkout.rb +26 -0
- data/lib/payson_api/v2/requests/customer.rb +23 -0
- data/lib/payson_api/v2/requests/list_checkouts.rb +23 -0
- data/lib/payson_api/v2/requests/merchant.rb +25 -0
- data/lib/payson_api/v2/requests/order.rb +22 -0
- data/lib/payson_api/v2/requests/order_item.rb +27 -0
- data/lib/payson_api/v2/requests/update_checkout.rb +25 -0
- data/lib/payson_api/version.rb +3 -1
- metadata +70 -53
- data/.gitignore +0 -7
- data/.travis.yml +0 -5
- data/Gemfile +0 -2
- data/Guardfile +0 -9
- data/README.rdoc +0 -155
- data/Rakefile +0 -24
- data/lib/payson_api/client.rb +0 -79
- data/lib/payson_api/config.rb +0 -50
- data/lib/payson_api/envelope.rb +0 -21
- data/lib/payson_api/funding.rb +0 -34
- data/lib/payson_api/order_item.rb +0 -52
- data/lib/payson_api/receiver.rb +0 -52
- data/lib/payson_api/remote_error.rb +0 -31
- data/lib/payson_api/request/ipn.rb +0 -15
- data/lib/payson_api/request/payment.rb +0 -68
- data/lib/payson_api/request/payment_details.rb +0 -15
- data/lib/payson_api/request/payment_update.rb +0 -22
- data/lib/payson_api/response/ipn.rb +0 -36
- data/lib/payson_api/response/payment.rb +0 -22
- data/lib/payson_api/response/payment_details.rb +0 -43
- data/lib/payson_api/response/payment_update.rb +0 -16
- data/lib/payson_api/response/validate.rb +0 -15
- data/lib/payson_api/sender.rb +0 -29
- data/lib/payson_api/shipping_address.rb +0 -36
- data/payson_api.gemspec +0 -23
- data/test/fixtures/config.yml +0 -2
- data/test/fixtures/payment_data.yml +0 -37
- data/test/integration/config_test.rb +0 -15
- data/test/integration/payment_details_test.rb +0 -21
- data/test/integration/payment_test.rb +0 -65
- data/test/test_helper.rb +0 -76
data/.travis.yml
DELETED
data/Gemfile
DELETED
data/Guardfile
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
guard 'test' do
|
2
|
-
watch(%r{^lib/(.+)\.rb$}) { "test" }
|
3
|
-
watch(%r{^lib/payson_api/(.+)\.rb$}) { "test" }
|
4
|
-
|
5
|
-
watch(%r{^test/unit/.+_test\.rb$}) { "test" }
|
6
|
-
watch(%r{^test/fixtures/(.+)\.yml$}) { "test" }
|
7
|
-
watch(%r{^test/integration/.+_test\.rb$}) { "test" }
|
8
|
-
watch(%r{^test/.+_helper\.rb$}) { "test" }
|
9
|
-
end
|
data/README.rdoc
DELETED
@@ -1,155 +0,0 @@
|
|
1
|
-
= Payson API
|
2
|
-
|
3
|
-
A simple utility to handle requests against the Payson payment gateway API.
|
4
|
-
|
5
|
-
|
6
|
-
== Supported versions
|
7
|
-
|
8
|
-
* Ruby 1.9.3, 2.0.0, 2.1.0
|
9
|
-
|
10
|
-
|
11
|
-
== Install
|
12
|
-
|
13
|
-
Put this line in your Gemfile:
|
14
|
-
gem 'payson_api'
|
15
|
-
|
16
|
-
Then bundle:
|
17
|
-
$ bundle
|
18
|
-
|
19
|
-
|
20
|
-
== Usage
|
21
|
-
|
22
|
-
=== General configuration options
|
23
|
-
|
24
|
-
You need to configure the gem with your own Payson credentials through the <tt>PaysonAPI.configure</tt> method:
|
25
|
-
|
26
|
-
PaysonAPI.configure do |config|
|
27
|
-
config.api_user_id = 'XXXX'
|
28
|
-
config.api_password = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
|
29
|
-
end
|
30
|
-
|
31
|
-
Please note that if <tt>config.api_user_id</tt> is set to 4, the client will go into test mode. Valid test access credentials could be found in {documentation}[https://api.payson.se/#Testing/sandbox].
|
32
|
-
|
33
|
-
=== Initiating a payment
|
34
|
-
|
35
|
-
return_url = 'http://localhost/payson/success'
|
36
|
-
cancel_url = 'http://localhost/payson/cancel'
|
37
|
-
ipn_url = 'http://localhost/payson/ipn'
|
38
|
-
memo = 'Sample order description'
|
39
|
-
|
40
|
-
receivers = []
|
41
|
-
receivers << PaysonAPI::Receiver.new(
|
42
|
-
email = 'me@mydomain.com',
|
43
|
-
amount = 100,
|
44
|
-
first_name = 'Me',
|
45
|
-
last_name = 'Just me',
|
46
|
-
primary = true
|
47
|
-
)
|
48
|
-
|
49
|
-
sender = PaysonAPI::Sender.new(
|
50
|
-
email = 'mycustomer@mydomain.com',
|
51
|
-
first_name = 'My',
|
52
|
-
last_name = 'Customer'
|
53
|
-
)
|
54
|
-
|
55
|
-
order_items = []
|
56
|
-
order_items << PaysonAPI::OrderItem.new(
|
57
|
-
description = 'Order item description',
|
58
|
-
unit_price = 100,
|
59
|
-
quantity = 1,
|
60
|
-
tax = 0,
|
61
|
-
sku = 'MY-ITEM-1'
|
62
|
-
)
|
63
|
-
|
64
|
-
payment = PaysonAPI::Request::Payment.new(
|
65
|
-
return_url,
|
66
|
-
cancel_url,
|
67
|
-
ipn_url,
|
68
|
-
memo,
|
69
|
-
sender,
|
70
|
-
receivers
|
71
|
-
)
|
72
|
-
payment.order_items = order_items
|
73
|
-
|
74
|
-
response = PaysonAPI::Client.initiate_payment(payment)
|
75
|
-
|
76
|
-
if response.success?
|
77
|
-
# Redirect to response.forward_url
|
78
|
-
else
|
79
|
-
puts response.errors
|
80
|
-
end
|
81
|
-
|
82
|
-
|
83
|
-
=== Requesting payment details
|
84
|
-
|
85
|
-
token = 'token-received-from-payment-request'
|
86
|
-
|
87
|
-
payment_details = PaysonAPI::Request::PaymentDetails.new(token)
|
88
|
-
|
89
|
-
response = PaysonAPI::Client.get_payment_details(payment_details)
|
90
|
-
|
91
|
-
if response.success?
|
92
|
-
# Do stuff with response object
|
93
|
-
else
|
94
|
-
puts response.errors
|
95
|
-
end
|
96
|
-
|
97
|
-
|
98
|
-
=== Updating a payment
|
99
|
-
|
100
|
-
token = 'token-received-from-payment-request'
|
101
|
-
action = 'CANCELORDER'
|
102
|
-
|
103
|
-
payment_update = PaysonAPI::Request::PaymentUpdate.new(token, action)
|
104
|
-
|
105
|
-
response = PaysonAPI::Client.update_payment(payment_update)
|
106
|
-
|
107
|
-
if response.success?
|
108
|
-
# Do stuff with response object
|
109
|
-
else
|
110
|
-
puts response.errors
|
111
|
-
end
|
112
|
-
|
113
|
-
|
114
|
-
=== Validating an IPN response
|
115
|
-
|
116
|
-
This example assumes the use of the Rails web framework.
|
117
|
-
|
118
|
-
class Payson < ApplicationController
|
119
|
-
def ipn_responder
|
120
|
-
request_body = request.body.read
|
121
|
-
ipn_response = PaysonAPI::Response::IPN.new(request_body)
|
122
|
-
|
123
|
-
# Do business stuff, e.g. update the corresponding order:
|
124
|
-
# order = Order.find_by_payson_token(ipn_response.token)
|
125
|
-
# order.payson_status = ipn_response.status
|
126
|
-
# order.save!
|
127
|
-
|
128
|
-
# Create a new IPN request object containing the raw response from above
|
129
|
-
ipn_request = PaysonAPI::Request::IPN.new(ipn_response.raw)
|
130
|
-
|
131
|
-
validate = PaysonAPI::Client.validate_ipn(ipn_request)
|
132
|
-
|
133
|
-
unless validate.verified?
|
134
|
-
raise "Something went terribly wrong."
|
135
|
-
end
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
|
140
|
-
== Todo
|
141
|
-
|
142
|
-
Nothing at the moment. Will focus on writing more thourough test cases and look over the code all in all.
|
143
|
-
|
144
|
-
|
145
|
-
== Build Status {<img src="https://secure.travis-ci.org/stoffus/payson_api.png"/>}[http://travis-ci.org/stoffus/payson_api]
|
146
|
-
|
147
|
-
|
148
|
-
== Questions, Feedback
|
149
|
-
|
150
|
-
Feel free to message me on Github (stoffus).
|
151
|
-
|
152
|
-
|
153
|
-
== Copyright
|
154
|
-
|
155
|
-
Copyright (c) 2014 Christopher Svensson.
|
data/Rakefile
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
require 'bundler/gem_tasks'
|
2
|
-
|
3
|
-
task :default => ["test"]
|
4
|
-
|
5
|
-
task :test do
|
6
|
-
Rake::Task['test:unit'].execute
|
7
|
-
Rake::Task['test:integration'].execute
|
8
|
-
end
|
9
|
-
|
10
|
-
namespace :test do
|
11
|
-
desc "Run unit tests"
|
12
|
-
task :unit do
|
13
|
-
Dir["test/unit/*_test.rb"].each do |path|
|
14
|
-
system "ruby -Ilib -Itest #{path}"
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
desc "Run integration tests"
|
19
|
-
task :integration do
|
20
|
-
Dir["test/integration/*_test.rb"].each do |path|
|
21
|
-
system "ruby -Ilib -Itest #{path}"
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
data/lib/payson_api/client.rb
DELETED
@@ -1,79 +0,0 @@
|
|
1
|
-
require 'net/https'
|
2
|
-
|
3
|
-
module PaysonAPI
|
4
|
-
class Client
|
5
|
-
def self.initiate_payment(payment_data)
|
6
|
-
response = payson_request(
|
7
|
-
PAYSON_API_PAY_ACTION,
|
8
|
-
payment_data.to_hash
|
9
|
-
)
|
10
|
-
response_hash = params_to_hash(response.body)
|
11
|
-
PaysonAPI::Response::Payment.new(response_hash)
|
12
|
-
end
|
13
|
-
|
14
|
-
def self.get_payment_details(payment_details_data)
|
15
|
-
response = payson_request(
|
16
|
-
PAYSON_API_PAYMENT_DETAILS_ACTION,
|
17
|
-
payment_details_data.to_hash
|
18
|
-
)
|
19
|
-
response_hash = params_to_hash(response.body)
|
20
|
-
PaysonAPI::Response::PaymentDetails.new(response_hash)
|
21
|
-
end
|
22
|
-
|
23
|
-
def self.update_payment(payment_update_data)
|
24
|
-
response = payson_request(
|
25
|
-
PAYSON_API_PAYMENT_DETAILS_ACTION,
|
26
|
-
payment_update_data.to_hash
|
27
|
-
)
|
28
|
-
response_hash = params_to_hash(response.body)
|
29
|
-
PaysonAPI::Response::PaymentUpdate.new(response_hash)
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.validate_ipn(ipn_data)
|
33
|
-
response = payson_request(
|
34
|
-
PAYSON_API_PAYMENT_VALIDATE_ACTION,
|
35
|
-
ipn_data.to_s
|
36
|
-
)
|
37
|
-
PaysonAPI::Response::Validate.new(response.body)
|
38
|
-
end
|
39
|
-
|
40
|
-
def self.hash_to_params(hash)
|
41
|
-
hash.map { |k, v| "#{k}=#{v}" }.join('&')
|
42
|
-
end
|
43
|
-
|
44
|
-
def self.params_to_hash(params)
|
45
|
-
{}.tap do |hash|
|
46
|
-
params.split('&').each do |param|
|
47
|
-
key, val = param.split('=')
|
48
|
-
hash[key] = val
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
private
|
54
|
-
|
55
|
-
def self.payson_request(action, data)
|
56
|
-
action = '/%s/%s/' % [PAYSON_API_VERSION, action]
|
57
|
-
url = PAYSON_API_ENDPOINT % (PaysonAPI.test? ? 'test-api' : 'api') + action
|
58
|
-
headers = {
|
59
|
-
'PAYSON-SECURITY-USERID' => PaysonAPI.config.api_user_id,
|
60
|
-
'PAYSON-SECURITY-PASSWORD' => PaysonAPI.config.api_password,
|
61
|
-
'Content-Type' => 'application/x-www-form-urlencoded'
|
62
|
-
}
|
63
|
-
post(url, data, headers)
|
64
|
-
end
|
65
|
-
|
66
|
-
def self.post(url, data, headers)
|
67
|
-
uri = URI.parse(url)
|
68
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
69
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
70
|
-
http.use_ssl = uri.scheme == 'https'
|
71
|
-
req = Net::HTTP::Post.new(uri.path)
|
72
|
-
req.body = data.is_a?(Hash) ? hash_to_params(data) : data
|
73
|
-
headers.each do |name, value|
|
74
|
-
req[name] = value
|
75
|
-
end
|
76
|
-
http.request(req)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
data/lib/payson_api/config.rb
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
module PaysonAPI
|
2
|
-
extend self
|
3
|
-
|
4
|
-
PAYSON_WWW_HOST = "https://%s.payson.se"
|
5
|
-
PAYSON_WWW_PAY_FORWARD_URL = "/paysecure/?token=%s"
|
6
|
-
|
7
|
-
PAYSON_API_ENDPOINT = "https://%s.payson.se"
|
8
|
-
PAYSON_API_VERSION = "1.0"
|
9
|
-
PAYSON_API_PAY_ACTION = "Pay"
|
10
|
-
PAYSON_API_PAYMENT_DETAILS_ACTION = "PaymentDetails"
|
11
|
-
PAYSON_API_PAYMENT_UPDATE_ACTION = "PaymentUpdate"
|
12
|
-
PAYSON_API_PAYMENT_VALIDATE_ACTION = "Validate"
|
13
|
-
|
14
|
-
LOCALES = %w[SV EN FI]
|
15
|
-
CURRENCIES = %w[SEK EUR]
|
16
|
-
FEES_PAYERS = %w[EACHRECEIVER SENDER PRIMARYRECEIVER SECONDARYONLY]
|
17
|
-
FUNDING_CONSTRAINTS = %w[CREDITCARD BANK INVOICE SMS]
|
18
|
-
GUARANTEE_OFFERINGS = %w[OPTIONAL REQUIRED NO]
|
19
|
-
PAYMENT_STATUSES = %w[CREATED PENDING PROCESSING COMPLETED CREDITED
|
20
|
-
INCOMPLETE ERROR EXPIRED REVERSALERROR ABORTED]
|
21
|
-
PAYMENT_TYPES = %w[TRANSFER GUARANTEE INVOICE]
|
22
|
-
GUARANTEE_STATUSES = %w[WAITINGFORSEND WAITINGFORACCEPTANCE WAITINGFORRETURN
|
23
|
-
WAITINGFORRETURNACCEPTANCE RETURNNOTACCEPTED NOTRECEIVED RETURNNOTRECEIVED
|
24
|
-
MONEYRETURNEDTOSENDER RETURNACCEPTED
|
25
|
-
]
|
26
|
-
INVOICE_STATUSES = %w[PENDING ORDERCREATED CANCELED SHIPPED DONE CREDITED]
|
27
|
-
PAYMENT_ACTIONS = %w[CANCELORDER SHIPORDER CREDITORDER REFUND]
|
28
|
-
|
29
|
-
def configure(&block)
|
30
|
-
yield @config ||= Configuration.new
|
31
|
-
end
|
32
|
-
|
33
|
-
def config
|
34
|
-
@config
|
35
|
-
end
|
36
|
-
|
37
|
-
class Configuration
|
38
|
-
attr_accessor :api_user_id, :api_password
|
39
|
-
end
|
40
|
-
|
41
|
-
configure do |config|
|
42
|
-
config.api_user_id = 'XXXX'
|
43
|
-
config.api_password = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
|
44
|
-
end
|
45
|
-
|
46
|
-
def test?
|
47
|
-
@config.api_user_id == '4'
|
48
|
-
end
|
49
|
-
|
50
|
-
end
|
data/lib/payson_api/envelope.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
require 'cgi'
|
2
|
-
|
3
|
-
module PaysonAPI
|
4
|
-
class Envelope
|
5
|
-
attr_accessor :ack, :timestamp, :correlation_id
|
6
|
-
FORMAT_STRING = "responseEnvelope.%s"
|
7
|
-
|
8
|
-
def initialize(ack, timestamp, correlation_id)
|
9
|
-
@ack = ack
|
10
|
-
@timestamp = timestamp
|
11
|
-
@correlation_id = correlation_id
|
12
|
-
end
|
13
|
-
|
14
|
-
def self.parse(data)
|
15
|
-
ack = data[FORMAT_STRING % 'ack']
|
16
|
-
timestamp = DateTime.parse(CGI.unescape(data[FORMAT_STRING % 'timestamp'].to_s))
|
17
|
-
correlation_id = data[FORMAT_STRING % 'correlationId']
|
18
|
-
self.new(ack, timestamp, correlation_id)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
data/lib/payson_api/funding.rb
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
module PaysonAPI
|
2
|
-
class Funding
|
3
|
-
FORMAT_STRING = "fundingList.fundingConstraint(%d).%s"
|
4
|
-
attr_accessor :constraint
|
5
|
-
|
6
|
-
def initialize(constraint)
|
7
|
-
if !FUNDING_CONSTRAINTS.include?(constraint)
|
8
|
-
raise "Unknown funding constraint: #{constraint}"
|
9
|
-
end
|
10
|
-
@constraint = constraint
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.to_hash(fundings)
|
14
|
-
{}.tap do |hash|
|
15
|
-
fundings.each_with_index do |funding, index|
|
16
|
-
hash.merge!({
|
17
|
-
FORMAT_STRING % [index, 'constraint'] => funding.constraint
|
18
|
-
})
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def self.parse(data)
|
24
|
-
[].tap do |fundings|
|
25
|
-
i = 0
|
26
|
-
while data[FORMAT_STRING % [i, 'constraint']]
|
27
|
-
constraint = data[FORMAT_STRING % [i, 'constraint']]
|
28
|
-
fundings << self.new(constraint)
|
29
|
-
i += 1
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
@@ -1,52 +0,0 @@
|
|
1
|
-
require 'cgi'
|
2
|
-
|
3
|
-
module PaysonAPI
|
4
|
-
class OrderItem
|
5
|
-
attr_accessor :description, :quantity, :unit_price, :sku, :tax
|
6
|
-
FORMAT_STRING = "orderItemList.orderItem(%d).%s"
|
7
|
-
|
8
|
-
def initialize(description, unit_price, quantity, tax, sku)
|
9
|
-
@description = description
|
10
|
-
@unit_price = unit_price
|
11
|
-
@quantity = quantity
|
12
|
-
@tax = tax
|
13
|
-
@sku = sku
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.to_hash(order_items)
|
17
|
-
{}.tap do |hash|
|
18
|
-
order_items.each_with_index do |item, index|
|
19
|
-
hash.merge!({
|
20
|
-
FORMAT_STRING % [index, 'description'] => item.description,
|
21
|
-
FORMAT_STRING % [index, 'unitPrice'] => item.unit_price,
|
22
|
-
FORMAT_STRING % [index, 'quantity'] => item.quantity,
|
23
|
-
FORMAT_STRING % [index, 'taxPercentage'] => item.tax,
|
24
|
-
FORMAT_STRING % [index, 'sku'] => item.sku
|
25
|
-
})
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.parse(data)
|
31
|
-
[].tap do |order_items|
|
32
|
-
i = 0
|
33
|
-
while data[FORMAT_STRING % [i, 'description']]
|
34
|
-
description = CGI.unescape(data[FORMAT_STRING % [i, 'description']].to_s)
|
35
|
-
unit_price = data[FORMAT_STRING % [i, 'unitPrice']]
|
36
|
-
quantity = data[FORMAT_STRING % [i, 'quantity']]
|
37
|
-
tax = data[FORMAT_STRING % [i, 'taxPercentage']]
|
38
|
-
sku = data[FORMAT_STRING % [i, 'sku']]
|
39
|
-
|
40
|
-
order_items << OrderItem.new(
|
41
|
-
description,
|
42
|
-
unit_price,
|
43
|
-
quantity,
|
44
|
-
tax,
|
45
|
-
sku
|
46
|
-
)
|
47
|
-
i += 1
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|