paypkg 0.1.0 → 0.1.1

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.
data/lib/paypkg.rb CHANGED
@@ -1,21 +1,52 @@
1
1
  require "net/http"
2
2
  require "yaml"
3
3
 
4
- class NilClass
5
- def empty?
6
- true
4
+ # @author Michael J. Welch, Ph.D.
5
+
6
+ # The PaypkgResponse class converts a standard hash to a nested class object...
7
+ # NOTE: The outside object MUST BE a hash
8
+ # For example:
9
+ # e = PaypkgResponse.new({'x'=>7,'a'=>[{'f'=>1},{'g'=>2}]})
10
+ # yields:
11
+ # <PaypkgResponse:0x00000004dc0e20 @x=7, @a=[#<PaypkgResponse:0x00000004dc0ce0 @f=1>, #<PaypkgResponse:0x00000004dc0bf0 @g=2>]>
12
+ # and can be accessed like the example below.
13
+ #
14
+ # @param hash [Hash] The hash to be converted into an object
15
+ # @example PaypkgResponse
16
+ # puts e => #<Response:0x00000004dd3c50>
17
+ # puts e.x => 7
18
+ # puts e.a => [#<Response:0x00000004dd3b10>, #<Response:0x00000004dd39f8>]
19
+ # puts e.a[0].f => 1
20
+ # puts e.a[1].g => 2
21
+ class PaypkgResponse
22
+ def initialize(hash)
23
+ hash.each do |name, value|
24
+ case
25
+ when value.class==Array
26
+ obj = []
27
+ value.each { |item| obj << PaypkgResponse.new(item) }
28
+ self.class.__send__(:attr_accessor, name)
29
+ instance_variable_set("@#{name}", obj)
30
+ when value.class==Hash
31
+ self.class.__send__(:attr_accessor, name)
32
+ instance_variable_set("@#{name}", PaypkgResponse.new(value))
33
+ else
34
+ self.class.__send__(:attr_accessor, name)
35
+ instance_variable_set("@#{name}", value)
36
+ end
37
+ end
7
38
  end
8
39
  end
9
40
 
10
41
  class Paypkg
11
42
 
12
- # when changing this, also change the gemspec
13
- VERSION = "0.1.0"
14
-
15
43
  attr_reader :json, :hash, :status, :mode, :link
16
44
 
17
45
  private
18
46
 
47
+ # The initialize method reads the config file, calls PayPal for an access_token,
48
+ # stores the access_token in the session, and initializes some variables
49
+ # @param session [Hash] The session object from your ApplicationController subclass
19
50
  def initialize(session=nil)
20
51
  @session = if session then session else {} end
21
52
  @session[:paypal_authorization] ||= {}
@@ -37,6 +68,8 @@ private
37
68
  @status = []
38
69
  end
39
70
 
71
+ # The set_access_token method is called before each PayPal request to validate
72
+ # the access_token -- if the token is stale, a new one is obtained
40
73
  def set_access_token
41
74
  if (Time.now-5)>@session[:paypal_authorization][:expires_after]
42
75
  request = Net::HTTP::Post.new("/v1/oauth2/token")
@@ -63,6 +96,25 @@ private
63
96
 
64
97
  public
65
98
 
99
+ # The call_paypal method is used to call PayPal with a json string, and return the
100
+ # response json string and HTTP exit code -- The json response, the response
101
+ # converted into a hash, and the status code are all stored -- some calls (like
102
+ # validate_credit_card) actually make two PayPal calls, so the json, hash,
103
+ # and status are arrays
104
+ #
105
+ # @param endpoint [String] The PayPal endpoint depends on which service
106
+ # you're requesting -- required
107
+ # @param data [json String] The "put" data, if any, in the form of a json string
108
+ # @param reset [:yes or :no] If the json, hash, and status should be cleared, then :yes,
109
+ # or :no for the second PayPal call in a two call function
110
+ # @param method [:get, :post, or :delete] The HTTP type
111
+ # @example
112
+ # call_paypal("/v1/payments/payment/PAY-2BG385817G530460DKNDSITI/execute/", "{
113
+ # 'payer_id' : 'EC-71588296U3330482A'
114
+ # }")
115
+ # @return [json String] The json response from PayPal, if any
116
+ # @return [Hash] The json String converted into a hash
117
+ # @return [String] The HTTP status code
66
118
  def call_paypal(endpoint, data=nil, options={reset: :yes, method: :get})
