solidus_paypal_commerce_platform 0.7.0 → 1.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +21 -9
  3. data/.gem_release.yml +1 -1
  4. data/.gitignore +1 -0
  5. data/.rspec +0 -1
  6. data/.rubocop.yml +3 -2
  7. data/CHANGELOG.md +12 -17
  8. data/Gemfile +0 -41
  9. data/README.md +10 -14
  10. data/Rakefile +6 -1
  11. data/app/models/solidus_paypal_commerce_platform/payment_method.rb +1 -18
  12. data/bin/dummy-app +37 -0
  13. data/bin/rails-dummy-app +17 -0
  14. data/bin/rspec +11 -0
  15. data/bin/sandbox +3 -8
  16. data/config/locales/en.yml +0 -1
  17. data/lib/generators/solidus_paypal_commerce_platform/install/install_generator.rb +35 -21
  18. data/lib/generators/solidus_paypal_commerce_platform/install/templates/app/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform/button_actions.js +272 -0
  19. data/{app → lib/generators/solidus_paypal_commerce_platform/install/templates/app}/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform.js +7 -0
  20. data/{app → lib/generators/solidus_paypal_commerce_platform/install/templates/app}/controllers/solidus_paypal_commerce_platform/paypal_orders_controller.rb +1 -1
  21. data/lib/{views/frontend/spree/checkout → generators/solidus_paypal_commerce_platform/install/templates/app/views/checkouts}/payment/_paypal_commerce_platform.html.erb +5 -4
  22. data/lib/{views/frontend/spree → generators/solidus_paypal_commerce_platform/install/templates/app/views}/orders/payment/_paypal_commerce_platform.html.erb +4 -3
  23. data/lib/{views/frontend/spree → generators/solidus_paypal_commerce_platform/install/templates/app/views}/products/payment/_paypal_commerce_platform.html.erb +1 -1
  24. data/lib/{views/frontend → generators/solidus_paypal_commerce_platform/install/templates/app/views}/solidus_paypal_commerce_platform/shared/_javascript_sdk_tag.html.erb +4 -2
  25. data/lib/solidus_paypal_commerce_platform/version.rb +1 -1
  26. data/solidus_paypal_commerce_platform.gemspec +1 -2
  27. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/CHECKOUT.ORDER.COMPLETED.v2.json +121 -0
  28. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/CHECKOUT.ORDER.PROCESSED.v2.json +121 -0
  29. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.COMPLETED.v1.json +50 -0
  30. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.COMPLETED.v2.json +72 -0
  31. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.DENIED.v1.json +50 -0
  32. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.DENIED.v2.json +68 -0
  33. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.REFUNDED.v1.json +51 -0
  34. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.REFUNDED.v2.json +63 -0
  35. data/spec/jobs/solidus_paypal_commerce_platform/webhook_job_spec.rb +44 -0
  36. data/spec/lib/solidus_paypal_commerce_platform/client_spec.rb +21 -0
  37. data/spec/lib/solidus_paypal_commerce_platform/configuration_spec.rb +91 -0
  38. data/spec/models/solidus_paypal_commerce_platform/payment_method_spec.rb +200 -0
  39. data/spec/models/solidus_paypal_commerce_platform/payment_source_spec.rb +119 -0
  40. data/spec/models/solidus_paypal_commerce_platform/paypal_address_spec.rb +67 -0
  41. data/spec/models/solidus_paypal_commerce_platform/paypal_order_spec.rb +80 -0
  42. data/spec/models/solidus_paypal_commerce_platform/state_guesser_spec.rb +38 -0
  43. data/spec/models/solidus_paypal_commerce_platform/wizard_spec.rb +9 -0
  44. data/spec/requests/solidus_paypal_commerce_platform/orders_controller_spec.rb +36 -0
  45. data/spec/requests/solidus_paypal_commerce_platform/shipping_rates_controller_spec.rb +44 -0
  46. data/spec/requests/solidus_paypal_commerce_platform/wizard_controller_spec.rb +59 -0
  47. data/spec/solidus_paypal_commerce_platform_spec_helper.rb +5 -0
  48. data/spec/support/solidus_paypal_commerce_platform/factories.rb +5 -0
  49. data/spec/support/solidus_paypal_commerce_platform/paypal_sdk_script_tag_helper.rb +13 -0
  50. data/spec/system/backend/new_payment_method_spec.rb +40 -0
  51. data/spec/system/frontend/cart_spec.rb +53 -0
  52. data/spec/system/frontend/checkout_spec.rb +104 -0
  53. data/spec/system/frontend/product_spec.rb +98 -0
  54. metadata +53 -37
  55. data/app/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform/button_actions.js +0 -206
  56. /data/{app → lib/generators/solidus_paypal_commerce_platform/install/templates/app}/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform/buttons.js +0 -0
  57. /data/{app → lib/generators/solidus_paypal_commerce_platform/install/templates/app}/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform/namespace.js +0 -0
  58. /data/{app → lib/generators/solidus_paypal_commerce_platform/install/templates/app}/assets/stylesheets/spree/frontend/solidus_paypal_commerce_platform.css +0 -0
  59. /data/{app → lib/generators/solidus_paypal_commerce_platform/install/templates/app}/controllers/solidus_paypal_commerce_platform/orders_controller.rb +0 -0
  60. /data/{app → lib/generators/solidus_paypal_commerce_platform/install/templates/app}/controllers/solidus_paypal_commerce_platform/payments_controller.rb +0 -0
  61. /data/{app → lib/generators/solidus_paypal_commerce_platform/install/templates/app}/controllers/solidus_paypal_commerce_platform/shipping_rates_controller.rb +0 -0
  62. /data/{app → lib/generators/solidus_paypal_commerce_platform/install/templates/app}/controllers/solidus_paypal_commerce_platform/wizard_controller.rb +0 -0
  63. /data/lib/{views/frontend → generators/solidus_paypal_commerce_platform/install/templates/app/views}/solidus_paypal_commerce_platform/cart/_cart_buttons.html.erb +0 -0
  64. /data/lib/{views/frontend → generators/solidus_paypal_commerce_platform/install/templates/app/views}/solidus_paypal_commerce_platform/payments/_payment.html.erb +0 -0
  65. /data/lib/{views/frontend → generators/solidus_paypal_commerce_platform/install/templates/app/views}/solidus_paypal_commerce_platform/product/_product_buttons.html.erb +0 -0
  66. /data/lib/generators/solidus_paypal_commerce_platform/install/templates/{initializer.rb → config/initializers/solidus_paypal_commerce_platform.rb} +0 -0
