workarea-paypal 2.0.12 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc.json +2 -1
  3. data/.gitignore +16 -11
  4. data/CHANGELOG.md +29 -5
  5. data/README.md +100 -6
  6. data/Rakefile +4 -5
  7. data/app/assets/javascripts/workarea/storefront/paypal/config.js.erb +44 -0
  8. data/app/assets/javascripts/workarea/storefront/paypal/modules/paypal_buttons.js +71 -0
  9. data/app/assets/javascripts/workarea/storefront/paypal/modules/paypal_hosted_fields.js +96 -0
  10. data/app/assets/javascripts/workarea/storefront/paypal/modules/update_checkout_submit_text.js +11 -5
  11. data/app/assets/javascripts/workarea/storefront/paypal/templates/paypal_fields.jst.ejs +43 -0
  12. data/app/controllers/workarea/storefront/checkout/place_order_controller.decorator +6 -4
  13. data/app/controllers/workarea/storefront/paypal_controller.rb +32 -26
  14. data/app/helpers/workarea/storefront/paypal_helper.rb +38 -0
  15. data/app/models/workarea/payment/authorize/paypal.rb +13 -13
  16. data/app/models/workarea/payment/capture/paypal.rb +10 -20
  17. data/app/models/workarea/payment/null_address.rb +37 -0
  18. data/app/models/workarea/payment/purchase/paypal.rb +1 -25
  19. data/app/models/workarea/payment/refund/paypal.rb +3 -6
  20. data/app/models/workarea/payment/tender/paypal.rb +14 -2
  21. data/app/models/workarea/payment.decorator +17 -3
  22. data/app/services/workarea/paypal/approve_order.rb +104 -0
  23. data/app/services/workarea/paypal/create_order.rb +177 -0
  24. data/app/services/workarea/paypal/update_order.rb +44 -0
  25. data/app/views/workarea/admin/orders/tenders/_paypal.html.haml +5 -2
  26. data/app/views/workarea/api/orders/tenders/_paypal.json.jbuilder +7 -1
  27. data/app/views/workarea/storefront/carts/_paypal_checkout.html.haml +6 -1
  28. data/app/views/workarea/storefront/checkouts/_paypal_payment.html.haml +16 -5
  29. data/app/views/workarea/storefront/order_mailer/tenders/_paypal.html.haml +5 -3
  30. data/app/views/workarea/storefront/orders/tenders/_paypal.html.haml +9 -2
  31. data/app/views/workarea/storefront/paypal/_paypal_sdk.html.haml +1 -0
  32. data/app/workers/workarea/paypal/handle_webhook_event.rb +64 -0
  33. data/config/initializers/append_points.rb +17 -5
  34. data/config/initializers/fields.rb +27 -0
  35. data/config/initializers/workarea.rb +41 -5
  36. data/config/locales/en.yml +14 -4
  37. data/config/routes.rb +3 -2
  38. data/lib/tasks/workarea/create_webhooks.rake +28 -0
  39. data/lib/workarea/paypal/engine.rb +4 -0
  40. data/lib/workarea/paypal/gateway.rb +200 -0
  41. data/lib/workarea/paypal/requests/create_webhook.rb +21 -0
  42. data/lib/workarea/paypal/requests/delete_webhook.rb +17 -0
  43. data/lib/workarea/paypal/requests/generate_token.rb +21 -0
  44. data/lib/workarea/paypal/requests/list_webhooks.rb +17 -0
  45. data/lib/workarea/paypal/version.rb +1 -1
  46. data/lib/workarea/paypal.rb +22 -19
  47. data/package.json +9 -0
  48. data/test/dummy/config/initializers/workarea.rb +1 -1
  49. data/test/factories/workarea/capture_completed_webhook.json +70 -0
  50. data/test/factories/workarea/capture_denied_webhook.json +68 -0
  51. data/test/factories/workarea/paypal.rb +34 -0
  52. data/test/helpers/workarea/storefront/paypal_helper_test.rb +35 -0
  53. data/test/integration/workarea/storefront/papyal_place_order_integration_test.rb +42 -0
  54. data/test/integration/workarea/storefront/paypal_integration_test.rb +104 -294
  55. data/test/lib/workarea/paypal/gateway_test.rb +236 -0
  56. data/test/models/workarea/payment/authorize/paypal_test.rb +57 -46
  57. data/test/models/workarea/payment/capture/paypal_test.rb +9 -51
  58. data/test/models/workarea/payment/null_address_test.rb +53 -0
  59. data/test/models/workarea/payment/refund/paypal_test.rb +39 -38
  60. data/test/models/workarea/paypal_payment_test.rb +65 -0
  61. data/test/models/workarea/search/paypal_order_text_test.rb +14 -0
  62. data/test/services/workarea/paypal/approve_order_test.rb +35 -0
  63. data/test/services/workarea/paypal/create_order_test.rb +127 -0
  64. data/test/services/workarea/paypal/update_order_test.rb +73 -0
  65. data/test/support/workarea/paypal_setup.rb +49 -0
  66. data/test/system/workarea/storefront/cart_system_test.decorator +1 -1
  67. data/test/system/workarea/storefront/logged_in_checkout_system_test.decorator +1 -1
  68. data/test/vcr_cassettes/paypal_approve_order.yml +106 -0
  69. data/test/vcr_cassettes/paypal_create_order.yml +110 -0
  70. data/test/vcr_cassettes/paypal_gateway_create_order.yml +105 -0
  71. data/test/vcr_cassettes/paypal_gateway_generate_token.yml +103 -0
  72. data/test/vcr_cassettes/paypal_gateway_get_order.yml +103 -0
  73. data/test/vcr_cassettes/paypal_gateway_update_order.yml +199 -0
  74. data/test/vcr_cassettes/paypal_gateway_webhooks.yml +403 -0
  75. data/test/vcr_cassettes/paypal_update_order.yml +204 -0
  76. data/test/workers/workarea/paypal/handle_webhook_event_test.rb +60 -0
  77. data/workarea-paypal.gemspec +2 -1
  78. metadata +64 -16
  79. data/app/services/workarea/paypal/setup.rb +0 -114
  80. data/app/services/workarea/paypal/update.rb +0 -69
  81. data/app/views/workarea/storefront/checkouts/_paypal_error.html.haml +0 -6
  82. data/app/views/workarea/storefront/order_mailer/tenders/_paypal.text.haml +0 -2
  83. data/lib/workarea/paypal/ext/active_merchant/paypal_express_gateway.rb +0 -9
  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
  91. data/test/workarea/paypal/ext/active_merchant/paypal_express_gateway_test.rb +0 -17
