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
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
|
+
|