workarea-paypal 2.0.9 → 3.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc.json +2 -1
  3. data/.gitignore +16 -11
  4. data/CHANGELOG.md +79 -0
  5. data/README.md +105 -6
  6. data/Rakefile +4 -5
  7. data/UPGRADE.md +46 -0
  8. data/app/assets/javascripts/workarea/storefront/paypal/config.js.erb +44 -0
  9. data/app/assets/javascripts/workarea/storefront/paypal/modules/paypal_buttons.js +71 -0
  10. data/app/assets/javascripts/workarea/storefront/paypal/modules/paypal_hosted_fields.js +96 -0
  11. data/app/assets/javascripts/workarea/storefront/paypal/modules/update_checkout_submit_text.js +11 -5
  12. data/app/assets/javascripts/workarea/storefront/paypal/templates/paypal_fields.jst.ejs +43 -0
  13. data/app/controllers/workarea/storefront/checkout/place_order_controller.decorator +6 -4
  14. data/app/controllers/workarea/storefront/paypal_controller.rb +32 -26
  15. data/app/helpers/workarea/storefront/paypal_helper.rb +38 -0
  16. data/app/models/workarea/payment.decorator +17 -3
  17. data/app/models/workarea/payment/authorize/paypal.rb +13 -13
  18. data/app/models/workarea/payment/capture/paypal.rb +10 -20
  19. data/app/models/workarea/payment/null_address.rb +37 -0
  20. data/app/models/workarea/payment/purchase/paypal.rb +1 -25
  21. data/app/models/workarea/payment/refund/paypal.rb +3 -6
  22. data/app/models/workarea/payment/tender/paypal.rb +14 -2
  23. data/app/services/workarea/paypal/approve_order.rb +104 -0
  24. data/app/services/workarea/paypal/create_order.rb +177 -0
  25. data/app/services/workarea/paypal/update_order.rb +44 -0
  26. data/app/views/workarea/admin/orders/tenders/_paypal.html.haml +5 -2
  27. data/app/views/workarea/api/orders/tenders/_paypal.json.jbuilder +7 -1
  28. data/app/views/workarea/storefront/carts/_paypal_checkout.html.haml +6 -1
  29. data/app/views/workarea/storefront/checkouts/_paypal_payment.html.haml +16 -5
  30. data/app/views/workarea/storefront/order_mailer/tenders/_paypal.html.haml +5 -3
  31. data/app/views/workarea/storefront/orders/tenders/_paypal.html.haml +9 -2
  32. data/app/views/workarea/storefront/paypal/_paypal_sdk.html.haml +1 -0
  33. data/app/workers/workarea/paypal/handle_webhook_event.rb +64 -0
  34. data/config/initializers/append_points.rb +17 -5
  35. data/config/initializers/fields.rb +27 -0
  36. data/config/initializers/workarea.rb +41 -5
  37. data/config/locales/en.yml +14 -4
  38. data/config/routes.rb +3 -2
  39. data/lib/tasks/workarea/create_webhooks.rake +29 -0
  40. data/lib/workarea/paypal.rb +22 -18
  41. data/lib/workarea/paypal/engine.rb +4 -0
  42. data/lib/workarea/paypal/gateway.rb +200 -0
  43. data/lib/workarea/paypal/requests/create_webhook.rb +21 -0
  44. data/lib/workarea/paypal/requests/delete_webhook.rb +17 -0
  45. data/lib/workarea/paypal/requests/generate_token.rb +21 -0
  46. data/lib/workarea/paypal/requests/list_webhooks.rb +17 -0
  47. data/lib/workarea/paypal/version.rb +1 -1
  48. data/package.json +9 -0
  49. data/test/dummy/config/initializers/workarea.rb +1 -1
  50. data/test/factories/workarea/capture_completed_webhook.json +70 -0
  51. data/test/factories/workarea/capture_denied_webhook.json +68 -0
  52. data/test/factories/workarea/paypal.rb +34 -0
  53. data/test/helpers/workarea/storefront/paypal_helper_test.rb +35 -0
  54. data/test/integration/workarea/storefront/paypal_integration_test.rb +104 -294
  55. data/test/integration/workarea/storefront/paypal_place_order_integration_test.rb +42 -0
  56. data/test/lib/workarea/paypal/gateway_test.rb +236 -0
  57. data/test/models/workarea/payment/authorize/paypal_test.rb +57 -46
  58. data/test/models/workarea/payment/capture/paypal_test.rb +9 -51
  59. data/test/models/workarea/payment/null_address_test.rb +53 -0
  60. data/test/models/workarea/payment/refund/paypal_test.rb +39 -38
  61. data/test/models/workarea/paypal_payment_test.rb +65 -0
  62. data/test/models/workarea/search/paypal_order_text_test.rb +14 -0
  63. data/test/services/workarea/paypal/approve_order_test.rb +35 -0
  64. data/test/services/workarea/paypal/create_order_test.rb +127 -0
  65. data/test/services/workarea/paypal/update_order_test.rb +73 -0
  66. data/test/support/workarea/paypal_setup.rb +49 -0
  67. data/test/system/workarea/storefront/cart_system_test.decorator +1 -1
  68. data/test/system/workarea/storefront/logged_in_checkout_system_test.decorator +1 -1
  69. data/test/vcr_cassettes/paypal_approve_order.yml +106 -0
  70. data/test/vcr_cassettes/paypal_create_order.yml +110 -0
  71. data/test/vcr_cassettes/paypal_gateway_create_order.yml +105 -0
  72. data/test/vcr_cassettes/paypal_gateway_generate_token.yml +103 -0
  73. data/test/vcr_cassettes/paypal_gateway_get_order.yml +103 -0
  74. data/test/vcr_cassettes/paypal_gateway_update_order.yml +199 -0
  75. data/test/vcr_cassettes/paypal_gateway_webhooks.yml +403 -0
  76. data/test/vcr_cassettes/paypal_update_order.yml +204 -0
  77. data/test/workers/workarea/paypal/handle_webhook_event_test.rb +60 -0
  78. data/workarea-paypal.gemspec +2 -1
  79. metadata +65 -14
  80. data/app/services/workarea/paypal/setup.rb +0 -114
  81. data/app/services/workarea/paypal/update.rb +0 -69
  82. data/app/views/workarea/storefront/checkouts/_paypal_error.html.haml +0 -6
  83. data/app/views/workarea/storefront/order_mailer/tenders/_paypal.text.haml +0 -2
  84. data/test/dummy/config/initializers/session_store.rb +0 -3
  85. data/test/integration/workarea/storefront/place_order_integration_test.decorator +0 -11
  86. data/test/models/workarea/payment/purchase/paypal_test.rb +0 -94
  87. data/test/models/workarea/payment_test.decorator +0 -34
  88. data/test/models/workarea/search/admin/order_test.decorator +0 -32
  89. data/test/services/workarea/paypal/setup_test.rb +0 -120
  90. data/test/services/workarea/paypal/update_test.rb +0 -221