67
119
  set_access_token
68
120
  options = {:reset => :yes, :method => :get}.merge(options)
@@ -89,546 +141,22 @@ public
89
141
  @status << response.code
90
142
  end
91
143
 
92
- ######################
93
- ### CURRENCY CODES ###
94
- ######################
95
-
96
- PAYPAL_CURRENCIES = {
97
- "Australian dollar" => "AUD",
98
- "Brazilian real" => "BRL",
99
- "Canadian dollar" => "CAD",
100
- "Czech koruna" => "CZK",
101
- "Danish krone" => "DKK",
102
- "Euro" => "EUR",
103
- "Hong Kong dollar" => "HKD",
104
- "Hungarian forint" => "HUF",
105
- "Israeli new shekel" => "ILS",
106
- "Japanese yen" => "JPY",
107
- "Malaysian ringgit" => "MYR",
108
- "Mexican peso" => "MXN",
109
- "New Taiwan dollar" => "TWD",
110
- "New Zealand dollar" => "NZD",
111
- "Norwegian krone" => "NOK",
112
- "Philippine peso" => "PHP",
113
- "Polish złoty" => "PLN",
114
- "Pound sterling" => "GBP",
115
- "Singapore dollar" => "SGD",
116
- "Swedish krona" => "SEK",
117
- "Swiss franc" => "CHF",
118
- "Thai baht" => "THB",
119
- "Turkish lira" => "TRY",
120
- "United States dollar" => "USD"
121
- }
122
-
123
- ######################
124
- ### LANGUAGE CODES ###
125
- ######################
126
-
127
- PAYPAL_LANGUAGES = [
128
- "da_DK",
129
- "de_DE",
130
- "en_AU",
131
- "en_GB",
132
- "en_US",
133
- "es_ES",
134
- "es_XC",
135
- "fr_CA",
136
- "fr_FR",
137
- "fr_XC",
138
- "he_IL",
139
- "id_ID",
140
- "it_IT",
141
- "ja_JP",
142
- "nl_NL",
143
- "no_NO",
144
- "pl_PL",
145
- "pt_BR",
146
- "pt_PT",
147
- "ru_RU",
148
- "sv_SE",
149
- "th_TH",
150
- "tr_TR",
151
- "zh_CN",
152
- "zh_HK",
153
- "zh_TW",
154
- "zh_XC"
155
- ]
156
-
157
- #####################
158
- ### COUNTRY CODES ###
159
- #####################
160
-
161
- PAYPAL_COUNTRIES = {
162
- "ALAND ISLANDS" => "AX",
163
- "ALBANIA" => "AL",
164
- "ALGERIA" => "DZ",
165
- "AMERICAN SAMOA" => "AS",
166
- "ANDORRA" => "AD",
167
- "ANGOLA" => "AO",
168
- "ANGUILLA" => "AI",
169
- "ANTARCTICA" => "AQ",
170
- "ANTIGUA AND BARBUDA" => "AG",
171
- "ARGENTINA" => "AR",
172
- "ARMENIA" => "AM",
173
- "ARUBA" => "AW",
174
- "AUSTRALIA" => "AU",
175
- "AUSTRIA" => "AT",
176
- "AZERBAIJAN" => "AZ",
177
- "BAHAMAS" => "BS",
178
- "BAHRAIN" => "BH",
179
- "BANGLADESH" => "BD",
180
- "BARBADOS" => "BB",
181
- "BELGIUM" => "BE",
182
- "BELIZE" => "BZ",
183
- "BENIN" => "BJ",
184
- "BERMUDA" => "BM",
185
- "BHUTAN" => "BT",
186
- "BOLIVIA" => "BO",
187
- "BOSNIA-HERZEGOVINA" => "BA",
188
- "BOTSWANA" => "BW",
189
- "BOUVET ISLAND" => "BV",
190
- "BRAZIL" => "BR",
191
- "BRITISH INDIAN OCEAN TERRITORY" => "IO",
192
- "BRUNEI DARUSSALAM" => "BN",
193
- "BULGARIA" => "BG",
194
- "BURKINA FASO" => "BF",
195
- "BURUNDI" => "BI",
196
- "CAMBODIA" => "KH",
197
- "CANADA" => "CA",
198
- "CAPE VERDE" => "CV",
199
- "CAYMAN ISLANDS" => "KY",
200
- "CENTRAL AFRICAN REPUBLIC" => "CF",
201
- "CHAD" => "TD",
202
- "CHILE" => "CL",
203
- "CHINA" => "CN (For domestic Chinese bank transactions only)",
204
- "CHRISTMAS ISLAND" => "CX",
205
- "COCOS (KEELING) ISLANDS" => "CC",
206
- "COLOMBIA" => "CO",
207
- "COMOROS" => "KM",
208
- "DEMOCRATIC REPUBLIC OF CONGO" => "CD",
209
- "CONGO" => "CG",
210
- "COOK ISLANDS" => "CK",
211
- "COSTA RICA" => "CR",
212
- "CROATIA" => "HR",
213
- "CYPRUS" => "CY",
214
- "CZECH REPUBLIC" => "CZ",
215
- "DENMARK" => "DK",
216
- "DJIBOUTI" => "DJ",
217
- "DOMINICA" => "DM",
218
- "DOMINICAN REPUBLIC" => "DO",
219
- "ECUADOR" => "EC",
220
- "EGYPT" => "EG",
221
- "EL SALVADOR" => "SV",
222
- "ERITERIA" => "ER",
223
- "ESTONIA" => "EE",
224
- "ETHIOPIA" => "ET",
225
- "FALKLAND ISLANDS (MALVINAS)" => "FK",
226
- "FAROE ISLANDS" => "FO",
227
- "FIJI" => "FJ",
228
- "FINLAND" => "FI",
229
- "FRANCE" => "FR",
230
- "FRENCH GUIANA" => "GF",
231
- "FRENCH POLYNESIA" => "PF",
232
- "FRENCH SOUTHERN TERRITORIES" => "TF",
233
- "GABON" => "GA",
234
- "GAMBIA" => "GM",
235
- "GEORGIA" => "GE",
236
- "GERMANY" => "DE",
237
- "GHANA" => "GH",
238
- "GIBRALTAR" => "GI",
239
- "GREECE" => "GR",
240
- "GREENLAND" => "GL",
241
- "GRENADA" => "GD",
242
- "GUADELOUPE" => "GP",
243
- "GUAM" => "GU",
244
- "GUATEMALA" => "GT",
245
- "GUERNSEY" => "GG",
246
- "GUINEA" => "GN",
247
- "GUINEA BISSAU" => "GW",
248
- "GUYANA" => "GY",
249
- "HEARD ISLAND AND MCDONALD ISLANDS" => "HM",
250
- "HOLY SEE (VATICAN CITY STATE)" => "VA",
251
- "HONDURAS" => "HN",
252
- "HONG KONG" => "HK",
253
- "HUNGARY" => "HU",
254
- "ICELAND" => "IS",
255
- "INDIA" => "IN",
256
- "INDONESIA" => "ID",
257
- "IRELAND" => "IE",
258
- "ISLE OF MAN" => "IM",
259
- "ISRAEL" => "IL",
260
- "ITALY" => "IT",
261
- "JAMAICA" => "JM",
262
- "JAPAN" => "JP",
263
- "JERSEY" => "JE",
264
- "JORDAN" => "JO",
265
- "KAZAKHSTAN" => "KZ",
266
- "KENYA" => "KE",
267
- "KIRIBATI" => "KI",
268
- "KOREA, REPUBLIC OF" => "KR",
269
- "KUWAIT" => "KW",
270
- "KYRGYZSTAN" => "KG",
271
- "LAOS" => "LA",
272
- "LATVIA" => "LV",
273
- "LESOTHO" => "LS",
274
- "LIECHTENSTEIN" => "LI",
275
- "LITHUANIA" => "LT",
276
- "LUXEMBOURG" => "LU",
277
- "MACAO" => "MO",
278
- "MACEDONIA" => "MK",
279
- "MADAGASCAR" => "MG",
280
- "MALAWI" => "MW",
281
- "MALAYSIA" => "MY",
282
- "MALDIVES" => "MV",
283
- "MALI" => "ML",
284
- "MALTA" => "MT",
285
- "MARSHALL ISLANDS" => "MH",
286
- "MARTINIQUE" => "MQ",
287
- "MAURITANIA" => "MR",
288
- "MAURITIUS" => "MU",
289
- "MAYOTTE" => "YT",
290
- "MEXICO" => "MX",
291
- "MICRONESIA, FEDERATED STATES OF" => "FM",
292
- "MOLDOVA, REPUBLIC OF" => "MD",
293
- "MONACO" => "MC",
294
- "MONGOLIA" => "MN",
295
- "MONTENEGRO" => "ME",
296
- "MONTSERRAT" => "MS",
297
- "MOROCCO" => "MA",
298
- "MOZAMBIQUE" => "MZ",
299
- "NAMIBIA" => "NA",
300
- "NAURU" => "NR",
301
- "NEPAL" => "NP",
302
- "NETHERLANDS" => "NL",
303
- "NETHERLANDS ANTILLES" => "AN",
304
- "NEW CALEDONIA" => "NC",
305
- "NEW ZEALAND" => "NZ",
306
- "NICARAGUA" => "NI",
307
- "NIGER" => "NE",
308
- "NIUE" => "NU",
309
- "NORFOLK ISLAND" => "NF",
310
- "NORTHERN MARIANA ISLANDS" => "MP",
311
- "NORWAY" => "NO",
312
- "OMAN" => "OM",
313
- "PALAU" => "PW",
314
- "PALESTINE" => "PS",
315
- "PANAMA" => "PA",
316
- "PARAGUAY" => "PY",
317
- "PAPUA NEW GUINEA" => "PG",
318
- "PERU" => "PE",
319
- "PHILIPPINES" => "PH",
320
- "PITCAIRN" => "PN",
321
- "POLAND" => "PL",
322
- "PORTUGAL" => "PT",
323
- "PUERTO RICO" => "PR",
324
- "QATAR" => "QA",
325
- "REUNION" => "RE",
326
- "ROMANIA" => "RO",
327
- "REPUBLIC OF SERBIA" => "RS",
328
- "RUSSIAN FEDERATION" => "RU",
329
- "RWANDA" => "RW",
330
- "SAINT HELENA" => "SH",
331
- "SAINT KITTS AND NEVIS" => "KN",
332
- "SAINT LUCIA" => "LC",
333
- "SAINT PIERRE AND MIQUELON" => "PM",
334
- "SAINT VINCENT AND THE GRENADINES" => "VC",
335
- "SAMOA" => "WS",
336
- "SAN MARINO" => "SM",
337
- "SAO TOME AND PRINCIPE" => "ST",
338
- "SAUDI ARABIA" => "SA",
339
- "SENEGAL" => "SN",
340
- "SEYCHELLES" => "SC",
341
- "SIERRA LEONE" => "SL",
342
- "SINGAPORE" => "SG",
343
- "SLOVAKIA" => "SK",
344
- "SLOVENIA" => "SI",
345
- "SOLOMON ISLANDS" => "SB",
346
- "SOMALIA" => "SO",
347
- "SOUTH AFRICA" => "ZA",
348
- "SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS" => "GS",
349
- "SPAIN" => "ES",
350
- "SRI LANKA" => "LK",
351
- "SURINAME" => "SR",
352
- "SVALBARD AND JAN MAYEN" => "SJ",
353
- "SWAZILAND" => "SZ",
354
- "SWEDEN" => "SE",
355
- "SWITZERLAND" => "CH",
356
- "TAIWAN, PROVINCE OF CHINA" => "TW",
357
- "TAJIKISTAN" => "TJ",
358
- "TANZANIA, UNITED REPUBLIC OF" => "TZ",
359
- "THAILAND" => "TH",
360
- "TIMOR-LESTE" => "TL",
361
- "TOGO" => "TG",
362
- "TOKELAU" => "TK",
363
- "TONGA" => "TO",
364
- "TRINIDAD AND TOBAGO" => "TT",
365
- "TUNISIA" => "TN",
366
- "TURKEY" => "TR",
367
- "TURKMENISTAN" => "TM",
368
- "TURKS AND CAICOS ISLANDS" => "TC",
369
- "TUVALU" => "TV",
370
- "UGANDA" => "UG",
371
- "UKRAINE" => "UA",
372
- "UNITED ARAB EMIRATES" => "AE",
373
- "UNITED KINGDOM" => "GB",
374
- "UNITED STATES" => "US",
375
- "UNITED STATES MINOR OUTLYING ISLANDS" => "UM",
376
- "URUGUAY" => "UY",
377
- "UZBEKISTAN" => "UZ",
378
- "VANUATU" => "VU",
379
- "VENEZUELA" => "VE",
380
- "VIETNAM" => "VN",
381
- "VIRGIN ISLANDS, BRITISH" => "VG",
382
- "VIRGIN ISLANDS, U.S." => "VI",
383
- "WALLIS AND FUTUNA" => "WF",
384
- "WESTERN SAHARA" => "EH",
385
- "YEMEN" => "YE",
386
- "ZAMBIA" => "ZM"
387
- }
388
-
389
- ############################
390
- ### Validate Credit Card ###
391
- ############################
392
-
393
- def validate_credit_card(type, number, expire_month, expire_year, cvv2, \
394
- first_name, last_name, line1, city, state, postal_code, country_code)
395
- call_paypal("/v1/payments/payment", "{
396
- 'intent':'authorize',
397
- 'payer':{
398
- 'payment_method':'credit_card',
399
- 'funding_instruments':[
400
- {
401
- 'credit_card':{
402
- 'number':'#{number}',
403
- 'type':'#{type}',
404
- 'expire_month':#{expire_month},
405
- 'expire_year':#{expire_year},
406
- 'cvv2':'#{cvv2}',
407
- 'first_name':'#{first_name}',
408
- 'last_name':'#{last_name}',
409
- 'billing_address':{
410
- 'line1':'#{line1}',
411
- 'city':'#{city}',
412
- 'state':'#{state}',
413
- 'postal_code':'#{postal_code}',
414
- 'country_code':'#{country_code}'
415
- }
416
- }
417
- }
418
- ]
419
- },
420
- 'transactions':[
421
- {
422
- 'amount':{
423
- 'total':0.01,
424
- 'currency':'USD'
425
- },
426
- 'description':'This is a validation transaction.'
427
- }
428
- ]
429
- }")
430
- if (@status.last=='201') && (@hash.last[:state]=='approved')
431
- link = @hash.last[:transactions][0][:related_resources][0][:authorization][:links].select{|link| link[:rel]=='void'}
432
- call_paypal(link[0][:href], nil, :method => :post, :reset => :no)
433
- return true if (@status.last=='200') && (@hash.last[:state]=='voided')
434
- end
435
- return false
436
- end
437
-
438
- #########################
439
- ### Store Credit Card ###
440
- #########################
441
-
442
- def store_credit_card(type, number, expire_month, expire_year, cvv2, first_name,
443
- last_name, line1, line2, city, state, postal_code, country_code, payer_id)
444
- json = "{
445
- 'payer_id':'#{payer_id}',
446
- 'type':'#{type}',
447
- 'number':'#{number}',
448
- 'expire_month':'#{expire_month}',
449
- 'expire_year':'#{expire_year}',
450
- 'cvv2':'#{cvv2}',
451
- 'first_name':'#{first_name}',
452
- 'last_name':'#{last_name}',
453
- 'billing_address':{
454
- 'line1':'#{line1}',\n"
455
- json << " 'line2':'#{line2}',\n" if line2
456
- json << " 'city':'#{city}',
457
- 'state':'#{state}',
458
- 'postal_code':'#{postal_code}',
459
- 'country_code':'#{country_code}'
460
- }
461
- }"
462
- call_paypal("/v1/vault/credit-card", json)
463
- return (@status.last=='201') && (@hash.last[:state]=='ok')
464
- end
465
-
466
- ############################
467
- ### Retrieve Credit Card ###
468
- ############################
469
-
470
- def retrieve_credit_card(vault_id)
471
- call_paypal("/v1/vault/credit-card/#{vault_id}")
472
- return (@status.last=='200') && (@hash.last[:state]=='ok')
473
- end
474
-
475
- ##########################
476
- ### Delete Credit Card ###
477
- ##########################
478
-
479
- def delete_credit_card(vault_id)
480
- call_paypal("/v1/vault/credit-card/#{vault_id}", nil, :method => :delete)
481
- return (@status.last=='204') && (@hash.last==nil)
482
- end
483
-
484
- ##########################################
485
- ### Payment Using Accepted Credit Card ###
486
- ##########################################
487
-
488
- def accept_tendered_cc_payment(type, number, expire_month, expire_year, cvv2, first_name,
489
- last_name, amount, desc)
490
- formatted_amount = "%0.2f"%amount
491
- json = "{
492
- 'intent':'sale',
493
- 'payer':{
494
- 'payment_method':'credit_card',
495
- 'funding_instruments':[
496
- {
497
- 'credit_card':{
498
- 'type':'#{type}',
499
- 'number':'#{number}',"
500
- json << " 'cvv2':'#{cvv2}'," if cvv2
501
- json << " 'first_name':'#{first_name}'," if first_name
502
- json << " 'last_name':'#{last_name}'," if last_name
503
- json << " 'expire_month':'#{expire_month}',
504
- 'expire_year':'#{expire_year}'
505
- }
506
- }
507
- ]
508
- },
509
- 'transactions':[
510
- {
511
- 'amount':{
512
- 'total':'#{formatted_amount}',
513
- 'currency':'USD'
514
- },
515
- 'description':'#{desc}'
516
- }
517
- ]
518
- }"
519
- call_paypal("/v1/payments/payment", json)
520
- return (@status.last=='201') && (@hash.last[:state]=='approved')
521
- end
522
-
523
- ########################################
524
- ### Payment Using Stored Credit Card ###
525
- ########################################
526
-
527
- def accept_stored_cc_payment(card_id, amount, desc, email, payer_id)
528
- formatted_amount = "%0.2f"%amount
529
- call_paypal("/v1/payments/payment", "{
530
- 'intent':'sale',
531
- 'payer':{
532
- 'payment_method':'credit_card',
533
- 'payer_info':{
534
- 'email':'#{email}'
535
- },
536
- 'funding_instruments':[
537
- {
538
- 'credit_card_token':{
539
- 'credit_card_id':'#{card_id}',
540
- 'payer_id':'#{payer_id}'
541
- }
542
- }
543
- ]
544
- },
545
- 'transactions':[
546
- {
547
- 'amount':{
548
- 'total':'#{formatted_amount}',
549
- 'currency':'USD'
550
- },
551
- 'description':'#{desc}'
552
- }
553
- ]
554
- }")
555
- return (@status.last=='201') && (@hash.last[:state]=='approved')
556
- end
557
-
558
- ##############################
559
- ### Payment Through PayPal ###
560
- ##############################
561
-
562
- def accept_pp_payment(amount, desc, approved_url, cancelled_url, payer_id)
563
- set_access_token # we need this here to set the @website
564
- formatted_amount = "%0.2f"%amount
565
- json, status = call_paypal("/v1/payments/payment", "{
566
- 'intent':'sale',
567
- 'redirect_urls':{
568
- 'return_url':'#{@website}/#{approved_url}/',
569
- 'cancel_url':'#{@website}/#{cancelled_url}/'
570
- },
571
- 'payer':{
572
- 'payment_method':'paypal'
573
- },
574
- 'transactions':[
575
- {
576
- 'amount':{
577
- 'total':'#{formatted_amount}',
578
- 'currency':'USD'
579
- },
580
- 'description':'#{desc}'
581
- }
582
- ]
583
- }")
584
- if (@status.last=='201') && (@hash.last[:state]=='created')
585
- @session[:payment_id] = @hash.last[:id]
586
- @link = @hash.last[:links].select{|link| link[:rel]=='approval_url'}[0][:href]
587
- return true
588
- else
589
- return false
590
- end
591
- end
592
-
593
- # this is executed by the code at the 'accepted' url
594
- def execute_payment(payer_id, payment_id)
595
- call_paypal("/v1/payments/payment/#{payment_id}/execute/", "{
596
- 'payer_id' : '#{payer_id}'
597
- }")
598
- return (@status.last=='200') && (@hash.last[:state]=='approved')
144
+ # This is a getter which is used to obtain the PaypkgResponse Object
145
+ # from the hash
146
+ # @return [PaypkgResponse Instance]
147
+ def response
148
+ if hash.last then PaypkgResponse.new(hash.last) else nil end
599
149
  end
