├── .bundle └── config ├── .github └── PULL_REQUEST_TEMPLATE.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── LoginandPaywithAmazonforSpreeCommerce.pdf ├── NOTICE ├── README.md ├── Rakefile ├── app ├── assets │ ├── javascripts │ │ └── spree │ │ │ ├── backend │ │ │ ├── payments │ │ │ │ └── new.js │ │ │ └── spree_amazon_payments.js │ │ │ └── frontend │ │ │ └── spree_amazon_payments.js │ └── stylesheets │ │ └── spree │ │ ├── backend │ │ └── spree_amazon_payments.css │ │ └── frontend │ │ └── spree_amazon_payments.css ├── controllers │ └── spree │ │ ├── admin │ │ └── amazon_controller.rb │ │ ├── amazon_callback_controller.rb │ │ └── amazon_controller.rb ├── models │ └── spree │ │ ├── amazon_transaction.rb │ │ ├── app_configuration_decorator.rb │ │ ├── gateway │ │ └── amazon.rb │ │ ├── order_decorator.rb │ │ ├── payment │ │ └── processing_decorator.rb │ │ └── payment_decorator.rb ├── overrides │ └── spree │ │ ├── admin │ │ └── shared │ │ │ └── sub_menu │ │ │ └── _configuration.rb │ │ ├── checkout │ │ ├── _delivery │ │ │ └── add_buttons_to_delivery.html.erb.deface │ │ └── _payment │ │ │ └── remove_amazon_payment_method.html.erb.deface │ │ └── orders │ │ └── edit │ │ └── add_pay_with_amazon.html.erb.deface └── views │ └── spree │ ├── admin │ ├── amazon │ │ └── edit.html.erb │ ├── log_entries │ │ └── _amazon.html.erb │ └── payments │ │ ├── source_forms │ │ └── _amazon.html.erb │ │ └── source_views │ │ └── _amazon.html.erb │ ├── amazon │ ├── _login.html.erb │ ├── _order_details.html.erb │ ├── _payment.html.erb │ ├── address.html.erb │ ├── complete.html.erb │ ├── confirm.html.erb │ └── delivery.html.erb │ └── checkout │ └── payment │ └── _amazon.html.erb ├── bin └── rails ├── config ├── locales │ └── en.yml └── routes.rb ├── db └── migrate │ ├── 20141103030543_create_spree_amazon_transactions.rb │ └── 20141106031627_add_authorization_and_capture_code_to_transaction.rb ├── lib ├── amazon_mws.rb ├── generators │ └── spree_amazon_payments │ │ └── install │ │ └── install_generator.rb ├── spree_amazon_payments.rb └── spree_amazon_payments │ ├── engine.rb │ └── factories.rb ├── spec └── spec_helper.rb └── spree_amazon_payments.gemspec /.bundle/config: -------------------------------------------------------------------------------- 1 | --- 2 | BUNDLE_JOBS: 4 3 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | *Issue #, if available:* 2 | 3 | *Description of changes:* 4 | 5 | 6 | By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. 7 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check [existing open](https://github.com/amzn/spree_pay_with_amazon/issues), or [recently closed](https://github.com/amzn/spree_pay_with_amazon/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20), issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *master* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels ((enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any ['help wanted'](https://github.com/amzn/spree_pay_with_amazon/labels/help%20wanted) issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](https://github.com/amzn/spree_pay_with_amazon/blob/master/LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | 61 | We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes. 62 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | ## 2 | # Amazon Payments - Login and Pay for Spree Commerce 3 | # 4 | # @category Amazon 5 | # @package Amazon_Payments 6 | # @copyright Copyright (c) 2014 Amazon.com 7 | # @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 8 | # 9 | ## 10 | source 'https://rubygems.org' 11 | 12 | gem 'spree', github: 'spree/spree', branch: '3-0-stable' 13 | # Provides basic authentication functionality for testing parts of your engine 14 | gem 'spree_auth_devise', github: 'spree/spree_auth_devise', branch: '3-0-stable' 15 | 16 | gemspec 17 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GIT 2 | remote: git://github.com/spree/spree.git 3 | revision: 45dab9f701dc01880ce5195371dfc04ad5f8562a 4 | branch: 3-0-stable 5 | specs: 6 | spree (3.0.2.beta) 7 | spree_api (= 3.0.2.beta) 8 | spree_backend (= 3.0.2.beta) 9 | spree_cmd (= 3.0.2.beta) 10 | spree_core (= 3.0.2.beta) 11 | spree_frontend (= 3.0.2.beta) 12 | spree_sample (= 3.0.2.beta) 13 | spree_api (3.0.2.beta) 14 | rabl (~> 0.9.4.pre1) 15 | spree_core (= 3.0.2.beta) 16 | versioncake (~> 2.3.1) 17 | spree_backend (3.0.2.beta) 18 | bootstrap-sass (~> 3.3.1) 19 | jquery-rails (~> 4.0.3) 20 | jquery-ui-rails (~> 5.0.0) 21 | select2-rails (= 3.5.9.1) 22 | spree_api (= 3.0.2.beta) 23 | spree_core (= 3.0.2.beta) 24 | sprockets-rails (~> 2.2) 25 | spree_cmd (3.0.2.beta) 26 | thor (~> 0.14) 27 | spree_core (3.0.2.beta) 28 | activemerchant (~> 1.47.0) 29 | acts_as_list (~> 0.6) 30 | awesome_nested_set (~> 3.0.1) 31 | cancancan (~> 1.10.1) 32 | carmen (~> 1.0.0) 33 | deface (~> 1.0.0) 34 | ffaker (~> 1.16) 35 | font-awesome-rails (~> 4.0) 36 | friendly_id (~> 5.1.0) 37 | highline (~> 1.6.18) 38 | httparty (~> 0.11) 39 | json (~> 1.7) 40 | kaminari (~> 0.15, >= 0.15.1) 41 | monetize (~> 1.1) 42 | paperclip (~> 4.2.0) 43 | paranoia (~> 2.1.0) 44 | premailer-rails 45 | rails (~> 4.2.0) 46 | ransack (~> 1.4.1) 47 | responders 48 | state_machines-activerecord (~> 0.2) 49 | stringex 50 | truncate_html (= 0.9.2) 51 | twitter_cldr (~> 3.0) 52 | spree_frontend (3.0.2.beta) 53 | bootstrap-sass (~> 3.3.1) 54 | canonical-rails (~> 0.0.4) 55 | jquery-rails (~> 4.0.3) 56 | spree_api (= 3.0.2.beta) 57 | spree_core (= 3.0.2.beta) 58 | sprockets-rails (~> 2.2) 59 | spree_sample (3.0.2.beta) 60 | spree_core (= 3.0.2.beta) 61 | 62 | GIT 63 | remote: git://github.com/spree/spree_auth_devise.git 64 | revision: d2ee454e21746094d6e0bc79b9d4421b5849c20e 65 | branch: 3-0-stable 66 | specs: 67 | spree_auth_devise (3.0.0) 68 | devise (~> 3.4.1) 69 | devise-encryptable (= 0.1.2) 70 | json 71 | multi_json 72 | spree_core (~> 3.0.0) 73 | 74 | PATH 75 | remote: . 76 | specs: 77 | spree_amazon_payments (2.3.4) 78 | spree_core 79 | 80 | GEM 81 | remote: https://rubygems.org/ 82 | specs: 83 | actionmailer (4.2.1) 84 | actionpack (= 4.2.1) 85 | actionview (= 4.2.1) 86 | activejob (= 4.2.1) 87 | mail (~> 2.5, >= 2.5.4) 88 | rails-dom-testing (~> 1.0, >= 1.0.5) 89 | actionpack (4.2.1) 90 | actionview (= 4.2.1) 91 | activesupport (= 4.2.1) 92 | rack (~> 1.6) 93 | rack-test (~> 0.6.2) 94 | rails-dom-testing (~> 1.0, >= 1.0.5) 95 | rails-html-sanitizer (~> 1.0, >= 1.0.1) 96 | actionview (4.2.1) 97 | activesupport (= 4.2.1) 98 | builder (~> 3.1) 99 | erubis (~> 2.7.0) 100 | rails-dom-testing (~> 1.0, >= 1.0.5) 101 | rails-html-sanitizer (~> 1.0, >= 1.0.1) 102 | activejob (4.2.1) 103 | activesupport (= 4.2.1) 104 | globalid (>= 0.3.0) 105 | activemerchant (1.47.0) 106 | activesupport (>= 3.2.14, < 5.0.0) 107 | builder (>= 2.1.2, < 4.0.0) 108 | i18n (>= 0.6.9) 109 | nokogiri (~> 1.4) 110 | activemodel (4.2.1) 111 | activesupport (= 4.2.1) 112 | builder (~> 3.1) 113 | activerecord (4.2.1) 114 | activemodel (= 4.2.1) 115 | activesupport (= 4.2.1) 116 | arel (~> 6.0) 117 | activesupport (4.2.1) 118 | i18n (~> 0.7) 119 | json (~> 1.7, >= 1.7.7) 120 | minitest (~> 5.1) 121 | thread_safe (~> 0.3, >= 0.3.4) 122 | tzinfo (~> 1.1) 123 | acts_as_list (0.7.2) 124 | activerecord (>= 3.0) 125 | addressable (2.3.8) 126 | arel (6.0.0) 127 | autoprefixer-rails (5.2.0) 128 | execjs 129 | json 130 | awesome_nested_set (3.0.2) 131 | activerecord (>= 4.0.0, < 5) 132 | bcrypt (3.1.10) 133 | bootstrap-sass (3.3.4.1) 134 | autoprefixer-rails (>= 5.0.0.1) 135 | sass (>= 3.2.19) 136 | builder (3.2.2) 137 | camertron-eprun (1.1.0) 138 | cancancan (1.10.1) 139 | canonical-rails (0.0.9) 140 | rails (>= 3.1, < 5.0) 141 | capybara (2.4.4) 142 | mime-types (>= 1.16) 143 | nokogiri (>= 1.3.3) 144 | rack (>= 1.0.0) 145 | rack-test (>= 0.5.4) 146 | xpath (~> 2.0) 147 | carmen (1.0.2) 148 | activesupport (>= 3.0.0) 149 | childprocess (0.5.6) 150 | ffi (~> 1.0, >= 1.0.11) 151 | cldr-plurals-runtime-rb (1.0.0) 152 | climate_control (0.0.3) 153 | activesupport (>= 3.0) 154 | cocaine (0.5.7) 155 | climate_control (>= 0.0.3, < 1.0) 156 | coffee-rails (4.1.0) 157 | coffee-script (>= 2.2.0) 158 | railties (>= 4.0.0, < 5.0) 159 | coffee-script (2.4.1) 160 | coffee-script-source 161 | execjs 162 | coffee-script-source (1.9.1.1) 163 | colorize (0.7.7) 164 | css_parser (1.3.6) 165 | addressable 166 | database_cleaner (1.4.1) 167 | deface (1.0.1) 168 | colorize (>= 0.5.8) 169 | nokogiri (~> 1.6.0) 170 | polyglot 171 | rails (>= 3.1) 172 | devise (3.4.1) 173 | bcrypt (~> 3.0) 174 | orm_adapter (~> 0.1) 175 | railties (>= 3.2.6, < 5) 176 | responders 177 | thread_safe (~> 0.1) 178 | warden (~> 1.2.3) 179 | devise-encryptable (0.1.2) 180 | devise (>= 2.1.0) 181 | diff-lcs (1.2.5) 182 | docile (1.1.5) 183 | erubis (2.7.0) 184 | execjs (2.5.2) 185 | factory_girl (4.5.0) 186 | activesupport (>= 3.0.0) 187 | ffaker (1.32.1) 188 | ffi (1.9.8) 189 | font-awesome-rails (4.3.0.0) 190 | railties (>= 3.2, < 5.0) 191 | friendly_id (5.1.0) 192 | activerecord (>= 4.0.0) 193 | globalid (0.3.5) 194 | activesupport (>= 4.1.0) 195 | highline (1.6.21) 196 | hike (1.2.3) 197 | htmlentities (4.3.3) 198 | httparty (0.13.5) 199 | json (~> 1.8) 200 | multi_xml (>= 0.5.2) 201 | i18n (0.7.0) 202 | jquery-rails (4.0.3) 203 | rails-dom-testing (~> 1.0) 204 | railties (>= 4.2.0) 205 | thor (>= 0.14, < 2.0) 206 | jquery-ui-rails (5.0.5) 207 | railties (>= 3.2.16) 208 | json (1.8.3) 209 | kaminari (0.16.3) 210 | actionpack (>= 3.0.0) 211 | activesupport (>= 3.0.0) 212 | loofah (2.0.2) 213 | nokogiri (>= 1.5.9) 214 | mail (2.6.3) 215 | mime-types (>= 1.16, < 3) 216 | mime-types (2.6.1) 217 | mini_portile (0.6.2) 218 | minitest (5.7.0) 219 | monetize (1.3.0) 220 | money (~> 6.5.0) 221 | money (6.5.1) 222 | i18n (>= 0.6.4, <= 0.7.0) 223 | multi_json (1.11.0) 224 | multi_xml (0.5.5) 225 | nokogiri (1.6.6.2) 226 | mini_portile (~> 0.6.0) 227 | orm_adapter (0.5.0) 228 | paperclip (4.2.1) 229 | activemodel (>= 3.0.0) 230 | activesupport (>= 3.0.0) 231 | cocaine (~> 0.5.3) 232 | mime-types 233 | paranoia (2.1.2) 234 | activerecord (~> 4.0) 235 | polyamorous (1.2.0) 236 | activerecord (>= 3.0) 237 | polyglot (0.3.5) 238 | premailer (1.8.4) 239 | css_parser (>= 1.3.6) 240 | htmlentities (>= 4.0.0) 241 | premailer-rails (1.8.2) 242 | actionmailer (>= 3, < 5) 243 | premailer (~> 1.7, >= 1.7.9) 244 | rabl (0.9.4.pre1) 245 | activesupport (>= 2.3.14) 246 | rack (1.6.1) 247 | rack-test (0.6.3) 248 | rack (>= 1.0) 249 | rails (4.2.1) 250 | actionmailer (= 4.2.1) 251 | actionpack (= 4.2.1) 252 | actionview (= 4.2.1) 253 | activejob (= 4.2.1) 254 | activemodel (= 4.2.1) 255 | activerecord (= 4.2.1) 256 | activesupport (= 4.2.1) 257 | bundler (>= 1.3.0, < 2.0) 258 | railties (= 4.2.1) 259 | sprockets-rails 260 | rails-deprecated_sanitizer (1.0.3) 261 | activesupport (>= 4.2.0.alpha) 262 | rails-dom-testing (1.0.6) 263 | activesupport (>= 4.2.0.beta, < 5.0) 264 | nokogiri (~> 1.6.0) 265 | rails-deprecated_sanitizer (>= 1.0.1) 266 | rails-html-sanitizer (1.0.2) 267 | loofah (~> 2.0) 268 | railties (4.2.1) 269 | actionpack (= 4.2.1) 270 | activesupport (= 4.2.1) 271 | rake (>= 0.8.7) 272 | thor (>= 0.18.1, < 2.0) 273 | rake (10.4.2) 274 | ransack (1.4.1) 275 | actionpack (>= 3.0) 276 | activerecord (>= 3.0) 277 | activesupport (>= 3.0) 278 | i18n 279 | polyamorous (~> 1.1) 280 | responders (2.1.0) 281 | railties (>= 4.2.0, < 5) 282 | rspec-core (3.2.3) 283 | rspec-support (~> 3.2.0) 284 | rspec-expectations (3.2.1) 285 | diff-lcs (>= 1.2.0, < 2.0) 286 | rspec-support (~> 3.2.0) 287 | rspec-mocks (3.2.1) 288 | diff-lcs (>= 1.2.0, < 2.0) 289 | rspec-support (~> 3.2.0) 290 | rspec-rails (3.2.1) 291 | actionpack (>= 3.0, < 4.3) 292 | activesupport (>= 3.0, < 4.3) 293 | railties (>= 3.0, < 4.3) 294 | rspec-core (~> 3.2.0) 295 | rspec-expectations (~> 3.2.0) 296 | rspec-mocks (~> 3.2.0) 297 | rspec-support (~> 3.2.0) 298 | rspec-support (3.2.2) 299 | rubyzip (1.1.7) 300 | sass (3.2.19) 301 | sass-rails (4.0.5) 302 | railties (>= 4.0.0, < 5.0) 303 | sass (~> 3.2.2) 304 | sprockets (~> 2.8, < 3.0) 305 | sprockets-rails (~> 2.0) 306 | select2-rails (3.5.9.1) 307 | thor (~> 0.14) 308 | selenium-webdriver (2.45.0) 309 | childprocess (~> 0.5) 310 | multi_json (~> 1.0) 311 | rubyzip (~> 1.0) 312 | websocket (~> 1.0) 313 | simplecov (0.10.0) 314 | docile (~> 1.1.0) 315 | json (~> 1.8) 316 | simplecov-html (~> 0.10.0) 317 | simplecov-html (0.10.0) 318 | sprockets (2.12.3) 319 | hike (~> 1.2) 320 | multi_json (~> 1.0) 321 | rack (~> 1.0) 322 | tilt (~> 1.1, != 1.3.0) 323 | sprockets-rails (2.3.1) 324 | actionpack (>= 3.0) 325 | activesupport (>= 3.0) 326 | sprockets (>= 2.8, < 4.0) 327 | sqlite3 (1.3.10) 328 | state_machines (0.2.2) 329 | state_machines-activemodel (0.1.2) 330 | activemodel (~> 4.1) 331 | state_machines (~> 0.2.0) 332 | state_machines-activerecord (0.2.0) 333 | activerecord (~> 4.1) 334 | state_machines-activemodel (~> 0.1.0) 335 | stringex (2.5.2) 336 | thor (0.19.1) 337 | thread_safe (0.3.5) 338 | tilt (1.4.1) 339 | truncate_html (0.9.2) 340 | twitter_cldr (3.1.2) 341 | camertron-eprun 342 | cldr-plurals-runtime-rb (~> 1.0.0) 343 | json 344 | tzinfo 345 | tzinfo (1.2.2) 346 | thread_safe (~> 0.1) 347 | versioncake (2.3.1) 348 | actionpack (>= 3.2) 349 | activesupport (>= 3.2) 350 | railties (>= 3.2) 351 | tzinfo 352 | warden (1.2.3) 353 | rack (>= 1.0) 354 | websocket (1.2.2) 355 | xpath (2.0.0) 356 | nokogiri (~> 1.3) 357 | 358 | PLATFORMS 359 | ruby 360 | 361 | DEPENDENCIES 362 | capybara (~> 2.4) 363 | coffee-rails 364 | database_cleaner 365 | factory_girl (~> 4.4) 366 | ffaker 367 | rspec-rails (~> 3.1) 368 | sass-rails (~> 4.0.2) 369 | selenium-webdriver 370 | simplecov 371 | spree! 372 | spree_amazon_payments! 373 | spree_auth_devise! 374 | sqlite3 375 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /LoginandPaywithAmazonforSpreeCommerce.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amazon-archives/spree_pay_with_amazon/7206b1f5e4af3d4f47dd0fcaba456e7d0bcab2cd/LoginandPaywithAmazonforSpreeCommerce.pdf -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Login and Pay for Spree Commerce Plugin 2 | Copyright 2014 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | spree_pay_with_amazon 2 | =================== 3 | 4 | Add Pay with Amazon to your Spree Commerce solution. 5 | 6 | Installation 7 | ------------ 8 | 9 | Add spree_amazon_payments to your Gemfile: 10 | 11 | ``` 12 | gem 'spree_social', github: 'spree-contrib/spree_social', branch: '3-0-stable' 13 | gem 'spree_amazon_payments', github: 'amzn/spree_pay_with_amazon' 14 | ``` 15 | 16 | Bundle your dependencies and run the installation generator: 17 | 18 | ``` 19 | bundle 20 | bundle exec rails g spree_amazon_payments:install 21 | bundle exec rails g spree_social:install 22 | ``` 23 | 24 | Registration 25 | -------------- 26 | [Register for your Amazon Payments account here](https://payments.amazon.com/register?registration_source=SPPD&spId=A31NP5KFHXSFV1) 27 | 28 | Refund Callback 29 | -------------- 30 | You will need to configure Instant Notification Settings in order to accept the callback when a refund is completed. Configure your IPN settings by logging into your [Seller Central Account](https://sellercentral.amazon.com/gp/pyop/seller/account/settings/user-settings-view.html?). 31 | 32 | The IPN URL will be in the Configuration section of your Spree Commerce instance. 33 | 34 | User Guide 35 | -------------- 36 | Please see the user guide [here](https://github.com/amzn/spree_pay_with_amazon/blob/master/LoginandPaywithAmazonforSpreeCommerce.pdf?raw=true) for more information 37 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | ## 2 | # Amazon Payments - Login and Pay for Spree Commerce 3 | # 4 | # @category Amazon 5 | # @package Amazon_Payments 6 | # @copyright Copyright (c) 2014 Amazon.com 7 | # @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 8 | # 9 | ## 10 | require 'bundler' 11 | Bundler::GemHelper.install_tasks 12 | 13 | require 'rspec/core/rake_task' 14 | require 'spree/testing_support/extension_rake' 15 | 16 | RSpec::Core::RakeTask.new 17 | 18 | task :default do 19 | if Dir["spec/dummy"].empty? 20 | Rake::Task[:test_app].invoke 21 | Dir.chdir("../../") 22 | end 23 | Rake::Task[:spec].invoke 24 | end 25 | 26 | desc 'Generates a dummy app for testing' 27 | task :test_app do 28 | ENV['LIB_NAME'] = 'spree_amazon_payments' 29 | Rake::Task['extension:test_app'].invoke 30 | end 31 | -------------------------------------------------------------------------------- /app/assets/javascripts/spree/backend/payments/new.js: -------------------------------------------------------------------------------- 1 | /*## 2 | # Amazon Payments - Login and Pay for Spree Commerce 3 | # 4 | # @category Amazon 5 | # @package Amazon_Payments 6 | # @copyright Copyright (c) 2014 Amazon.com 7 | # @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 8 | # 9 | ##*/ 10 | // Pull in file to fix https://github.com/spree/spree/commit/66446eaa8b5726690c3a6933a354be9650660fa2 11 | 12 | //= require jquery.payment 13 | $(document).ready(function() { 14 | if ($("#new_payment").is("*")) { 15 | $(".cardNumber").payment('formatCardNumber'); 16 | $(".cardExpiry").payment('formatCardExpiry'); 17 | $(".cardCode").payment('formatCardCVC'); 18 | 19 | $(".cardNumber").change(function() { 20 | $(".ccType").val($.payment.cardType(this.value)) 21 | }) 22 | 23 | $('.payment_methods_radios').click( 24 | function() { 25 | $('.payment-methods').hide(); 26 | $('.payment-methods input').prop('disabled', true); 27 | if (this.checked) { 28 | $('#payment_method_' + this.value + ' input').prop('disabled', false); 29 | $('#payment_method_' + this.value).show(); 30 | } 31 | } 32 | ); 33 | 34 | $('.payment_methods_radios').each( 35 | function() { 36 | if (this.checked) { 37 | $('#payment_method_' + this.value + ' input').prop('disabled', false); 38 | $('#payment_method_' + this.value).show(); 39 | } else { 40 | $('#payment_method_' + this.value).hide(); 41 | $('#payment_method_' + this.value + ' input').prop('disabled', true); 42 | } 43 | 44 | if ($("#card_new" + this.value).is("*")) { 45 | $("#card_new" + this.value).radioControlsVisibilityOfElement('#card_form' + this.value); 46 | } 47 | } 48 | ); 49 | 50 | $('.cvvLink').click(function(event){ 51 | window_name = 'cvv_info'; 52 | window_options = 'left=20,top=20,width=500,height=500,toolbar=0,resizable=0,scrollbars=1'; 53 | window.open($(this).prop('href'), window_name, window_options); 54 | event.preventDefault(); 55 | }); 56 | 57 | $('select.jump_menu').change(function(){ 58 | window.location = this.options[this.selectedIndex].value; 59 | }); 60 | } 61 | }); 62 | -------------------------------------------------------------------------------- /app/assets/javascripts/spree/backend/spree_amazon_payments.js: -------------------------------------------------------------------------------- 1 | /*## 2 | # Amazon Payments - Login and Pay for Spree Commerce 3 | # 4 | # @category Amazon 5 | # @package Amazon_Payments 6 | # @copyright Copyright (c) 2014 Amazon.com 7 | # @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 8 | # 9 | ##*/ 10 | // Placeholder manifest file. 11 | // the installer will append this file to the app vendored assets here: vendor/assets/javascripts/spree/backend/all.js' -------------------------------------------------------------------------------- /app/assets/javascripts/spree/frontend/spree_amazon_payments.js: -------------------------------------------------------------------------------- 1 | /*## 2 | # Amazon Payments - Login and Pay for Spree Commerce 3 | # 4 | # @category Amazon 5 | # @package Amazon_Payments 6 | # @copyright Copyright (c) 2014 Amazon.com 7 | # @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 8 | # 9 | ##*/ 10 | // Placeholder manifest file. 11 | // the installer will append this file to the app vendored assets here: vendor/assets/javascripts/spree/frontend/all.js' -------------------------------------------------------------------------------- /app/assets/stylesheets/spree/backend/spree_amazon_payments.css: -------------------------------------------------------------------------------- 1 | /*## 2 | # Amazon Payments - Login and Pay for Spree Commerce 3 | # 4 | # @category Amazon 5 | # @package Amazon_Payments 6 | # @copyright Copyright (c) 2014 Amazon.com 7 | # @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 8 | # 9 | ##*/ 10 | /* 11 | Placeholder manifest file. 12 | the installer will append this file to the app vendored assets here: 'vendor/assets/stylesheets/spree/backend/all.css' 13 | */ 14 | -------------------------------------------------------------------------------- /app/assets/stylesheets/spree/frontend/spree_amazon_payments.css: -------------------------------------------------------------------------------- 1 | /*## 2 | # Amazon Payments - Login and Pay for Spree Commerce 3 | # 4 | # @category Amazon 5 | # @package Amazon_Payments 6 | # @copyright Copyright (c) 2014 Amazon.com 7 | # @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 8 | # 9 | ##*/ 10 | /* Please include the min-width, max-width, min-height and max-height */ 11 | /* if you plan to use a relative CSS unit measurement to make sure the */ 12 | /* widget renders in the optimal size allowed. */ 13 | 14 | #addressBookWidgetDiv, #walletWidgetDiv { height: 228px; width: 100%; } 15 | -------------------------------------------------------------------------------- /app/controllers/spree/admin/amazon_controller.rb: -------------------------------------------------------------------------------- 1 | ## 2 | # Amazon Payments - Login and Pay for Spree Commerce 3 | # 4 | # @category Amazon 5 | # @package Amazon_Payments 6 | # @copyright Copyright (c) 2014 Amazon.com 7 | # @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 8 | # 9 | ## 10 | class Spree::Admin::AmazonController < Spree::Admin::BaseController 11 | respond_to :html 12 | 13 | def edit 14 | @amazon_callback_url = "#{root_url}amazon_callback" 15 | end 16 | 17 | def update 18 | Spree::Config[:amazon_client_id]=params[:amazon_client_id] 19 | Spree::Config[:amazon_merchant_id] = params[:amazon_merchant_id] 20 | Spree::Config[:amazon_aws_access_key_id] = params[:amazon_aws_access_key_id] 21 | Spree::Config[:amazon_aws_secret_access_key] = params[:amazon_aws_secret_access_key] 22 | flash[:success] = Spree.t(:successfully_updated, :resource => Spree.t(:amazon_settings)) 23 | redirect_to edit_admin_amazon_path 24 | end 25 | end -------------------------------------------------------------------------------- /app/controllers/spree/amazon_callback_controller.rb: -------------------------------------------------------------------------------- 1 | ## 2 | # Amazon Payments - Login and Pay for Spree Commerce 3 | # 4 | # @category Amazon 5 | # @package Amazon_Payments 6 | # @copyright Copyright (c) 2014 Amazon.com 7 | # @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 8 | # 9 | ## 10 | class Spree::AmazonCallbackController < ApplicationController 11 | skip_before_filter :verify_authenticity_token 12 | 13 | def new 14 | response = JSON.parse(request.body.read) 15 | if JSON.parse(response["Message"])["NotificationType"] == "PaymentRefund" 16 | refund_id = Hash.from_xml(JSON.parse(response["Message"])[ "NotificationData"])["RefundNotification"]["RefundDetails"]["AmazonRefundId"] 17 | payment = Spree::LogEntry.where('details LIKE ?', "%#{refund_id}%").last.try(:source) 18 | if payment 19 | l = payment.log_entries.build(details: response.to_yaml) 20 | l.save 21 | end 22 | end 23 | render nothing: true 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /app/controllers/spree/amazon_controller.rb: -------------------------------------------------------------------------------- 1 | ## 2 | # Amazon Payments - Login and Pay for Spree Commerce 3 | # 4 | # @category Amazon 5 | # @package Amazon_Payments 6 | # @copyright Copyright (c) 2014 Amazon.com 7 | # @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 8 | # 9 | ## 10 | class Spree::AmazonController < Spree::StoreController 11 | 12 | helper 'spree/orders' 13 | before_filter :check_for_current_order 14 | before_filter :load_amazon_mws, except: [:address, :payment, :complete] 15 | 16 | respond_to :json 17 | 18 | def address 19 | current_order.state = 'cart' 20 | current_order.save! 21 | end 22 | 23 | def payment 24 | payment = current_order.payments.valid.first{|p| p.source_type == "Spree::AmazonTransaction"} || current_order.payments.create 25 | payment.number = params[:order_reference] 26 | payment.payment_method = Spree::PaymentMethod.find_by(:type => "Spree::Gateway::Amazon") 27 | payment.source ||= Spree::AmazonTransaction.create(:order_reference => params[:order_reference], :order_id => current_order.id) 28 | 29 | payment.save! 30 | 31 | render json: {}.to_json 32 | end 33 | 34 | def delivery 35 | data = @mws.fetch_order_data 36 | current_order.state = 'cart' 37 | 38 | if data.destination && data.destination["PhysicalDestination"] 39 | current_order.email = "pending@amazon.com" 40 | address = data.destination["PhysicalDestination"] 41 | spree_address = Spree::Address.new( 42 | "firstname" => "Amazon", 43 | "lastname" => "User", 44 | "address1" => "TBD", 45 | "phone" => "TBD", 46 | "city" => address["City"], 47 | "zipcode" => address["PostalCode"], 48 | "state_name" => address["StateOrRegion"], 49 | "country" => Spree::Country.where("iso = ? OR iso_name = ?", address["CountryCode"],address["CountryCode"]).first) 50 | spree_address.save! 51 | current_order.ship_address_id = spree_address.id 52 | current_order.bill_address_id = spree_address.id 53 | current_order.save! 54 | current_order.next! # to Address 55 | current_order.next! # to Delivery 56 | 57 | current_order.reload 58 | else 59 | redirect_to address_amazon_order_path, :notice => "Unable to load Address data from Amazon" 60 | end 61 | render :layout => false 62 | end 63 | 64 | def confirm 65 | 66 | if current_order.update_from_params(params, permitted_checkout_attributes, request.headers.env) 67 | 68 | @mws.set_order_data(current_order.total, current_order.currency) 69 | 70 | result = @mws.confirm_order 71 | 72 | data = @mws.fetch_order_data 73 | 74 | if data.destination && data.destination["PhysicalDestination"] 75 | current_order.email = data.email 76 | current_order.save! 77 | address = data.destination["PhysicalDestination"] 78 | first_name = address["Name"].split(" ")[0] rescue "Amazon" 79 | last_name = address["Name"].split(" ")[1..10].join(" ") 80 | spree_address = current_order.ship_address 81 | spree_address.update({ 82 | "firstname" => first_name, 83 | "lastname" => last_name, 84 | "address1" => address["AddressLine1"], 85 | "phone" => address["Phone"] || "n/a", 86 | "city" => address["City"], 87 | "zipcode" => address["PostalCode"], 88 | "state_name" => address["StateOrRegion"], 89 | "country" => Spree::Country.find_by_iso(address["CountryCode"])}) 90 | spree_address.save! 91 | else 92 | raise "There is a problem with your order" 93 | end 94 | current_order.create_tax_charge! 95 | current_order.reload 96 | payment = current_order.payments.valid.first{|p| p.source_type == "Spree::AmazonTransaction"} 97 | payment.amount = current_order.total 98 | payment.save! 99 | @order = current_order 100 | 101 | # Remove the following line to enable the confirmation step. 102 | redirect_to amazon_order_complete_path(@order) 103 | else 104 | render :edit 105 | end 106 | 107 | end 108 | 109 | def complete 110 | @order = Spree::Order.find_by(:number => params[:amazon_order_id]) 111 | authorize!(:edit, @order, cookies.signed[:guest_token]) 112 | 113 | redirect_to root_path if @order.nil? 114 | while(@order.next) do 115 | 116 | end 117 | 118 | if @order.completed? 119 | @current_order = nil 120 | flash.notice = Spree.t(:order_processed_successfully) 121 | end 122 | 123 | if @order.complete? 124 | redirect_to spree.order_path(@order) 125 | else 126 | @order.state = 'cart' 127 | @order.amazon_transactions.destroy_all 128 | redirect_to cart_path, :notice => "Unable to process order" 129 | return true 130 | end 131 | end 132 | 133 | def load_amazon_mws 134 | render :nothing => true, :status => 200 if current_order.amazon_order_reference_id.nil? 135 | @mws ||= AmazonMws.new(current_order.amazon_order_reference_id, Spree::Gateway::Amazon.first.preferred_test_mode) 136 | end 137 | 138 | private 139 | 140 | 141 | def check_for_current_order 142 | redirect_to root_path, :notice => "No Order Found" if current_order.nil? 143 | return true 144 | end 145 | end 146 | -------------------------------------------------------------------------------- /app/models/spree/amazon_transaction.rb: -------------------------------------------------------------------------------- 1 | ## 2 | # Amazon Payments - Login and Pay for Spree Commerce 3 | # 4 | # @category Amazon 5 | # @package Amazon_Payments 6 | # @copyright Copyright (c) 2014 Amazon.com 7 | # @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 8 | # 9 | ## 10 | module Spree 11 | class AmazonTransaction < ActiveRecord::Base 12 | has_many :payments, :as => :source 13 | 14 | def name 15 | "Pay with Amazon" 16 | end 17 | 18 | def cc_type 19 | "n/a" 20 | end 21 | 22 | def display_number 23 | "n/a" 24 | end 25 | 26 | def month 27 | "n" 28 | end 29 | 30 | def year 31 | "a" 32 | end 33 | 34 | def reusable_sources(_order) 35 | [] 36 | end 37 | 38 | def self.with_payment_profile 39 | [] 40 | end 41 | 42 | def can_capture?(payment) 43 | (payment.pending? || payment.checkout?) && payment.amount > 0 44 | end 45 | 46 | def can_credit?(payment) 47 | (payment.pending? || payment.checkout?) && payment.amount < 0 48 | end 49 | 50 | def can_void?(payment) 51 | false 52 | end 53 | 54 | def can_close?(payment) 55 | !payment.closed? 56 | end 57 | 58 | def actions 59 | %w{capture credit close} 60 | end 61 | 62 | end 63 | end -------------------------------------------------------------------------------- /app/models/spree/app_configuration_decorator.rb: -------------------------------------------------------------------------------- 1 | ## 2 | # Amazon Payments - Login and Pay for Spree Commerce 3 | # 4 | # @category Amazon 5 | # @package Amazon_Payments 6 | # @copyright Copyright (c) 2014 Amazon.com 7 | # @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 8 | # 9 | ## 10 | Spree::AppConfiguration.class_eval do 11 | preference :amazon_checkout_display_mode, :string, :default => 'modified_checkout' 12 | preference :amazon_client_id, :string 13 | preference :amazon_merchant_id, :string 14 | preference :amazon_aws_access_key_id, :string 15 | preference :amazon_aws_secret_access_key, :string 16 | end -------------------------------------------------------------------------------- /app/models/spree/gateway/amazon.rb: -------------------------------------------------------------------------------- 1 | ## 2 | # Amazon Payments - Login and Pay for Spree Commerce 3 | # 4 | # @category Amazon 5 | # @package Amazon_Payments 6 | # @copyright Copyright (c) 2014 Amazon.com 7 | # @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 8 | # 9 | ## 10 | module Spree 11 | class Gateway::Amazon < Gateway 12 | 13 | has_one :provider 14 | 15 | def supports?(source) 16 | true 17 | end 18 | 19 | def method_type 20 | "amazon" 21 | end 22 | 23 | def provider_class 24 | AmazonTransaction 25 | end 26 | 27 | def payment_source_class 28 | AmazonTransaction 29 | end 30 | 31 | def source_required? 32 | true 33 | end 34 | 35 | def authorize(amount, amazon_checkout, gateway_options={}) 36 | if amount < 0 37 | return ActiveMerchant::Billing::Response.new(true, "Success", {}) 38 | end 39 | order = Spree::Order.find_by(:number => gateway_options[:order_id].split("-")[0]) 40 | load_amazon_mws(order.amazon_order_reference_id) 41 | response = @mws.authorize(gateway_options[:order_id], amount / 100.0, Spree::Config.currency) 42 | if response["ErrorResponse"] 43 | return ActiveMerchant::Billing::Response.new(false, response["ErrorResponse"]["Error"]["Message"], response) 44 | end 45 | t = order.amazon_transaction 46 | t.authorization_id = response["AuthorizeResponse"]["AuthorizeResult"]["AuthorizationDetails"]["AmazonAuthorizationId"] 47 | t.save 48 | return ActiveMerchant::Billing::Response.new(response["AuthorizeResponse"]["AuthorizeResult"]["AuthorizationDetails"]["AuthorizationStatus"]["State"] == "Open", "Success", response) 49 | end 50 | 51 | def capture(amount, amazon_checkout, gateway_options={}) 52 | if amount < 0 53 | return credit(amount.abs, nil, nil, gateway_options) 54 | end 55 | order = Spree::Order.find_by(:number => gateway_options[:order_id].split("-")[0]) 56 | load_amazon_mws(order.amazon_order_reference_id) 57 | 58 | authorization_id = order.amazon_transaction.authorization_id 59 | response = @mws.capture(authorization_id, "C#{Time.now.to_i}", amount / 100.00, Spree::Config.currency) 60 | t = order.amazon_transaction 61 | t.capture_id = response.fetch("CaptureResponse", {}).fetch("CaptureResult", {}).fetch("CaptureDetails", {}).fetch("AmazonCaptureId", nil) 62 | t.save! 63 | return ActiveMerchant::Billing::Response.new(response.fetch("CaptureResponse", {}).fetch("CaptureResult", {}).fetch("CaptureDetails", {}).fetch("CaptureStatus", {})["State"] == "Completed", "OK", response) 64 | end 65 | 66 | def purchase(amount, amazon_checkout, gateway_options={}) 67 | authorize(amount, amazon_checkout, gateway_options) 68 | capture(amount, amazon_checkout, gateway_options) 69 | end 70 | 71 | def credit(amount, _credit_card, gateway_options={}) 72 | order = Spree::Order.find_by(:number => gateway_options[:order_id].split("-")[0]) 73 | load_amazon_mws(order.amazon_order_reference_id) 74 | capture_id = order.amazon_transaction.capture_id 75 | response = @mws.refund(capture_id, gateway_options[:order_id], amount / 100.00, Spree::Config.currency) 76 | return ActiveMerchant::Billing::Response.new(true, "Success", response) 77 | end 78 | 79 | def void(response_code, gateway_options) 80 | order = Spree::Order.find_by(:number => gateway_options[:order_id].split("-")[0]) 81 | load_amazon_mws(order.amazon_order_reference_id) 82 | capture_id = order.amazon_transaction.capture_id 83 | response = @mws.refund(capture_id, gateway_options[:order_id], order.total, Spree::Config.currency) 84 | return ActiveMerchant::Billing::Response.new(true, "Success", response) 85 | end 86 | 87 | def close(amount, amazon_checkout, gateway_options={}) 88 | order = Spree::Order.find_by(:number => gateway_options[:order_id].split("-")[0]) 89 | load_amazon_mws(order.amazon_order_reference_id) 90 | 91 | authorization_id = order.amazon_transaction.authorization_id 92 | response = @mws.close(authorization_id) 93 | return ActiveMerchant::Billing::Response.new(true, "Success", response) 94 | end 95 | 96 | private 97 | 98 | def load_amazon_mws(reference) 99 | @mws ||= AmazonMws.new(reference, self.preferred_test_mode) 100 | end 101 | end 102 | end -------------------------------------------------------------------------------- /app/models/spree/order_decorator.rb: -------------------------------------------------------------------------------- 1 | ## 2 | # Amazon Payments - Login and Pay for Spree Commerce 3 | # 4 | # @category Amazon 5 | # @package Amazon_Payments 6 | # @copyright Copyright (c) 2014 Amazon.com 7 | # @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 8 | # 9 | ## 10 | Spree::Order.class_eval do 11 | has_many :amazon_transactions 12 | 13 | def amazon_transaction 14 | amazon_transactions.last 15 | end 16 | 17 | def amazon_order_reference_id 18 | amazon_transaction.try(:order_reference) 19 | end 20 | end -------------------------------------------------------------------------------- /app/models/spree/payment/processing_decorator.rb: -------------------------------------------------------------------------------- 1 | ## 2 | # Amazon Payments - Login and Pay for Spree Commerce 3 | # 4 | # @category Amazon 5 | # @package Amazon_Payments 6 | # @copyright Copyright (c) 2014 Amazon.com 7 | # @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 8 | # 9 | ## 10 | Spree::Payment::Processing.class_eval do 11 | def close! 12 | gateway_action(source, :close, :close) 13 | end 14 | end -------------------------------------------------------------------------------- /app/models/spree/payment_decorator.rb: -------------------------------------------------------------------------------- 1 | ## 2 | # Amazon Payments - Login and Pay for Spree Commerce 3 | # 4 | # @category Amazon 5 | # @package Amazon_Payments 6 | # @copyright Copyright (c) 2014 Amazon.com 7 | # @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 8 | # 9 | ## 10 | Spree::Payment.class_eval do 11 | # order state machine (see http://github.com/pluginaweek/state_machine/tree/master for details) 12 | state_machine initial: :checkout do 13 | # With card payments, happens before purchase or authorization happens 14 | # 15 | # Setting it after creating a profile and authorizing a full amount will 16 | # prevent the payment from being authorized again once Order transitions 17 | # to complete 18 | event :started_processing do 19 | transition from: [:checkout, :pending, :completed, :processing], to: :processing 20 | end 21 | # When processing during checkout fails 22 | event :failure do 23 | transition from: [:pending, :processing], to: :failed 24 | end 25 | # With card payments this represents authorizing the payment 26 | event :pend do 27 | transition from: [:checkout, :processing], to: :pending 28 | end 29 | # With card payments this represents completing a purchase or capture transaction 30 | event :complete do 31 | transition from: [:processing, :pending, :checkout], to: :completed 32 | end 33 | event :close do 34 | transition from: [:pending, :processing, :completed, :checkout], to: :closed 35 | end 36 | event :void do 37 | transition from: [:pending, :processing, :completed, :checkout], to: :void 38 | end 39 | # when the card brand isnt supported 40 | event :invalidate do 41 | transition from: [:checkout], to: :invalid 42 | end 43 | 44 | after_transition do |payment, transition| 45 | payment.state_changes.create!( 46 | previous_state: transition.from, 47 | next_state: transition.to, 48 | name: 'payment', 49 | ) 50 | end 51 | end 52 | end -------------------------------------------------------------------------------- /app/overrides/spree/admin/shared/sub_menu/_configuration.rb: -------------------------------------------------------------------------------- 1 | Deface::Override.new( 2 | virtual_path: 'spree/admin/shared/sub_menu/_configuration', 3 | name: 'add_amazon_link_configuration_menu', 4 | insert_bottom: '[data-hook="admin_configurations_sidebar_menu"]', 5 | text: '<%= configurations_sidebar_menu_item Spree.t(:amazon_settings), spree.edit_admin_amazon_path %>' 6 | ) 7 | -------------------------------------------------------------------------------- /app/overrides/spree/checkout/_delivery/add_buttons_to_delivery.html.erb.deface: -------------------------------------------------------------------------------- 1 | 2 |
3 | <%= submit_tag Spree.t(:place_order), :class => 'btn btn-lg btn-success' %> 4 |
5 | -------------------------------------------------------------------------------- /app/overrides/spree/checkout/_payment/remove_amazon_payment_method.html.erb.deface: -------------------------------------------------------------------------------- 1 | 2 | <% next if method.type.eql?('Spree::Gateway::Amazon') %> 3 | -------------------------------------------------------------------------------- /app/overrides/spree/orders/edit/add_pay_with_amazon.html.erb.deface: -------------------------------------------------------------------------------- 1 | 2 | <% if Spree::Gateway::Amazon.count > 0 %> 3 | <%= render :partial => "spree/amazon/login" %> 4 | <% end %> 5 | -------------------------------------------------------------------------------- /app/views/spree/admin/amazon/edit.html.erb: -------------------------------------------------------------------------------- 1 | <%# %> 2 | <%# Amazon Payments - Login and Pay for Spree Commerce %> 3 | <%# %> 4 | <%# @category Amazon %> 5 | <%# @package Amazon_Payments %> 6 | <%# @copyright Copyright (c) 2014 Amazon.com %> 7 | <%# @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 %> 8 | <%# %> 9 | 10 | <% content_for :page_title do %> 11 | <%= Spree.t(:amazon_settings) %> 12 | <% end %> 13 | 14 |