@@ -0,0 +1,204 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://api.sandbox.paypal.com/v1/oauth2/token
6
+ body:
7
+ encoding: UTF-8
8
+ string: grant_type=client_credentials
9
+ headers:
10
+ Content-Type:
11
+ - application/x-www-form-urlencoded
12
+ Authorization:
13
+ - Basic RkFLRV9QQVlQQUxfQ0xJRU5UX0lEOkZBS0VfUEFZUEFMX0NMSUVOVF9TRUNS\nRVQ=
14
+ Accept-Encoding:
15
+ - gzip
16
+ Sdk-Name:
17
+ - Checkout SDK
18
+ Sdk-Version:
19
+ - 1.0.3
20
+ Sdk-Tech-Stack:
21
+ - Ruby2.6.3
22
+ Api-Integration-Type:
23
+ - PAYPALSDK
24
+ User-Agent:
25
+ - PayPalSDK/rest-sdk-ruby 1.0.3 (paypal-checkout-sdk 1.0.3; ruby 2.6.3p62-x86_64-darwin18;OpenSSL
26
+ 1.0.2s 28 May 2019)
27
+ Accept:
28
+ - "*/*"
29
+ response:
30
+ status:
31
+ code: 200
32
+ message: OK
33
+ headers:
34
+ Cache-Control:
35
+ - max-age=0, no-cache, no-store, must-revalidate
36
+ Content-Length:
37
+ - '918'
38
+ Content-Type:
39
+ - application/json
40
+ Date:
41
+ - Wed, 29 Jan 2020 18:26:51 GMT
42
+ Paypal-Debug-Id:
43
+ - d6a0f863a1bd2
44
+ X-Paypal-Token-Service:
45
+ - IAAS
46
+ body:
47
+ encoding: UTF-8
48
+ string: '{"scope":"https://uri.paypal.com/services/invoicing https://uri.paypal.com/services/disputes/read-buyer
49
+ https://uri.paypal.com/services/payments/realtimepayment https://uri.paypal.com/services/disputes/update-seller
50
+ https://uri.paypal.com/services/payments/payment/authcapture openid https://uri.paypal.com/services/disputes/read-seller
51
+ https://uri.paypal.com/services/payments/refund https://api.paypal.com/v1/vault/credit-card
52
+ https://api.paypal.com/v1/payments/.* https://uri.paypal.com/payments/payouts
53
+ https://api.paypal.com/v1/vault/credit-card/.* https://uri.paypal.com/services/subscriptions
54
+ https://uri.paypal.com/services/applications/webhooks","access_token":"A21AAH8JBaCq97a9fIWYVjR13RiayfAPxcb-o5l9hZ57HACn0JwaefBkRcSfh9rEwmZR6JozBLLU2MsRYTuFsZ91mOZR9jFMQ","token_type":"Bearer","app_id":"APP-80W284485P519543T","expires_in":32031,"nonce":"2020-01-29T18:20:43ZDKF3VcEmtOhEC5S6ZO80QnoxtZ-lP5lrj73RBoqrBwI"}'
55
+ http_version:
56
+ recorded_at: Wed, 29 Jan 2020 18:26:52 GMT
57
+ - request:
58
+ method: patch
59
+ uri: https://api.sandbox.paypal.com/v2/checkout/orders/6DJ616473D999571D
60
+ body:
61
+ encoding: UTF-8
62
+ string: '[{"op":"replace","path":"/purchase_units/@reference_id==''default''/shipping/name","value":{"full_name":"Ben
63
+ Crouse"}},{"op":"replace","path":"/purchase_units/@reference_id==''default''/shipping/address","value":{"address_line_1":"22
64
+ S. 3rd St.","address_line_2":"Second Floor","admin_area_2":"Philadelphia","admin_area_1":"PA","postal_code":"19106","country_code":"US"}},{"op":"replace","path":"/purchase_units/@reference_id==''default''/amount","value":{"currency_code":"USD","value":"6.60","breakdown":{"item_total":{"currency_code":"USD","value":"10.00"},"shipping":{"currency_code":"USD","value":"1.00"},"tax_total":{"currency_code":"USD","value":"0.60"},"discount":{"currency_code":"USD","value":"5.00"},"shipping_discount":{"currency_code":"USD","value":"0.00"}}}}]'
65
+ headers:
66
+ Content-Type:
67
+ - application/json
68
+ Authorization:
69
+ - Bearer A21AAH8JBaCq97a9fIWYVjR13RiayfAPxcb-o5l9hZ57HACn0JwaefBkRcSfh9rEwmZR6JozBLLU2MsRYTuFsZ91mOZR9jFMQ
70
+ Accept-Encoding:
71
+ - gzip
72
+ Sdk-Name:
73
+ - Checkout SDK
74
+ Sdk-Version:
75
+ - 1.0.3
76
+ Sdk-Tech-Stack:
77
+ - Ruby2.6.3
78
+ Api-Integration-Type:
79
+ - PAYPALSDK
80
+ User-Agent:
81
+ - PayPalSDK/rest-sdk-ruby 1.0.3 (paypal-checkout-sdk 1.0.3; ruby 2.6.3p62-x86_64-darwin18;OpenSSL
82
+ 1.0.2s 28 May 2019)
83
+ Accept:
84
+ - "*/*"
85
+ response:
86
+ status:
87
+ code: 204
88
+ message: No Content
89
+ headers:
90
+ Cache-Control:
91
+ - max-age=0, no-cache, no-store, must-revalidate
92
+ Date:
93
+ - Wed, 29 Jan 2020 18:26:52 GMT
94
+ Paypal-Debug-Id:
95
+ - d6a0f840188e6
96
+ body:
97
+ encoding: UTF-8
98
+ string: ''
99
+ http_version:
100
+ recorded_at: Wed, 29 Jan 2020 18:26:52 GMT
101
+ - request:
102
+ method: post
103
+ uri: https://api.sandbox.paypal.com/v1/oauth2/token
104
+ body:
105
+ encoding: UTF-8
106
+ string: grant_type=client_credentials
107
+ headers:
108
+ Content-Type:
109
+ - application/x-www-form-urlencoded
110
+ Authorization:
111
+ - Basic QWM1N1dtTEJsaHhZcXpoOHhJbng5cGRTaTA1alZQMGVDOEtuTE1OMlF5Zkw0RGtCaHVIUV8ycktlekhMRGluVVdkdDFVM2hJejdsODdTTEc6RU4tN3JrbVFzdjZGdUVtT215VmQ1Mk5MN0wwaFNmdUN0M2RFVGtqelhYUy05UDFwQmlTS1Q1OGtGRWtkd3pFX2o0MDY3ZGc5V0dwQnREQlc=
112
+ Accept-Encoding:
113
+ - gzip
114
+ Sdk-Name:
115
+ - Checkout SDK
116
+ Sdk-Version:
117
+ - 1.0.3
118
+ Sdk-Tech-Stack:
119
+ - Ruby2.6.3
120
+ Api-Integration-Type:
121
+ - PAYPALSDK
122
+ User-Agent:
123
+ - PayPalSDK/rest-sdk-ruby 1.0.3 (paypal-checkout-sdk 1.0.3; ruby 2.6.3p62-x86_64-darwin18;OpenSSL
124
+ 1.0.2s 28 May 2019)
125
+ Accept:
126
+ - "*/*"
127
+ response:
128
+ status:
129
+ code: 200
130
+ message: OK
131
+ headers:
132
+ Cache-Control:
133
+ - max-age=0, no-cache, no-store, must-revalidate
134
+ Content-Length:
135
+ - '918'
136
+ Content-Type:
137
+ - application/json
138
+ Date:
139
+ - Wed, 29 Jan 2020 18:26:53 GMT
140
+ Paypal-Debug-Id:
141
+ - 759fb44acfade
142
+ X-Paypal-Token-Service:
143
+ - IAAS
144
+ body:
145
+ encoding: UTF-8
146
+ string: '{"scope":"https://uri.paypal.com/services/invoicing https://uri.paypal.com/services/disputes/read-buyer
147
+ https://uri.paypal.com/services/payments/realtimepayment https://uri.paypal.com/services/disputes/update-seller
148
+ https://uri.paypal.com/services/payments/payment/authcapture openid https://uri.paypal.com/services/disputes/read-seller
149
+ https://uri.paypal.com/services/payments/refund https://api.paypal.com/v1/vault/credit-card
150
+ https://api.paypal.com/v1/payments/.* https://uri.paypal.com/payments/payouts
151
+ https://api.paypal.com/v1/vault/credit-card/.* https://uri.paypal.com/services/subscriptions
152
+ https://uri.paypal.com/services/applications/webhooks","access_token":"A21AAH8JBaCq97a9fIWYVjR13RiayfAPxcb-o5l9hZ57HACn0JwaefBkRcSfh9rEwmZR6JozBLLU2MsRYTuFsZ91mOZR9jFMQ","token_type":"Bearer","app_id":"APP-80W284485P519543T","expires_in":32030,"nonce":"2020-01-29T18:20:43ZDKF3VcEmtOhEC5S6ZO80QnoxtZ-lP5lrj73RBoqrBwI"}'
153
+ http_version:
154
+ recorded_at: Wed, 29 Jan 2020 18:26:53 GMT
155
+ - request:
156
+ method: get
157
+ uri: https://api.sandbox.paypal.com/v2/checkout/orders/6DJ616473D999571D
158
+ body:
159
+ encoding: US-ASCII
160
+ string: ''
161
+ headers:
162
+ Content-Type:
163
+ - application/json
164
+ Authorization:
165
+ - Bearer A21AAH8JBaCq97a9fIWYVjR13RiayfAPxcb-o5l9hZ57HACn0JwaefBkRcSfh9rEwmZR6JozBLLU2MsRYTuFsZ91mOZR9jFMQ
166
+ Accept-Encoding:
167
+ - gzip
168
+ Sdk-Name:
169
+ - Checkout SDK
170
+ Sdk-Version:
171
+ - 1.0.3
172
+ Sdk-Tech-Stack:
173
+ - Ruby2.6.3
174
+ Api-Integration-Type:
175
+ - PAYPALSDK
176
+ User-Agent:
177
+ - PayPalSDK/rest-sdk-ruby 1.0.3 (paypal-checkout-sdk 1.0.3; ruby 2.6.3p62-x86_64-darwin18;OpenSSL
178
+ 1.0.2s 28 May 2019)
179
+ Accept:
180
+ - "*/*"
181
+ response:
182
+ status:
183
+ code: 200
184
+ message: OK
185
+ headers:
186
+ Cache-Control:
187
+ - max-age=0, no-cache, no-store, must-revalidate
188
+ Content-Length:
189
+ - '1431'
190
+ Content-Type:
191
+ - application/json
192
+ Date:
193
+ - Wed, 29 Jan 2020 18:26:53 GMT
194
+ Paypal-Debug-Id:
195
+ - 759fb42d45c87
196
+ body:
197
+ encoding: UTF-8
198
+ string: '{"id":"6DJ616473D999571D","intent":"CAPTURE","purchase_units":[{"reference_id":"default","amount":{"currency_code":"USD","value":"6.60","breakdown":{"item_total":{"currency_code":"USD","value":"10.00"},"shipping":{"currency_code":"USD","value":"1.00"},"tax_total":{"currency_code":"USD","value":"0.60"},"shipping_discount":{"currency_code":"USD","value":"0.00"},"discount":{"currency_code":"USD","value":"5.00"}}},"payee":{"email_address":"sb-43jrhs896881@business.example.com","merchant_id":"M3XMHZJKTFK88","display_data":{"brand_name":"Workarea
199
+ Paypal Plugin"}},"custom_id":"PAYPAL_TEST","items":[{"name":"Test Product","unit_amount":{"currency_code":"USD","value":"5.00"},"tax":{"currency_code":"USD","value":"0.30"},"quantity":"2","description":"","sku":"SKU","category":"PHYSICAL_GOODS"}],"shipping":{"method":"Ground","name":{"full_name":"Ben
200
+ Crouse"},"address":{"address_line_1":"22 S. 3rd St.","address_line_2":"Second
201
+ Floor","admin_area_2":"Philadelphia","admin_area_1":"PA","postal_code":"19106","country_code":"US"}}}],"create_time":"2020-01-29T18:20:45Z","links":[{"href":"https://api.sandbox.paypal.com/v2/checkout/orders/6DJ616473D999571D","rel":"self","method":"GET"},{"href":"https://www.sandbox.paypal.com/checkoutnow?token=6DJ616473D999571D","rel":"approve","method":"GET"},{"href":"https://api.sandbox.paypal.com/v2/checkout/orders/6DJ616473D999571D/capture","rel":"capture","method":"POST"}],"status":"CREATED"}'
202
+ http_version:
203
+ recorded_at: Wed, 29 Jan 2020 18:26:54 GMT
204
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,60 @@
1
+ require 'test_helper'
2
+
3
+ module Workarea
4
+ module Paypal
5
+ class HandleWebhookEventTest < TestCase
6
+ setup :payment
7
+
8
+ def payment
9
+ @payment ||=
10
+ create_payment(paypal: { paypal_id: '123', approved: true }).tap do |p|
11
+ p.paypal.build_transaction(
12
+ action: 'authorize',
13
+ amount: 5.to_m,
14
+ response: ActiveMerchant::Billing::Response.new(
15
+ true,
16
+ 'PayPal capture succeeded',
17
+ id: 'CAPTURE001',
18
+ status: 'PENDING'
19
+ )
20
+ ).save!
21
+ end
22
+ end
23
+
24
+ def test_payment_capture_completed
25
+ payload = webhook_capture_completed_payload
26
+
27
+ HandleWebhookEvent.new.perform(
28
+ payload['event_type'],
29
+ payload['resource']
30
+ )
31
+
32
+ payment.reload
33
+
34
+ assert_equal(2, payment.paypal.transactions.count)
35
+
36
+ txn = payment.paypal.transactions.captures.first
37
+ assert(txn.success?)
38
+ assert_equal(5.to_m, txn.amount)
39
+ end
40
+
41
+ def test_payment_capture_denied
42
+ payload = webhook_capture_denied_payload
43
+
44
+ HandleWebhookEvent.new.perform(
45
+ payload['event_type'],
46
+ payload['resource']
47
+ )
48
+
49
+ payment.reload
50
+
51
+ assert_equal(1, payment.paypal.transactions.count)
52
+
53
+ txn = payment.paypal.transactions.first
54
+ assert(txn.success?)
55
+ assert(txn.canceled?)
56
+ assert(txn.cancellation.success?)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -17,5 +17,6 @@ Gem::Specification.new do |s|
17
17
 
