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.
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b5b0aa6a615a910d02a4c57fa7c2a70fbf95eeb3
|
4
|
+
data.tar.gz: 1fd27b3481a219eb03e2c98d11e4fa1e7a24033c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 59f31039f45400d9897354dde0e50aaa23226f1ceb623f42a8adc20fbf9d82cf170466097cbbff8a0204ce295fa95e9ea58701d1c48239c2d1fe2e150d7420e3
|
7
|
+
data.tar.gz: 115c69d5783457506a674ee76505818c4ce00e648e6af3a5996b7ee94fc2386c00b061a58f13e8d239a48717f15d2bc4f553b830e68f99e457558f97928db947
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
0.1.1
|
2
|
+
-----
|
3
|
+
* Added PaypkgResponse, a class that converts a hash equivilent of the json output to an object.
|
4
|
+
This will make it more compatible with existing code based on ActiveRecord.
|
5
|
+
* Added more documentation. See the README.md file.
|
6
|
+
* Split out all the PayPal functions into individual files so that new functions can be added
|
7
|
+
without risking damaging anything. This also makes it easier to add new functions to the gem.
|
8
|
+
* Added a PaypkgTestController and a paypkg_test views folder that can be used for testing,
|
9
|
+
and seeing how to use the package.
|
10
|
+
|
11
|
+
0.1.0
|
12
|
+
-----
|
13
|
+
* Created initial Pay Package gem and uploaded it to rubygems.org. There is no documentation yet.
|
data/README.md
ADDED
@@ -0,0 +1,222 @@
|
|
1
|
+
Copyright (c) 2014, Michael J. Welch, Ph.D. and Contributors. All Rights Reserved.
|
2
|
+
Email: rubygems@czarmail.com
|
3
|
+
|
4
|
+
This project is licenced under the [MIT License](LICENSE.md).
|
5
|
+
|
6
|
+
|
7
|
+
###############
|
8
|
+
### Install ###
|
9
|
+
###############
|
10
|
+
|
11
|
+
To install this gem, use:
|
12
|
+
gem install paypkg
|
13
|
+
|
14
|
+
I also recommend pretty_inspect, which I use in my example below
|
15
|
+
and in the test page:
|
16
|
+
gem install pretty_inspect
|
17
|
+
|
18
|
+
Add the following routes to your route file:
|
19
|
+
get 'paypkg_test/test1' => 'paypkg_test#test1'
|
20
|
+
get 'paypkg_test/test2' => 'paypkg_test#test2'
|
21
|
+
get 'paypkg_test/approved' => 'paypkg_test#approved'
|
22
|
+
get 'paypkg_test/cancelled' => 'paypkg_test#cancelled'
|
23
|
+
|
24
|
+
Copy the files in the gem's test folder to the app/controllers and app/views, as appropriate:
|
25
|
+
|
26
|
+
|
27
|
+
####################################
|
28
|
+
### Setup the Configuration File ###
|
29
|
+
####################################
|
30
|
+
|
31
|
+
This gem requires a config file in config/paypkg.yml in your
|
32
|
+
Rails project that looks like this:
|
33
|
+
|
34
|
+
--- begin config/paypkg.yml -----------------------------------------------
|
35
|
+
development:
|
36
|
+
client_id: 'AZPi5hCY-0SoaLmignRs9XV6N4mvRS2TVKFDF2ni53alKL0iJTvtcy9BSR4D'
|
37
|
+
secret: 'EDubEBAg_ZztC-_HlsW16IFZcxBIatFt7c0ILuxNTpWAVnvrsO9ywVxnHr7J'
|
38
|
+
uri_base: 'https://api.sandbox.paypal.com'
|
39
|
+
website: 'http://www.example.com:3000'
|
40
|
+
|
41
|
+
test:
|
42
|
+
client_id: 'AZPi5hCY-0SoaLmignRs9XV6N4mvRS2TVKFDF2ni53alKL0iJTvtcy9BSR4D'
|
43
|
+
secret: 'EDubEBAg_ZztC-_HlsW16IFZcxBIatFt7c0ILuxNTpWAVnvrsO9ywVxnHr7J'
|
44
|
+
uri_base: 'https://api.sandbox.paypal.com'
|
45
|
+
website: 'http://www.example.com:3000'
|
46
|
+
|
47
|
+
production:
|
48
|
+
client_id: 'AVWiuBCE6_ps2zCh0Qaq0MaIbP8v2bjfFnKH5esYR9v6sNvu-MzVeWny3crM'
|
49
|
+
secret: 'EKKoNhCgFn_0lmpUAxXir0ySN4cmaLzGugUmnkgZHR90Kg9Y_DFmJbI2H0Ee'
|
50
|
+
uri_base: 'https://api.paypal.com'
|
51
|
+
website: 'https://www.example.com'
|
52
|
+
--- end config/paypkg.yml -------------------------------------------------
|
53
|
+
|
54
|
+
See the sample in this gem under config/paypkg.yml.
|
55
|
+
|
56
|
+
You have to place your client_id and secret in the file in place of these,
|
57
|
+
and you have to replace the website with yours. Note that the production
|
58
|
+
website has https, not http. If your production website is not encrypted
|
59
|
+
with SSL, use http instead of https.
|
60
|
+
|
61
|
+
|
62
|
+
######################
|
63
|
+
### Testing in irb ###
|
64
|
+
######################
|
65
|
+
|
66
|
+
The Paypkg class can't see the session variable (because it's only visible
|
67
|
+
in ApplicationController classes), so to test this interactively, go into
|
68
|
+
your project and run "rails c" to start irb with a Rails environment, then
|
69
|
+
create a session variable, and create an instance. You can then run the
|
70
|
+
functions.
|
71
|
+
|
72
|
+
Why can't I just use irb? Because you need the Rails environment.
|
73
|
+
That's why the tests are supplied as a controller/views.
|
74
|
+
|
75
|
+
|
76
|
+
######################
|
77
|
+
### Using Bundler? ###
|
78
|
+
######################
|
79
|
+
|
80
|
+
If you're using bundler, you'll have to add 'paypkg' and 'pretty_inspect'
|
81
|
+
to your Gemfile, then do a 'bundler install' to be able to use them.
|
82
|
+
|
83
|
+
|
84
|
+
###############################
|
85
|
+
### An Example in "rails c" ###
|
86
|
+
###############################
|
87
|
+
|
88
|
+
To use the example, by the way, you'll have to put in a 'CARD-XXX...'
|
89
|
+
number of your own.
|
90
|
+
|
91
|
+
Here is an example:
|
92
|
+
|
93
|
+
devel@mail:~/czar$ rails c
|
94
|
+
Loading development environment (Rails 4.0.4)
|
95
|
+
irb(main):001:0> session = {}
|
96
|
+
=> {}
|
97
|
+
irb(main):002:0> pp = Paypkg.new session
|
98
|
+
=> #<Paypkg:0x000000049f5138 @session={:paypal_authorization=>{:expires_after=>2014-04-19 04:54:05 +0000,\
|
99
|
+
:access_token=>"8PhJDJVg1mxxGUpSHj9RzzUxB0.sS0qiajx2Nxa1.Fg"}}, @mode=:development,
|
100
|
+
@credentials={"client_id"=>"AZPi5hCY-0SoaLsvRSni5mignR3a9XlKL2TVKFDFV6N4m20iJTvtcy9BSR4D",
|
101
|
+
"secret"=>"EDubEBAg_ZztC-_HlscxNTpWAVtFt7c0ILZW1BIaOnvrsux6IF9ywVxnHr7J",
|
102
|
+
"uri_base"=>"https://api.sandbox.paypal.com", "website"=>"http://www.example.com:3000"},
|
103
|
+
@website="http://www.example.com:3000", @uri_base="https://api.sandbox.paypal.com",
|
104
|
+
@http=#<Net::HTTP api.sandbox.paypal.com:443 open=false>,
|
105
|
+
@access_token="8PhJDJVg1mxxGUpSHj9RzzUxB0.sS0qiajx2Nxa1.Fg", @json=[], @hash=[], @status=[]>
|
106
|
+
irb(main):003:0> @ok = pp.retrieve_credit_card('CARD-22T35414AU135641UKLX6GPQ')
|
107
|
+
=> true
|
108
|
+
irb(main):004:0> puts pp.json
|
109
|
+
{"id":"CARD-22T35414AU135641UKLX6GPQ","state":"ok","payer_id":"admin","type":"visa",
|
110
|
+
"number":"xxxxxxxxxxxx0331","expire_month":"11","expire_year":"2018","first_name":"Betsy",
|
111
|
+
"last_name":"Buyer","billing_address":{"line1":"111 First Street", "city":"Saratoga",
|
112
|
+
"state":"CA","postal_code":"95070","country_code":"US"},
|
113
|
+
"valid_until":"2017-02-02T00:00:00Z","create_time":"2014-02-03T18:43:10Z",
|
114
|
+
"update_time":"2014-02-03T18:43:10Z",
|
115
|
+
"links":[{"href":"https://api.sandbox.paypal.com/v1/vault/credit-card/CARD-22T35414AU135641UKLX6GPQ","rel":"self","method":"GET"},
|
116
|
+
{"href":"https://api.sandbox.paypal.com/v1/vault/credit-card/CARD-22T35414AU135641UKLX6GPQ","rel":"delete","method":"DELETE"},
|
117
|
+
{"href":"https://api.sandbox.paypal.com/v1/vault/credit-card/CARD-22T35414AU135641UKLX6GPQ","rel":"patch","method":"PATCH"}]}
|
118
|
+
=> nil
|
119
|
+
irb(main):005:0> puts pp.status
|
120
|
+
200
|
121
|
+
=> nil
|
122
|
+
irb(main):006:0> puts pp.mode
|
123
|
+
development
|
124
|
+
=> nil
|
125
|
+
irb(main):007:0> puts pp.hash
|
126
|
+
{:id=>"CARD-22T35414AU135641UKLX6GPQ", :state=>"ok", :payer_id=>"admin", :type=>"visa",
|
127
|
+
:number=>"xxxxxxxxxxxx0331", :expire_month=>"11", :expire_year=>"2018", :first_name=>"Betsy",
|
128
|
+
:last_name=>"Buyer", :billing_address=>{:line1=>"111 First Street", :city=>"Saratoga",
|
129
|
+
:state=>"CA", :postal_code=>"95070", :country_code=>"US"},
|
130
|
+
:valid_until=>"2017-02-02T00:00:00Z", :create_time=>"2014-02-03T18:43:10Z",
|
131
|
+
:update_time=>"2014-02-03T18:43:10Z",
|
132
|
+
:links=>[{:href=>"https://api.sandbox.paypal.com/v1/vault/credit-card/CARD-22T35414AU135641UKLX6GPQ", :rel=>"self", :method=>"GET"},
|
133
|
+
{:href=>"https://api.sandbox.paypal.com/v1/vault/credit-card/CARD-22T35414AU135641UKLX6GPQ", :rel=>"delete", :method=>"DELETE"},
|
134
|
+
{:href=>"https://api.sandbox.paypal.com/v1/vault/credit-card/CARD-22T35414AU135641UKLX6GPQ", :rel=>"patch", :method=>"PATCH"}]}
|
135
|
+
=> nil
|
136
|
+
irb(main):008:0> puts pp.hash.pretty_inspect
|
137
|
+
[
|
138
|
+
{
|
139
|
+
:id => "CARD-22T35414AU135641UKLX6GPQ",
|
140
|
+
:state => "ok",
|
141
|
+
:payer_id => "admin",
|
142
|
+
:type => "visa",
|
143
|
+
:number => "xxxxxxxxxxxx0331",
|
144
|
+
:expire_month => "11",
|
145
|
+
:expire_year => "2018",
|
146
|
+
:first_name => "Betsy",
|
147
|
+
:last_name => "Buyer",
|
148
|
+
:billing_address => {
|
149
|
+
:line1 => "111 First Street",
|
150
|
+
:city => "Saratoga",
|
151
|
+
:state => "CA",
|
152
|
+
:postal_code => "95070",
|
153
|
+
:country_code => "US"
|
154
|
+
},
|
155
|
+
:valid_until => "2017-02-02T00:00:00Z",
|
156
|
+
:create_time => "2014-02-03T18:43:10Z",
|
157
|
+
:update_time => "2014-02-03T18:43:10Z",
|
158
|
+
:links => [
|
159
|
+
{
|
160
|
+
:href => "https://api.sandbox.paypal.com/v1/vault/credit-card/CARD-22T35414AU135641UKLX6GPQ",
|
161
|
+
:rel => "self",
|
162
|
+
:method => "GET"
|
163
|
+
},
|
164
|
+
{
|
165
|
+
:href => "https://api.sandbox.paypal.com/v1/vault/credit-card/CARD-22T35414AU135641UKLX6GPQ",
|
166
|
+
:rel => "delete",
|
167
|
+
:method => "DELETE"
|
168
|
+
},
|
169
|
+
{
|
170
|
+
:href => "https://api.sandbox.paypal.com/v1/vault/credit-card/CARD-22T35414AU135641UKLX6GPQ",
|
171
|
+
:rel => "patch",
|
172
|
+
:method => "PATCH"
|
173
|
+
}
|
174
|
+
]
|
175
|
+
}
|
176
|
+
]
|
177
|
+
=> nil
|
178
|
+
irb(main):009:0> r=pp.response
|
179
|
+
=> #<PaypkgResponse:0x000000045fe7a0 @id="CARD-22T35414AU135641UKLX6GPQ", @state="ok", @payer_id="admin", @type="visa", @number="xxxxxxxxxxxx0331", @expire_month="11", @expire_year="2018", @first_name="Betsy", @last_name="Buyer", @billing_address=#<PaypkgResponse:0x000000045fd170 @state="CA", @line1="111 First Street", @city="Saratoga", @postal_code="95070", @country_code="US">, @valid_until="2017-02-02T00:00:00Z", @create_time="2014-02-03T18:43:10Z", @update_time="2014-02-03T18:43:10Z", @links=[#<PaypkgResponse:0x00000004603f20 @href="https://api.sandbox.paypal.com/v1/vault/credit-card/CARD-22T35414AU135641UKLX6GPQ", @rel="self", @method="GET">, #<PaypkgResponse:0x00000004603728 @href="https://api.sandbox.paypal.com/v1/vault/credit-card/CARD-22T35414AU135641UKLX6GPQ", @rel="delete", @method="DELETE">, #<PaypkgResponse:0x000000046030c0 @href="https://api.sandbox.paypal.com/v1/vault/credit-card/CARD-22T35414AU135641UKLX6GPQ", @rel="patch", @method="PATCH">]>
|
180
|
+
irb(main):010:0> r.billing_address.line1
|
181
|
+
=> "2945 Hampton Ave"
|
182
|
+
irb(main):009:0>
|
183
|
+
|
184
|
+
|
185
|
+
############################
|
186
|
+
### PaypkgResponse Class ###
|
187
|
+
############################
|
188
|
+
|
189
|
+
The class PaypkgResponse is used to objectize a response hash (or almost any
|
190
|
+
hash object). Free free to use it separately in other projects, if it works for you.
|
191
|
+
|
192
|
+
To get the PayPal response in an object format, after a successful call, use response = pp.response.
|
193
|
+
If you want this, for example:
|
194
|
+
|
195
|
+
payment_data = pp.hash.last
|
196
|
+
@amount = payment_data[:transactions][0][:related_resources][0][:sale][:amount][:total]
|
197
|
+
|
198
|
+
you would use this:
|
199
|
+
|
200
|
+
payment_data = pp.response # this will convert pp.hash.last
|
201
|
+
@amount = payment_data.transactions[0].related_resources[0].sale.amount.total
|
202
|
+
|
203
|
+
This is provided to be more compatible with views using ActiveRecord conventions.
|
204
|
+
|
205
|
+
|
206
|
+
###############
|
207
|
+
### Caveats ###
|
208
|
+
###############
|
209
|
+
|
210
|
+
Caveats:
|
211
|
+
1. This class is designed to do the most common things most people want
|
212
|
+
to do, but without much fuss.
|
213
|
+
2. You can make your own calls to PayPal by creating a json data string
|
214
|
+
and calling call_paypal. See the cURL commands in the documentation
|
215
|
+
to see how the json should be configured. Look at the existing methods
|
216
|
+
in lib/paypkg to see how they are structured. Just add yours to the
|
217
|
+
lib/paypkg folder, and it will be available after the gem is
|
218
|
+
reloaded. Refer to https://developer.paypal.com/webapps/developer/docs/api/
|
219
|
+
for PayPal Restful calls.
|
220
|
+
3. Be sure to look at the PaypkgTestController for information on how
|
221
|
+
to use the calls in your appication.
|
222
|
+
|
data/config/paypkg.yml
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
development:
|
2
|
+
client_id: 'AZPi5hCY-0SoaLmignRs9XV6N4mvRS2TVKFDF2ni53alKL0iJTvtcy9BSR4D'
|
3
|
+
secret: 'EDubEBAg_ZztC-_HlsW16IFZcxBIatFt7c0ILuxNTpWAVnvrsO9ywVxnHr7J'
|
4
|
+
uri_base: 'https://api.sandbox.paypal.com'
|
5
|
+
website: 'http://www.example.com:3000'
|
6
|
+
|
7
|
+
test:
|
8
|
+
client_id: 'AZPi5hCY-0SoaLmignRs9XV6N4mvRS2TVKFDF2ni53alKL0iJTvtcy9BSR4D'
|
9
|
+
secret: 'EDubEBAg_ZztC-_HlsW16IFZcxBIatFt7c0ILuxNTpWAVnvrsO9ywVxnHr7J'
|
10
|
+
uri_base: 'https://api.sandbox.paypal.com'
|
11
|
+
website: 'http://www.example.com:3000'
|
12
|
+
|
13
|
+
production:
|
14
|
+
client_id: 'AVWiuBCE6_ps2zCh0Qaq0MaIbP8v2bjfFnKH5esYR9v6sNvu-MzVeWny3crM'
|
15
|
+
secret: 'EKKoNhCgFn_0lmpUAxXir0ySN4cmaLzGugUmnkgZHR90Kg9Y_DFmJbI2H0Ee'
|
16
|
+
uri_base: 'https://api.paypal.com'
|
17
|
+
website: 'https://www.example.com'
|
18
|
+
|
@@ -0,0 +1,77 @@
|
|
1
|
+
##############################
|
2
|
+
### Payment Through PayPal ###
|
3
|
+
##############################
|
4
|
+
|
5
|
+
class Paypkg
|
6
|
+
# This method is intended for use when you want to charge
|
7
|
+
# a user's PayPay account. The user will be required to give
|
8
|
+
# an on-line approval.
|
9
|
+
#
|
10
|
+
# The two urls shown here must be in your controller, and
|
11
|
+
# in your config/routes.rb file. See the execute_payment
|
12
|
+
# method below. You should store the payment_id you get
|
13
|
+
# back from this call (in session[:payment_id] here).
|
14
|
+
#
|
15
|
+
# @param amount
|
16
|
+
# @param desc
|
17
|
+
# @param approved_url
|
18
|
+
# @param cancelled_url
|
19
|
+
# @param payer_id
|
20
|
+
def accept_pp_payment(amount, desc, approved_url, cancelled_url, payer_id)
|
21
|
+
set_access_token # we need this here to set the @website
|
22
|
+
formatted_amount = "%0.2f"%amount
|
23
|
+
json, status = call_paypal("/v1/payments/payment", "{
|
24
|
+
'intent':'sale',
|
25
|
+
'redirect_urls':{
|
26
|
+
'return_url':'#{@website}/#{approved_url}/',
|
27
|
+
'cancel_url':'#{@website}/#{cancelled_url}/'
|
28
|
+
},
|
29
|
+
'payer':{
|
30
|
+
'payment_method':'paypal'
|
31
|
+
},
|
32
|
+
'transactions':[
|
33
|
+
{
|
34
|
+
'amount':{
|
35
|
+
'total':'#{formatted_amount}',
|
36
|
+
'currency':'USD'
|
37
|
+
},
|
38
|
+
'description':'#{desc}'
|
39
|
+
}
|
40
|
+
]
|
41
|
+
}")
|
42
|
+
if (@status.last=='201') && (@hash.last[:state]=='created')
|
43
|
+
@session[:payment_id] = @hash.last[:id]
|
44
|
+
@link = @hash.last[:links].select{|link| link[:rel]=='approval_url'}[0][:href]
|
45
|
+
return true
|
46
|
+
else
|
47
|
+
return false
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# This is executed by the code at the 'accepted' url.
|
52
|
+
#
|
53
|
+
# Your controller must provide two url's that look like
|
54
|
+
# the code below, and are in your config/routes.rb
|
55
|
+
#
|
56
|
+
# def approved
|
57
|
+
# pp = Paypkg.new(session)
|
58
|
+
# @ok = pp.execute_payment(params[:PayerID],session[:payment_id])
|
59
|
+
# ... more logic ...
|
60
|
+
# end
|
61
|
+
#
|
62
|
+
# def cancelled
|
63
|
+
# ... handle the user cancelling out ...
|
64
|
+
# end
|
65
|
+
#
|
66
|
+
# You should save the sale_id returned from this call in your
|
67
|
+
# database.
|
68
|
+
#
|
69
|
+
# @param payer_id
|
70
|
+
# @param payment_id
|
71
|
+
def execute_payment(payer_id, payment_id)
|
72
|
+
call_paypal("/v1/payments/payment/#{payment_id}/execute/", "{
|
73
|
+
'payer_id' : '#{payer_id}'
|
74
|
+
}")
|
75
|
+
return (@status.last=='200') && (@hash.last[:state]=='approved')
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
########################################
|
2
|
+
### Payment Using Stored Credit Card ###
|
3
|
+
########################################
|
4
|
+
|
5
|
+
class Paypkg
|
6
|
+
# This method is intended for use when you want to charge
|
7
|
+
# a card stored in the vault.
|
8
|
+
# @param card_id [String] Required.
|
9
|
+
# @param amount [Numeric] Required.
|
10
|
+
# @param desc [String] Required.
|
11
|
+
# @param email [String] Required.
|
12
|
+
# @param payer_id [String] Required.
|
13
|
+
def accept_stored_cc_payment(card_id, amount, desc, email, payer_id)
|
14
|
+
formatted_amount = "%0.2f"%amount
|
15
|
+
call_paypal("/v1/payments/payment", "{
|
16
|
+
'intent':'sale',
|
17
|
+
'payer':{
|
18
|
+
'payment_method':'credit_card',
|
19
|
+
'payer_info':{
|
20
|
+
'email':'#{email}'
|
21
|
+
},
|
22
|
+
'funding_instruments':[
|
23
|
+
{
|
24
|
+
'credit_card_token':{
|
25
|
+
'credit_card_id':'#{card_id}',
|
26
|
+
'payer_id':'#{payer_id}'
|
27
|
+
}
|
28
|
+
}
|
29
|
+
]
|
30
|
+
},
|
31
|
+
'transactions':[
|
32
|
+
{
|
33
|
+
'amount':{
|
34
|
+
'total':'#{formatted_amount}',
|
35
|
+
'currency':'USD'
|
36
|
+
},
|
37
|
+
'description':'#{desc}'
|
38
|
+
}
|
39
|
+
]
|
40
|
+
}")
|
41
|
+
return (@status.last=='201') && (@hash.last[:state]=='approved')
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
##########################################
|
2
|
+
### Payment Using Accepted Credit Card ###
|
3
|
+
##########################################
|
4
|
+
|
5
|
+
class Paypkg
|
6
|
+
# This call is intended for use when the card is presented, but
|
7
|
+
# not stored in the vault.
|
8
|
+
# @param number [String] Required.
|
9
|
+
# @param cvv2 [String] Optional.
|
10
|
+
# @param first_name [String] Optional.
|
11
|
+
# @param last_name [String] Optional.
|
12
|
+
# @param expire_month [String] Required.
|
13
|
+
# @param expire_year [String] Required.
|
14
|
+
# @param amount [String] Required.
|
15
|
+
# @param desc [String] Required.
|
16
|
+
def accept_tendered_cc_payment(type, number, expire_month, expire_year, cvv2, first_name,
|
17
|
+
last_name, amount, desc)
|
18
|
+
formatted_amount = "%0.2f"%amount
|
19
|
+
json = "{
|
20
|
+
'intent':'sale',
|
21
|
+
'payer':{
|
22
|
+
'payment_method':'credit_card',
|
23
|
+
'funding_instruments':[
|
24
|
+
{
|
25
|
+
'credit_card':{
|
26
|
+
'type':'#{type}',
|
27
|
+
'number':'#{number}',"
|
28
|
+
json << " 'cvv2':'#{cvv2}'," if cvv2
|
29
|
+
json << " 'first_name':'#{first_name}'," if first_name
|
30
|
+
json << " 'last_name':'#{last_name}'," if last_name
|
31
|
+
json << " 'expire_month':'#{expire_month}',
|
32
|
+
'expire_year':'#{expire_year}'
|
33
|
+
}
|
34
|
+
}
|
35
|
+
]
|
36
|
+
},
|
37
|
+
'transactions':[
|
38
|
+
{
|
39
|
+
'amount':{
|
40
|
+
'total':'#{formatted_amount}',
|
41
|
+
'currency':'USD'
|
42
|
+
},
|
43
|
+
'description':'#{desc}'
|
44
|
+
}
|
45
|
+
]
|
46
|
+
}"
|
47
|
+
call_paypal("/v1/payments/payment", json)
|
48
|
+
return (@status.last=='201') && (@hash.last[:state]=='approved')
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
##########################
|
2
|
+
### Delete Credit Card ###
|
3
|
+
##########################
|
4
|
+
|
5
|
+
class Paypkg
|
6
|
+
# Delete a card from the vault. If Paypal already removed the card
|
7
|
+
# because it expired, just ignore the error. NO JSON STRING is
|
8
|
+
# returned with this call.
|
9
|
+
def delete_credit_card(vault_id)
|
10
|
+
call_paypal("/v1/vault/credit-card/#{vault_id}", nil, :method => :delete)
|
11
|
+
return (@status.last=='204') && (@hash.last==nil)
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
#####################################################
|
2
|
+
### This extends NilClass to add empty? #############
|
3
|
+
### It just makes sense that nil is empty, right? ###
|
4
|
+
#####################################################
|
5
|
+
|
6
|
+
class NilClass
|
7
|
+
# This adds the empty? method to nil, so that nil.empty? => true
|
8
|
+
def empty?
|
9
|
+
true
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|