@@ -0,0 +1,272 @@
1
+ // Attach inline GET-compatible params to a path.
2
+ // The path is assumed to be base off the current location.
3
+ // The data structure will wrap keys beyond the first level in
4
+ // square brackets, e.g. `{a: {b: 123}}` will become `a[b]=123`.
5
+ const urlWithParams = (path, data) => {
6
+ const url = new URL(path, window.location)
7
+
8
+ const formKey = (keys) => {
9
+ if (keys.length === 0) return ''
10
+ if (keys.length === 1) return keys[0]
11
+
12
+ // Wrap any key beyond the first one in square brackets
13
+ return `${keys.shift()}${keys.map((k) => `[${k}]`).join()}`
14
+ }
15
+
16
+ const appendSearchParams = (parentKeys, data) =>
17
+ Object.entries(data).forEach(([key, value]) => {
18
+
19
+ if (typeof value === 'object')
20
+ appendSearchParams([...parentKeys, key], value)
21
+ else
22
+ url.searchParams.append(formKey([...parentKeys, key]), value)
23
+ })
24
+
25
+ appendSearchParams([], data)
26
+ return url
27
+ }
28
+
29
+ const authHeader = (options = {}) => {
30
+ const apiKey = SolidusPaypalCommercePlatform.api_key
31
+ if (options.require && !apiKey) throw new Error("Missing api key")
32
+
33
+
34
+ return {
35
+ 'Authorization': `Bearer ${apiKey}`,
36
+ [document.querySelector('meta[name="csrf-param"]')?.content]: document.querySelector('meta[name="csrf-token"]')?.content,
37
+ }
38
+ }
39
+ SolidusPaypalCommercePlatform.showOverlay = function() {
40
+ document.getElementById("paypal_commerce_platform_overlay").style.display = "block";
41
+ }
42
+
43
+ SolidusPaypalCommercePlatform.hideOverlay = function() {
44
+ document.getElementById("paypal_commerce_platform_overlay").style.display = "none";
45
+ }
46
+
47
+ SolidusPaypalCommercePlatform.handleError = function(error) {
48
+ console.error(error);
49
+ alert("There was a problem connecting with PayPal.")
50
+ throw error
51
+ }
52
+
53
+ SolidusPaypalCommercePlatform.sendOrder = async function(payment_method_id) {
54
+ if (!payment_method_id) throw new Error("payment_method_id is missing!")
55
+
56
+ const url = urlWithParams(`/solidus_paypal_commerce_platform/paypal_orders/${SolidusPaypalCommercePlatform.current_order_id}`, {
57
+ payment_method_id: payment_method_id,
58
+ order_token: SolidusPaypalCommercePlatform.current_order_token,
59
+ })
60
+
61
+ const response = await fetch(url, {headers: authHeader()})
62
+ const data = await response.json()
63
+
64
+ if (response.ok) {
65
+ return data.table.result.table.id
66
+ } else {
67
+ return data.table.error.table
68
+ }
69
+ }
70
+
71
+ SolidusPaypalCommercePlatform.createAndSendOrder = async function(payment_method_id) {
72
+ await SolidusPaypalCommercePlatform.createOrder()
73
+ return await SolidusPaypalCommercePlatform.sendOrder(payment_method_id)
74
+ }
75
+
76
+ SolidusPaypalCommercePlatform.createOrder = async function() {
77
+ const response = await fetch(
78
+ "/solidus_paypal_commerce_platform/orders",
79
+ {
80
+ method: 'POST',
81
+ headers: {
82
+ ...authHeader(),
83
+ 'Content-Type': 'application/json'
84
+ },
85
+ body: JSON.stringify({
86
+ order: {
87
+ line_items_attributes: [{
88
+ variant_id: SolidusPaypalCommercePlatform.getVariantId(),
89
+ quantity: SolidusPaypalCommercePlatform.getQuantity()
90
+ }]
91
+ }
92
+ }),
93
+ }
94
+ )
95
+ const data = await response.json()
96
+
97
+ if (response.ok) {
98
+ SolidusPaypalCommercePlatform.current_order_id = data.number
99
+ SolidusPaypalCommercePlatform.current_order_token = data.guest_token
100
+ } else {
101
+ console.error('A problem has occurred while creating your order', data);
102
+ alert('A problem has occurred while creating your order - ' + JSON.stringify(data))
103
+ }
104
+ }
105
+
106
+ SolidusPaypalCommercePlatform.getVariantId = function() {
107
+ var variants = document.getElementsByName("variant_id")
108
+ var variant_id;
109
+
110
+ if (variants.length == 1){
111
+ variant_id = variants[0].value
112
+ } else {
113
+ for (var i = 0; i < variants.length; i++) {
114
+ if (variants[i].checked) {
115
+ variant_id = variants[i].value
116
+ }
117
+ }
118
+ }
119
+ return variant_id
120
+ }
121
+
122
+ SolidusPaypalCommercePlatform.getQuantity = function() {
123
+ return document.getElementById("quantity").value
124
+ }
125
+
126
+ SolidusPaypalCommercePlatform.approveOrder = function(data, actions) {
127
+ SolidusPaypalCommercePlatform.showOverlay()
128
+ actions.order.get().then(function(response){
129
+ SolidusPaypalCommercePlatform.updateAddress(response).then(function() {
130
+ SolidusPaypalCommercePlatform.verifyTotal(response.purchase_units[0].amount.value).then(function(){
131
+ document.querySelector("#payments_source_paypal_order_id").value = data.orderID
132
+ document.querySelector("#payments_source_paypal_email").value = response.payer.email_address
133
+ document.querySelector("#payments_source_paypal_funding_source").value = SolidusPaypalCommercePlatform.fundingSource
134
+ document.querySelector("#checkout_form_payment").submit()
135
+ })
136
+ })
137
+ })
138
+ }
139
+
140
+ SolidusPaypalCommercePlatform.shippingChange = async function(paypalData, actions) {
141
+ const shipping_address = paypalData.shipping_address
142
+
143
+ url = urlWithParams('/solidus_paypal_commerce_platform/shipping_rates', {
144
+ order_id: SolidusPaypalCommercePlatform.current_order_id,
145
+ order_token: SolidusPaypalCommercePlatform.current_order_token,
146
+ address: shipping_address,
147
+ })
148
+
149
+ const response = await fetch(url, {headers: authHeader()})
150
+ const data = await response.json()
151
+
152
+ if (response.ok) {
153
+ return actions.order.patch([data]).catch(function(e) {
154
+ console.error('There were some problems with your payment address while trying to patch the order', e);
155
+ actions.reject()
156
+ })
157
+ } else {
158
+ console.error('There were some problems with your payment address', data);
159
+ return actions.reject()
160
+ }
161
+ }
162
+
163
+ SolidusPaypalCommercePlatform.verifyTotal = async function(paypal_total) {
164
+ const response = await fetch(
165
+ urlWithParams('/solidus_paypal_commerce_platform/verify_total', {
166
+ order_id: SolidusPaypalCommercePlatform.current_order_id,
167
+ order_token: SolidusPaypalCommercePlatform.current_order_token,
168
+ paypal_total: paypal_total
169
+ }), {
170
+ headers: authHeader()
171
+ })
172
+
173
+ if (!response.ok) {
174
+ SolidusPaypalCommercePlatform.hideOverlay()
175
+ alert('There were some problems with your payment - ' + response.responseJSON.errors.expected_total);
176
+ }
177
+ }
178
+
179
+ SolidusPaypalCommercePlatform.finalizeOrder = function(payment_method_id, data, actions) {
180
+ SolidusPaypalCommercePlatform.showOverlay()
181
+ actions.order.get().then(function(response){
182
+ SolidusPaypalCommercePlatform.updateAddress(response).then(function() {
183
+ var paypal_amount = response.purchase_units[0].amount.value
184
+ SolidusPaypalCommercePlatform.advanceOrder().then(function() {
185
+ SolidusPaypalCommercePlatform.verifyTotal(paypal_amount).then(function(){
186
+ SolidusPaypalCommercePlatform.addPayment(paypal_amount, payment_method_id, data, response.payer.email_address).then(function() {
187
+ window.location.href = SolidusPaypalCommercePlatform.checkout_url
188
+ })
189
+ })
190
+ })
191
+ })
192
+ })
193
+ }
194
+
195
+ SolidusPaypalCommercePlatform.advanceOrder = async function() {
196
+ const response = await fetch(
197
+ `/api/checkouts/${SolidusPaypalCommercePlatform.current_order_id}/advance`, {
198
+ headers: {
199
+ ...authHeader(),
200
+ 'Content-Type': 'application/json'
201
+ },
202
+ method: 'PUT',
203
+ body: JSON.stringify({
204
+ order_token: SolidusPaypalCommercePlatform.current_order_token
205
+ })
206
+ })
207
+
208
+ if (!response.ok) {
209
+ SolidusPaypalCommercePlatform.hideOverlay()
210
+ alert('There were some problems with your order');
211
+ }
212
+ }
213
+
214
+ SolidusPaypalCommercePlatform.addPayment = async function(paypal_amount, payment_method_id, data, email) {
215
+ const response = await fetch(
216
+ `/api/checkouts/${SolidusPaypalCommercePlatform.current_order_id}/payments`, {
217
+ method: 'POST',
218
+ headers: {
219
+ ...authHeader(),
220
+ 'Content-Type': 'application/json'
221
+ },
222
+ body: JSON.stringify({
223
+ order_token: SolidusPaypalCommercePlatform.current_order_token,
224
+ payment: {
225
+ amount: paypal_amount,
226
+ payment_method_id: payment_method_id,
227
+ source_attributes: {
228
+ paypal_order_id: data.orderID,
229
+ paypal_email: email,
230
+ paypal_funding_source: SolidusPaypalCommercePlatform.fundingSource
231
+ }
232
+ }
233
+ })
234
+ })
235
+
236
+ if (!response.ok) {
237
+ SolidusPaypalCommercePlatform.hideOverlay()
238
+ alert('There were some problems with your payment');
239
+ }
240
+ }
241
+
242
+ SolidusPaypalCommercePlatform.updateAddress = async function(payload) {
243
+ var shipping = payload.purchase_units[0].shipping
244
+ if (!shipping) return Promise.resolve({})
245
+
246
+ var updated_address = shipping.address
247
+
248
+ const response = await fetch(
249
+ '/solidus_paypal_commerce_platform/update_address', {
250
+ method: 'POST',
251
+ headers: {
252
+ ...authHeader(),
253
+ 'Content-Type': 'application/json'
254
+ },
255
+ body: JSON.stringify({
256
+ address: {
257
+ updated_address: updated_address,
258
+ recipient: payload.payer
259
+ },
260
+ order_id: SolidusPaypalCommercePlatform.current_order_id,
261
+ order_token: SolidusPaypalCommercePlatform.current_order_token
262
+ }),
263
+ }
264
+ )
265
+
266
+ if (!response.ok) {
267
+ SolidusPaypalCommercePlatform.hideOverlay()
268
+ const message = await response.text()
269
+ console.error('There were some problems with your payment address - ', message);
270
+ alert('There were some problems with your payment address - ' + message)
271
+ }
272
+ }
@@ -1,3 +1,10 @@
1
1
  //= require spree/frontend/solidus_paypal_commerce_platform/namespace