18
18
  s.required_ruby_version = '>= 2.0.0'
19
19
 
20
- s.add_dependency 'workarea', '~> 3.x'
20
+ s.add_dependency 'workarea', '~> 3.x', '>= 3.5.x'
21
+ s.add_dependency 'paypal-checkout-sdk', '~> 1.0.3'
21
22
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: workarea-paypal
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.9
4
+ version: 3.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - bcrouse
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-30 00:00:00.000000000 Z
11
+ date: 2020-05-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: workarea
@@ -17,6 +17,9 @@ dependencies:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: 3.x
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 3.5.x
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -24,6 +27,23 @@ dependencies:
24
27
  - - "~>"
25
28
  - !ruby/object:Gem::Version
26
29
  version: 3.x
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 3.5.x
33
+ - !ruby/object:Gem::Dependency
34
+ name: paypal-checkout-sdk
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 1.0.3
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: 1.0.3
27
47
  description: Add PayPal as a payment method to the Workarea Commerce Platform.
28
48
  email:
29
49
  - bcrouse@workarea.com
@@ -52,20 +72,28 @@ files:
52
72
  - LICENSE
53
73
  - README.md
54
74
  - Rakefile
75
+ - UPGRADE.md
55
76
  - app/assets/images/workarea/admin/payment_icons/paypal.svg