Login to get your keys.

15 | <%= form_tag admin_amazon_path, :method => :put do %> 16 |
17 |
18 |
19 | <%= label_tag "Amazon Client Id" %> 20 | <%= text_field_tag :amazon_client_id, Spree::Config[:amazon_client_id], class: 'form-control' %> 21 |
22 | 23 |
24 | <%= label_tag "Amazon Merchant Id" %> 25 | <%= text_field_tag :amazon_merchant_id, Spree::Config[:amazon_merchant_id], class: 'form-control' %> 26 |
27 | 28 |
29 | <%= label_tag "Amazon MWS Access Key" %> 30 | <%= text_field_tag :amazon_aws_access_key_id, Spree::Config[:amazon_aws_access_key_id], class: 'form-control' %> 31 |
32 | 33 |
34 | <%= label_tag "Amazon MWS Secret Key" %> 35 | <%= text_field_tag :amazon_aws_secret_access_key, Spree::Config[:amazon_aws_secret_access_key], class: 'form-control' %> 36 |
37 | 38 |
39 | <%= label_tag "Amazon Callback Url" %> 40 | <%= text_field_tag :amazon_callback_url, @amazon_callback_url, class: 'form-control', disabled: true %> 41 |
42 | 43 |
44 | <%= button Spree.t('actions.update'), 'save' %> 45 | <%= Spree.t(:or) %> 46 | <%= button_link_to Spree.t('actions.cancel'), edit_admin_general_settings_url, icon: 'delete' %> 47 |
48 |
49 |
50 | <% end %> 51 | -------------------------------------------------------------------------------- /app/views/spree/admin/log_entries/_amazon.html.erb: -------------------------------------------------------------------------------- 1 | <%# %> 2 | <%# Amazon Payments - Login and Pay for Spree Commerce %> 3 | <%# %> 4 | <%# @category Amazon %> 5 | <%# @package Amazon_Payments %> 6 | <%# @copyright Copyright (c) 2014 Amazon.com %> 7 | <%# @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 %> 8 | <%# %> 9 | 10 | Message 11 | <%= entry.parsed_details.message %> 12 | -------------------------------------------------------------------------------- /app/views/spree/admin/payments/source_forms/_amazon.html.erb: -------------------------------------------------------------------------------- 1 | <%# %> 2 | <%# Amazon Payments - Login and Pay for Spree Commerce %> 3 | <%# %> 4 | <%# @category Amazon %> 5 | <%# @package Amazon_Payments %> 6 | <%# @copyright Copyright (c) 2014 Amazon.com %> 7 | <%# @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 %> 8 | <%# %> 9 |
10 | <%= hidden_field_tag "card", @order.amazon_transaction.try(:id) %> 11 |
12 | 13 | Billing existing Amazon Card -------------------------------------------------------------------------------- /app/views/spree/admin/payments/source_views/_amazon.html.erb: -------------------------------------------------------------------------------- 1 | <%# %> 2 | <%# Amazon Payments - Login and Pay for Spree Commerce %> 3 | <%# %> 4 | <%# @category Amazon %> 5 | <%# @package Amazon_Payments %> 6 | <%# @copyright Copyright (c) 2014 Amazon.com %> 7 | <%# @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 %> 8 | <%# %> 9 |
10 | <%= Spree.t(:transaction, :scope => :amazon) %> 11 | 12 |
13 |
14 |
15 |
<%= Spree.t(:payer_id, :scope => :amazon) %>:
16 |
<%= payment.number %>
17 |
18 |
19 | 20 | <% if payment.state != 'void' %> 21 | <%= button_link_to Spree.t('actions.refund', :scope => :amazon), "#", :icon => 'icon-dollar' %> 22 | <% else %> 23 |
24 |
25 |
<%= Spree.t(:state, :scope => :amazon) %>:
26 |
<%= payment.state.titleize %>
27 |
28 |
29 | <% end %> 30 |
31 |
32 | -------------------------------------------------------------------------------- /app/views/spree/amazon/_login.html.erb: -------------------------------------------------------------------------------- 1 | <%# %> 2 | <%# Amazon Payments - Login and Pay for Spree Commerce %> 3 | <%# %> 4 | <%# @category Amazon %> 5 | <%# @package Amazon_Payments %> 6 | <%# @copyright Copyright (c) 2014 Amazon.com %> 7 | <%# @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 %> 8 | <%# %> 9 | 14 | 17 | 18 |
19 | 20 | 34 | -------------------------------------------------------------------------------- /app/views/spree/amazon/_order_details.html.erb: -------------------------------------------------------------------------------- 1 | <%# %> 2 | <%# Amazon Payments - Login and Pay for Spree Commerce %> 3 | <%# %> 4 | <%# @category Amazon %> 5 | <%# @package Amazon_Payments %> 6 | <%# @copyright Copyright (c) 2014 Amazon.com %> 7 | <%# @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 %> 8 | <%# %> 9 |
10 | 11 | <% if order.has_step?("address") %> 12 | 13 |
14 |
<%= Spree.t(:billing_address) %>
15 | <%= render :partial => 'spree/shared/address', :locals => { :address => order.bill_address } %> 16 |
17 | 18 | <% if order.has_step?("delivery") %> 19 |
20 |
<%= Spree.t(:shipping_address) %>
21 | <%= render :partial => 'spree/shared/address', :locals => { :address => order.ship_address } %> 22 |
23 | <% end %> 24 | 25 | <% if @order.has_step?("delivery") %> 26 |
27 |
<%= Spree.t(:shipments) %>
28 |
29 | <% order.shipments.each do |shipment| %> 30 |
31 | 32 | <%= Spree.t(:shipment_details, :stock_location => shipment.stock_location.name, :shipping_method => shipment.selected_shipping_rate.name) %> 33 |
34 | <% end %> 35 |
36 | <%= render(:partial => 'spree/shared/shipment_tracking', :locals => {:order => @order}) if @order.shipped? %> 37 |
38 | <% end %> 39 | <% end %> 40 | 41 |
42 |
<%= Spree.t(:payment_information) %>
43 |
44 | <% order.payments.valid.each do |payment| %> 45 | <%= render payment%>
46 | <% end %> 47 |
48 |
49 | 50 |
51 | 52 |
53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | <% @order.line_items.each do |item| %> 72 | 73 | 80 | 85 | 86 | 87 | 88 | 89 | <% end %> 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | <% if @order.line_item_adjustments.exists? %> 106 | <% if order.all_adjustments.promotion.eligible.exists? %> 107 | 108 | <% order.all_adjustments.promotion.eligible.group_by(&:label).each do |label, adjustments| %> 109 | 110 | 111 | 112 | 113 | <% end %> 114 | 115 | <% end %> 116 | <% end %> 117 | 118 | 119 | <% order.shipments.group_by { |s| s.selected_shipping_rate.name }.each do |name, shipments| %> 120 | 121 | 122 | 123 | 124 | <% end %> 125 | 126 | 127 | <% if order.all_adjustments.tax.exists? %> 128 | 129 | <% order.all_adjustments.tax.group_by(&:label).each do |label, adjustments| %> 130 | 131 | 132 | 133 | 134 | <% end %> 135 | 136 | <% end %> 137 | 138 | 139 | <% @order.adjustments.eligible.each do |adjustment| %> 140 | <% next if (adjustment.source_type == 'Spree::TaxRate') and (adjustment.amount == 0) %> 141 | 142 | 143 | 144 | 145 | <% end %> 146 | 147 | 148 |
<%= Spree.t(:item) %><%= Spree.t(:price) %><%= Spree.t(:qty) %><%= Spree.t(:total) %>
74 | <% if item.variant.images.length == 0 %> 75 | <%= link_to small_image(item.variant.product), item.variant.product %> 76 | <% else %> 77 | <%= link_to image_tag(item.variant.images.first.attachment.url(:small)), item.variant.product %> 78 | <% end %> 79 | 81 |