@@ -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.12
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - bcrouse
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-14 00:00:00.000000000 Z
11
+ date: 2020-03-03 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
@@ -54,18 +74,25 @@ files:
54
74
  - Rakefile
55
75
  - app/assets/images/workarea/admin/payment_icons/paypal.svg
56
76
  - app/assets/images/workarea/storefront/payment_icons/paypal.svg
77
+ - app/assets/javascripts/workarea/storefront/paypal/config.js.erb
78
+ - app/assets/javascripts/workarea/storefront/paypal/modules/paypal_buttons.js
79
+ - app/assets/javascripts/workarea/storefront/paypal/modules/paypal_hosted_fields.js
57
80
  - app/assets/javascripts/workarea/storefront/paypal/modules/update_checkout_submit_text.js
81
+ - app/assets/javascripts/workarea/storefront/paypal/templates/paypal_fields.jst.ejs
58
82
  - app/controllers/workarea/storefront/checkout/place_order_controller.decorator
59
83
  - app/controllers/workarea/storefront/paypal_controller.rb
84
+ - app/helpers/workarea/storefront/paypal_helper.rb
60
85
  - app/models/workarea/payment.decorator
61
86
  - app/models/workarea/payment/authorize/paypal.rb
62
87
  - app/models/workarea/payment/capture/paypal.rb
88
+ - app/models/workarea/payment/null_address.rb
63
89
  - app/models/workarea/payment/purchase/paypal.rb
64
90
  - app/models/workarea/payment/refund/paypal.rb
65
91
  - app/models/workarea/payment/tender/paypal.rb
66
92
  - app/models/workarea/search/order_text.decorator
67
- - app/services/workarea/paypal/setup.rb
68
- - app/services/workarea/paypal/update.rb
93
+ - app/services/workarea/paypal/approve_order.rb
94
+ - app/services/workarea/paypal/create_order.rb
95
+ - app/services/workarea/paypal/update_order.rb
69
96
  - app/view_models/workarea/admin/paypal_view_model.rb
70
97
  - app/view_models/workarea/store_front/checkout/payment_view_model.decorator
71
98
  - app/view_models/workarea/store_front/credit_card_view_model.decorator
@@ -73,20 +100,27 @@ files:
73
100
  - app/views/workarea/admin/orders/tenders/_paypal.html.haml
74
101
  - app/views/workarea/api/orders/tenders/_paypal.json.jbuilder
75
102
  - app/views/workarea/storefront/carts/_paypal_checkout.html.haml
76
- - app/views/workarea/storefront/checkouts/_paypal_error.html.haml
77
103
  - app/views/workarea/storefront/checkouts/_paypal_payment.html.haml