150
+ end
600
151
 
601
- #################################
602
- ### Retrieve Sale Transaction ###
603
- #################################
604
-
605
- def retrieve_sale_transaction(sale_id)
606
- call_paypal("/v1/payments/sale/#{sale_id}")
607
- return (@status.last=='200') && (['pending', 'completed', 'refunded', 'partially_refunded'].index(@hash.last[:state])>0)
608
- end
609
-
610
- ###############################################
611
- ### Full or Partial Refund Previous Payment ###
612
- ###############################################
613
-
614
- def refund_sale(sale_id,amount)
615
- formatted_amount = "%0.2f"%amount
616
- call_paypal("/v1/payments/sale/#{sale_id}/refund", "{
617
- 'amount': {
618
- 'total': #{formatted_amount},
619
- 'currency': 'USD'
620
- }
621
- }")
622
- return (@status.last=='201') && (@hash.last[:state]=='completed')
623
- end
624
-
625
- ###################################
626
- ### Retrieve Refund Transaction ###
627
- ###################################
628
-
629
- def retrieve_refund_transaction(refund_id)
630
- call_paypal("/v1/payments/refund/#{refund_id}")
631
- return (@status.last=='200') && (['pending', 'completed', 'refunded', 'partially_refunded'].index(@hash.last[:state])>0)
632
- end
152
+ # This require loop has to be after the Paypkg class.
153
+ # File.dirname(__FILE__) => the location of this file in
154
+ # the place where your system installed this gem.
155
+ Dir[File.dirname(__FILE__) + '/paypkg/*.rb'].each {|file| require(file) }
633
156
 