2
2
  //= require spree/frontend/solidus_paypal_commerce_platform/button_actions
3
3
  //= require spree/frontend/solidus_paypal_commerce_platform/buttons
4
+ //= require_self
5
+
6
+ Object.assign(SolidusPaypalCommercePlatform, {
7
+ current_order_id: null,
8
+ current_order_token: null,
9
+ api_key: null,
10
+ })
@@ -7,7 +7,7 @@ module SolidusPaypalCommercePlatform
7
7
 
8
8
  def show
9
9
  authorize! :show, @order, order_token
10
- order_request = @payment_method.gateway.create_order(@order, @payment_method.auto_capture?)
10
+ order_request = @payment_method.gateway.create_order(@order, @payment_method.auto_capture)
11
11
 
12
12
  render json: order_request, status: order_request.status_code
13
13
  end
@@ -9,13 +9,14 @@
9
9
  <input type="hidden" name="payment_source[<%= payment_method.id %>][paypal_funding_source]" id="payments_source_paypal_funding_source">
10
10
 
11
11
  <script>
12
- Spree.current_order_id = "<%= @order.number %>"
13
- Spree.current_order_token = "<%= @order.guest_token %>"
12
+ SolidusPaypalCommercePlatform.api_key = "<%= spree_current_user.try(:spree_api_key) %>"
13
+ SolidusPaypalCommercePlatform.current_order_id = "<%= @order.number %>"
14
+ SolidusPaypalCommercePlatform.current_order_token = "<%= @order.guest_token %>"
14
15
  </script>