56
77
  - app/assets/images/workarea/storefront/payment_icons/paypal.svg
78
+ - app/assets/javascripts/workarea/storefront/paypal/config.js.erb
79
+ - app/assets/javascripts/workarea/storefront/paypal/modules/paypal_buttons.js
80
+ - app/assets/javascripts/workarea/storefront/paypal/modules/paypal_hosted_fields.js
57
81
  - app/assets/javascripts/workarea/storefront/paypal/modules/update_checkout_submit_text.js
82
+ - app/assets/javascripts/workarea/storefront/paypal/templates/paypal_fields.jst.ejs
58
83
  - app/controllers/workarea/storefront/checkout/place_order_controller.decorator
59
84
  - app/controllers/workarea/storefront/paypal_controller.rb
85
+ - app/helpers/workarea/storefront/paypal_helper.rb
60
86
  - app/models/workarea/payment.decorator
61
87
  - app/models/workarea/payment/authorize/paypal.rb
62
88
  - app/models/workarea/payment/capture/paypal.rb
89
+ - app/models/workarea/payment/null_address.rb
63
90
  - app/models/workarea/payment/purchase/paypal.rb
64
91
  - app/models/workarea/payment/refund/paypal.rb
65
92
  - app/models/workarea/payment/tender/paypal.rb