<%= item.variant.product.name %>

82 | <%= truncated_product_description(item.variant.product) %> 83 | <%= "(" + item.variant.options_text + ")" unless item.variant.option_values.empty? %> 84 |
<%= item.single_money.to_html %><%= item.quantity %><%= item.display_amount.to_html %>
<%= Spree.t(:order_total) %>:<%= @order.display_total.to_html %>
<%= Spree.t(:subtotal) %>:<%= @order.display_item_total.to_html %>
<%= Spree.t(:promotion) %>: <%= label %><%= Spree::Money.new(adjustments.sum(&:amount), currency: order.currency) %>
<%= Spree.t(:shipping) %>: <%= name %><%= Spree::Money.new(shipments.sum(&:discounted_cost), currency: order.currency).to_html %>
<%= Spree.t(:tax) %>: <%= label %><%= Spree::Money.new(adjustments.sum(&:amount), currency: order.currency) %>
<%= adjustment.label %><%= adjustment.display_amount.to_html %>
149 | -------------------------------------------------------------------------------- /app/views/spree/amazon/_payment.html.erb: -------------------------------------------------------------------------------- 1 | <%# %> 2 | <%# Amazon Payments - Login and Pay for Spree Commerce %> 3 | <%# %> 4 | <%# @category Amazon %> 5 | <%# @package Amazon_Payments %> 6 | <%# @copyright Copyright (c) 2014 Amazon.com %> 7 | <%# @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 %> 8 | <%# %> 9 | new OffAmazonPayments.Widgets.Wallet({ 10 | sellerId: '<%= Spree::Config[:amazon_merchant_id] %>', 11 | onPaymentSelect: function(orderReference) { 12 | jQuery.post('/amazon_order/payment', {"order_reference": order_reference}); 13 | $('#continue_to_delivery').click(); 14 | }, 15 | design: { 16 | designMode: 'responsive' 17 | }, 18 | onError: function(error) { 19 | // your error handling code 20 | } 21 | }).bind("walletWidgetDiv"); 22 | -------------------------------------------------------------------------------- /app/views/spree/amazon/address.html.erb: -------------------------------------------------------------------------------- 1 | <%# %> 2 | <%# Amazon Payments - Login and Pay for Spree Commerce %> 3 | <%# %> 4 | <%# @category Amazon %> 5 | <%# @package Amazon_Payments %> 6 | <%# @copyright Copyright (c) 2014 Amazon.com %> 7 | <%# @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 %> 8 | <%# %> 9 | <% content_for :head do %> 10 | 11 | 12 | 18 | 21 | 22 | 51 | <% end %> 52 | 53 |
54 | 55 |
56 |
57 |
58 |
59 | 60 |
61 |
62 |
63 |
64 | 65 | 68 | 69 |
70 | Loading... 71 |
72 | 73 |
74 | -------------------------------------------------------------------------------- /app/views/spree/amazon/complete.html.erb: -------------------------------------------------------------------------------- 1 | <%# %> 2 | <%# Amazon Payments - Login and Pay for Spree Commerce %> 3 | <%# %> 4 | <%# @category Amazon %> 5 | <%# @package Amazon_Payments %> 6 | <%# @copyright Copyright (c) 2014 Amazon.com %> 7 | <%# @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 %> 8 | <%# %> 9 |
10 | <%= Spree.t(:order_number, :number => @order.number) %> 11 |

