paypkg 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/README.md +222 -0
- data/config/paypkg.yml +18 -0
- data/lib/paypkg/accept-pp-payment.rb +77 -0
- data/lib/paypkg/accept-stored-cc-payment.rb +43 -0
- data/lib/paypkg/accept-tendered-cc-payment.rb +50 -0
- data/lib/paypkg/delete-credit-card.rb +13 -0
- data/lib/paypkg/nil-empty?.rb +12 -0
- data/lib/paypkg/paypal-countries.rb +233 -0
- data/lib/paypkg/paypal-currencies.rb +32 -0
- data/lib/paypkg/paypal-languages.rb +35 -0
- data/lib/paypkg/refund-sale.rb +26 -0
- data/lib/paypkg/retrieve-credit-card.rb +18 -0
- data/lib/paypkg/retrieve-refund-transaction.rb +14 -0
- data/lib/paypkg/retrieve-sale-transaction.rb +14 -0
- data/lib/paypkg/store-credit-card.rb +48 -0
- data/lib/paypkg/validate-credit-card.rb +71 -0
- data/lib/paypkg/version.rb +3 -0
- data/lib/paypkg.rb +73 -545
- data/test/paypkg_test/approved.html.erb +10 -0
- data/test/paypkg_test/cancelled.html.erb +2 -0
- data/test/paypkg_test/test1.html.erb +15 -0
- data/test/paypkg_test_controller.rb +229 -0
- metadata +28 -8
data/lib/paypkg.rb
CHANGED
@@ -1,21 +1,52 @@
|
|
1
1
|
require "net/http"
|
2
2
|
require "yaml"
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
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
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
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
|
-
|
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,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>
|