66
93
  - app/models/workarea/search/order_text.decorator
67
- - app/services/workarea/paypal/setup.rb
68
- - app/services/workarea/paypal/update.rb
94
+ - app/services/workarea/paypal/approve_order.rb
95
+ - app/services/workarea/paypal/create_order.rb
96
+ - app/services/workarea/paypal/update_order.rb
69
97
  - app/view_models/workarea/admin/paypal_view_model.rb
70
98
  - app/view_models/workarea/store_front/checkout/payment_view_model.decorator
71
99
  - app/view_models/workarea/store_front/credit_card_view_model.decorator
@@ -73,19 +101,27 @@ files:
73
101
  - app/views/workarea/admin/orders/tenders/_paypal.html.haml
74
102
  - app/views/workarea/api/orders/tenders/_paypal.json.jbuilder
75
103
  - app/views/workarea/storefront/carts/_paypal_checkout.html.haml
76
- - app/views/workarea/storefront/checkouts/_paypal_error.html.haml
77
104
  - app/views/workarea/storefront/checkouts/_paypal_payment.html.haml
78
105
  - app/views/workarea/storefront/order_mailer/tenders/_paypal.html.haml
79
- - app/views/workarea/storefront/order_mailer/tenders/_paypal.text.haml
80
106
  - app/views/workarea/storefront/orders/tenders/_paypal.html.haml
