samurai 0.2.18 → 0.2.19
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +2 -0
- data/Gemfile.lock +11 -2
- data/README.markdown +3 -163
- data/Rakefile +16 -0
- data/api_reference.markdown +303 -0
- data/lib/samurai.rb +16 -3
- data/lib/samurai/base.rb +7 -1
- data/lib/samurai/cacheable_by_token.rb +8 -2
- data/lib/samurai/message.rb +7 -1
- data/lib/samurai/payment_method.rb +14 -7
- data/lib/samurai/processor.rb +27 -16
- data/lib/samurai/processor_response.rb +5 -0
- data/lib/samurai/rails/helpers.rb +5 -0
- data/lib/samurai/rails/views.rb +14 -0
- data/lib/samurai/transaction.rb +14 -6
- data/lib/samurai/version.rb +1 -1
- data/samurai.gemspec +1 -1
- data/spec/lib/authorization_spec.rb +9 -9
- data/spec/lib/{generate_docs_spec.rb → generate_docs_spec.rb.bak} +3 -32
- data/spec/lib/processor_spec.rb +4 -4
- data/spec/lib/purchase_spec.rb +2 -2
- data/spec/spec_helper.rb +55 -11
- data/spec/support/response_logger.rb +2 -2
- data/spec/support/transaction_seed.rb +10 -0
- data/spec/support/transparent_redirect_helper.rb +19 -0
- metadata +68 -55
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,15 @@
|
|
1
|
+
GIT
|
2
|
+
remote: git://github.com/jkrall/rspec_junit_formatter.git
|
3
|
+
revision: a40f6008cfd085bddb801047760c406d6ea2ed83
|
4
|
+
specs:
|
5
|
+
rspec_junit_formatter (0.1.0)
|
6
|
+
builder
|
7
|
+
rspec (~> 2.0)
|
8
|
+
|
1
9
|
PATH
|
2
10
|
remote: .
|
3
11
|
specs:
|
4
|
-
samurai (0.2.
|
12
|
+
samurai (0.2.19)
|
5
13
|
activeresource (>= 2.2.2)
|
6
14
|
|
7
15
|
GEM
|
@@ -18,7 +26,7 @@ GEM
|
|
18
26
|
activesupport (3.1.0)
|
19
27
|
multi_json (~> 1.0)
|
20
28
|
archive-tar-minitar (0.5.2)
|
21
|
-
bcrypt-ruby (3.0.
|
29
|
+
bcrypt-ruby (3.0.1)
|
22
30
|
builder (3.0.0)
|
23
31
|
columnize (0.3.4)
|
24
32
|
diff-lcs (1.1.3)
|
@@ -53,5 +61,6 @@ DEPENDENCIES
|
|
53
61
|
bundler (>= 1.0.0)
|
54
62
|
fakeweb
|
55
63
|
rspec (>= 2.6.0)
|
64
|
+
rspec_junit_formatter!
|
56
65
|
ruby-debug19
|
57
66
|
samurai!
|
data/README.markdown
CHANGED
@@ -46,170 +46,10 @@ can always call `Samurai::Processor.find('an_arbitrary_processor_token')` to
|
|
46
46
|
retrieve any of your processors.
|
47
47
|
|
48
48
|
|
49
|
-
|
50
|
-
|
49
|
+
Samurai API Reference
|
50
|
+
---------------------
|
51
51
|
|
52
|
-
|
53
|
-
in Samurai.
|
54
|
-
|
55
|
-
### Creating Payment Methods
|
56
|
-
|
57
|
-
To let your customers create a Payment Method, place a credit card
|
58
|
-
entry form on your site like the one below.
|
59
|
-
|
60
|
-
<form action="https://api.samurai.feefighters.com/v1/payment_methods" method="POST">
|
61
|
-
<fieldset>
|
62
|
-
<input name="redirect_url" type="hidden" value="http://yourdomain.com/anywhere" />
|
63
|
-
<input name="merchant_key" type="hidden" value="[Your Merchant Key]" />
|
64
|
-
|
65
|
-
<!-- Before populating the ‘custom’ parameter, remember to escape reserved xml characters
|
66
|
-
like <, > and & into their safe counterparts like <, > and & -->
|
67
|
-
<input name="custom" type="hidden" value="Any value you want us to save with this payment method" />
|
68
|
-
|
69
|
-
<label for="credit_card_first_name">First name</label>
|
70
|
-
<input id="credit_card_first_name" name="credit_card[first_name]" type="text" />
|
71
|
-
|
72
|
-
<label for="credit_card_last_name">Last name</label>
|
73
|
-
<input id="credit_card_last_name" name="credit_card[last_name]" type="text" />
|
74
|
-
|
75
|
-
<label for="credit_card_address_1">Address 1</label>
|
76
|
-
<input id="credit_card_address_1" name="credit_card[address_1]" type="text" />
|
77
|
-
|
78
|
-
<label for="credit_card_address_2">Address 2</label>
|
79
|
-
<input id="credit_card_address_2" name="credit_card[address_2]" type="text" />
|
80
|
-
|
81
|
-
<label for="credit_card_city">City</label>
|
82
|
-
<input id="credit_card_city" name="credit_card[city]" type="text" />
|
83
|
-
|
84
|
-
<label for="credit_card_state">State</label>
|
85
|
-
<input id="credit_card_state" name="credit_card[state]" type="text" />
|
86
|
-
|
87
|
-
<label for="credit_card_zip">Zip</label>
|
88
|
-
<input id="credit_card_zip" name="credit_card[zip]" type="text" />
|
89
|
-
|
90
|
-
<label for="credit_card_card_type">Card Type</label>
|
91
|
-
<select id="credit_card_card_type" name="credit_card[card_type]">
|
92
|
-
<option value="visa">Visa</option>
|
93
|
-
<option value="master">MasterCard</option>
|
94
|
-
</select>
|
95
|
-
|
96
|
-
<label for="credit_card_card_number">Card Number</label>
|
97
|
-
<input id="credit_card_card_number" name="credit_card[card_number]" type="text" />
|
98
|
-
|
99
|
-
<label for="credit_card_verification_value">Security Code</label>
|
100
|
-
<input id="credit_card_verification_value" name="credit_card[cvv]" type="text" />
|
101
|
-
|
102
|
-
<label for="credit_card_month">Expires on</label>
|
103
|
-
<input id="credit_card_month" name="credit_card[expiry_month]" type="text" />
|
104
|
-
<input id="credit_card_year" name="credit_card[expiry_year]" type="text" />
|
105
|
-
|
106
|
-
<button type="submit">Submit Payment</button>
|
107
|
-
</fieldset>
|
108
|
-
</form>
|
109
|
-
|
110
|
-
After the form submits to Samurai, the user's browser will be returned to the
|
111
|
-
URL that you specify in the redirect_url field, with an additional query
|
112
|
-
parameter containing the `payment_method_token`. You should save the
|
113
|
-
`payment_method_token` and use it from this point forward.
|
114
|
-
|
115
|
-
### Fetching a Payment Method
|
116
|
-
|
117
|
-
To retrieve the payment method and ensure that the sensitive data is valid:
|
118
|
-
|
119
|
-
payment_method = Samurai::PaymentMethod.find(payment_method_token)
|
120
|
-
payment_method.is_sensitive_data_valid # => true if the credit_card[card_number] passed checksum
|
121
|
-
# and the cvv (if included) is a number of 3 or 4 digits
|
122
|
-
|
123
|
-
**NB:** Samurai will not validate any non-sensitive data so it is up to your
|
124
|
-
application to perform any additional validation on the payment_method.
|
125
|
-
|
126
|
-
### Updating Payment Methods
|
127
|
-
|
128
|
-
You can update the payment method by directly updating its properties or by
|
129
|
-
loading it from a set of attributes and then saving the object:
|
130
|
-
|
131
|
-
payment_method.first_name = 'Graeme'
|
132
|
-
payment_method.save
|
133
|
-
|
134
|
-
OR
|
135
|
-
|
136
|
-
payment_method.load(hash_of_credit_card_values)
|
137
|
-
payment_method.save
|
138
|
-
|
139
|
-
### Retaining and Redacting Payment Methods
|
140
|
-
|
141
|
-
Unless you create a transaction on a payment method right away, that payment
|
142
|
-
method will be purged from Samurai. If you want to hang on to a payment method
|
143
|
-
for a while before making an authorization or purchase on it, you must retain it:
|
144
|
-
|
145
|
-
payment_method.retain
|
146
|
-
|
147
|
-
If you are finished with a payment method that you have either previously retained
|
148
|
-
or done one or more transactions with, you may redact the payment method. This
|
149
|
-
removes any sensitive information from Samurai related to the payment method,
|
150
|
-
but it still keeps the transaction data for reference. No further transactions
|
151
|
-
can be processed on a redacted payment method.
|
152
|
-
|
153
|
-
payment_method.redact
|
154
|
-
|
155
|
-
|
156
|
-
Processing Transactions
|
157
|
-
-----------------------
|
158
|
-
|
159
|
-
Your application needs to be prepared to track several identifiers. The payment_method_token
|
160
|
-
identifies a payment method stored in Samurai. Each transaction processed
|
161
|
-
has a transaction_token that identifies a group of transactions (initiated with
|
162
|
-
a purchase or authorization) and a reference_id that identifies the specific
|
163
|
-
transaction.
|
164
|
-
|
165
|
-
### Purchases and Authorizations
|
166
|
-
|
167
|
-
When you want to start to process a new purchase or authorization on a payment
|
168
|
-
method, Samurai needs to know which of your processors you want to use. You can
|
169
|
-
initiate a purchase (if your processor supports it) or an authorization against
|
170
|
-
a processor by:
|
171
|
-
|
172
|
-
processor = Samurai::Processor.the_processor # if you set Samurai.options[:processor_token]
|
173
|
-
processor = Samurai::Processor.find('a_processor_token') # if you have multiple processors
|
174
|
-
purchase = processor.purchase(payment_method_token, amount, options)
|
175
|
-
purchase_reference_id = purchase.reference_id # save this value, you can find the transaction with it later
|
176
|
-
|
177
|
-
An authorization is created the same way:
|
178
|
-
|
179
|
-
authorization = processor.authorize(payment_method_token, amount, options)
|
180
|
-
authorization_reference_id = authorization.reference_id # save this value, you can find the transaction with it later
|
181
|
-
|
182
|
-
You can specify options for either transaction type. Options is a hash that may contain:
|
183
|
-
|
184
|
-
* descriptor: a string description of the charge
|
185
|
-
* billing_reference: a string reference for the transaction
|
186
|
-
* customer_reference: a string that identifies the customer to your application
|
187
|
-
* custom: a custom value that Samurai will store but not forward to the processor
|
188
|
-
|
189
|
-
### Capturing an Authorization
|
190
|
-
|
191
|
-
An authorization only puts a hold on the funds that you specified. It won't
|
192
|
-
capture the money. You'll need to call capture on the authorization to do this.
|
193
|
-
|
194
|
-
authorization = Samurai::Transaction.find(authorization_reference_id) # get the authorization created previously
|
195
|
-
capture = authorization.capture # captures the full amount of the authorization
|
196
|
-
|
197
|
-
### Voiding a Transaction
|
198
|
-
|
199
|
-
A transaction that was recently created can be voided, if is has not been
|
200
|
-
settled. A transaction that has settled has already deposited funds into your
|
201
|
-
merchant account.
|
202
|
-
|
203
|
-
transaction = Samurai::Transaction.find(purchase_reference_id) # gets the purchase created before previously
|
204
|
-
void_transaction = transaction.void # voids the transaction
|
205
|
-
|
206
|
-
### Crediting a Transaction
|
207
|
-
|
208
|
-
Once a captured authorization or purchase has settled, you need to credit the
|
209
|
-
transaction if you want to reverse a charge.
|
210
|
-
|
211
|
-
purchase = Samurai::Transaction.find(purchase_reference_id)
|
212
|
-
credit = purchse.credit # credits the full amount of the original purchase
|
52
|
+
See the [API Reference](https://samurai.feefighters.com/developers/api-reference/ruby) for a full explanation of how this gem works with the Samurai API.
|
213
53
|
|
214
54
|
|
215
55
|
ActiveResource::Base
|
data/Rakefile
CHANGED
@@ -1,2 +1,18 @@
|
|
1
1
|
require 'bundler'
|
2
2
|
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
RSpec::Core::RakeTask.new(:spec)
|
6
|
+
RSpec::Core::RakeTask.new(:rcov)
|
7
|
+
|
8
|
+
task :default => :spec
|
9
|
+
|
10
|
+
require 'rake/rdoctask'
|
11
|
+
Rake::RDocTask.new do |rdoc|
|
12
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
13
|
+
|
14
|
+
rdoc.rdoc_dir = 'rdoc'
|
15
|
+
rdoc.title = "samurai-client-ruby #{version}"
|
16
|
+
rdoc.rdoc_files.include('README*')
|
17
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
18
|
+
end
|
@@ -0,0 +1,303 @@
|
|
1
|
+
## Overview
|
2
|
+
|
3
|
+
The Samurai API uses simple XML payloads transmitted over 256-bit encrypted <code class="post request">HTTPS POST</code> with Basic Authentication. The Samurai ruby gem uses ActiveResource to handle all of the authentication & XML serialization. It encapsulates the API calls as simple method calls on PaymentMethod and Transaction models, so you shouldn't need to think about the details of the actual API.
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
## Getting Started
|
8
|
+
|
9
|
+
To use the Samurai API, you'll need a <mark>Merchant Key</mark>, <mark>Merchant Password</mark> and a <mark>Processor Token</mark>.
|
10
|
+
[Sign up for an account](https://samurai.feefighters.com/users/sign_up) to get started.
|
11
|
+
|
12
|
+
|
13
|
+
### Samurai Credentials
|
14
|
+
|
15
|
+
Once you have these credentials, you can add them to an initializer in your Rails app (or anywhere after requiring the gem in a Sinatra/plain-ol'-ruby app):
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
require 'samurai'
|
19
|
+
Samurai.options = {
|
20
|
+
:merchant_key => '[merchant_key]',
|
21
|
+
:merchant_password => '[merchant_password]',
|
22
|
+
:processor_token => '[processor_token]',
|
23
|
+
}
|
24
|
+
```
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
## Payment Methods
|
29
|
+
|
30
|
+
Each time a user stores their billing information in the Samurai system, we call it a <mark>Payment Method</mark>.
|
31
|
+
|
32
|
+
Our [transparent redirect](https://samurai.feefighters.com/transparent-redirect) uses a simple HTML form on your website that submits your user’s billing information directly to us over SSL so that you never have to worry about handling credit card data yourself. We’ll quickly store the sensitive information, tokenize it for you and return the user to a page on your website of your choice with the new <mark>Payment Method Token</mark>.
|
33
|
+
|
34
|
+
From that point forward, you always refer to the Payment Method Token anytime you’d like to use that billing information for anything.
|
35
|
+
|
36
|
+
### Creating a Payment Method (via Transparent Redirect)
|
37
|
+
|
38
|
+
The Samurai ruby gem makes setting up a transparent redirect form extremely simple. We have included some handy helper methods to set everything up for you:
|
39
|
+
|
40
|
+
#### In your controller:
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
include Samurai::Rails::Helpers
|
44
|
+
|
45
|
+
def payment_form
|
46
|
+
setup_for_transparent_redirect(params)
|
47
|
+
end
|
48
|
+
```
|
49
|
+
|
50
|
+
#### In your view:
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
<%= render Samurai::Rails::Views.errors %>
|
54
|
+
<%= render Samurai::Rails::Views.payment_form :redirect_url => your_redirect_url,
|
55
|
+
:sandbox => true %>
|
56
|
+
```
|
57
|
+
|
58
|
+
|
59
|
+
Here’s an example of the form that will be added to your view. Key fields are highlighted in bold text, the style and labels are yours to configure however you like.
|
60
|
+
|
61
|
+
```html
|
62
|
+
<form action="https://api.samurai.feefighters.com/v1/payment_methods" method="POST">
|
63
|
+
<fieldset>
|
64
|
+
<input name="redirect_url" type="hidden" value="http://yourdomain.com/anywhere" />
|
65
|
+
<input name="merchant_key" type="hidden" value="[merchant_key]" />
|
66
|
+
<input name="sandbox" type="hidden" value="true" />
|
67
|
+
|
68
|
+
<!-- Before populating the ‘custom’ parameter, remember to escape reserved characters
|
69
|
+
like <, > and & into their safe counterparts like <, > and & -->
|
70
|
+
<input name="custom" type="hidden" value="Any value you want us to save with this payment method" />
|
71
|
+
|
72
|
+
<label for="credit_card_first_name">First name</label>
|
73
|
+
<input id="credit_card_first_name" name="credit_card[first_name]" type="text" />
|
74
|
+
|
75
|
+
<label for="credit_card_last_name">Last name</label>
|
76
|
+
<input id="credit_card_last_name" name="credit_card[last_name]" type="text" />
|
77
|
+
|
78
|
+
<label for="credit_card_address_1">Address 1</label>
|
79
|
+
<input id="credit_card_address_1" name="credit_card[address_1]" type="text" />
|
80
|
+
|
81
|
+
<label for="credit_card_address_2">Address 2</label>
|
82
|
+
<input id="credit_card_address_2" name="credit_card[address_2]" type="text" />
|
83
|
+
|
84
|
+
<label for="credit_card_city">City</label>
|
85
|
+
<input id="credit_card_city" name="credit_card[city]" type="text" />
|
86
|
+
|
87
|
+
<label for="credit_card_state">State</label>
|
88
|
+
<input id="credit_card_state" name="credit_card[state]" type="text" />
|
89
|
+
|
90
|
+
<label for="credit_card_zip">Zip</label>
|
91
|
+
<input id="credit_card_zip" name="credit_card[zip]" type="text" />
|
92
|
+
|
93
|
+
<label for="credit_card_card_number">Card Number</label>
|
94
|
+
<input id="credit_card_card_number" name="credit_card[card_number]" type="text" />
|
95
|
+
|
96
|
+
<label for="credit_card_cvv">Security Code</label>
|
97
|
+
<input id="credit_card_cvv" name="credit_card[cvv]" type="text" />
|
98
|
+
|
99
|
+
<label for="credit_card_month">Expires on</label>
|
100
|
+
<input id="credit_card_month" name="credit_card[expiry_month]" type="text" />
|
101
|
+
<input id="credit_card_year" name="credit_card[expiry_year]" type="text" />
|
102
|
+
|
103
|
+
<button type='submit'>Submit Payment</button>
|
104
|
+
</fieldset>
|
105
|
+
</form>
|
106
|
+
```
|
107
|
+
|
108
|
+
When we return the user to the URL that you specified in the `redirect_url` field, we’ll append the new Payment Method Token to the query string. You should save the Payment Method Token and use it from this point forward.
|
109
|
+
|
110
|
+
The following fields are required by Samurai, and submitting a Payment Method without them will trigger an error: `card_number`, `cvv`, `expiry_month`, `expiry_year`. However, in practice, most Processors will also require `first_name`, `last_name`, and the address fields as well. In that case, leaving these fields blank will trigger an error from the Processor when the Payment Method is used to create a transaction.
|
111
|
+
|
112
|
+
The `sandbox` field is a boolean that specifies whether the payment method is intended to be used with a <mark>Sandbox Processor</mark>. Sandbox processors can only process transactions with sandbox Payment Methods, and vice versa. You may omit this field in production, the default value is "false".
|
113
|
+
|
114
|
+
### Update a Payment Method (via Transparent Redirect)
|
115
|
+
|
116
|
+
Updating a payment method is very similar to creating a new one. (in fact, it is so similar that we've considered calling it "regenerating" instead)
|
117
|
+
|
118
|
+
To update a payment method, we add an additional hidden input `payment_method_token` for the desired payment method to be regenerated via the transparent redirect. Key fields are highlighted in bold text, the style and labels are yours to configure however you like. All credit card related fields are optional along with the custom and sandbox fields.
|
119
|
+
|
120
|
+
The semantics around regenerating a Payment Method using an existing `payment_method_token` are:
|
121
|
+
|
122
|
+
* If `field` does not exist, use old Payment Method value
|
123
|
+
* If `field` exists, but is invalid, use old Payment Method value
|
124
|
+
* If `field` exists, and is valid (or has no validations), replace old Payment Method value
|
125
|
+
* __The only fields that are required by Samurai are `card_number, cvv, expiry_month, expiry_year`. For the other fields, blank values will be considered valid.__
|
126
|
+
|
127
|
+
This is designed to allow you to load the old Payment Method data into your form fields, including the sanitized card number (`last_four_digits`) and cvv values. Then, when the user changes any of the fields and submits the form it should regenerate the new Payment Method keeping the old data intact and updating only the fresh data.
|
128
|
+
|
129
|
+
**_The bottom line:_ If you are using the Samurai ruby gem with the sample code above, you don't need to do anything to support updating a payment method. Your customers will be able to view Payment Method validation errors, act on them, and re-submit with new data.**
|
130
|
+
|
131
|
+
|
132
|
+
### Fetching a Payment Method
|
133
|
+
|
134
|
+
Since the transparent redirect form submits directly to Samurai, you don’t get to see the data that the user entered until you read it from us. This way, you can see if the user made any input errors and ask them to resubmit the transparent redirect form if necessary.
|
135
|
+
|
136
|
+
We’ll only send you non-sensitive data, so you will no be able to pre-populate the sensitive fields (card number and cvv) in the resubmission form.
|
137
|
+
|
138
|
+
```ruby
|
139
|
+
@payment_method = Samurai::PaymentMethod.find params[:payment_method_token]
|
140
|
+
@payment_method.is_sensitive_data_valid # => true if the credit_card[card_number] passed checksum
|
141
|
+
# and the cvv (if included) is a number of 3 or 4 digits
|
142
|
+
```
|
143
|
+
|
144
|
+
**NOTE:** Samurai will not validate any non-sensitive data so it is up to your
|
145
|
+
application to perform any additional validation on the payment_method.
|
146
|
+
|
147
|
+
|
148
|
+
### Retaining a Payment Method
|
149
|
+
|
150
|
+
Once you have determined that you’d like to keep a Payment Method in the Samurai vault, you must tell us to retain it. If you don’t explicitly issue a retain command, we will delete the Payment Method within 48 hours in order to comply with PCI DSS requirement 3.1, which states:
|
151
|
+
|
152
|
+
> "3.1 Keep cardholder data storage to a minimum. Develop a data retention and disposal policy. Limit storage amount and retention time to that which is required for business, legal, and/or regulatory purposes, as documented in the data retention policy."
|
153
|
+
|
154
|
+
However, if you perform a purchase or authorize transaction with a Payment Method, it will be automatically retained for future use.
|
155
|
+
|
156
|
+
```ruby
|
157
|
+
@payment_method = Samurai::PaymentMethod.find params[:payment_method_token]
|
158
|
+
@payment_method.retain
|
159
|
+
```
|
160
|
+
|
161
|
+
### Redacting a Payment Method
|
162
|
+
|
163
|
+
It’s important that you redact payment methods whenever you know you won’t need them anymore. Typically this is after the credit card’s expiration date or when your user has supplied you with a different card to use.
|
164
|
+
|
165
|
+
```ruby
|
166
|
+
@payment_method = Samurai::PaymentMethod.find params[:payment_method_token]
|
167
|
+
@payment_method.redact
|
168
|
+
```
|
169
|
+
|
170
|
+
|
171
|
+
|
172
|
+
## Processing Payments (Simple)
|
173
|
+
|
174
|
+
When you’re ready to process a payment, the simplest way to do so is with the `purchase` method.
|
175
|
+
|
176
|
+
```ruby
|
177
|
+
@purchase = Samurai::Processor.purchase(payment_method_token, 100.0, {
|
178
|
+
:billing_reference => 'billing data',
|
179
|
+
:customer_reference => 'customer data',
|
180
|
+
:custom => 'custom data',
|
181
|
+
:descriptor => 'descriptor',
|
182
|
+
})
|
183
|
+
```
|
184
|
+
|
185
|
+
The following optional parameters are available on a purchase transaction:
|
186
|
+
|
187
|
+
* `descriptor`: descriptor for the transaction
|
188
|
+
* `custom`: custom data, this data does not get passed to the processor, it is stored within api.samurai.feefighters.com only
|
189
|
+
* `customer_reference`: an identifier for the customer, this will appear in the processor if supported
|
190
|
+
* `billing_reference`: an identifier for the purchase, this will appear in the processor if supported
|
191
|
+
|
192
|
+
|
193
|
+
|
194
|
+
## Processing Payments (Complex)
|
195
|
+
|
196
|
+
In some cases, a simple purchase isn’t flexible enough. The alternative is to do an Authorize first, then a Capture if you want to process a previously authorized transaction or a Void if you want to cancel it. Be sure to save the `transaction_token` that is returned to you from an authorization because you’ll need it to capture or void the transaction.
|
197
|
+
|
198
|
+
### Authorize
|
199
|
+
|
200
|
+
An Authorize doesn’t charge your user’s credit card. It only reserves the transaction amount and it has the added benefit of telling you if your processor thinks that the transaction will succeed whenever you Capture it.
|
201
|
+
|
202
|
+
```ruby
|
203
|
+
@authorization = Samurai::Processor.authorize(payment_method_token, 1.0, {
|
204
|
+
:billing_reference => 'billing data',
|
205
|
+
:customer_reference => 'customer data',
|
206
|
+
:custom => 'custom data',
|
207
|
+
:descriptor => 'descriptor',
|
208
|
+
})
|
209
|
+
```
|
210
|
+
|
211
|
+
See the [purchase transaction](#processing-payments-simple) documentation for details on the optional data parameters.
|
212
|
+
|
213
|
+
### Capture
|
214
|
+
|
215
|
+
You can only execute a capture on a transaction that has previously been authorized. You’ll need the Transaction Token value from your Authorize command to construct the URL to use for capturing it.
|
216
|
+
|
217
|
+
```ruby
|
218
|
+
@authorization = Samurai::Transaction.find(transaction_token) # get the authorization created previously
|
219
|
+
@capture = @authorization.capture # capture the full amount (or specify an optional amount)
|
220
|
+
```
|
221
|
+
|
222
|
+
### Void
|
223
|
+
|
224
|
+
You can only execute a void on a transaction that has previously been captured or purchased. You’ll need the Transaction Token value from your Authorize command to construct the URL to use for voiding it.
|
225
|
+
|
226
|
+
**A transaction can only be voided if it has not settled yet.** Settlement typically takes 24 hours, but it depends on the processor connection you are using. For this reason, it is often convenient to use the [Reverse](#reverse) instead.
|
227
|
+
|
228
|
+
```ruby
|
229
|
+
@transaction = Samurai::Transaction.find(transaction_token) # get the transaction
|
230
|
+
@void = @transaction.void
|
231
|
+
```
|
232
|
+
|
233
|
+
### Credit
|
234
|
+
|
235
|
+
You can only execute a credit on a transaction that has previously been captured or purchased. You’ll need the Transaction Token value from your Authorize command to construct the URL to use for crediting it.
|
236
|
+
|
237
|
+
**A transaction can only be credited if it has settled.** Settlement typically takes 24 hours, but it depends on the processor connection you are using. For this reason, it is often convenient to use the [Reverse](#reverse) instead.
|
238
|
+
|
239
|
+
```ruby
|
240
|
+
@transaction = Samurai::Transaction.find(transaction_token) # get the transaction
|
241
|
+
@credit = @transaction.credit # credit the full amount (or specify an optional amount)
|
242
|
+
```
|
243
|
+
|
244
|
+
### Reverse
|
245
|
+
|
246
|
+
You can only execute a reverse on a transaction that has previously been captured or purchased. You’ll need the Transaction Token value from your Authorize command to construct the URL to use for reversing it.
|
247
|
+
|
248
|
+
*A reverse is equivalent to a void, followed by a full-value credit if the void is unsuccessful.*
|
249
|
+
|
250
|
+
```ruby
|
251
|
+
@transaction = Samurai::Transaction.find(transaction_token) # get the transaction
|
252
|
+
@reverse = @transaction.reverse
|
253
|
+
```
|
254
|
+
|
255
|
+
|
256
|
+
|
257
|
+
## Fetching a Transaction
|
258
|
+
|
259
|
+
Each time you use one of the transaction processing functions (purchase, authorize, capture, void, credit) you are given a `reference_id` that uniquely identifies the transaction for reporting purposes. If you want to retrieve transaction data, you can use this fetch method on the `reference_id`.
|
260
|
+
|
261
|
+
```ruby
|
262
|
+
@transaction = Samurai::Transaction.find reference_id
|
263
|
+
```
|
264
|
+
|
265
|
+
|
266
|
+
|
267
|
+
## Server-to-Server Payment Method API
|
268
|
+
|
269
|
+
We don't typically recommend using our server-to-server API for creating/updating Payment Methods, because it requires credit card data to pass through your server and exposes you to a much greater PCI compliance & risk liability.
|
270
|
+
|
271
|
+
However, there are situations where using the server-to-server API is appropriate, such as integrating a server that is already PCI-secure with Samurai or if you need to perform complex transactions and don't mind bearing the burden of greater compliance and risk.
|
272
|
+
|
273
|
+
|
274
|
+
### Creating a Payment Method (S2S)
|
275
|
+
|
276
|
+
_Documentation coming soon._
|
277
|
+
|
278
|
+
### Updating a Payment Method (S2S)
|
279
|
+
|
280
|
+
Any payment method that has been retained (either explicitly via the retain function or implicitly via purchase or authorize) cannot be updated any longer.
|
281
|
+
|
282
|
+
_Documentation coming soon._
|
283
|
+
|
284
|
+
|
285
|
+
|
286
|
+
## Error Messages
|
287
|
+
|
288
|
+
The PaymentMethod and Transaction classes both load errors automatically from the Samurai API, adding them to an Errors class that uses the same API as an ActiveRecord model.
|
289
|
+
|
290
|
+
```ruby
|
291
|
+
@transaction = Samurai::Transaction.find reference_id
|
292
|
+
puts @transaction.errors.full_messages
|
293
|
+
puts @transaction.payment_method.errors.full_messages
|
294
|
+
```
|
295
|
+
|
296
|
+
Displaying these error messages in your payment form is simple, using the included Rails helper module:
|
297
|
+
|
298
|
+
```ruby
|
299
|
+
<%= render Samurai::Rails::Views.errors %>
|
300
|
+
```
|
301
|
+
|
302
|
+
|
303
|
+
|