78
104
  - app/views/workarea/storefront/order_mailer/tenders/_paypal.html.haml
79
- - app/views/workarea/storefront/order_mailer/tenders/_paypal.text.haml
80
105
  - app/views/workarea/storefront/orders/tenders/_paypal.html.haml
106
+ - app/views/workarea/storefront/paypal/_paypal_sdk.html.haml
107
+ - app/workers/workarea/paypal/handle_webhook_event.rb
81
108
  - bin/rails
82
109
  - config/initializers/append_points.rb
110
+ - config/initializers/fields.rb
83
111
  - config/initializers/workarea.rb
84
112
  - config/locales/en.yml
85
113
  - config/routes.rb
114
+ - lib/tasks/workarea/create_webhooks.rake
86
115
  - lib/workarea/paypal.rb
87
116
  - lib/workarea/paypal/engine.rb
88
- - lib/workarea/paypal/ext/active_merchant/paypal_express_gateway.rb
117
+ - lib/workarea/paypal/gateway.rb
118
+ - lib/workarea/paypal/requests/create_webhook.rb
119
+ - lib/workarea/paypal/requests/delete_webhook.rb
120
+ - lib/workarea/paypal/requests/generate_token.rb
121
+ - lib/workarea/paypal/requests/list_webhooks.rb
89
122
  - lib/workarea/paypal/version.rb
123
+ - package.json
90
124
  - test/dummy/Rakefile
91
125
  - test/dummy/app/assets/config/manifest.js
92
126
  - test/dummy/app/assets/javascripts/application.js
@@ -119,7 +153,6 @@ files:
119
153
  - test/dummy/config/initializers/inflections.rb
120
154
  - test/dummy/config/initializers/mime_types.rb
121
155
  - test/dummy/config/initializers/new_framework_defaults.rb
122
- - test/dummy/config/initializers/session_store.rb
123
156
  - test/dummy/config/initializers/workarea.rb
124
157
  - test/dummy/config/initializers/wrap_parameters.rb
125
158
  - test/dummy/config/locales/en.yml
@@ -135,20 +168,35 @@ files:
135
168
  - test/dummy/public/apple-touch-icon-precomposed.png
136
169
  - test/dummy/public/apple-touch-icon.png
137
170
  - test/dummy/public/favicon.ico
171
+ - test/factories/workarea/capture_completed_webhook.json
172
+ - test/factories/workarea/capture_denied_webhook.json
173
+ - test/factories/workarea/paypal.rb
174
+ - test/helpers/workarea/storefront/paypal_helper_test.rb
175
+ - test/integration/workarea/storefront/papyal_place_order_integration_test.rb
138
176
  - test/integration/workarea/storefront/paypal_integration_test.rb
139
- - test/integration/workarea/storefront/place_order_integration_test.decorator
177
+ - test/lib/workarea/paypal/gateway_test.rb
140
178
  - test/models/workarea/payment/authorize/paypal_test.rb
141
179
  - test/models/workarea/payment/capture/paypal_test.rb
142
- - test/models/workarea/payment/purchase/paypal_test.rb
180
+ - test/models/workarea/payment/null_address_test.rb
143
181
  - test/models/workarea/payment/refund/paypal_test.rb
144
- - test/models/workarea/payment_test.decorator
145
- - test/models/workarea/search/admin/order_test.decorator
146
- - test/services/workarea/paypal/setup_test.rb
147
- - test/services/workarea/paypal/update_test.rb
182
+ - test/models/workarea/paypal_payment_test.rb
183
+ - test/models/workarea/search/paypal_order_text_test.rb
184
+ - test/services/workarea/paypal/approve_order_test.rb
185
+ - test/services/workarea/paypal/create_order_test.rb
186
+ - test/services/workarea/paypal/update_order_test.rb
187
+ - test/support/workarea/paypal_setup.rb
148
188
  - test/system/workarea/storefront/cart_system_test.decorator
149
189
  - test/system/workarea/storefront/logged_in_checkout_system_test.decorator
150
190
  - test/test_helper.rb
151
- - test/workarea/paypal/ext/active_merchant/paypal_express_gateway_test.rb
191
+ - test/vcr_cassettes/paypal_approve_order.yml
192
+ - test/vcr_cassettes/paypal_create_order.yml
193
+ - test/vcr_cassettes/paypal_gateway_create_order.yml
194
+ - test/vcr_cassettes/paypal_gateway_generate_token.yml
195
+ - test/vcr_cassettes/paypal_gateway_get_order.yml
196
+ - test/vcr_cassettes/paypal_gateway_update_order.yml
197
+ - test/vcr_cassettes/paypal_gateway_webhooks.yml
198
+ - test/vcr_cassettes/paypal_update_order.yml
199
+ - test/workers/workarea/paypal/handle_webhook_event_test.rb
152
200
  - workarea-paypal.gemspec