107
+ - app/views/workarea/storefront/paypal/_paypal_sdk.html.haml
108
+ - app/workers/workarea/paypal/handle_webhook_event.rb
81
109
  - bin/rails
82
110
  - config/initializers/append_points.rb
111
+ - config/initializers/fields.rb
83
112
  - config/initializers/workarea.rb
84
113
  - config/locales/en.yml
85
114
  - config/routes.rb
115
+ - lib/tasks/workarea/create_webhooks.rake
86
116
  - lib/workarea/paypal.rb
87
117
  - lib/workarea/paypal/engine.rb
118
+ - lib/workarea/paypal/gateway.rb
119
+ - lib/workarea/paypal/requests/create_webhook.rb
120
+ - lib/workarea/paypal/requests/delete_webhook.rb
121
+ - lib/workarea/paypal/requests/generate_token.rb
122
+ - lib/workarea/paypal/requests/list_webhooks.rb
88
123
  - lib/workarea/paypal/version.rb
124
+ - package.json
89
125
  - test/dummy/Rakefile
90
126
  - test/dummy/app/assets/config/manifest.js
91
127
  - test/dummy/app/assets/javascripts/application.js
@@ -118,7 +154,6 @@ files:
118
154
  - test/dummy/config/initializers/inflections.rb
119
155
  - test/dummy/config/initializers/mime_types.rb
