paypkg 0.1.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.
- checksums.yaml +7 -0
- data/lib/paypkg.rb +634 -0
- metadata +47 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7a1b1e82c065451cb13a76219b3a7f1cc89f3103
|
4
|
+
data.tar.gz: 8e3d7e284685f149e6e3184177214483186a77eb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2a81c0cda26d8a17407a211c53d619c8c4120c033c639f41983d7cdec42afec95c0bb5239cea66b102e9aafa2d5345a535e9f4a5a59f4199c3f0f7cea754fe00
|
7
|
+
data.tar.gz: 6d204a7697be19548a9f9090a8b7c2d91f969fbc16fc4f8b740df08daa79e8b78c3f008bdcdaa48974a342402b7d15e81d1945841516b467c77abbf6ea370bca
|
data/lib/paypkg.rb
ADDED
@@ -0,0 +1,634 @@
|
|
1
|
+
require "net/http"
|
2
|
+
require "yaml"
|
3
|
+
|
4
|
+
class NilClass
|
5
|
+
def empty?
|
6
|
+
true
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class Paypkg
|
11
|
+
|
12
|
+
# when changing this, also change the gemspec
|
13
|
+
VERSION = "0.1.0"
|
14
|
+
|
15
|
+
attr_reader :json, :hash, :status, :mode, :link
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def initialize(session=nil)
|
20
|
+
@session = if session then session else {} end
|
21
|
+
@session[:paypal_authorization] ||= {}
|
22
|
+
@session[:paypal_authorization][:expires_after] ||= Time.now-6
|
23
|
+
@session[:paypal_authorization][:access_token] ||= ""
|
24
|
+
env = Rails.env
|
25
|
+
@mode = env.to_sym
|
26
|
+
@credentials = YAML.load_file("#{Rails.root.to_path}/config/paypkg.yml")[env]
|
27
|
+
@website = @credentials['website']
|
28
|
+
@uri_base = @credentials['uri_base']
|
29
|
+
uri = URI.parse(@uri_base)
|
30
|
+
@http = Net::HTTP.new(uri.host, uri.port)
|
31
|
+
@http.use_ssl = true
|
32
|
+
#@http.set_debug_output $stderr # <-- ONLY FOR DEBUG!
|
33
|
+
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
34
|
+
set_access_token
|
35
|
+
@json = []
|
36
|
+
@hash = []
|
37
|
+
@status = []
|
38
|
+
end
|
39
|
+
|
40
|
+
def set_access_token
|
41
|
+
if (Time.now-5)>@session[:paypal_authorization][:expires_after]
|
42
|
+
request = Net::HTTP::Post.new("/v1/oauth2/token")
|
43
|
+
request.add_field("Accept","application/json")
|
44
|
+
request.add_field("Accept-Language","en_US")
|
45
|
+
request.basic_auth(@credentials['client_id'], @credentials['secret'])
|
46
|
+
request.body = "grant_type=client_credentials"
|
47
|
+
response = @http.request(request)
|
48
|
+
if response.code!='200'
|
49
|
+
@session[:paypal_authorization][:expires_after] = Time.now-1
|
50
|
+
@session[:paypal_authorization][:access_token] = ""
|
51
|
+
@access_token = nil
|
52
|
+
raise Net::HTTPServerException.new("Unable to obtain access token from PayPal", response)
|
53
|
+
else
|
54
|
+
hash = JSON.parse(response.body, :symbolize_names=>true)
|
55
|
+
@session[:paypal_authorization][:expires_after] = Time.now+hash[:expires_in]
|
56
|
+
@session[:paypal_authorization][:access_token] = hash[:access_token]
|
57
|
+
@access_token = @session[:paypal_authorization][:access_token]
|
58
|
+
end
|
59
|
+
else
|
60
|
+
@access_token = @session[:paypal_authorization][:access_token]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
public
|
65
|
+
|
66
|
+
def call_paypal(endpoint, data=nil, options={reset: :yes, method: :get})
|
67
|
+
set_access_token
|
68
|
+
options = {:reset => :yes, :method => :get}.merge(options)
|
69
|
+
if options[:reset]==:yes
|
70
|
+
@json = []
|
71
|
+
@hash = []
|
72
|
+
@status = []
|
73
|
+
end
|
74
|
+
case
|
75
|
+
when options[:method]==:delete
|
76
|
+
request = Net::HTTP::Delete.new(endpoint)
|
77
|
+
when options[:method]==:post || data # a json string
|
78
|
+
request = Net::HTTP::Post.new(endpoint)
|
79
|
+
when options[:method]==:get
|
80
|
+
request = Net::HTTP::Get.new(endpoint)
|
81
|
+
end
|
82
|
+
request.add_field("Content-Type","application/json")
|
83
|
+
request.add_field("Authorization", "Bearer #{@access_token}")
|
84
|
+
request.body = data.gsub("'",'"') if data
|
85
|
+
response = @http.request(request)
|
86
|
+
response.body = nil if response.body.empty?
|
87
|
+
@json << response.body
|
88
|
+
@hash << if response.body then JSON.parse(response.body, :symbolize_names=>true) else nil end
|
89
|
+
@status << response.code
|
90
|
+
end
|
91
|
+
|
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')
|
599
|
+
end
|
600
|
+
|
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
|
633
|
+
|
634
|
+
end
|
metadata
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: paypkg
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Michael J. Welch, Ph.D.
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-04-16 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: An interface to PayPal that's simple and transparent. This gem uses Net::HTTP
|
14
|
+
to communicate with the PayPal servers, and json files that conform to the specs
|
15
|
+
on developer.paypal.com. Look at lib/paypkg.rb in the gem. This gem has absolutely
|
16
|
+
no documentation yet, but I'll get around to it later.
|
17
|
+
email: paypkg@czarmail.com
|
18
|
+
executables: []
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- lib/paypkg.rb
|
23
|
+
homepage: http://rubygems.org/gems/paypkg
|
24
|
+
licenses:
|
25
|
+
- MIT
|
26
|
+
metadata: {}
|
27
|
+
post_install_message:
|
28
|
+
rdoc_options: []
|
29
|
+
require_paths:
|
30
|
+
- lib
|
31
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - '>='
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0'
|
36
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
requirements: []
|
42
|
+
rubyforge_project:
|
43
|
+
rubygems_version: 2.0.7
|
44
|
+
signing_key:
|
45
|
+
specification_version: 4
|
46
|
+
summary: Pay Package (paypkg) is a simple, transparent interface to PayPal.
|
47
|
+
test_files: []
|