153
201
  homepage: https://github.com/workarea-commerce/workarea-paypal
154
202
  licenses:
@@ -169,7 +217,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
169
217
  - !ruby/object:Gem::Version
170
218
  version: '0'
171
219
  requirements: []
172
- rubygems_version: 3.0.3
220
+ rubygems_version: 3.0.6
173
221
  signing_key:
174
222
  specification_version: 4
175
223
  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
@@ -1,69 +0,0 @@
1
- module Workarea
2
- module Paypal
3
- class Update
4
- attr_reader :order, :payment, :shipping, :token
5
-
6
- def initialize(order, payment, shipping, token)
7
- @order = order
8
- @payment = payment
9
- @shipping = shipping
10
- @token = token
11
- end
12
-
13
- def details
14
- @details ||= Workarea::Paypal.gateway.details_for(token)
15
- end
16
-
17
- def apply
18
- order.email ||= details.email
19
- set_shipping_address(details.params)
20
- set_shipping_service
21
- set_billing_address(details.params)
22
-
23
- payment.clear_credit_card
24
- payment.set_paypal(
25
- token: details.token,
26
- payer_id: details.payer_id,
27
- details: details.params
28
- )
29
-
30
- Pricing.perform(order, shipping)
31
- payment.adjust_tender_amounts(order.total_price)
32
- end
33
-
34
- private
35
-
36
- def set_shipping_address(params)
37
- shipping.set_address(
38
- first_name: params['first_name'],
39
- last_name: params['last_name'],
40
- street: params['PaymentDetails']['ShipToAddress']['Street1'],
41
- street_2: params['PaymentDetails']['ShipToAddress']['Street2'],
42
- city: params['PaymentDetails']['ShipToAddress']['CityName'],
43
- region: params['PaymentDetails']['ShipToAddress']['StateOrProvince'],
44
- postal_code: params['PaymentDetails']['ShipToAddress']['PostalCode'],
45
- country: params['PaymentDetails']['ShipToAddress']['Country'],
46
- phone_number: params['PaymentDetails']['ShipToAddress']['Phone']
47
- )
48
- end
49
-
50
- def set_billing_address(params)
51
- payment.set_address(
52
- first_name: params['PayerInfo']['PayerName']['FirstName'],
53
- last_name: params['PayerInfo']['PayerName']['LastName'],
54
- street: params['PayerInfo']['Address']['Street1'],
55
- street_2: params['PayerInfo']['Address']['Street2'],
56
- city: params['PayerInfo']['Address']['CityName'],
57
- region: params['PayerInfo']['Address']['StateOrProvince'],
58
- postal_code: params['PayerInfo']['Address']['PostalCode'],
59
- country: params['PayerInfo']['Address']['Country'],
60
- phone_number: params['PayerInfo']['Address']['Phone']
61
- )
62
- end
63
-
64
- def set_shipping_service
65
- Checkout::Steps::Shipping.new(self).update({})
66
- end
67
- end
68
- end
69
- end
@@ -1,6 +0,0 @@
1
- - if step.paypal? && step.payment.paypal.errors.any?
2
- - step.payment.paypal.errors.full_messages.each do |message|
3
- .message.message--error
4
- %p.message__type
5
- %span.message__icon= t('workarea.storefront.messages.error')
6
- %p.message__text= message
@@ -1,2 +0,0 @@
1
- = t('workarea.storefront.paypal.paid_with_paypal')
2
- = number_to_currency tender.amount
@@ -1,9 +0,0 @@
1
- module ActiveMerchant
2
- module Billing
3
- decorate PaypalExpressGateway, with: :workarea do
4
- def add_button_source(xml)
5
- xml.tag! 'n2:ButtonSource', 'Workarea_SP'
6
- end
7
- end
8
- end
9
- end
@@ -1,3 +0,0 @@
1
- # Be sure to restart your server when you modify this file.
2
-
3
- Rails.application.config.session_store :cookie_store, key: '_dummy_session', expire_after: 30.minutes
@@ -1,11 +0,0 @@
1
- require 'test_helper'
2
-
3
- module Workarea
4
- decorate Storefront::PlaceOrderIntegrationTest, with: :paypal do
5
- def test_place_order_redirects_to_paypal
6
- patch storefront.checkout_place_order_path, params: { payment: 'paypal' }
7
-
8
- assert_redirected_to(storefront.start_paypal_path)
9
- end
10
- end
11
- end