120
156
  - test/dummy/config/initializers/new_framework_defaults.rb
121
- - test/dummy/config/initializers/session_store.rb
122
157
  - test/dummy/config/initializers/workarea.rb
123
158
  - test/dummy/config/initializers/wrap_parameters.rb
124
159
  - test/dummy/config/locales/en.yml
@@ -134,19 +169,35 @@ files:
134
169
  - test/dummy/public/apple-touch-icon-precomposed.png
135
170
  - test/dummy/public/apple-touch-icon.png
136
171
  - test/dummy/public/favicon.ico
172
+ - test/factories/workarea/capture_completed_webhook.json
173
+ - test/factories/workarea/capture_denied_webhook.json
174
+ - test/factories/workarea/paypal.rb
175
+ - test/helpers/workarea/storefront/paypal_helper_test.rb
137
176
  - test/integration/workarea/storefront/paypal_integration_test.rb
138
- - test/integration/workarea/storefront/place_order_integration_test.decorator
177
+ - test/integration/workarea/storefront/paypal_place_order_integration_test.rb
178
+ - test/lib/workarea/paypal/gateway_test.rb
139
179
  - test/models/workarea/payment/authorize/paypal_test.rb
140
180
  - test/models/workarea/payment/capture/paypal_test.rb
141
- - test/models/workarea/payment/purchase/paypal_test.rb
181
+ - test/models/workarea/payment/null_address_test.rb
142
182
  - test/models/workarea/payment/refund/paypal_test.rb
143
- - test/models/workarea/payment_test.decorator
144
- - test/models/workarea/search/admin/order_test.decorator
145
- - test/services/workarea/paypal/setup_test.rb
146
- - test/services/workarea/paypal/update_test.rb
183
+ - test/models/workarea/paypal_payment_test.rb
184
+ - test/models/workarea/search/paypal_order_text_test.rb
185
+ - test/services/workarea/paypal/approve_order_test.rb
186
+ - test/services/workarea/paypal/create_order_test.rb
187
+ - test/services/workarea/paypal/update_order_test.rb
188
+ - test/support/workarea/paypal_setup.rb
147
189
  - test/system/workarea/storefront/cart_system_test.decorator
148
190
  - test/system/workarea/storefront/logged_in_checkout_system_test.decorator
149
191
  - test/test_helper.rb
