pay_with_amazon 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,806 @@
1
+ require 'uri'
2
+ require 'net/http'
3
+ require 'net/https'
4
+ require 'base64'
5
+ require 'openssl'
6
+ require 'time'
7
+
8
+ module PayWithAmazon
9
+
10
+ # Pay with Amazon API
11
+ #
12
+ # This client allows you to make all the necessary API calls
13
+ # to integrate with Login and Pay with Amazon. This client only
14
+ # uses the standard Ruby library and is not dependant on Rails.
15
+ class Client
16
+
17
+ MAX_RETRIES = 4
18
+
19
+ attr_reader(
20
+ :merchant_id,
21
+ :access_key,
22
+ :secret_key,
23
+ :sandbox,
24
+ :currency_code,
25
+ :region,
26
+ :platform_id,
27
+ :throttle,
28
+ :application_name,
29
+ :application_version)
30
+
31
+ attr_accessor(
32
+ :sandbox,
33
+ :proxy_addr,
34
+ :proxy_port,
35
+ :proxy_user,
36
+ :proxy_pass)
37
+
38
+ # API keys are located at:
39
+ # @see htps://sellercentral.amazon.com
40
+ # @param merchant_id [String]
41
+ # @param access_key [String]
42
+ # @param secret_key [String]
43
+ # @optional sandbox [Boolean] Default: false
44
+ # @optional currency_code [Symbol] Default: :usd
45
+ # @optional region [Symbol] Default: :na
46
+ # @optional platform_id [String] Default: nil
47
+ # @optional throttle [Boolean]
48
+ # @optional application_name [String]
49
+ # @optional application_version [String]
50
+ # @optional proxy_addr [String]
51
+ # @optional proxy_port [String]
52
+ # @optional proxy_user [String]
53
+ # @optional proxy_pass [String]
54
+ def initialize(
55
+ merchant_id,
56
+ access_key,
57
+ secret_key,
58
+ sandbox: false,
59
+ currency_code: :usd,
60
+ region: :na,
61
+ platform_id: nil,
62
+ throttle: true,
63
+ application_name: nil,
64
+ application_version: nil,
65
+ proxy_addr: :ENV,
66
+ proxy_port: nil,
67
+ proxy_user: nil,
68
+ proxy_pass: nil)
69
+
70
+ @merchant_id = merchant_id
71
+ @access_key = access_key
72
+ @secret_key = secret_key
73
+ @currency_code = currency_code.to_s.upcase
74
+ @sandbox = sandbox
75
+ @sandbox_str = @sandbox ? 'OffAmazonPayments_Sandbox' : 'OffAmazonPayments'
76
+ @region = region
77
+ @mws_endpoint = region_hash[@region] ? region_hash[@region] : raise("Invalid Region Code. (#{@region})")
78
+ @platform_id = platform_id
79
+ @throttle = throttle
80
+ @application_name = application_name
81
+ @application_version = application_version
82
+ @proxy_addr = proxy_addr
83
+ @proxy_port = proxy_port
84
+ @proxy_user = proxy_user
85
+ @proxy_pass = proxy_pass
86
+
87
+ @default_hash = {
88
+ 'AWSAccessKeyId' => @access_key,
89
+ 'SignatureMethod' => 'HmacSHA256',
90
+ 'SignatureVersion' => '2',
91
+ 'Timestamp' => Time.now.utc.iso8601,
92
+ 'Version' => PayWithAmazon::API_VERSION
93
+ }
94
+
95
+ @default_hash['PlatformId'] = @platform_id if @platform_id
96
+ end
97
+
98
+ # Returns the operational status of the Off-Amazon Payments API section
99
+ # The GetServiceStatus operation returns the operational status of the Off-Amazon Payments API
100
+ # section of Amazon Marketplace Web Service (Amazon MWS). Status values are GREEN, GREEN_I, YELLOW, and RED.
101
+ # @see http://docs.developer.amazonservices.com/en_US/off_amazon_payments/OffAmazonPayments_GetServiceStatus.html
102
+ def get_service_status
103
+ parameters = {
104
+ 'Action' => 'GetServiceStatus'
105
+ }
106
+
107
+ operation(parameters, {})
108
+ end
109
+
110
+ # Creates an order reference for the given object
111
+ # @see http://docs.developer.amazonservices.com/en_US/off_amazon_payments/OffAmazonPayments_CreateOrderReferenceForId.html
112
+ # @param id [String]
113
+ # @param id_type [String]
114
+ # @optional inherit_shipping_address [Boolean]
115
+ # @optional confirm_now [Boolean]
116
+ # @optional amount [String] (required when confirm_now is set to true)
117
+ # @optional currency_code [String]
118
+ # @optional platform_id [String]
119
+ # @optional seller_note [String]
120
+ # @optional seller_order_id [String]
121
+ # @optional store_name [String]
122
+ # @optional custom_information [String]
123
+ # @optional merchant_id [String]
124
+ # @optional mws_auth_token [String]
125
+ def create_order_reference_for_id(
126
+ id,
127
+ id_type,
128
+ inherit_shipping_address: nil,
129
+ confirm_now: nil,
130
+ amount: nil,
131
+ currency_code: @currency_code,
132
+ platform_id: nil,
133
+ seller_note: nil,
134
+ seller_order_id: nil,
135
+ store_name: nil,
136
+ custom_information: nil,
137
+ merchant_id: @merchant_id,
138
+ mws_auth_token: nil)
139
+
140
+ parameters = {
141
+ 'Action' => 'CreateOrderReferenceForId',
142
+ 'SellerId' => merchant_id,
143
+ 'Id' => id,
144
+ 'IdType' => id_type
145
+ }
146
+
147
+ optional = {
148
+ 'InheritShippingAddress' => inherit_shipping_address,
149
+ 'ConfirmNow' => confirm_now,
150
+ 'OrderReferenceAttributes.OrderTotal.Amount' => amount,
151
+ 'OrderReferenceAttributes.OrderTotal.CurrencyCode' => currency_code,
152
+ 'OrderReferenceAttributes.PlatformId' => platform_id,
153
+ 'OrderReferenceAttributes.SellerNote' => seller_note,
154
+ 'OrderReferenceAttributes.SellerOrderAttributes.SellerOrderId' => seller_order_id,
155
+ 'OrderReferenceAttributes.SellerOrderAttributes.StoreName' => store_name,
156
+ 'OrderReferenceAttributes.SellerOrderAttributes.CustomInformation' => custom_information,
157
+ 'MWSAuthToken' => mws_auth_token
158
+ }
159
+
160
+ operation(parameters, optional)
161
+ end
162
+
163
+ # Returns details about the Billing Agreement object and its current state
164
+ # @see http://docs.developer.amazonservices.com/en_US/off_amazon_payments/OffAmazonPayments_GetBillingAgreementDetails.html
165
+ # @param amazon_billing_agreement_id [String]
166
+ # @optional address_consent_token [String]
167
+ # @optional merchant_id [String]
168
+ # @optional mws_auth_token [String]
169
+ def get_billing_agreement_details(
170
+ amazon_billing_agreement_id,
171
+ address_consent_token: nil,
172
+ merchant_id: @merchant_id,
173
+ mws_auth_token: nil)
174
+
175
+ parameters = {
176
+ 'Action' => 'GetBillingAgreementDetails',
177
+ 'SellerId' => merchant_id,
178
+ 'AmazonBillingAgreementId' => amazon_billing_agreement_id
179
+ }
180
+
181
+ optional = {
182
+ 'AddressConsentToken' => address_consent_token,
183
+ 'MWSAuthToken' => mws_auth_token
184
+ }
185
+
186
+ operation(parameters, optional)
187
+ end
188
+
189
+ # Sets billing agreement details such as a description of the agreement
190
+ # and other information about the seller.
191
+ # @see http://docs.developer.amazonservices.com/en_US/off_amazon_payments/OffAmazonPayments_SetBillingAgreementDetails.html
192
+ # @param amazon_billing_agreement_id [String]
193
+ # @optional platform_id [String]
194
+ # @optional seller_note [String]
195
+ # @optional seller_billing_agreement_id [String]
196
+ # @optional custom_information [String]
197
+ # @optional store_name [String]
198
+ # @optional merchant_id [String]
199
+ # @optional mws_auth_token [String]
200
+ def set_billing_agreement_details(
201
+ amazon_billing_agreement_id,
202
+ platform_id: nil,
203
+ seller_note: nil,
204
+ seller_billing_agreement_id: nil,
205
+ custom_information: nil,
206
+ store_name: nil,
207
+ merchant_id: @merchant_id,
208
+ mws_auth_token: nil)
209
+
210
+ parameters = {
211
+ 'Action' => 'SetBillingAgreementDetails',
212
+ 'SellerId' => merchant_id,
213
+ 'AmazonBillingAgreementId' => amazon_billing_agreement_id
214
+ }
215
+
216
+ optional = {
217
+ 'BillingAgreementAttributes.PlatformId' => platform_id,
218
+ 'BillingAgreementAttributes.SellerNote' => seller_note,
219
+ 'BillingAgreementAttributes.SellerBillingAgreementAttributes.SellerBillingAgreementId' => seller_billing_agreement_id,
220
+ 'BillingAgreementAttributes.SellerBillingAgreementAttributes.CustomInformation' => custom_information,
221
+ 'BillingAgreementAttributes.SellerBillingAgreementAttributes.StoreName' => store_name,
222
+ 'MWSAuthToken' => mws_auth_token
223
+ }
224
+
225
+ operation(parameters, optional)
226
+ end
227
+
228
+ # Confirms that the billing agreement is free of constraints and all
229
+ # required information has been set on the billing agreement
230
+ # @see http://docs.developer.amazonservices.com/en_US/off_amazon_payments/OffAmazonPayments_ConfirmBillingAgreement.html
231
+ # @param amazon_billing_agreement_id [String]
232
+ # @optional merchant_id [String]
233
+ # @optional mws_auth_token [String]
234
+ def confirm_billing_agreement(
235
+ amazon_billing_agreement_id,
236
+ merchant_id: @merchant_id,
237
+ mws_auth_token: nil)
238
+
239
+ parameters = {
240
+ 'Action' => 'ConfirmBillingAgreement',
241
+ 'SellerId' => merchant_id,
242
+ 'AmazonBillingAgreementId' => amazon_billing_agreement_id
243
+ }
244
+
245
+ optional = {
246
+ 'MWSAuthToken' => mws_auth_token
247
+ }
248
+
249
+ operation(parameters, optional)
250
+ end
251
+
252
+ # Validates the status of the BillingAgreement object and the payment
253
+ # method associated with it
254
+ # @see http://docs.developer.amazonservices.com/en_US/off_amazon_payments/OffAmazonPayments_ValidateBillingAgreement.html
255
+ # @param amazon_billing_agreement_id [String]
256
+ # @optional merchant_id [String]
257
+ # @optional mws_auth_token [String]
258
+ def validate_billing_agreement(
259
+ amazon_billing_agreement_id,
260
+ merchant_id: @merchant_id,
261
+ mws_auth_token: nil)
262
+
263
+ parameters = {
264
+ 'Action' => 'ValidateBillingAgreement',
265
+ 'SellerId' => merchant_id,
266
+ 'AmazonBillingAgreementId' => amazon_billing_agreement_id
267
+ }
268
+
269
+ optional = {
270
+ 'MWSAuthToken' => mws_auth_token
271
+ }
272
+
273
+ operation(parameters, optional)
274
+ end
275
+
276
+ # Reserves a specified amount against the payment method(s) stored in the
277
+ # billing agreement
278
+ # @see http://docs.developer.amazonservices.com/en_US/off_amazon_payments/OffAmazonPayments_AuthorizeOnBillingAgreement.html
279
+ # @param amazon_billing_agreement_id [String]
280
+ # @param authorization_reference_id [String]
281
+ # @param amount [String]
282
+ # @optional currency_code [String]
283
+ # @optional seller_authorization_note [String]
284
+ # @optional transaction_timeout [Integer]
285
+ # @optional capture_now [Boolean]
286
+ # @optional soft_descriptor [String]
287
+ # @optional seller_note [String]
288
+ # @optional platform_id [String]
289
+ # @optional custom_information [String]
290
+ # @optional seller_order_id [String]
291
+ # @optional store_name [String]
292
+ # @optional inherit_shipping_address [Boolean]
293
+ # @optional merchant_id [String]
294
+ # @optional mws_auth_token [String]
295
+ def authorize_on_billing_agreement(
296
+ amazon_billing_agreement_id,
297
+ authorization_reference_id,
298
+ amount,
299
+ currency_code: @currency_code,
300
+ seller_authorization_note: nil,
301
+ transaction_timeout: nil,
302
+ capture_now: false,
303
+ soft_descriptor: nil,
304
+ seller_note: nil,
305
+ platform_id: nil,
306
+ custom_information: nil,
307
+ seller_order_id: nil,
308
+ store_name: nil,
309
+ inherit_shipping_adderess: nil,
310
+ merchant_id: @merchant_id,
311
+ mws_auth_token: nil)
312
+
313
+ parameters = {
314
+ 'Action' => 'AuthorizeOnBillingAgreement',
315
+ 'SellerId' => merchant_id,
316
+ 'AmazonBillingAgreementId' => amazon_billing_agreement_id,
317
+ 'AuthorizationReferenceId' => authorization_reference_id,
318
+ 'AuthorizationAmount.Amount' => amount,
319
+ 'AuthorizationAmount.CurrencyCode' => currency_code
320
+ }
321
+
322
+ optional = {
323
+ 'SellerAuthorizationNote' => seller_authorization_note,
324
+ 'TransactionTimeout' => transaction_timeout,
325
+ 'CaptureNow' => capture_now,
326
+ 'SoftDescriptor' => soft_descriptor,
327
+ 'SellerNote' => seller_note,
328
+ 'PlatformId' => platform_id,
329
+ 'SellerOrderAttributes.CustomInformation' => custom_information,
330
+ 'SellerOrderAttributes.SellerOrderId' => seller_order_id,
331
+ 'SellerOrderAttributes.StoreName' => store_name,
332
+ 'InheritShippingAddress' => inherit_shipping_adderess,
333
+ 'MWSAuthToken' => mws_auth_token
334
+ }
335
+
336
+ operation(parameters, optional)
337
+ end
338
+
339
+ # Confirms that you want to terminate the billing agreement with the buyer
340
+ # and that you do not expect to create any new order references or
341
+ # authorizations on this billing agreement
342
+ # @see http://docs.developer.amazonservices.com/en_US/off_amazon_payments/OffAmazonPayments_CloseBillingAgreement.html
343
+ # @param amazon_billing_agreement_id [String]
344
+ # @optional closure_reason [String]
345
+ # @optional merchant_id [String]
346
+ # @optional mws_auth_token [String]
347
+ def close_billing_agreement(
348
+ amazon_billing_agreement_id,
349
+ closure_reason: nil,
350
+ merchant_id: @merchant_id,
351
+ mws_auth_token: nil)
352
+
353
+ parameters = {
354
+ 'Action' => 'CloseBillingAgreement',
355
+ 'SellerId' => merchant_id,
356
+ 'AmazonBillingAgreementId' => amazon_billing_agreement_id
357
+ }
358
+
359
+ optional = {
360
+ 'ClosureReason' => closure_reason,
361
+ 'MWSAuthToken' => mws_auth_token
362
+ }
363
+
364
+ operation(parameters, optional)
365
+ end
366
+
367
+ # Returns details about the Order Reference object and its current state
368
+ # @see http://docs.developer.amazonservices.com/en_US/off_amazon_payments/OffAmazonPayments_GetOrderReferenceDetails.html
369
+ # @param amazon_order_reference_id [String]
370
+ # @optional address_consent_token [String]
371
+ # @optional merchant_id [String]
372
+ # @optional mws_auth_token [String]
373
+ def get_order_reference_details(
374
+ amazon_order_reference_id,
375
+ address_consent_token: nil,
376
+ merchant_id: @merchant_id,
377
+ mws_auth_token: nil)
378
+
379
+ parameters = {
380
+ 'Action' => 'GetOrderReferenceDetails',
381
+ 'SellerId' => merchant_id,
382
+ 'AmazonOrderReferenceId' => amazon_order_reference_id
383
+ }
384
+
385
+ optional = {
386
+ 'AddressConsentToken' => address_consent_token,
387
+ 'MWSAuthToken' => mws_auth_token
388
+ }
389
+
390
+ operation(parameters, optional)
391
+ end
392
+
393
+ # Sets order reference details such as the order total and a description
394
+ # for the order
395
+ # @see http://docs.developer.amazonservices.com/en_US/off_amazon_payments/OffAmazonPayments_SetOrderReferenceDetails.html
396
+ # @param amazon_order_reference_id [String]
397
+ # @param amount [String]
398
+ # @optional currency_code [String]
399
+ # @optional platform_id [String]
400
+ # @optional seller_note [String]
401
+ # @optional seller_order_id [String]
402
+ # @optional store_name [String]
403
+ # @optional custom_information [String]
404
+ # @optional merchant_id [String]
405
+ # @optional mws_auth_token [String]
406
+ def set_order_reference_details(
407
+ amazon_order_reference_id,
408
+ amount,
409
+ currency_code: @currency_code,
410
+ platform_id: nil,
411
+ seller_note: nil,
412
+ seller_order_id: nil,
413
+ store_name: nil,
414
+ custom_information: nil,
415
+ merchant_id: @merchant_id,
416
+ mws_auth_token: nil)
417
+
418
+ parameters = {
419
+ 'Action' => 'SetOrderReferenceDetails',
420
+ 'SellerId' => merchant_id,
421
+ 'AmazonOrderReferenceId' => amazon_order_reference_id,
422
+ 'OrderReferenceAttributes.OrderTotal.Amount' => amount,
423
+ 'OrderReferenceAttributes.OrderTotal.CurrencyCode' => currency_code
424
+ }
425
+
426
+ optional = {
427
+ 'OrderReferenceAttributes.PlatformId' => platform_id,
428
+ 'OrderReferenceAttributes.SellerNote' => seller_note,
429
+ 'OrderReferenceAttributes.SellerOrderAttributes.SellerOrderId' => seller_order_id,
430
+ 'OrderReferenceAttributes.SellerOrderAttributes.StoreName' => store_name,
431
+ 'OrderReferenceAttributes.SellerOrderAttributes.CustomInformation' => custom_information,
432
+ 'MWSAuthToken' => mws_auth_token
433
+ }
434
+
435
+ operation(parameters, optional)
436
+ end
437
+
438
+ # Confirms that the order reference is free of constraints and all required
439
+ # information has been set on the order reference
440
+ # @see http://docs.developer.amazonservices.com/en_US/off_amazon_payments/OffAmazonPayments_ConfirmOrderReference.html
441
+ # @param amazon_order_reference_id [String]
442
+ # @optional merchant_id [String]
443
+ # @optional mws_auth_token [String]
444
+ def confirm_order_reference(
445
+ amazon_order_reference_id,
446
+ merchant_id: @merchant_id,
447
+ mws_auth_token: nil)
448
+
449
+ parameters = {
450
+ 'Action' => 'ConfirmOrderReference',
451
+ 'SellerId' => merchant_id,
452
+ 'AmazonOrderReferenceId' => amazon_order_reference_id
453
+ }
454
+
455
+ optional = {
456
+ 'MWSAuthToken' => mws_auth_token
457
+ }
458
+
459
+ operation(parameters, optional)
460
+ end
461
+
462
+ # Cancels a previously confirmed order reference
463
+ # @see http://docs.developer.amazonservices.com/en_US/off_amazon_payments/OffAmazonPayments_CancelOrderReference.html
464
+ # @param amazon_order_reference_id [String]
465
+ # @optional cancelation_reason [String]
466
+ # @optional merchant_id [String]
467
+ # @optional mws_auth_token [String]
468
+ def cancel_order_reference(
469
+ amazon_order_reference_id,
470
+ cancelation_reason: nil,
471
+ merchant_id: @merchant_id,
472
+ mws_auth_token: nil)
473
+
474
+ parameters = {
475
+ 'Action' => 'CancelOrderReference',
476
+ 'SellerId' => merchant_id,
477
+ 'AmazonOrderReferenceId' => amazon_order_reference_id
478
+ }
479
+
480
+ optional = {
481
+ 'CancelationReason' => cancelation_reason,
482
+ 'MWSAuthToken' => mws_auth_token
483
+ }
484
+
485
+ operation(parameters, optional)
486
+ end
487
+
488
+ # Reserves a specified amount against the payment method(s) stored in the
489
+ # order reference
490
+ # @see http://docs.developer.amazonservices.com/en_US/off_amazon_payments/OffAmazonPayments_Authorize.html
491
+ # @param amazon_order_reference_id [String]
492
+ # @param authorization_reference_id [String]
493
+ # @param amount [String]
494
+ # @optional currency_code [String]
495
+ # @optional seller_authorization_note [String]
496
+ # @optional transaction_timeout [Integer]
497
+ # @optional capture_now [Boolean]
498
+ # @optional soft_descriptor [String]
499
+ # @optional merchant_id [String]
500
+ # @optional mws_auth_token [String]
501
+ def authorize(
502
+ amazon_order_reference_id,
503
+ authorization_reference_id,
504
+ amount,
505
+ currency_code: @currency_code,
506
+ seller_authorization_note: nil,
507
+ transaction_timeout: nil,
508
+ capture_now: nil,
509
+ soft_descriptor: nil,
510
+ merchant_id: @merchant_id,
511
+ mws_auth_token: nil)
512
+
513
+ parameters = {
514
+ 'Action' => 'Authorize',
515
+ 'SellerId' => merchant_id,
516
+ 'AmazonOrderReferenceId' => amazon_order_reference_id,
517
+ 'AuthorizationReferenceId' => authorization_reference_id,
518
+ 'AuthorizationAmount.Amount' => amount,
519
+ 'AuthorizationAmount.CurrencyCode' => currency_code
520
+ }
521
+
522
+ optional = {
523
+ 'SellerAuthorizationNote' => seller_authorization_note,
524
+ 'TransactionTimeout' => transaction_timeout,
525
+ 'CaptureNow' => capture_now,
526
+ 'SoftDescriptor' => soft_descriptor,
527
+ 'MWSAuthToken' => mws_auth_token
528
+ }
529
+
530
+ operation(parameters, optional)
531
+ end
532
+
533
+ # Returns the status of a particular authorization and the total amount
534
+ # captured on the authorization
535
+ # @see http://docs.developer.amazonservices.com/en_US/off_amazon_payments/OffAmazonPayments_GetAuthorizationDetails.html
536
+ # @param amazon_authorization_id [String]
537
+ # @optional merchant_id [String]
538
+ # @optional mws_auth_token [String]
539
+ def get_authorization_details(
540
+ amazon_authorization_id,
541
+ merchant_id: @merchant_id,
542
+ mws_auth_token: nil)
543
+
544
+ parameters = {
545
+ 'Action' => 'GetAuthorizationDetails',
546
+ 'SellerId' => merchant_id,
547
+ 'AmazonAuthorizationId' => amazon_authorization_id
548
+ }
549
+
550
+ optional = {
551
+ 'MWSAuthToken' => mws_auth_token
552
+ }
553
+
554
+ operation(parameters, optional)
555
+ end
556
+
557
+ # Captures funds from an authorized payment instrument.
558
+ # @see http://docs.developer.amazonservices.com/en_US/off_amazon_payments/OffAmazonPayments_Capture.html
559
+ # @param amazon_authorization_id [String]
560
+ # @param capture_reference_id [String]
561
+ # @param amount [String]
562
+ # @optional currency_code [String]
563
+ # @optional seller_capture_note [String]
564
+ # @optional soft_descriptor [String]
565
+ # @optional merchant_id [String]
566
+ # @optional mws_auth_token [String]
567
+ def capture(
568
+ amazon_authorization_id,
569
+ capture_reference_id,
570
+ amount,
571
+ currency_code: @currency_code,
572
+ seller_capture_note: nil,
573
+ soft_descriptor: nil,
574
+ merchant_id: @merchant_id,
575
+ mws_auth_token: nil)
576
+
577
+ parameters = {
578
+ 'Action' => 'Capture',
579
+ 'SellerId' => merchant_id,
580
+ 'AmazonAuthorizationId' => amazon_authorization_id,
581
+ 'CaptureReferenceId' => capture_reference_id,
582
+ 'CaptureAmount.Amount' => amount,
583
+ 'CaptureAmount.CurrencyCode' => currency_code
584
+ }
585
+
586
+ optional = {
587
+ 'SellerCaptureNote' => seller_capture_note,
588
+ 'SoftDescriptor' => soft_descriptor,
589
+ 'MWSAuthToken' => mws_auth_token
590
+ }
591
+
592
+ operation(parameters, optional)
593
+ end
594
+
595
+ # Returns the status of a particular capture and the total amount refunded
596
+ # on the capture
597
+ # @see http://docs.developer.amazonservices.com/en_US/off_amazon_payments/OffAmazonPayments_GetCaptureDetails.html
598
+ # @param amazon_capture_id [String]
599
+ # @optional merchant_id [String]
600
+ # @optional mws_auth_token [String]
601
+ def get_capture_details(
602
+ amazon_capture_id,
603
+ merchant_id: @merchant_id,
604
+ mws_auth_token: nil)
605
+
606
+ parameters = {
607
+ 'Action' => 'GetCaptureDetails',
608
+ 'SellerId' => merchant_id,
609
+ 'AmazonCaptureId' => amazon_capture_id
610
+ }
611
+
612
+ optional = {
613
+ 'MWSAuthToken' => mws_auth_token
614
+ }
615
+
616
+ operation(parameters, optional)
617
+ end
618
+
619
+ # Refunds a previously captured amount
620
+ # @see http://docs.developer.amazonservices.com/en_US/off_amazon_payments/OffAmazonPayments_Refund.html
621
+ # @param amazon_capture_id [String]
622
+ # @param refund_reference_id [String]
623
+ # @param amount [String]
624
+ # @optional currency_code [String]
625
+ # @optional seller_refund_note [String]
626
+ # @optional soft_descriptor [String]
627
+ # @optional merchant_id [String]
628
+ # @optional mws_auth_token [String]
629
+ def refund(
630
+ amazon_capture_id,
631
+ refund_reference_id,
632
+ amount,
633
+ currency_code: @currency_code,
634
+ seller_refund_note: nil,
635
+ soft_descriptor: nil,
636
+ merchant_id: @merchant_id,
637
+ mws_auth_token: nil)
638
+
639
+ parameters = {
640
+ 'Action' => 'Refund',
641
+ 'SellerId' => merchant_id,
642
+ 'AmazonCaptureId' => amazon_capture_id,
643
+ 'RefundReferenceId' => refund_reference_id,
644
+ 'RefundAmount.Amount' => amount,
645
+ 'RefundAmount.CurrencyCode' => currency_code
646
+ }
647
+
648
+ optional = {
649
+ 'SellerRefundNote' => seller_refund_note,
650
+ 'SoftDescriptor' => soft_descriptor,
651
+ 'MWSAuthToken' => mws_auth_token
652
+ }
653
+
654
+ operation(parameters, optional)
655
+ end
656
+
657
+ # Returns the status of a particular refund
658
+ # @see http://docs.developer.amazonservices.com/en_US/off_amazon_payments/OffAmazonPayments_GetRefundDetails.html
659
+ # @param amazon_refund_id [String]
660
+ # @optional merchant_id [String]
661
+ # @optional mws_auth_token [String]
662
+ def get_refund_details(
663
+ amazon_refund_id,
664
+ merchant_id: @merchant_id,
665
+ mws_auth_token: nil)
666
+
667
+ parameters = {
668
+ 'Action' => 'GetRefundDetails',
669
+ 'SellerId' => merchant_id,
670
+ 'AmazonRefundId' => amazon_refund_id
671
+ }
672
+
673
+ optional = {
674
+ 'MWSAuthToken' => mws_auth_token
675
+ }
676
+
677
+ operation(parameters, optional)
678
+ end
679
+
680
+ # Closes an authorization
681
+ # @see http://docs.developer.amazonservices.com/en_US/off_amazon_payments/OffAmazonPayments_CloseAuthorization.html
682
+ # @param amazon_authorization_id [String]
683
+ # @optional closure_reason [String]
684
+ # @optional merchant_id [String]
685
+ # @optional mws_auth_token [String]
686
+ def close_authorization(
687
+ amazon_authorization_id,
688
+ closure_reason: nil,
689
+ merchant_id: @merchant_id,
690
+ mws_auth_token: nil)
691
+
692
+ parameters = {
693
+ 'Action' => 'CloseAuthorization',
694
+ 'SellerId' => merchant_id,
695
+ 'AmazonAuthorizationId' => amazon_authorization_id
696
+ }
697
+
698
+ optional = {
699
+ 'ClosureReason' => closure_reason,
700
+ 'MWSAuthToken' => mws_auth_token
701
+ }
702
+
703
+ operation(parameters, optional)
704
+ end
705
+
706
+ # Confirms that an order reference has been fulfilled (fully or partially)
707
+ # and that you do not expect to create any new authorizations on this
708
+ # order reference
709
+ # @see http://docs.developer.amazonservices.com/en_US/off_amazon_payments/OffAmazonPayments_CloseOrderReference.html
710
+ # @param amazon_order_reference_id [String]
711
+ # @optional closure_reason [String]
712
+ # @optional merchant_id [String]
713
+ # @optional mws_auth_token [String]
714
+ def close_order_reference(
715
+ amazon_order_reference_id,
716
+ closure_reason: nil,
717
+ merchant_id: @merchant_id,
718
+ mws_auth_token: nil)
719
+
720
+ parameters = {
721
+ 'Action' => 'CloseOrderReference',
722
+ 'SellerId' => merchant_id,
723
+ 'AmazonOrderReferenceId' => amazon_order_reference_id
724
+ }
725
+
726
+ optional = {
727
+ 'ClosureReason' => closure_reason,
728
+ 'MWSAuthToken' => mws_auth_token
729
+ }
730
+
731
+ operation(parameters, optional)
732
+ end
733
+
734
+ private
735
+
736
+ def region_hash
737
+ {
738
+ :jp => 'mws.amazonservices.jp',
739
+ :uk => 'mws-eu.amazonservices.com',
740
+ :de => 'mws-eu.amazonservices.com',
741
+ :eu => 'mws-eu.amazonservices.com',
742
+ :us => 'mws.amazonservices.com',
743
+ :na => 'mws.amazonservices.com'
744
+ }
745
+ end
746
+
747
+ # This method combines the required and optional
748
+ # parameters to generate the post url, sign the post body,
749
+ # and send the post request.
750
+ def operation(parameters, optional)
751
+ optional.map { |k, v| parameters[k] = v unless v.nil? }
752
+ parameters = @default_hash.merge(parameters)
753
+ post_url = parameters.sort.map { |k, v| "#{k}=#{ custom_escape(v) }" }.join("&")
754
+ post_body = ["POST", "#{@mws_endpoint}", "/#{@sandbox_str}/#{PayWithAmazon::API_VERSION}", post_url].join("\n")
755
+ post_url += "&Signature=" + sign(post_body)
756
+ send_request(@mws_endpoint, @sandbox_str, post_url)
757
+ end
758
+
759
+ # This method signs the post body request that is being sent
760
+ # using the secret key provided.
761
+ def sign(post_body)
762
+ custom_escape(Base64.strict_encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::SHA256.new, @secret_key, post_body)))
763
+ end
764
+
765
+ # This method performs the post to the MWS end point.
766
+ # It will retry three times after the initial post if
767
+ # the status code comes back as either 500 or 503.
768
+ def send_request(mws_endpoint, sandbox_str, post_url)
769
+ uri = URI("https://#{mws_endpoint}/#{sandbox_str}/#{PayWithAmazon::API_VERSION}")
770
+ https = Net::HTTP.new(uri.host, uri.port, @proxy_addr, @proxy_port, @proxy_user, @proxy_pass)
771
+ https.use_ssl = true
772
+ https.verify_mode = OpenSSL::SSL::VERIFY_PEER
773
+ user_agent = {"User-Agent" => "Language=Ruby; ApplicationLibraryVersion=#{PayWithAmazon::VERSION}; Platform=#{RUBY_PLATFORM}; MWSClientVersion=#{PayWithAmazon::API_VERSION}; ApplicationName=#{@application_name}; ApplicationVersion=#{@application_version}"}
774
+ tries = 0
775
+ begin
776
+ response = https.post(uri.path, post_url, user_agent)
777
+ if @throttle.eql?(true)
778
+ if response.code.eql?('500')
779
+ raise 'InternalServerError'
780
+ elsif response.code.eql?('503')
781
+ raise 'ServiceUnavailable or RequestThrottled'
782
+ end
783
+ end
784
+ PayWithAmazon::Response.new(response)
785
+ rescue => error
786
+ tries += 1
787
+ sleep(get_seconds_for_try_count(tries))
788
+ retry if tries < MAX_RETRIES
789
+ raise error.message
790
+ end
791
+ end
792
+
793
+ def get_seconds_for_try_count(try_count)
794
+ seconds = { 1=>1, 2=>4, 3=>10, 4=>0 }
795
+ seconds[try_count]
796
+ end
797
+
798
+ def custom_escape(val)
799
+ val.to_s.gsub(/([^\w.~-]+)/) do
800
+ "%" + $1.unpack("H2" * $1.bytesize).join("%").upcase
801
+ end
802
+ end
803
+
804
+ end
805
+
806
+ end