157
+ # This has to be after the above require loop because the
158
+ # Version module is one of the files being required.
159
+ class Paypkg
160
+ include Version
634
161
  end
162
+
@@ -0,0 +1,10 @@
1
+ <h1>Paypkg -- Buyer Approved</h1>
2
+ <p>The buyer selected to approve the purchase.</p>
3
+ <br/>
4
+ <% if @note %>
5
+ <p>Response: <%= @note %></p>
6
+ <% else %>
7
+ <p>payment ID: <%= @payment_id %></p>
8
+ <p>Sale ID: <%= @sale_id %></p>
9
+ <p>Amount: <%= @amount %></p>
10
+ <% end %>
@@ -0,0 +1,2 @@
1
+ <h1>Paypkg -- Buyer Canceled</h1>
2
+ <p>The buyer selected to cancel the purchase.</p>
@@ -0,0 +1,15 @@
1
+ <style>
2
+ red: { color: red; }
3
+ </style>
4
+
5
+ <h1>Paypkg Test1</h1>
6
+
7
+ <pre>
8
+ <% @notes.each do |note| %>
9
+ <% if note.index(' NOT ') || note.index(' Failed') %>
10
+ <red><%= note %></red>
11
+ <% else %>
12
+ <%= note %>
13
+ <% end %>
14
+ <% end %>
15
+ </pre>