<%= accurate_title %>

12 | <% if order_just_completed?(@order) %> 13 | <%= Spree.t(:thank_you_for_your_order) %> 14 | <% end %> 15 | 16 |
17 | <%= render :partial => 'spree/shared/order_details', :locals => { :order => @order } %> 18 | 19 |
20 | 21 |

22 | <%= link_to Spree.t(:back_to_store), spree.root_path, :class => "button" %> 23 | <% unless order_just_completed?(@order) %> 24 | <% if try_spree_current_user && respond_to?(:spree_account_path) %> 25 | <%= link_to Spree.t(:my_account), spree_account_path, :class => "button" %> 26 | <% end %> 27 | <% end %> 28 |

29 |
30 |
31 | -------------------------------------------------------------------------------- /app/views/spree/amazon/confirm.html.erb: -------------------------------------------------------------------------------- 1 | <%# %> 2 | <%# Amazon Payments - Login and Pay for Spree Commerce %> 3 | <%# %> 4 | <%# @category Amazon %> 5 | <%# @package Amazon_Payments %> 6 | <%# @copyright Copyright (c) 2014 Amazon.com %> 7 | <%# @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 %> 8 | <%# %> 9 |
10 |
11 | <%= Spree.t(:confirm) %> 12 | <%= render :partial => 'spree/amazon/order_details', :locals => { :order => @order } %> 13 |
14 | 15 | <%= form_tag amazon_order_complete_path(@order), :class => 'edit_order' do %> 16 |
17 | <%= submit_tag Spree.t(:place_order), :class => 'btn btn-lg btn-success' %> 18 | 19 |
20 | <% end %> 21 | -------------------------------------------------------------------------------- /app/views/spree/amazon/delivery.html.erb: -------------------------------------------------------------------------------- 1 | <%# %> 2 | <%# Amazon Payments - Login and Pay for Spree Commerce %> 3 | <%# %> 4 | <%# @category Amazon %> 5 | <%# @package Amazon_Payments %> 6 | <%# @copyright Copyright (c) 2014 Amazon.com %> 7 | <%# @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 %> 8 | <%# %> 9 | <%= form_for current_order, :url => confirm_amazon_order_path, :method => :post do |form| %> 10 | <%= render partial: 'spree/checkout/delivery', locals: {form: form} %> 11 | <% end %> -------------------------------------------------------------------------------- /app/views/spree/checkout/payment/_amazon.html.erb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amazon-archives/spree_pay_with_amazon/7206b1f5e4af3d4f47dd0fcaba456e7d0bcab2cd/app/views/spree/checkout/payment/_amazon.html.erb -------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 1 | ## 2 | # Amazon Payments - Login and Pay for Spree Commerce 3 | # 4 | # @category Amazon 5 | # @package Amazon_Payments 6 | # @copyright Copyright (c) 2014 Amazon.com 7 | # @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 8 | # 9 | ## 10 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. 11 | 12 | ENGINE_ROOT = File.expand_path('../..', __FILE__) 13 | ENGINE_PATH = File.expand_path('../../lib/spree_amazon_payments/engine', __FILE__) 14 | 15 | require 'rails/all' 16 | require 'rails/engine/commands' 17 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | ## 2 | # Amazon Payments - Login and Pay for Spree Commerce 3 | # 4 | # @category Amazon 5 | # @package Amazon_Payments 6 | # @copyright Copyright (c) 2014 Amazon.com 7 | # @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 8 | # 9 | ## 10 | # Sample localization file for English. Add more files in this directory for other locales. 11 | # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. 12 | 13 | en: 14 | spree: 15 | amazon_settings: "Amazon Settings" 16 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | ## 2 | # Amazon Payments - Login and Pay for Spree Commerce 3 | # 4 | # @category Amazon 5 | # @package Amazon_Payments 6 | # @copyright Copyright (c) 2014 Amazon.com 7 | # @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 8 | # 9 | ## 10 | Spree::Core::Engine.routes.draw do 11 | resource :amazon_order, only: [], controller: "amazon" do 12 | member do 13 | get 'address' 14 | post 'payment' 15 | get 'delivery' 16 | post 'confirm' 17 | end 18 | end 19 | 20 | resources :amazon_order, only: [], controller: "amazon" do 21 | post 'complete' 22 | get 'complete' 23 | end 24 | 25 | post 'amazon_callback', to: 'amazon_callback#new' 26 | get 'amazon_callback', to: 'amazon_callback#new' 27 | 28 | namespace :admin do 29 | resource :amazon, only: [:edit, :update], controller: "amazon" 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /db/migrate/20141103030543_create_spree_amazon_transactions.rb: -------------------------------------------------------------------------------- 1 | ## 2 | # Amazon Payments - Login and Pay for Spree Commerce 3 | # 4 | # @category Amazon 5 | # @package Amazon_Payments 6 | # @copyright Copyright (c) 2014 Amazon.com 7 | # @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 8 | # 9 | ## 10 | class CreateSpreeAmazonTransactions < ActiveRecord::Migration 11 | def change 12 | create_table :spree_amazon_transactions do |t| 13 | t.integer :order_id 14 | t.string :order_reference 15 | end 16 | end 17 | end -------------------------------------------------------------------------------- /db/migrate/20141106031627_add_authorization_and_capture_code_to_transaction.rb: -------------------------------------------------------------------------------- 1 | ## 2 | # Amazon Payments - Login and Pay for Spree Commerce 3 | # 4 | # @category Amazon 5 | # @package Amazon_Payments 6 | # @copyright Copyright (c) 2014 Amazon.com 7 | # @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 8 | # 9 | ## 10 | class AddAuthorizationAndCaptureCodeToTransaction < ActiveRecord::Migration 11 | def change 12 | add_column :spree_amazon_transactions, :authorization_id, :string 13 | add_column :spree_amazon_transactions, :capture_id, :string 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/amazon_mws.rb: -------------------------------------------------------------------------------- 1 | ## 2 | # Amazon Payments - Login and Pay for Spree Commerce 3 | # 4 | # @category Amazon 5 | # @package Amazon_Payments 6 | # @copyright Copyright (c) 2014 Amazon.com 7 | # @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 8 | # 9 | ## 10 | class AmazonMwsOrderResponse 11 | def initialize(response) 12 | @response = response.fetch("GetOrderReferenceDetailsResponse", {}) 13 | end 14 | 15 | def destination 16 | @response.fetch("GetOrderReferenceDetailsResult", {}).fetch("OrderReferenceDetails", {}).fetch("Destination", {}) 17 | end 18 | 19 | def constraints 20 | @response.fetch("GetOrderReferenceDetailsResult", {}).fetch("OrderReferenceDetails", {}).fetch("Constraints", {}).fetch("Constraint", {}) 21 | end 22 | 23 | def state 24 | @response.fetch("GetOrderReferenceDetailsResult", {}).fetch("OrderReferenceDetails", {}).fetch("OrderReferenceStatus", {}).fetch("State", {}) 25 | end 26 | 27 | def total 28 | total_block = @response.fetch("GetOrderReferenceDetailsResult", {}).fetch("OrderReferenceDetails", {}).fetch("OrderTotal", {}) 29 | Spree::Money.new(total_block.fetch("Amount", 0), :with_currency => total_block.fetch("CurrencyCode", "USD")) 30 | end 31 | 32 | def email 33 | @response.fetch("GetOrderReferenceDetailsResult", {}).fetch("OrderReferenceDetails", {}).fetch("Buyer", {}).fetch("Email", {}) 34 | end 35 | end 36 | 37 | class AmazonMws 38 | require 'httparty' 39 | 40 | def initialize(number, test_mode) 41 | @number = number 42 | @test_mode = test_mode 43 | end 44 | 45 | 46 | def fetch_order_data 47 | AmazonMwsOrderResponse.new(process({ 48 | "Action"=>"GetOrderReferenceDetails", 49 | "AmazonOrderReferenceId" => @number 50 | })) 51 | end 52 | 53 | def set_order_data(total, currency) 54 | process({ 55 | "Action"=>"SetOrderReferenceDetails", 56 | "AmazonOrderReferenceId" => @number, 57 | "OrderReferenceAttributes.OrderTotal.Amount" => total, 58 | "OrderReferenceAttributes.OrderTotal.CurrencyCode" => currency 59 | }) 60 | end 61 | 62 | def confirm_order 63 | process({ 64 | "Action"=>"ConfirmOrderReference", 65 | "AmazonOrderReferenceId" => @number 66 | }) 67 | end 68 | 69 | def authorize(ref_number, total, currency) 70 | process({ 71 | "Action"=>"Authorize", 72 | "AmazonOrderReferenceId" => @number, 73 | "AuthorizationReferenceId" => ref_number, 74 | "AuthorizationAmount.Amount" => total, 75 | "AuthorizationAmount.CurrencyCode" => currency, 76 | "CaptureNow" => Spree::Config[:auto_capture], 77 | "TransactionTimeout" => 0 78 | }) 79 | end 80 | 81 | def get_authorization_details(ref_number) 82 | process({ 83 | "Action" => "GetAuthorizationDetails", 84 | "AmazonAuthorizationId" => ref_number 85 | }) 86 | end 87 | 88 | def capture(auth_number, ref_number, total, currency) 89 | process({ 90 | "Action"=>"Capture", 91 | "AmazonAuthorizationId" => auth_number, 92 | "CaptureReferenceId" => ref_number, 93 | "CaptureAmount.Amount" => total, 94 | "CaptureAmount.CurrencyCode" => currency 95 | }) 96 | end 97 | 98 | def get_capture_details(ref_number) 99 | process({ 100 | "Action" => "GetCaptureDetails", 101 | "AmazonCaptureId" => ref_number 102 | }) 103 | end 104 | 105 | def refund(capture_id, ref_number, total, currency) 106 | process({ 107 | "Action"=>"Refund", 108 | "AmazonCaptureId" => capture_id, 109 | "RefundReferenceId" => ref_number, 110 | "RefundAmount.Amount" => total, 111 | "RefundAmount.CurrencyCode" => currency 112 | }) 113 | end 114 | 115 | def get_refund_details(ref_number) 116 | process({ 117 | "Action" => "GetRefundDetails", 118 | "AmazonRefundId" => ref_number 119 | }) 120 | end 121 | 122 | def close(ref_number) 123 | process({ 124 | "Action" => "CloseAuthorization", 125 | "AmazonAuthorizationId" => ref_number 126 | }) 127 | end 128 | 129 | private 130 | 131 | def default_hash 132 | { 133 | "AWSAccessKeyId"=>Spree::Config[:amazon_aws_access_key_id], 134 | "SellerId"=>Spree::Config[:amazon_merchant_id], 135 | "PlatformId"=>"A31NP5KFHXSFV1", 136 | "SignatureMethod"=>"HmacSHA256", 137 | "SignatureVersion"=>"2", 138 | "Timestamp"=>Time.now.utc.iso8601, 139 | "Version"=>"2013-01-01" 140 | } 141 | end 142 | 143 | def process(hash) 144 | hash = default_hash.reverse_merge(hash) 145 | sandbox_str = if @test_mode 146 | 'OffAmazonPayments_Sandbox' 147 | else 148 | 'OffAmazonPayments' 149 | end 150 | query_string = hash.sort.map { |k, v| "#{k}=#{ custom_escape(v) }" }.join("&") 151 | message = ["POST", "mws.amazonservices.com", "/#{sandbox_str}/2013-01-01", query_string].join("\n") 152 | query_string += "&Signature=" + custom_escape(Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::SHA256.new, Spree::Config[:amazon_aws_secret_access_key], message)).strip) 153 | HTTParty.post("https://mws.amazonservices.com/#{sandbox_str}/2013-01-01", :body => query_string) 154 | end 155 | 156 | def custom_escape(val) 157 | val.to_s.gsub(/([^\w.~-]+)/) do 158 | "%" + $1.unpack("H2" * $1.bytesize).join("%").upcase 159 | end 160 | end 161 | end 162 | -------------------------------------------------------------------------------- /lib/generators/spree_amazon_payments/install/install_generator.rb: -------------------------------------------------------------------------------- 1 | ## 2 | # Amazon Payments - Login and Pay for Spree Commerce 3 | # 4 | # @category Amazon 5 | # @package Amazon_Payments 6 | # @copyright Copyright (c) 2014 Amazon.com 7 | # @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 8 | # 9 | ## 10 | module SpreeAmazonPayments 11 | module Generators 12 | class InstallGenerator < Rails::Generators::Base 13 | 14 | class_option :auto_run_migrations, :type => :boolean, :default => false 15 | 16 | def add_javascripts 17 | append_file 'vendor/assets/javascripts/spree/frontend/all.js', "//= require spree/frontend/spree_amazon_payments\n" 18 | append_file 'vendor/assets/javascripts/spree/backend/all.js', "//= require spree/backend/spree_amazon_payments\n" 19 | end 20 | 21 | def add_stylesheets 22 | inject_into_file 'vendor/assets/stylesheets/spree/frontend/all.css', " *= require spree/frontend/spree_amazon_payments\n", :before => /\*\//, :verbose => true 23 | inject_into_file 'vendor/assets/stylesheets/spree/backend/all.css', " *= require spree/backend/spree_amazon_payments\n", :before => /\*\//, :verbose => true 24 | end 25 | 26 | def add_migrations 27 | run 'bundle exec rake railties:install:migrations FROM=spree_amazon_payments' 28 | end 29 | 30 | def run_migrations 31 | run_migrations = options[:auto_run_migrations] || ['', 'y', 'Y'].include?(ask 'Would you like to run the migrations now? [Y/n]') 32 | if run_migrations 33 | run 'bundle exec rake db:migrate' 34 | else 35 | puts 'Skipping rake db:migrate, don\'t forget to run it!' 36 | end 37 | end 38 | end 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /lib/spree_amazon_payments.rb: -------------------------------------------------------------------------------- 1 | ## 2 | # Amazon Payments - Login and Pay for Spree Commerce 3 | # 4 | # @category Amazon 5 | # @package Amazon_Payments 6 | # @copyright Copyright (c) 2014 Amazon.com 7 | # @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 8 | # 9 | ## 10 | require 'spree_core' 11 | require 'spree_amazon_payments/engine' 12 | require 'amazon_mws' -------------------------------------------------------------------------------- /lib/spree_amazon_payments/engine.rb: -------------------------------------------------------------------------------- 1 | ## 2 | # Amazon Payments - Login and Pay for Spree Commerce 3 | # 4 | # @category Amazon 5 | # @package Amazon_Payments 6 | # @copyright Copyright (c) 2014 Amazon.com 7 | # @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 8 | # 9 | ## 10 | module SpreeAmazonPayments 11 | class Engine < Rails::Engine 12 | require 'spree/core' 13 | isolate_namespace Spree 14 | engine_name 'spree_amazon_payments' 15 | 16 | # use rspec for tests 17 | config.generators do |g| 18 | g.test_framework :rspec 19 | end 20 | 21 | initializer "spree.gateway.payment_methods", :after => "spree.register.payment_methods" do |app| 22 | app.config.spree.payment_methods << Spree::Gateway::Amazon 23 | end 24 | 25 | def self.activate 26 | Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')) do |c| 27 | Rails.configuration.cache_classes ? require(c) : load(c) 28 | end 29 | end 30 | 31 | config.to_prepare &method(:activate).to_proc 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /lib/spree_amazon_payments/factories.rb: -------------------------------------------------------------------------------- 1 | ## 2 | # Amazon Payments - Login and Pay for Spree Commerce 3 | # 4 | # @category Amazon 5 | # @package Amazon_Payments 6 | # @copyright Copyright (c) 2014 Amazon.com 7 | # @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 8 | # 9 | ## 10 | FactoryGirl.define do 11 | # Define your Spree extensions Factories within this file to enable applications, and other extensions to use and override them. 12 | # 13 | # Example adding this to your spec_helper will load these Factories for use: 14 | # require 'spree_amazon_payments/factories' 15 | end 16 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | ## 2 | # Amazon Payments - Login and Pay for Spree Commerce 3 | # 4 | # @category Amazon 5 | # @package Amazon_Payments 6 | # @copyright Copyright (c) 2014 Amazon.com 7 | # @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 8 | # 9 | ## 10 | # Run Coverage report 11 | require 'simplecov' 12 | SimpleCov.start do 13 | add_filter 'spec/dummy' 14 | add_group 'Controllers', 'app/controllers' 15 | add_group 'Helpers', 'app/helpers' 16 | add_group 'Mailers', 'app/mailers' 17 | add_group 'Models', 'app/models' 18 | add_group 'Views', 'app/views' 19 | add_group 'Libraries', 'lib' 20 | end 21 | 22 | # Configure Rails Environment 23 | ENV['RAILS_ENV'] = 'test' 24 | 25 | require File.expand_path('../dummy/config/environment.rb', __FILE__) 26 | 27 | require 'rspec/rails' 28 | require 'database_cleaner' 29 | require 'ffaker' 30 | 31 | # Requires supporting ruby files with custom matchers and macros, etc, 32 | # in spec/support/ and its subdirectories. 33 | Dir[File.join(File.dirname(__FILE__), 'support/**/*.rb')].each { |f| require f } 34 | 35 | # Requires factories and other useful helpers defined in spree_core. 36 | require 'spree/testing_support/authorization_helpers' 37 | require 'spree/testing_support/capybara_ext' 38 | require 'spree/testing_support/controller_requests' 39 | require 'spree/testing_support/factories' 40 | require 'spree/testing_support/url_helpers' 41 | 42 | # Requires factories defined in lib/spree_amazon_payments/factories.rb 43 | require 'spree_amazon_payments/factories' 44 | 45 | RSpec.configure do |config| 46 | config.include FactoryGirl::Syntax::Methods 47 | 48 | # Infer an example group's spec type from the file location. 49 | config.infer_spec_type_from_file_location! 50 | 51 | # == URL Helpers 52 | # 53 | # Allows access to Spree's routes in specs: 54 | # 55 | # visit spree.admin_path 56 | # current_path.should eql(spree.products_path) 57 | config.include Spree::TestingSupport::UrlHelpers 58 | 59 | # == Mock Framework 60 | # 61 | # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line: 62 | # 63 | # config.mock_with :mocha 64 | # config.mock_with :flexmock 65 | # config.mock_with :rr 66 | config.mock_with :rspec 67 | config.color = true 68 | 69 | # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures 70 | config.fixture_path = "#{::Rails.root}/spec/fixtures" 71 | 72 | # Capybara javascript drivers require transactional fixtures set to false, and we use DatabaseCleaner 73 | # to cleanup after each test instead. Without transactional fixtures set to false the records created 74 | # to setup a test will be unavailable to the browser, which runs under a separate server instance. 75 | config.use_transactional_fixtures = false 76 | 77 | # Ensure Suite is set to use transactions for speed. 78 | config.before :suite do 79 | DatabaseCleaner.strategy = :transaction 80 | DatabaseCleaner.clean_with :truncation 81 | end 82 | 83 | # Before each spec check if it is a Javascript test and switch between using database transactions or not where necessary. 84 | config.before :each do 85 | DatabaseCleaner.strategy = RSpec.current_example.metadata[:js] ? :truncation : :transaction 86 | DatabaseCleaner.start 87 | end 88 | 89 | # After each spec clean the database. 90 | config.after :each do 91 | DatabaseCleaner.clean 92 | end 93 | 94 | config.fail_fast = ENV['FAIL_FAST'] || false 95 | config.order = "random" 96 | end 97 | -------------------------------------------------------------------------------- /spree_amazon_payments.gemspec: -------------------------------------------------------------------------------- 1 | ## 2 | # Amazon Payments - Login and Pay for Spree Commerce 3 | # 4 | # @category Amazon 5 | # @package Amazon_Payments 6 | # @copyright Copyright (c) 2014 Amazon.com 7 | # @license http://opensource.org/licenses/Apache-2.0 Apache License, Version 2.0 8 | # 9 | ## 10 | # encoding: UTF-8 11 | Gem::Specification.new do |s| 12 | s.platform = Gem::Platform::RUBY 13 | s.name = 'spree_amazon_payments' 14 | s.version = '3.0.0' 15 | s.summary = 'Spree Amazon Payments' 16 | s.description = '' 17 | 18 | s.required_ruby_version = '>= 2.1.0' 19 | s.required_rubygems_version = '>= 1.8.23' 20 | 21 | s.author = 'Amazon Payments' 22 | 23 | s.require_path = 'lib' 24 | s.requirements << 'none' 25 | 26 | s.add_dependency 'spree_core', '~> 3.0.0' 27 | 28 | s.add_development_dependency 'capybara', '~> 2.4' 29 | s.add_development_dependency 'coffee-rails' 30 | s.add_development_dependency 'database_cleaner' 31 | s.add_development_dependency 'factory_girl', '~> 4.4' 32 | s.add_development_dependency 'ffaker' 33 | s.add_development_dependency 'rspec-rails', '~> 3.1' 34 | s.add_development_dependency 'sass-rails', '~> 4.0.2' 35 | s.add_development_dependency 'selenium-webdriver' 36 | s.add_development_dependency 'simplecov' 37 | s.add_development_dependency 'sqlite3' 38 | end 39 | --------------------------------------------------------------------------------