15
16
 
16
17
  <% unless payment_method.render_only_venmo_standalone? %>
17
18
  <script>
18
- $( document ).ready(function() {
19
+ window.addEventListener('DOMContentLoaded', () => {
19
20
  SolidusPaypalCommercePlatform.renderButton("<%= payment_method.id %>",<%= raw payment_method.button_style.to_json %>)
20
21
  })
21
22
  </script>
@@ -23,7 +24,7 @@
23
24
 
24
25
  <% if payment_method.venmo_standalone_enabled? %>
25
26
  <script>
26
- $( document ).ready(function() {
27
+ window.addEventListener('DOMContentLoaded', () => {
27
28
  SolidusPaypalCommercePlatform.renderVenmoStandalone("<%= payment_method.id %>",<%= raw payment_method.button_style.to_json %>)
28
29
  })
29
30
  </script>
@@ -6,10 +6,11 @@
6
6
  <div data-pp-message data-pp-placement="cart" data-pp-amount="<%= @order.total %>"></div>
7
7
 
8
8
  <script>
9
- Spree.current_order_id = "<%= @order.number %>"
10
- Spree.current_order_token = "<%= @order.guest_token %>"
9
+ SolidusPaypalCommercePlatform.api_key = "<%= spree_current_user.try(:spree_api_key) %>"
10
+ SolidusPaypalCommercePlatform.current_order_id = "<%= @order.number %>"
11
+ SolidusPaypalCommercePlatform.current_order_token = "<%= @order.guest_token %>"
11
12
  SolidusPaypalCommercePlatform.checkout_url = "<%= checkout_url %>"
12
- $( document ).ready(function() {
13
+ window.addEventListener('DOMContentLoaded', () => {
13
14
  SolidusPaypalCommercePlatform.renderCartButton("<%= payment_method.id %>",<%= raw payment_method.button_style.to_json %>)
14
15
  })
15
16
  </script>
@@ -7,7 +7,7 @@
7
7
 
8
8
  <script>
9
9
  SolidusPaypalCommercePlatform.checkout_url = "<%= checkout_url %>"
10
- $( document ).ready(function() {
10
+ window.addEventListener('DOMContentLoaded', () => {
11
11
  SolidusPaypalCommercePlatform.renderProductButton("<%= payment_method.id %>",<%= raw payment_method.button_style.to_json %>)
12
12
  })
13
13
  </script>
@@ -1,6 +1,8 @@
1
1
  <% currency = @order ? @order.currency : current_pricing_options.currency %>
2
2
 
3
- <script
4
- src="<%= payment_method.javascript_sdk_url(order: @order, currency: currency) %>"
3
+ <script
4
+ src="<%= payment_method.javascript_sdk_url(order: @order, currency: currency) %>"
5
5
  data-partner-attribution-id="<%= SolidusPaypalCommercePlatform.config.partner_code %>">
6
+
7
+ SolidusPaypalCommercePlatform.api_key = <%= spree_current_user&.spree_api_key.to_json %>
6
8
  </script>
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SolidusPaypalCommercePlatform
4
- VERSION = '0.7.0'
4
+ VERSION = '1.0.0.beta1'
5
5
  end
@@ -23,7 +23,7 @@ Gem::Specification.new do |spec|
23
23
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
24
24
  files = Dir.chdir(__dir__) { `git ls-files -z`.split("\x0") }
25
25
 
26
- spec.files = files.grep_v(%r{^(test|spec|features)/})
26
+ spec.files = files # don't exclude specs, they need to be copied to the target app
27
27
  spec.bindir = "exe"
28
28
  spec.executables = files.grep(%r{^exe/}) { |f| File.basename(f) }
29
29
  spec.require_paths = ["lib"]
@@ -36,6 +36,5 @@ Gem::Specification.new do |spec|
36
36
 
37
37
  spec.add_dependency 'paypalhttp'
38
38
 
39
- spec.add_development_dependency 'cuprite'
40
39
  spec.add_development_dependency 'solidus_dev_support', '~> 2.5'
41
40
  end
@@ -0,0 +1,121 @@
1
+ {
2
+ "id": "WH-COC11055RA711503B-4YM959094A144403T",
3
+ "create_time": "2018-04-16T21:21:49.000Z",
4
+ "resource_type": "checkout-order",
5
+ "event_type": "CHECKOUT.ORDER.COMPLETED",
6
+ "summary": "Checkout Order Completed",
7
+ "resource": {
8
+ "update_time": "2018-04-01T21:20:49Z",
9
+ "create_time": "2018-04-01T21:18:49Z",
10
+ "purchase_units": [
11
+ {
12
+ "reference_id": "d9f80740-38f0-11e8-b467-0ed5f89f718b",
13
+ "amount": {
14
+ "currency_code": "USD",
15
+ "value": "100.00"
16
+ },
17
+ "payee": {
18
+ "email_address": "seller@example.com"
19
+ },
20
+ "shipping": {
21
+ "method": "United States Postal Service",
22
+ "address": {
23
+ "address_line_1": "2211 N First Street",
24
+ "address_line_2": "Building 17",
25
+ "admin_area_2": "San Jose",
26
+ "admin_area_1": "CA",
27
+ "postal_code": "95131",
28
+ "country_code": "US"
29
+ }
30
+ },
31
+ "payments": {
32
+ "captures": [
33
+ {
34
+ "id": "3C679366HH908993F",
35
+ "status": "COMPLETED",
36
+ "amount": {
37
+ "currency_code": "USD",
38
+ "value": "100.00"
39
+ },
40
+ "seller_protection": {
41
+ "status": "ELIGIBLE",
42
+ "dispute_categories": [
43
+ "ITEM_NOT_RECEIVED",
44
+ "UNAUTHORIZED_TRANSACTION"
45
+ ]
46
+ },
47
+ "final_capture": true,
48
+ "seller_receivable_breakdown": {
49
+ "gross_amount": {
50
+ "currency_code": "USD",
51
+ "value": "100.00"
52
+ },
53
+ "paypal_fee": {
54
+ "currency_code": "USD",
55
+ "value": "3.00"
56
+ },
57
+ "net_amount": {
58
+ "currency_code": "USD",
59
+ "value": "97.00"
60
+ }
61
+ },
62
+ "create_time": "2018-04-01T21:20:49Z",
63
+ "update_time": "2018-04-01T21:20:49Z",
64
+ "links": [
65
+ {
66
+ "href": "https://api.paypal.com/v2/payments/captures/3C679366HH908993F",
67
+ "rel": "self",
68
+ "method": "GET"
69
+ },
70
+ {
71
+ "href": "https://api.paypal.com/v2/payments/captures/3C679366HH908993F/refund",
72
+ "rel": "refund",
73
+ "method": "POST"
74
+ }
75
+ ]
76
+ }
77
+ ]
78
+ }
79
+ }
80
+ ],
81
+ "links": [
82
+ {
83
+ "href": "https://api.paypal.com/v2/checkout/orders/5O190127TN364715T",
84
+ "rel": "self",
85
+ "method": "GET"
86
+ }
87
+ ],
88
+ "id": "5O190127TN364715T",
89
+ "gross_amount": {
90
+ "currency_code": "USD",
91
+ "value": "100.00"
92
+ },
93
+ "intent": "CAPTURE",
94
+ "payer": {
95
+ "name": {
96
+ "given_name": "John",
97
+ "surname": "Doe"
98
+ },
99
+ "email_address": "buyer@example.com",
100
+ "payer_id": "QYR5Z8XDVJNXQ"
101
+ },
102
+ "status": "COMPLETED"
103
+ },
104
+ "links": [
105
+ {
106
+ "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-COC11055RA711503B-4YM959094A144403T",
107
+ "rel": "self",
108
+ "method": "GET",
109
+ "encType": "application/json"
110
+ },
111
+ {
112
+ "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-COC11055RA711503B-4YM959094A144403T/resend",
113
+ "rel": "resend",
114
+ "method": "POST",
115
+ "encType": "application/json"
116
+ }
117
+ ],
118
+ "event_version": "1.0",
119
+ "zts": 1494957670,
120
+ "resource_version": "2.0"
121
+ }
@@ -0,0 +1,121 @@
1
+ {
2
+ "id": "WH-COC11055RA711503B-4YM959094A144403T",
3
+ "create_time": "2018-04-16T21:21:49.000Z",
4
+ "resource_type": "checkout-order",
5
+ "event_type": "CHECKOUT.ORDER.COMPLETED",
6
+ "summary": "Checkout Order Completed",
7
+ "resource": {
8
+ "update_time": "2018-04-01T21:20:49Z",
9
+ "create_time": "2018-04-01T21:18:49Z",
10
+ "purchase_units": [
11
+ {
12
+ "reference_id": "d9f80740-38f0-11e8-b467-0ed5f89f718b",
13
+ "amount": {
14
+ "currency_code": "USD",
15
+ "value": "100.00"
16
+ },
17
+ "payee": {
18
+ "email_address": "seller@example.com"
19
+ },
20
+ "shipping": {
21
+ "method": "United States Postal Service",
22
+ "address": {
23
+ "address_line_1": "2211 N First Street",
24
+ "address_line_2": "Building 17",
25
+ "admin_area_2": "San Jose",
26
+ "admin_area_1": "CA",
27
+ "postal_code": "95131",
28
+ "country_code": "US"
29
+ }
30
+ },
31
+ "payments": {
32
+ "captures": [
33
+ {
34
+ "id": "3C679366HH908993F",
35
+ "status": "COMPLETED",
36
+ "amount": {
37
+ "currency_code": "USD",
38
+ "value": "100.00"
39
+ },
40
+ "seller_protection": {
41
+ "status": "ELIGIBLE",
42
+ "dispute_categories": [
43
+ "ITEM_NOT_RECEIVED",
44
+ "UNAUTHORIZED_TRANSACTION"
45
+ ]
46
+ },
47
+ "final_capture": true,
48
+ "seller_receivable_breakdown": {
49
+ "gross_amount": {
50
+ "currency_code": "USD",
51
+ "value": "100.00"
52
+ },
53
+ "paypal_fee": {
54
+ "currency_code": "USD",
55
+ "value": "3.00"
56
+ },
57
+ "net_amount": {
58
+ "currency_code": "USD",
59
+ "value": "97.00"
60
+ }
61
+ },
62
+ "create_time": "2018-04-01T21:20:49Z",
63
+ "update_time": "2018-04-01T21:20:49Z",
64
+ "links": [
65
+ {
66
+ "href": "https://api.paypal.com/v2/payments/captures/3C679366HH908993F",
67
+ "rel": "self",
68
+ "method": "GET"
69
+ },
70
+ {
71
+ "href": "https://api.paypal.com/v2/payments/captures/3C679366HH908993F/refund",
72
+ "rel": "refund",
73
+ "method": "POST"
74
+ }
75
+ ]
76
+ }
77
+ ]
78
+ }
79
+ }
80
+ ],
81
+ "links": [
82
+ {
83
+ "href": "https://api.paypal.com/v2/checkout/orders/5O190127TN364715T",
84
+ "rel": "self",
85
+ "method": "GET"
86
+ }
87
+ ],
88
+ "id": "5O190127TN364715T",
89
+ "gross_amount": {
90
+ "currency_code": "USD",
91
+ "value": "100.00"
92
+ },
93
+ "intent": "CAPTURE",
94
+ "payer": {
95
+ "name": {
96
+ "given_name": "John",
97
+ "surname": "Doe"
98
+ },
99
+ "email_address": "buyer@example.com",
100
+ "payer_id": "QYR5Z8XDVJNXQ"
101
+ },
102
+ "status": "COMPLETED"
103
+ },
104
+ "links": [
105
+ {
106
+ "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-COC11055RA711503B-4YM959094A144403T",
107
+ "rel": "self",
108
+ "method": "GET",
109
+ "encType": "application/json"
110
+ },
111
+ {
112
+ "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-COC11055RA711503B-4YM959094A144403T/resend",
113
+ "rel": "resend",
114
+ "method": "POST",
115
+ "encType": "application/json"
116
+ }
117
+ ],
118
+ "event_version": "1.0",
119
+ "zts": 1494957670,
120
+ "resource_version": "2.0"
121
+ }
@@ -0,0 +1,50 @@
1
+ {
2
+ "id": "WH-7Y7254563A4550640-11V2185806837105M",
3
+ "create_time": "2015-02-17T18:51:33Z",
4
+ "resource_type": "capture",
5
+ "event_type": "PAYMENT.CAPTURE.COMPLETED",
6
+ "summary": "Payment completed for $ 7.47 USD",
7
+ "resource": {
8
+ "parent_payment": "PAY-3YE025760C441402AKTRY2PQ",
9
+ "update_time": "2015-02-17T18:50:45Z",
10
+ "amount": {
11
+ "total": "7.47",
12
+ "currency": "USD"
13
+ },
14
+ "create_time": "2015-02-17T18:50:44Z",
15
+ "links": [
16
+ {
17
+ "href": "https://api.paypal.com/v1/payments/capture/42311647XV020574X",
18
+ "rel": "self",
19
+ "method": "GET"
20
+ },
21
+ {
22
+ "href": "https://api.paypal.com/v1/payments/capture/42311647XV020574X/refund",
23
+ "rel": "refund",
24
+ "method": "POST"
25
+ },
26
+ {
27
+ "href": "https://api.paypal.com/v1/payments/payment/PAY-3YE025760C441402AKTRY2PQ",
28
+ "rel": "parent_payment",
29
+ "method": "GET"
30
+ }
31
+ ],
32
+ "id": "42311647XV020574X",
33
+ "state": "completed"
34
+ },
35
+ "links": [
36
+ {
37
+ "href": "https://api.paypal.com/v1/notifications/webhooks-events/WH-7Y7254563A4550640-11V2185806837105M",
38
+ "rel": "self",
39
+ "method": "GET",
40
+ "encType": "application/json"
41
+ },
42
+ {
43
+ "href": "https://api.paypal.com/v1/notifications/webhooks-events/WH-7Y7254563A4550640-11V2185806837105M/resend",
44
+ "rel": "resend",
45
+ "method": "POST",
46
+ "encType": "application/json"
47
+ }
48
+ ],
49
+ "event_version": "1.0"
50
+ }