192
+ - test/vcr_cassettes/paypal_approve_order.yml
193
+ - test/vcr_cassettes/paypal_create_order.yml
194
+ - test/vcr_cassettes/paypal_gateway_create_order.yml
195
+ - test/vcr_cassettes/paypal_gateway_generate_token.yml
196
+ - test/vcr_cassettes/paypal_gateway_get_order.yml
197
+ - test/vcr_cassettes/paypal_gateway_update_order.yml
198
+ - test/vcr_cassettes/paypal_gateway_webhooks.yml
199
+ - test/vcr_cassettes/paypal_update_order.yml
200
+ - test/workers/workarea/paypal/handle_webhook_event_test.rb
150
201
  - workarea-paypal.gemspec
151
202
  homepage: https://github.com/workarea-commerce/workarea-paypal
152
203
  licenses:
@@ -167,7 +218,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
167
218
  - !ruby/object:Gem::Version
168
219
  version: '0'
169
220
  requirements: []
170
- rubygems_version: 3.0.6
221
+ rubygems_version: 3.0.3
171
222
  signing_key:
172
223
  specification_version: 4
173
224
  summary: PayPal integration for the Workarea Commerce Platform
@@ -1,114 +0,0 @@
1
- module Workarea
2
- module Paypal
3
- class Setup
4
- attr_reader :order, :user, :shipping, :context
5
- delegate :request, to: :context
6
- delegate :gateway, to: Workarea::Paypal
7
-
8
- def initialize(order, user, shipping, context)
9
- @order = order
10
- @user = user
11
- @shipping = shipping
12
- @context = context
13
- end
14
-
15
- def paypal_response
16
- @paypal_response ||= gateway.setup_authorization(
17
- order.total_price.cents,
18
- ip: request.remote_ip,
19
- return_url: context.complete_paypal_url(order.id),
20
- cancel_return_url: context.cart_url,
21
- currency: order.total_price.currency,
22
- subtotal: subtotal,
23
- shipping: order.shipping_total.cents,
24
- handling: 0,
25
- tax: order.tax_total.cents,
26
- items: items,
27
- shipping_address: shipping_address,
28
- order_id: order.id
29
- )
30
- end
31
-
32
- def items
33
- order_items + item_level_discounts + order_level_discounts
34
- end
35
-
36
- def subtotal
37
- order.subtotal_price.cents +
38
- order.price_adjustments.adjusting('order').discounts.sum.cents
39
- end
40
-
41
- def shipping_address
42
- serialize_address(shipping.try(:address) || user.try(:default_shipping_address))
43
- end
44
-
45
- def token
46
- paypal_response.token
47
- end
48
-
49
- def redirect_url
50
- gateway.redirect_url_for(token)
51
- end
52
-
53
- private
54
-
55
- def serialize_address(address)
56
- return {} unless address
57
-
58
- name = "#{address.first_name} #{address.last_name}"
59
- phone = [address.phone_number, address.phone_extension].reject(&:blank?).join(' x')
60
-
61
- { name: name,
62
- address1: address.street,
63
- address2: address.street_2,
64
- city: address.city,
65
- state: address.region,
66
- country: address.country,
67
- zip: address.postal_code,
68
- phone: phone }
69
- end
70
-
71
- def order_items
72
- order.items.map do |item|
73
- item_discount_total = item.price_adjustments.discounts.sum.cents
74
-
75
- {
76
- name: item.product_attributes.with_indifferent_access[:name],
77
- quantity: item.quantity,
78
- amount: (item.total_price.cents - item_discount_total) / item.quantity
79
- }
80
- end
81
- end
82
-
83
- def item_level_discounts
84
- order_items_with_discounts = order.items.select do |item|
85
- item.price_adjustments.discounts.present?
86
- end
87
-
88
- order_items_with_discounts.flat_map do |item|
89
- item.price_adjustments.discounts.map do |discount|
90
- {
91
- name: discount.description.titleize,
92
- quantity: 1,
93
- amount: discount.amount.cents
94
- }
95
- end
96
- end
97
- end
98
-
99
- def order_level_discounts
100
- order
101
- .price_adjustments
102
- .adjusting('order')
103
- .discounts
104
- .map do |discount|
105
- {
106
- name: discount.description.titleize,
107
- quantity: 1,
108
- amount: discount.amount.cents
109
- }
110
- end
111
- end
112
- end
113
- end
114
- end