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 CHANGED
@@ -2,3 +2,5 @@ source :gemcutter
2
2
 
3
3
  # Specify your gem's dependencies in samurai.gemspec
4
4
  gemspec
5
+
6
+ gem 'rspec_junit_formatter', :git=>'git://github.com/jkrall/rspec_junit_formatter.git'
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.18)
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.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
- Payment Methods
50
- ---------------
49
+ Samurai API Reference
50
+ ---------------------
51
51
 
52
- A Payment Method is created each time a user stores their billing information
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 &lt;, &gt; and &amp; -->
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 &lt;, &gt; and &amp; -->
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
+