Repository: nov/paypal-express
Branch: master
Commit: 198de9274df8
Files: 85
Total size: 119.0 KB
Directory structure:
gitextract_wg6sknv5/
├── .document
├── .github/
│ └── FUNDING.yml
├── .gitignore
├── .rspec
├── .travis.yml
├── Gemfile
├── LICENSE
├── README.rdoc
├── Rakefile
├── VERSION
├── lib/
│ ├── paypal/
│ │ ├── base.rb
│ │ ├── exception/
│ │ │ ├── api_error.rb
│ │ │ └── http_error.rb
│ │ ├── exception.rb
│ │ ├── express/
│ │ │ ├── request.rb
│ │ │ └── response.rb
│ │ ├── express.rb
│ │ ├── ipn.rb
│ │ ├── nvp/
│ │ │ ├── request.rb
│ │ │ └── response.rb
│ │ ├── payment/
│ │ │ ├── common/
│ │ │ │ └── amount.rb
│ │ │ ├── recurring/
│ │ │ │ ├── activation.rb
│ │ │ │ ├── billing.rb
│ │ │ │ └── summary.rb
│ │ │ ├── recurring.rb
│ │ │ ├── request/
│ │ │ │ └── item.rb
│ │ │ ├── request.rb
│ │ │ ├── response/
│ │ │ │ ├── address.rb
│ │ │ │ ├── info.rb
│ │ │ │ ├── item.rb
│ │ │ │ ├── payer.rb
│ │ │ │ ├── reference.rb
│ │ │ │ └── refund.rb
│ │ │ └── response.rb
│ │ └── util.rb
│ └── paypal.rb
├── paypal-express.gemspec
└── spec/
├── fake_response/
│ ├── BillAgreementUpdate/
│ │ ├── fetch.txt
│ │ └── revoke.txt
│ ├── CreateBillingAgreement/
│ │ └── success.txt
│ ├── CreateRecurringPaymentsProfile/
│ │ ├── failure.txt
│ │ └── success.txt
│ ├── DoCapture/
│ │ ├── failure.txt
│ │ └── success.txt
│ ├── DoExpressCheckoutPayment/
│ │ ├── failure.txt
│ │ ├── success.txt
│ │ ├── success_with_billing_agreement.txt
│ │ └── success_with_many_items.txt
│ ├── DoReferenceTransaction/
│ │ ├── failure.txt
│ │ └── success.txt
│ ├── DoVoid/
│ │ └── success.txt
│ ├── GetExpressCheckoutDetails/
│ │ ├── failure.txt
│ │ ├── success.txt
│ │ └── with_billing_accepted_status.txt
│ ├── GetRecurringPaymentsProfileDetails/
│ │ ├── failure.txt
│ │ └── success.txt
│ ├── GetTransactionDetails/
│ │ ├── failure.txt
│ │ └── success.txt
│ ├── IPN/
│ │ ├── invalid.txt
│ │ └── valid.txt
│ ├── ManageRecurringPaymentsProfileStatus/
│ │ ├── failure.txt
│ │ └── success.txt
│ ├── RefundTransaction/
│ │ └── full.txt
│ └── SetExpressCheckout/
│ ├── failure.txt
│ └── success.txt
├── helpers/
│ └── fake_response_helper.rb
├── paypal/
│ ├── exception/
│ │ ├── api_error_spec.rb
│ │ └── http_error_spec.rb
│ ├── express/
│ │ ├── request_spec.rb
│ │ └── response_spec.rb
│ ├── ipn_spec.rb
│ ├── nvp/
│ │ ├── request_spec.rb
│ │ └── response_spec.rb
│ ├── payment/
│ │ ├── common/
│ │ │ └── amount_spec.rb
│ │ ├── recurring/
│ │ │ └── activation_spec.rb
│ │ ├── recurring_spec.rb
│ │ ├── request/
│ │ │ └── item_spec.rb
│ │ ├── request_spec.rb
│ │ ├── response/
│ │ │ ├── address_spec.rb
│ │ │ ├── info_spec.rb
│ │ │ ├── item_spec.rb
│ │ │ └── payer_spec.rb
│ │ └── response_spec.rb
│ └── util_spec.rb
└── spec_helper.rb
================================================
FILE CONTENTS
================================================
================================================
FILE: .document
================================================
README.rdoc
lib/**/*.rb
bin/*
features/**/*.feature
LICENSE
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
github: nov
================================================
FILE: .gitignore
================================================
## MAC OS
.DS_Store
## TEXTMATE
*.tmproj
tmtags
## EMACS
*~
\#*
.\#*
## VIM
*.swp
## PROJECT::GENERAL
coverage*
rdoc
pkg
## PROJECT::SPECIFIC
Gemfile.lock
================================================
FILE: .rspec
================================================
--color
--format=documentation
================================================
FILE: .travis.yml
================================================
before_install:
- gem install bundler
rvm:
- 2.0.0
- 2.1.2
================================================
FILE: Gemfile
================================================
source 'http://rubygems.org'
platform :jruby do
gem 'jruby-openssl', '>= 0.7'
end
gemspec
================================================
FILE: LICENSE
================================================
Copyright (c) 2011 nov matake
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: README.rdoc
================================================
= paypal-express
Handle PayPal Express Checkout.
Both Instance Payment and Recurring Payment are supported.
Express Checkout for Digital Goods is also supported.
{<img src="https://secure.travis-ci.org/nov/paypal-express.png" />}[http://travis-ci.org/nov/paypal-express]
== Installation
gem install paypal-express
== Usage
See Wiki on Github
https://github.com/nov/paypal-express/wiki
Play with Sample Rails App
https://github.com/nov/paypal-express-sample
https://paypal-express-sample.heroku.com
== Note on Patches/Pull Requests
* Fork the project.
* Make your feature addition or bug fix.
* Add tests for it. This is important so I don't break it in a
future version unintentionally.
* Commit, do not mess with rakefile, version, or history.
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
* Send me a pull request. Bonus points for topic branches.
== Copyright
Copyright (c) 2011 nov matake. See LICENSE for details.
================================================
FILE: Rakefile
================================================
require 'bundler'
Bundler::GemHelper.install_tasks
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new(:spec)
namespace :coverage do
desc "Open coverage report"
task :report do
require 'simplecov'
`open "#{File.join SimpleCov.coverage_path, 'index.html'}"`
end
end
task :spec do
Rake::Task[:'coverage:report'].invoke unless ENV['TRAVIS_RUBY_VERSION']
end
task :default => :spec
================================================
FILE: VERSION
================================================
0.8.1
================================================
FILE: lib/paypal/base.rb
================================================
module Paypal
class Base
include AttrRequired, AttrOptional, Util
def initialize(attributes = {})
if attributes.is_a?(Hash)
(required_attributes + optional_attributes).each do |key|
value = if numeric_attribute?(key)
Util.to_numeric(attributes[key])
else
attributes[key]
end
self.send "#{key}=", value
end
end
attr_missing!
end
end
end
================================================
FILE: lib/paypal/exception/api_error.rb
================================================
module Paypal
class Exception
class APIError < Exception
attr_accessor :response
def initialize(response = {})
@response = if response.is_a?(Hash)
Response.new response
else
response
end
end
def message
if response.respond_to?(:short_messages) && response.short_messages.any?
"PayPal API Error: " <<
response.short_messages.map{ |m| "'#{m}'" }.join(", ")
else
"PayPal API Error"
end
end
class Response
cattr_reader :attribute_mapping
@@attribute_mapping = {
:ACK => :ack,
:BUILD => :build,
:CORRELATIONID => :correlation_id,
:TIMESTAMP => :timestamp,
:VERSION => :version,
:ORDERTIME => :order_time,
:PENDINGREASON => :pending_reason,
:PAYMENTSTATUS => :payment_status,
:PAYMENTTYPE => :payment_type,
:REASONCODE => :reason_code,
:TRANSACTIONTYPE => :transaction_type
}
attr_accessor *@@attribute_mapping.values
attr_accessor :raw, :details
alias_method :colleration_id, :correlation_id # NOTE: I made a typo :p
class Detail
cattr_reader :attribute_mapping
@@attribute_mapping = {
:ERRORCODE => :error_code,
:SEVERITYCODE => :severity_code,
:LONGMESSAGE => :long_message,
:SHORTMESSAGE => :short_message
}
attr_accessor *@@attribute_mapping.values
def initialize(attributes = {})
@raw = attributes
attrs = attributes.dup
@@attribute_mapping.each do |key, value|
self.send "#{value}=", attrs.delete(key)
end
# warn ignored params
attrs.each do |key, value|
Paypal.log "Ignored Parameter (#{self.class}): #{key}=#{value}", :warn
end
end
end
def initialize(attributes = {})
attrs = attributes.dup
@raw = attributes
@@attribute_mapping.each do |key, value|
self.send "#{value}=", attrs.delete(key)
end
details = []
attrs.keys.each do |attribute|
key, index = attribute.to_s.scan(/^L_(\S+)(\d+)$/).first
next if [key, index].any?(&:blank?)
details[index.to_i] ||= {}
details[index.to_i][key.to_sym] = attrs.delete(attribute)
end
@details = details.collect do |_attrs_|
Detail.new _attrs_
end
# warn ignored params
attrs.each do |key, value|
Paypal.log "Ignored Parameter (#{self.class}): #{key}=#{value}", :warn
end
end
def short_messages
details.map(&:short_message).compact
end
end
end
end
end
================================================
FILE: lib/paypal/exception/http_error.rb
================================================
module Paypal
class Exception
class HttpError < Exception
attr_accessor :code, :message, :body
def initialize(code, message, body = '')
@code = code
@message = message
@body = body
end
end
end
end
================================================
FILE: lib/paypal/exception.rb
================================================
module Paypal
class Exception < StandardError
end
end
================================================
FILE: lib/paypal/express/request.rb
================================================
module Paypal
module Express
class Request < NVP::Request
# Common
def setup(payment_requests, return_url, cancel_url, options = {})
params = {
:RETURNURL => return_url,
:CANCELURL => cancel_url
}
if options[:no_shipping]
params[:REQCONFIRMSHIPPING] = 0
params[:NOSHIPPING] = 1
end
params[:ALLOWNOTE] = 0 if options[:allow_note] == false
{
:solution_type => :SOLUTIONTYPE,
:landing_page => :LANDINGPAGE,
:email => :EMAIL,
:brand => :BRANDNAME,
:locale => :LOCALECODE,
:logo => :LOGOIMG,
:cart_border_color => :CARTBORDERCOLOR,
:payflow_color => :PAYFLOWCOLOR
}.each do |option_key, param_key|
params[param_key] = options[option_key] if options[option_key]
end
Array(payment_requests).each_with_index do |payment_request, index|
params.merge! payment_request.to_params(index)
end
response = self.request :SetExpressCheckout, params
Response.new response, options
end
def details(token)
response = self.request :GetExpressCheckoutDetails, {:TOKEN => token}
Response.new response
end
def transaction_details(transaction_id)
response = self.request :GetTransactionDetails, {:TRANSACTIONID=> transaction_id}
Response.new response
end
def checkout!(token, payer_id, payment_requests)
params = {
:TOKEN => token,
:PAYERID => payer_id
}
Array(payment_requests).each_with_index do |payment_request, index|
params.merge! payment_request.to_params(index)
end
response = self.request :DoExpressCheckoutPayment, params
Response.new response
end
def capture!(authorization_id, amount, currency_code, complete_type = 'Complete')
params = {
:AUTHORIZATIONID => authorization_id,
:COMPLETETYPE => complete_type,
:AMT => amount,
:CURRENCYCODE => currency_code
}
response = self.request :DoCapture, params
Response.new response
end
def void!(authorization_id, params={})
params = {
:AUTHORIZATIONID => authorization_id,
:NOTE => params[:note]
}
response = self.request :DoVoid, params
Response.new response
end
# Recurring Payment Specific
def subscribe!(token, recurring_profile)
params = {
:TOKEN => token
}
params.merge! recurring_profile.to_params
response = self.request :CreateRecurringPaymentsProfile, params
Response.new response
end
def subscription(profile_id)
params = {
:PROFILEID => profile_id
}
response = self.request :GetRecurringPaymentsProfileDetails, params
Response.new response
end
def renew!(profile_id, action, options = {})
params = {
:PROFILEID => profile_id,
:ACTION => action
}
if options[:note]
params[:NOTE] = options[:note]
end
response = self.request :ManageRecurringPaymentsProfileStatus, params
Response.new response
end
def suspend!(profile_id, options = {})
renew!(profile_id, :Suspend, options)
end
def cancel!(profile_id, options = {})
renew!(profile_id, :Cancel, options)
end
def reactivate!(profile_id, options = {})
renew!(profile_id, :Reactivate, options)
end
# Reference Transaction Specific
def agree!(token, options = {})
params = {
:TOKEN => token
}
if options[:max_amount]
params[:MAXAMT] = Util.formatted_amount options[:max_amount]
end
response = self.request :CreateBillingAgreement, params
Response.new response
end
def agreement(reference_id)
params = {
:REFERENCEID => reference_id
}
response = self.request :BillAgreementUpdate, params
Response.new response
end
def charge!(reference_id, amount, options = {})
params = {
:REFERENCEID => reference_id,
:AMT => Util.formatted_amount(amount),
:PAYMENTACTION => options[:payment_action] || :Sale
}
if options[:currency_code]
params[:CURRENCYCODE] = options[:currency_code]
end
response = self.request :DoReferenceTransaction, params
Response.new response
end
def revoke!(reference_id)
params = {
:REFERENCEID => reference_id,
:BillingAgreementStatus => :Canceled
}
response = self.request :BillAgreementUpdate, params
Response.new response
end
# Refund Specific
def refund!(transaction_id, options = {})
params = {
:TRANSACTIONID => transaction_id,
:REFUNDTYPE => :Full
}
if options[:invoice_id]
params[:INVOICEID] = options[:invoice_id]
end
if options[:type]
params[:REFUNDTYPE] = options[:type]
params[:AMT] = options[:amount]
params[:CURRENCYCODE] = options[:currency_code]
end
if options[:note]
params[:NOTE] = options[:note]
end
response = self.request :RefundTransaction, params
Response.new response
end
end
end
end
================================================
FILE: lib/paypal/express/response.rb
================================================
module Paypal
module Express
class Response < NVP::Response
attr_accessor :pay_on_paypal, :mobile
def initialize(response, options = {})
super response
@pay_on_paypal = options[:pay_on_paypal]
@mobile = options[:mobile]
end
def redirect_uri
endpoint = URI.parse Paypal.endpoint
endpoint.query = query(:with_cmd).to_query
endpoint.to_s
end
def popup_uri
endpoint = URI.parse Paypal.popup_endpoint
endpoint.query = query.to_query
endpoint.to_s
end
private
def query(with_cmd = false)
_query_ = {:token => self.token}
_query_.merge!(:cmd => '_express-checkout') if with_cmd
_query_.merge!(:cmd => '_express-checkout-mobile') if mobile
_query_.merge!(:useraction => 'commit') if pay_on_paypal
_query_
end
end
end
end
================================================
FILE: lib/paypal/express.rb
================================================
require 'paypal'
================================================
FILE: lib/paypal/ipn.rb
================================================
module Paypal
module IPN
def self.endpoint
_endpoint_ = URI.parse Paypal.endpoint
_endpoint_.query = {
:cmd => '_notify-validate'
}.to_query
_endpoint_.to_s
end
def self.verify!(raw_post)
response = RestClient.post(
endpoint, raw_post
)
case response.body
when 'VERIFIED'
true
else
raise Exception::APIError.new(response.body)
end
end
end
end
================================================
FILE: lib/paypal/nvp/request.rb
================================================
module Paypal
module NVP
class Request < Base
attr_required :username, :password, :signature
attr_optional :subject
attr_accessor :version
ENDPOINT = {
:production => 'https://api-3t.paypal.com/nvp',
:sandbox => 'https://api-3t.sandbox.paypal.com/nvp'
}
def self.endpoint
if Paypal.sandbox?
ENDPOINT[:sandbox]
else
ENDPOINT[:production]
end
end
def initialize(attributes = {})
@version = Paypal.api_version
super
end
def common_params
{
:USER => self.username,
:PWD => self.password,
:SIGNATURE => self.signature,
:SUBJECT => self.subject,
:VERSION => self.version
}
end
def request(method, params = {})
handle_response do
post(method, params)
end
end
private
def post(method, params)
RestClient.post(self.class.endpoint, common_params.merge(params).merge(:METHOD => method))
end
def handle_response
response = yield
response = CGI.parse(response).inject({}) do |res, (k, v)|
res.merge!(k.to_sym => v.first)
end
case response[:ACK]
when 'Success', 'SuccessWithWarning'
response
else
raise Exception::APIError.new(response)
end
rescue RestClient::Exception => e
raise Exception::HttpError.new(e.http_code, e.message, e.http_body)
end
end
end
end
================================================
FILE: lib/paypal/nvp/response.rb
================================================
module Paypal
module NVP
class Response < Base
cattr_reader :attribute_mapping
@@attribute_mapping = {
:ACK => :ack,
:BUILD => :build,
:BILLINGAGREEMENTACCEPTEDSTATUS => :billing_agreement_accepted_status,
:CHECKOUTSTATUS => :checkout_status,
:CORRELATIONID => :correlation_id,
:COUNTRYCODE => :country_code,
:CURRENCYCODE => :currency_code,
:DESC => :description,
:NOTIFYURL => :notify_url,
:TIMESTAMP => :timestamp,
:TOKEN => :token,
:VERSION => :version,
# Some of the attributes below are duplicates of what
# exists in the payment response, but paypal doesn't
# prefix these with PAYMENTREQUEST when issuing a
# GetTransactionDetails response.
:RECEIVEREMAIL => :receiver_email,
:RECEIVERID => :receiver_id,
:SUBJECT => :subject,
:TRANSACTIONID => :transaction_id,
:TRANSACTIONTYPE => :transaction_type,
:PAYMENTTYPE => :payment_type,
:ORDERTIME => :order_time,
:PAYMENTSTATUS => :payment_status,
:PENDINGREASON => :pending_reason,
:REASONCODE => :reason_code,
:PROTECTIONELIGIBILITY => :protection_eligibility,
:PROTECTIONELIGIBILITYTYPE => :protection_eligibility_type,
:ADDRESSOWNER => :address_owner,
:ADDRESSSTATUS => :address_status,
:INVNUM => :invoice_number,
:CUSTOM => :custom
}
attr_accessor *@@attribute_mapping.values
attr_accessor :shipping_options_is_default, :success_page_redirect_requested, :insurance_option_selected
attr_accessor :amount, :description, :ship_to, :bill_to, :payer, :recurring, :billing_agreement, :refund
attr_accessor :payment_responses, :payment_info, :items
alias_method :colleration_id, :correlation_id # NOTE: I made a typo :p
def initialize(attributes = {})
attrs = attributes.dup
@@attribute_mapping.each do |key, value|
self.send "#{value}=", attrs.delete(key)
end
@shipping_options_is_default = attrs.delete(:SHIPPINGOPTIONISDEFAULT) == 'true'
@success_page_redirect_requested = attrs.delete(:SUCCESSPAGEREDIRECTREQUESTED) == 'true'
@insurance_option_selected = attrs.delete(:INSURANCEOPTIONSELECTED) == 'true'
@amount = Payment::Common::Amount.new(
:total => attrs.delete(:AMT),
:item => attrs.delete(:ITEMAMT),
:handing => attrs.delete(:HANDLINGAMT),
:insurance => attrs.delete(:INSURANCEAMT),
:ship_disc => attrs.delete(:SHIPDISCAMT),
:shipping => attrs.delete(:SHIPPINGAMT),
:tax => attrs.delete(:TAXAMT),
:fee => attrs.delete(:FEEAMT)
)
@ship_to = Payment::Response::Address.new(
:owner => attrs.delete(:SHIPADDRESSOWNER),
:status => attrs.delete(:SHIPADDRESSSTATUS),
:name => attrs.delete(:SHIPTONAME),
:zip => attrs.delete(:SHIPTOZIP),
:street => attrs.delete(:SHIPTOSTREET),
:street2 => attrs.delete(:SHIPTOSTREET2),
:city => attrs.delete(:SHIPTOCITY),
:state => attrs.delete(:SHIPTOSTATE),
:country_code => attrs.delete(:SHIPTOCOUNTRYCODE),
:country_name => attrs.delete(:SHIPTOCOUNTRYNAME)
)
@bill_to = Payment::Response::Address.new(
:owner => attrs.delete(:ADDRESSID),
:status => attrs.delete(:ADDRESSSTATUS),
:name => attrs.delete(:BILLINGNAME),
:zip => attrs.delete(:ZIP),
:street => attrs.delete(:STREET),
:street2 => attrs.delete(:STREET2),
:city => attrs.delete(:CITY),
:state => attrs.delete(:STATE),
:country_code => attrs.delete(:COUNTRY)
)
if attrs[:PAYERID]
@payer = Payment::Response::Payer.new(
:identifier => attrs.delete(:PAYERID),
:status => attrs.delete(:PAYERSTATUS),
:first_name => attrs.delete(:FIRSTNAME),
:last_name => attrs.delete(:LASTNAME),
:email => attrs.delete(:EMAIL),
:company => attrs.delete(:BUSINESS)
)
end
if attrs[:PROFILEID]
@recurring = Payment::Recurring.new(
:identifier => attrs.delete(:PROFILEID),
# NOTE:
# CreateRecurringPaymentsProfile returns PROFILESTATUS
# GetRecurringPaymentsProfileDetails returns STATUS
:description => @description,
:status => attrs.delete(:STATUS) || attrs.delete(:PROFILESTATUS),
:start_date => attrs.delete(:PROFILESTARTDATE),
:name => attrs.delete(:SUBSCRIBERNAME),
:reference => attrs.delete(:PROFILEREFERENCE),
:auto_bill => attrs.delete(:AUTOBILLOUTAMT),
:max_fails => attrs.delete(:MAXFAILEDPAYMENTS),
:aggregate_amount => attrs.delete(:AGGREGATEAMT),
:aggregate_optional_amount => attrs.delete(:AGGREGATEOPTIONALAMT),
:final_payment_date => attrs.delete(:FINALPAYMENTDUEDATE)
)
if attrs[:BILLINGPERIOD]
@recurring.billing = Payment::Recurring::Billing.new(
:amount => @amount,
:currency_code => @currency_code,
:period => attrs.delete(:BILLINGPERIOD),
:frequency => attrs.delete(:BILLINGFREQUENCY),
:total_cycles => attrs.delete(:TOTALBILLINGCYCLES),
:trial => {
:period => attrs.delete(:TRIALBILLINGPERIOD),
:frequency => attrs.delete(:TRIALBILLINGFREQUENCY),
:total_cycles => attrs.delete(:TRIALTOTALBILLINGCYCLES),
:currency_code => attrs.delete(:TRIALCURRENCYCODE),
:amount => attrs.delete(:TRIALAMT),
:tax_amount => attrs.delete(:TRIALTAXAMT),
:shipping_amount => attrs.delete(:TRIALSHIPPINGAMT),
:paid => attrs.delete(:TRIALAMTPAID)
}
)
end
if attrs[:REGULARAMT]
@recurring.regular_billing = Payment::Recurring::Billing.new(
:amount => attrs.delete(:REGULARAMT),
:shipping_amount => attrs.delete(:REGULARSHIPPINGAMT),
:tax_amount => attrs.delete(:REGULARTAXAMT),
:currency_code => attrs.delete(:REGULARCURRENCYCODE),
:period => attrs.delete(:REGULARBILLINGPERIOD),
:frequency => attrs.delete(:REGULARBILLINGFREQUENCY),
:total_cycles => attrs.delete(:REGULARTOTALBILLINGCYCLES),
:paid => attrs.delete(:REGULARAMTPAID)
)
@recurring.summary = Payment::Recurring::Summary.new(
:next_billing_date => attrs.delete(:NEXTBILLINGDATE),
:cycles_completed => attrs.delete(:NUMCYCLESCOMPLETED),
:cycles_remaining => attrs.delete(:NUMCYCLESREMAINING),
:outstanding_balance => attrs.delete(:OUTSTANDINGBALANCE),
:failed_count => attrs.delete(:FAILEDPAYMENTCOUNT),
:last_payment_date => attrs.delete(:LASTPAYMENTDATE),
:last_payment_amount => attrs.delete(:LASTPAYMENTAMT)
)
end
end
if attrs[:BILLINGAGREEMENTID]
@billing_agreement = Payment::Response::Reference.new(
:identifier => attrs.delete(:BILLINGAGREEMENTID),
:description => attrs.delete(:BILLINGAGREEMENTDESCRIPTION),
:status => attrs.delete(:BILLINGAGREEMENTSTATUS)
)
billing_agreement_info = Payment::Response::Info.attribute_mapping.keys.inject({}) do |billing_agreement_info, key|
billing_agreement_info.merge! key => attrs.delete(key)
end
@billing_agreement.info = Payment::Response::Info.new billing_agreement_info
@billing_agreement.info.amount = @amount
end
if attrs[:REFUNDTRANSACTIONID]
@refund = Payment::Response::Refund.new(
:transaction_id => attrs.delete(:REFUNDTRANSACTIONID),
:amount => {
:total => attrs.delete(:TOTALREFUNDEDAMOUNT),
:fee => attrs.delete(:FEEREFUNDAMT),
:gross => attrs.delete(:GROSSREFUNDAMT),
:net => attrs.delete(:NETREFUNDAMT)
}
)
end
# payment_responses
payment_responses = []
attrs.keys.each do |_attr_|
prefix, index, key = case _attr_.to_s
when /^PAYMENTREQUEST/, /^PAYMENTREQUESTINFO/
_attr_.to_s.split('_')
when /^L_PAYMENTREQUEST/
_attr_.to_s.split('_')[1..-1]
end
if prefix
payment_responses[index.to_i] ||= {}
payment_responses[index.to_i][key.to_sym] = attrs.delete(_attr_)
end
end
@payment_responses = payment_responses.collect do |_attrs_|
Payment::Response.new _attrs_
end
# payment_info
payment_info = []
attrs.keys.each do |_attr_|
prefix, index, key = _attr_.to_s.split('_')
if prefix == 'PAYMENTINFO'
payment_info[index.to_i] ||= {}
payment_info[index.to_i][key.to_sym] = attrs.delete(_attr_)
end
end
@payment_info = payment_info.collect do |_attrs_|
Payment::Response::Info.new _attrs_
end
# payment_info
items = []
attrs.keys.each do |_attr_|
key, index = _attr_.to_s.scan(/^L_(.+?)(\d+)$/).flatten
if index
items[index.to_i] ||= {}
items[index.to_i][key.to_sym] = attrs.delete(_attr_)
end
end
@items = items.collect do |_attrs_|
Payment::Response::Item.new _attrs_
end
# remove duplicated parameters
attrs.delete(:SHIPTOCOUNTRY) # NOTE: Same with SHIPTOCOUNTRYCODE
attrs.delete(:SALESTAX) # Same as TAXAMT
# warn ignored attrs
attrs.each do |key, value|
Paypal.log "Ignored Parameter (#{self.class}): #{key}=#{value}", :warn
end
end
end
end
end
================================================
FILE: lib/paypal/payment/common/amount.rb
================================================
module Paypal
module Payment
module Common
class Amount < Base
attr_optional :total, :item, :fee, :handing, :insurance, :ship_disc, :shipping, :tax, :gross, :net
def numeric_attribute?(key)
true
end
end
end
end
end
================================================
FILE: lib/paypal/payment/recurring/activation.rb
================================================
module Paypal
module Payment
class Recurring::Activation < Base
attr_optional :initial_amount, :failed_action
def to_params
{
:INITAMT => Util.formatted_amount(self.initial_amount),
:FAILEDINITAMTACTION => self.failed_action
}
end
end
end
end
================================================
FILE: lib/paypal/payment/recurring/billing.rb
================================================
module Paypal
module Payment
class Recurring::Billing < Base
attr_optional :period, :frequency, :paid, :currency_code, :total_cycles
attr_accessor :amount, :trial
def initialize(attributes = {})
@amount = if attributes[:amount].is_a?(Common::Amount)
attributes[:amount]
else
Common::Amount.new(
:total => attributes[:amount],
:tax => attributes[:tax_amount],
:shipping => attributes[:shipping_amount]
)
end
@trial = Recurring::Billing.new(attributes[:trial]) if attributes[:trial].present?
super
end
def to_params
trial_params = (trial.try(:to_params) || {}).inject({}) do |trial_params, (key, value)|
trial_params.merge(
:"TRIAL#{key}" => value
)
end
trial_params.merge(
:BILLINGPERIOD => self.period,
:BILLINGFREQUENCY => self.frequency,
:TOTALBILLINGCYCLES => self.total_cycles,
:AMT => Util.formatted_amount(self.amount.total),
:CURRENCYCODE => self.currency_code,
:SHIPPINGAMT => Util.formatted_amount(self.amount.shipping),
:TAXAMT => Util.formatted_amount(self.amount.tax)
)
end
end
end
end
================================================
FILE: lib/paypal/payment/recurring/summary.rb
================================================
module Paypal
module Payment
class Recurring::Summary < Base
attr_optional :next_billing_date, :cycles_completed, :cycles_remaining, :outstanding_balance, :failed_count, :last_payment_date, :last_payment_amount
def numeric_attribute?(key)
super || [:outstanding_balance, :failed_count].include?(key)
end
end
end
end
================================================
FILE: lib/paypal/payment/recurring.rb
================================================
module Paypal
module Payment
class Recurring < Base
attr_optional :start_date, :description, :identifier, :status, :name, :reference, :max_fails, :auto_bill, :aggregate_amount, :aggregate_optional_amount, :final_payment_date
attr_accessor :activation, :billing, :regular_billing, :summary
def initialize(attributes = {})
super
@activation = Activation.new attributes[:activation] if attributes[:activation]
@billing = Billing.new attributes[:billing] if attributes[:billing]
@regular_billing = Billing.new attributes[:regular_billing] if attributes[:regular_billing]
@summary = Summary.new attributes[:summary] if attributes[:summary]
end
def to_params
params = [
self.billing,
self.activation
].compact.inject({}) do |params, attribute|
params.merge! attribute.to_params
end
if self.start_date.is_a?(Time)
self.start_date = self.start_date.to_s(:db)
end
params.merge!(
:DESC => self.description,
:MAXFAILEDPAYMENTS => self.max_fails,
:AUTOBILLOUTAMT => self.auto_bill,
:PROFILESTARTDATE => self.start_date,
:SUBSCRIBERNAME => self.name,
:PROFILEREFERENCE => self.reference
)
params.delete_if do |k, v|
v.blank?
end
end
def numeric_attribute?(key)
super || [:max_fails, :failed_count].include?(key)
end
end
end
end
================================================
FILE: lib/paypal/payment/request/item.rb
================================================
module Paypal
module Payment
class Request::Item < Base
attr_optional :name, :description, :amount, :number, :quantity, :category, :url
def initialize(attributes = {})
super
@quantity ||= 1
end
def to_params(parent_index, index = 0)
{
:"L_PAYMENTREQUEST_#{parent_index}_NAME#{index}" => self.name,
:"L_PAYMENTREQUEST_#{parent_index}_DESC#{index}" => self.description,
:"L_PAYMENTREQUEST_#{parent_index}_AMT#{index}" => Util.formatted_amount(self.amount),
:"L_PAYMENTREQUEST_#{parent_index}_NUMBER#{index}" => self.number,
:"L_PAYMENTREQUEST_#{parent_index}_QTY#{index}" => self.quantity,
:"L_PAYMENTREQUEST_#{parent_index}_ITEMCATEGORY#{index}" => self.category,
:"L_PAYMENTREQUEST_#{parent_index}_ITEMURL#{index}" => self.url
}.delete_if do |k, v|
v.blank?
end
end
end
end
end
================================================
FILE: lib/paypal/payment/request.rb
================================================
module Paypal
module Payment
class Request < Base
attr_optional :action, :currency_code, :description, :notify_url, :billing_type, :billing_agreement_description, :billing_agreement_id, :request_id, :seller_id, :invoice_number, :custom
attr_accessor :amount, :items, :custom_fields
def initialize(attributes = {})
@amount = if attributes[:amount].is_a?(Common::Amount)
attributes[:amount]
else
Common::Amount.new(
:total => attributes[:amount],
:tax => attributes[:tax_amount],
:shipping => attributes[:shipping_amount]
)
end
@items = []
Array(attributes[:items]).each do |item_attrs|
@items << Item.new(item_attrs)
end
@custom_fields = attributes[:custom_fields] || {}
super
end
def to_params(index = 0)
params = {
:"PAYMENTREQUEST_#{index}_PAYMENTACTION" => self.action,
:"PAYMENTREQUEST_#{index}_AMT" => Util.formatted_amount(self.amount.total),
:"PAYMENTREQUEST_#{index}_TAXAMT" => Util.formatted_amount(self.amount.tax),
:"PAYMENTREQUEST_#{index}_SHIPPINGAMT" => Util.formatted_amount(self.amount.shipping),
:"PAYMENTREQUEST_#{index}_CURRENCYCODE" => self.currency_code,
:"PAYMENTREQUEST_#{index}_DESC" => self.description,
:"PAYMENTREQUEST_#{index}_INVNUM" => self.invoice_number,
:"PAYMENTREQUEST_#{index}_CUSTOM" => self.custom,
# NOTE:
# notify_url works only when DoExpressCheckoutPayment called.
# recurring payment doesn't support dynamic notify_url.
:"PAYMENTREQUEST_#{index}_NOTIFYURL" => self.notify_url,
:"L_BILLINGTYPE#{index}" => self.billing_type,
:"L_BILLINGAGREEMENTDESCRIPTION#{index}" => self.billing_agreement_description,
# FOR PARALLEL PAYMENT
:"PAYMENTREQUEST_#{index}_PAYMENTREQUESTID" => self.request_id,
:"PAYMENTREQUEST_#{index}_SELLERPAYPALACCOUNTID" => self.seller_id
}.delete_if do |k, v|
v.blank?
end
if self.items.present?
params[:"PAYMENTREQUEST_#{index}_ITEMAMT"] = Util.formatted_amount(self.items_amount)
self.items.each_with_index do |item, item_index|
params.merge! item.to_params(index, item_index)
end
end
self.custom_fields.each do |key, value|
field = key.to_s.upcase.gsub("{N}", index.to_s).to_sym
params[field] = value
end
params
end
def items_amount
self.items.sum do |item|
item.quantity * BigDecimal.new(item.amount.to_s)
end
end
end
end
end
================================================
FILE: lib/paypal/payment/response/address.rb
================================================
module Paypal
module Payment
class Response::Address < Base
attr_optional :owner, :status, :name, :zip, :street, :street2, :city, :state, :country_code, :country_name
end
end
end
================================================
FILE: lib/paypal/payment/response/info.rb
================================================
module Paypal
module Payment
class Response::Info < Base
cattr_reader :attribute_mapping
@@attribute_mapping = {
:ACK => :ack,
:CURRENCYCODE => :currency_code,
:ERRORCODE => :error_code,
:ORDERTIME => :order_time,
:PAYMENTSTATUS => :payment_status,
:PAYMENTTYPE => :payment_type,
:PENDINGREASON => :pending_reason,
:PROTECTIONELIGIBILITY => :protection_eligibility,
:PROTECTIONELIGIBILITYTYPE => :protection_eligibility_type,
:REASONCODE => :reason_code,
:RECEIPTID => :receipt_id,
:SECUREMERCHANTACCOUNTID => :secure_merchant_account_id,
:TRANSACTIONID => :transaction_id,
:TRANSACTIONTYPE => :transaction_type,
:PAYMENTREQUESTID => :request_id,
:SELLERPAYPALACCOUNTID => :seller_id,
:EXCHANGERATE => :exchange_rate
}
attr_accessor *@@attribute_mapping.values
attr_accessor :amount
def initialize(attributes = {})
attrs = attributes.dup
@@attribute_mapping.each do |key, value|
self.send "#{value}=", attrs.delete(key)
end
@amount = Common::Amount.new(
:total => attrs.delete(:AMT),
:fee => attrs.delete(:FEEAMT),
:tax => attrs.delete(:TAXAMT)
)
# warn ignored params
attrs.each do |key, value|
Paypal.log "Ignored Parameter (#{self.class}): #{key}=#{value}", :warn
end
end
end
end
end
================================================
FILE: lib/paypal/payment/response/item.rb
================================================
module Paypal
module Payment
class Response::Item < Base
cattr_reader :attribute_mapping
@@attribute_mapping = {
:NAME => :name,
:DESC => :description,
:QTY => :quantity,
:NUMBER => :number,
:ITEMCATEGORY => :category,
:ITEMWIDTHVALUE => :width,
:ITEMHEIGHTVALUE => :height,
:ITEMLENGTHVALUE => :length,
:ITEMWEIGHTVALUE => :weight,
:SHIPPINGAMT => :shipping,
:HANDLINGAMT => :handling,
:CURRENCYCODE => :currency
}
attr_accessor *@@attribute_mapping.values
attr_accessor :amount
def initialize(attributes = {})
attrs = attributes.dup
@@attribute_mapping.each do |key, value|
self.send "#{value}=", attrs.delete(key)
end
@quantity = @quantity.to_i
@amount = Common::Amount.new(
:total => attrs.delete(:AMT),
:tax => attrs.delete(:TAXAMT)
)
# warn ignored params
attrs.each do |key, value|
Paypal.log "Ignored Parameter (#{self.class}): #{key}=#{value}", :warn
end
end
end
end
end
================================================
FILE: lib/paypal/payment/response/payer.rb
================================================
module Paypal
module Payment
class Response::Payer < Base
attr_optional :identifier, :status, :first_name, :last_name, :email, :company
end
end
end
================================================
FILE: lib/paypal/payment/response/reference.rb
================================================
module Paypal
module Payment
class Response::Reference < Base
attr_required :identifier
attr_optional :description, :status
attr_accessor :info
end
end
end
================================================
FILE: lib/paypal/payment/response/refund.rb
================================================
module Paypal
module Payment
class Response::Refund < Base
attr_optional :transaction_id
attr_accessor :amount
def initialize(attributes = {})
super
@amount = Common::Amount.new(attributes[:amount])
end
end
end
end
================================================
FILE: lib/paypal/payment/response.rb
================================================
module Paypal
module Payment
class Response < Base
attr_accessor :amount, :ship_to, :bill_to, :description, :note, :items, :notify_url, :insurance_option_offered, :currency_code, :short_message, :long_message, :error_code, :severity_code, :ack, :transaction_id, :billing_agreement_id, :request_id, :seller_id
def initialize(attributes = {})
attrs = attributes.dup
@amount = Common::Amount.new(
:total => attrs.delete(:AMT),
:item => attrs.delete(:ITEMAMT),
:handing => attrs.delete(:HANDLINGAMT),
:insurance => attrs.delete(:INSURANCEAMT),
:ship_disc => attrs.delete(:SHIPDISCAMT),
:shipping => attrs.delete(:SHIPPINGAMT),
:tax => attrs.delete(:TAXAMT)
)
@ship_to = Payment::Response::Address.new(
:name => attrs.delete(:SHIPTONAME),
:zip => attrs.delete(:SHIPTOZIP),
:street => attrs.delete(:SHIPTOSTREET),
:street2 => attrs.delete(:SHIPTOSTREET2),
:city => attrs.delete(:SHIPTOCITY),
:state => attrs.delete(:SHIPTOSTATE),
:country_code => attrs.delete(:SHIPTOCOUNTRYCODE),
:country_name => attrs.delete(:SHIPTOCOUNTRYNAME)
)
@bill_to = Payment::Response::Address.new(
:owner => attrs.delete(:ADDRESSID),
:status => attrs.delete(:ADDRESSSTATUS),
:name => attrs.delete(:BILLINGNAME),
:zip => attrs.delete(:ZIP),
:street => attrs.delete(:STREET),
:street2 => attrs.delete(:STREET2),
:city => attrs.delete(:CITY),
:state => attrs.delete(:STATE),
:country_code => attrs.delete(:COUNTRY)
)
@description = attrs.delete(:DESC)
@note = attrs.delete(:NOTETEXT)
@notify_url = attrs.delete(:NOTIFYURL)
@insurance_option_offered = attrs.delete(:INSURANCEOPTIONOFFERED) == 'true'
@currency_code = attrs.delete(:CURRENCYCODE)
@short_message = attrs.delete(:SHORTMESSAGE)
@long_message = attrs.delete(:LONGMESSAGE)
@error_code = attrs.delete(:ERRORCODE)
@severity_code = attrs.delete(:SEVERITYCODE)
@ack = attrs.delete(:ACK)
@transaction_id = attrs.delete(:TRANSACTIONID)
@billing_agreement_id = attrs.delete(:BILLINGAGREEMENTID)
@request_id = attrs.delete(:PAYMENTREQUESTID)
@seller_id = attrs.delete(:SELLERPAYPALACCOUNTID)
# items
items = []
attrs.keys.each do |_attr_|
key, index = _attr_.to_s.scan(/^(.+?)(\d+)$/).flatten
if index
items[index.to_i] ||= {}
items[index.to_i][key.to_sym] = attrs.delete(:"#{key}#{index}")
end
end
@items = items.collect do |_attr_|
Item.new(_attr_)
end
# warn ignored params
attrs.each do |key, value|
Paypal.log "Ignored Parameter (#{self.class}): #{key}=#{value}", :warn
end
end
end
end
end
================================================
FILE: lib/paypal/util.rb
================================================
module Paypal
module Util
def self.formatted_amount(x)
# Thanks @nahi ;)
sprintf "%0.2f", BigDecimal.new(x.to_s).truncate(2)
end
def self.to_numeric(x)
if x.to_f == x.to_i
x.to_i
else
x.to_f
end
end
def numeric_attribute?(key)
!!(key.to_s =~ /(amount|frequency|cycles|paid)/)
end
def ==(other)
instance_variables.all? do |key|
instance_variable_get(key) == other.instance_variable_get(key)
end
end
end
end
================================================
FILE: lib/paypal.rb
================================================
require 'logger'
require 'active_support'
require 'active_support/core_ext'
require 'attr_required'
require 'attr_optional'
require 'rest_client'
module Paypal
mattr_accessor :api_version
self.api_version = '88.0'
ENDPOINT = {
:production => 'https://www.paypal.com/cgi-bin/webscr',
:sandbox => 'https://www.sandbox.paypal.com/cgi-bin/webscr'
}
POPUP_ENDPOINT = {
:production => 'https://www.paypal.com/incontext',
:sandbox => 'https://www.sandbox.paypal.com/incontext'
}
def self.endpoint
if sandbox?
Paypal::ENDPOINT[:sandbox]
else
Paypal::ENDPOINT[:production]
end
end
def self.popup_endpoint
if sandbox?
Paypal::POPUP_ENDPOINT[:sandbox]
else
Paypal::POPUP_ENDPOINT[:production]
end
end
def self.log(message, mode = :info)
self.logger.send mode, message
end
def self.logger
@@logger
end
def self.logger=(logger)
@@logger = logger
end
@@logger = Logger.new(STDERR)
@@logger.progname = 'Paypal::Express'
def self.sandbox?
@@sandbox
end
def self.sandbox!
self.sandbox = true
end
def self.sandbox=(boolean)
@@sandbox = boolean
end
self.sandbox = false
end
require 'paypal/util'
require 'paypal/exception'
require 'paypal/exception/http_error'
require 'paypal/exception/api_error'
require 'paypal/base'
require 'paypal/ipn'
require 'paypal/nvp/request'
require 'paypal/nvp/response'
require 'paypal/payment/common/amount'
require 'paypal/express/request'
require 'paypal/express/response'
require 'paypal/payment/request'
require 'paypal/payment/request/item'
require 'paypal/payment/response'
require 'paypal/payment/response/info'
require 'paypal/payment/response/item'
require 'paypal/payment/response/payer'
require 'paypal/payment/response/reference'
require 'paypal/payment/response/refund'
require 'paypal/payment/response/address'
require 'paypal/payment/recurring'
require 'paypal/payment/recurring/activation'
require 'paypal/payment/recurring/billing'
require 'paypal/payment/recurring/summary'
================================================
FILE: paypal-express.gemspec
================================================
Gem::Specification.new do |s|
s.name = "paypal-express"
s.version = File.read(File.join(File.dirname(__FILE__), "VERSION"))
s.required_rubygems_version = Gem::Requirement.new(">= 1.3.6") if s.respond_to? :required_rubygems_version=
s.authors = ["nov matake"]
s.description = %q{PayPal Express Checkout API Client for Instance, Recurring and Digital Goods Payment.}
s.summary = %q{PayPal Express Checkout API Client for Instance, Recurring and Digital Goods Payment.}
s.email = "nov@matake.jp"
s.extra_rdoc_files = ["LICENSE", "README.rdoc"]
s.rdoc_options = ["--charset=UTF-8"]
s.homepage = "http://github.com/nov/paypal-express"
s.require_paths = ["lib"]
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
s.add_dependency "activesupport", ">= 2.3"
s.add_dependency "rest-client"
s.add_dependency "attr_required", ">= 0.0.5"
s.add_development_dependency "rake", ">= 0.8"
s.add_development_dependency "simplecov"
s.add_development_dependency "rspec", "< 2.99"
s.add_development_dependency "fakeweb", ">= 1.3.0"
end
================================================
FILE: spec/fake_response/BillAgreementUpdate/fetch.txt
================================================
BILLINGAGREEMENTID=B%2d8XW15926RT2253736&BILLINGAGREEMENTDESCRIPTION=Reference%20Payment%20Agreement&BILLINGAGREEMENTSTATUS=Canceled&TIMESTAMP=2011%2d08%2d06T09%3a47%3a41Z&CORRELATIONID=28e5a24b3ea98&ACK=Success&VERSION=78%2e0&BUILD=2020243&EMAIL=client_1305381804_per%40matake%2ejp&PAYERID=CMJLWADKVFQYJ&PAYERSTATUS=verified&FIRSTNAME=Test&LASTNAME=User&COUNTRYCODE=US
================================================
FILE: spec/fake_response/BillAgreementUpdate/revoke.txt
================================================
BILLINGAGREEMENTID=B%2d8XW15926RT2253736&BILLINGAGREEMENTDESCRIPTION=Reference%20Payment%20Agreement&BILLINGAGREEMENTSTATUS=Canceled&TIMESTAMP=2011%2d08%2d06T09%3a47%3a41Z&CORRELATIONID=28e5a24b3ea98&ACK=Success&VERSION=78%2e0&BUILD=2020243&EMAIL=client_1305381804_per%40matake%2ejp&PAYERID=CMJLWADKVFQYJ&PAYERSTATUS=verified&FIRSTNAME=Test&LASTNAME=User&COUNTRYCODE=US
================================================
FILE: spec/fake_response/CreateBillingAgreement/success.txt
================================================
BILLINGAGREEMENTID=B%2d45776062X95244343&TIMESTAMP=2011%2d08%2d06T07%3a53%3a50Z&CORRELATIONID=9a16fde4456e1&ACK=Success&VERSION=78%2e0&BUILD=2020243
================================================
FILE: spec/fake_response/CreateRecurringPaymentsProfile/failure.txt
================================================
TIMESTAMP=2011%2d02%2d08T07%3a18%3a29Z&CORRELATIONID=fde1527b25b4f&ACK=Failure&VERSION=66%2e0&BUILD=1704252&L_ERRORCODE0=11502&L_SHORTMESSAGE0=Invalid%20Token&L_LONGMESSAGE0=The%20token%20is%20invalid&L_SEVERITYCODE0=Error
================================================
FILE: spec/fake_response/CreateRecurringPaymentsProfile/success.txt
================================================
PROFILEID=I%2dL8N58XFUCET3&PROFILESTATUS=ActiveProfile&TIMESTAMP=2011%2d02%2d08T07%3a17%3a51Z&CORRELATIONID=7d2e125f5ca63&ACK=Success&VERSION=66%2e0&BUILD=1704252
================================================
FILE: spec/fake_response/DoCapture/failure.txt
================================================
ACK=Failure&BUILD=8334781&CORRELATIONID=dd9e16358819b&L_ERRORCODE0=10609&L_LONGMESSAGE0=Transaction+id+is+invalid.&L_SEVERITYCODE0=Error&L_SHORTMESSAGE0=Invalid+transactionID.&TIMESTAMP=2013-11-05T17%3A43%3A56Z&VERSION=88.0
================================================
FILE: spec/fake_response/DoCapture/success.txt
================================================
ACK=Success&AMT=440.00&AUTHORIZATIONID=2RG78938NK8989844&BUILD=8334781&CORRELATIONID=311611c111b48&CURRENCYCODE=BRL&EXCHANGERATE=0.426354&FEEAMT=13.16&ORDERTIME=2013-11-05T17%3A34%3A56Z&PARENTTRANSACTIONID=2RG78938NK8989844&PAYMENTSTATUS=Completed&PAYMENTTYPE=instant&PENDINGREASON=None&PROTECTIONELIGIBILITY=Ineligible&PROTECTIONELIGIBILITYTYPE=None&REASONCODE=None&SETTLEAMT=181.98&TAXAMT=0.00&TIMESTAMP=2013-11-05T17%3A34%3A56Z&TRANSACTIONID=9VW4495267708531S&TRANSACTIONTYPE=expresscheckout&VERSION=88.0
================================================
FILE: spec/fake_response/DoExpressCheckoutPayment/failure.txt
================================================
TIMESTAMP=2011%2d02%2d08T07%3a15%3a19Z&CORRELATIONID=5dd0308345382&ACK=Failure&VERSION=66%2e0&BUILD=1721431&L_ERRORCODE0=10410&L_SHORTMESSAGE0=Invalid%20token&L_LONGMESSAGE0=Invalid%20token%2e&L_SEVERITYCODE0=Error
================================================
FILE: spec/fake_response/DoExpressCheckoutPayment/success.txt
================================================
TOKEN=EC-9E2743126S4330617&SUCCESSPAGEREDIRECTREQUESTED=false&TIMESTAMP=2011-02-08T03:23:55Z&CORRELATIONID=15b93874c358c&ACK=Success&VERSION=66.0&BUILD=1721431&INSURANCEOPTIONSELECTED=false&SHIPPINGOPTIONISDEFAULT=false&PAYMENTINFO_0_TRANSACTIONID=8NC65222871997739&PAYMENTINFO_0_TRANSACTIONTYPE=expresscheckout&PAYMENTINFO_0_PAYMENTTYPE=instant&PAYMENTINFO_0_ORDERTIME=2011-02-08T03:23:54Z&PAYMENTINFO_0_AMT=14.00&PAYMENTINFO_0_FEEAMT=0.85&PAYMENTINFO_0_TAXAMT=0.00&PAYMENTINFO_0_CURRENCYCODE=USD&PAYMENTINFO_0_PAYMENTSTATUS=Completed&PAYMENTINFO_0_PENDINGREASON=None&PAYMENTINFO_0_REASONCODE=None&PAYMENTINFO_0_PROTECTIONELIGIBILITY=Ineligible&PAYMENTINFO_0_PROTECTIONELIGIBILITYTYPE=None&PAYMENTINFO_0_ERRORCODE=0&PAYMENTINFO_0_ACK=Success
================================================
FILE: spec/fake_response/DoExpressCheckoutPayment/success_with_billing_agreement.txt
================================================
TOKEN=EC-9E2743126S4330617&SUCCESSPAGEREDIRECTREQUESTED=false&TIMESTAMP=2011-02-08T03:23:55Z&CORRELATIONID=15b93874c358c&ACK=Success&VERSION=66.0&BUILD=1721431&INSURANCEOPTIONSELECTED=false&SHIPPINGOPTIONISDEFAULT=false&PAYMENTINFO_0_TRANSACTIONID=8NC65222871997739&PAYMENTINFO_0_TRANSACTIONTYPE=expresscheckout&PAYMENTINFO_0_PAYMENTTYPE=instant&PAYMENTINFO_0_ORDERTIME=2011-02-08T03:23:54Z&PAYMENTINFO_0_AMT=14.00&PAYMENTINFO_0_FEEAMT=0.85&PAYMENTINFO_0_TAXAMT=0.00&PAYMENTINFO_0_CURRENCYCODE=USD&PAYMENTINFO_0_PAYMENTSTATUS=Completed&PAYMENTINFO_0_PENDINGREASON=None&PAYMENTINFO_0_REASONCODE=None&PAYMENTINFO_0_PROTECTIONELIGIBILITY=Ineligible&PAYMENTINFO_0_PROTECTIONELIGIBILITYTYPE=None&PAYMENTINFO_0_ERRORCODE=0&BILLINGAGREEMENTID=B-1XR87946TC504770W&PAYMENTINFO_0_ACK=Success
================================================
FILE: spec/fake_response/DoExpressCheckoutPayment/success_with_many_items.txt
================================================
TOKEN=EC%2d7HG122968U843864S&CHECKOUTSTATUS=PaymentActionNotInitiated&TIMESTAMP=2011%2d04%2d12T03%3a51%3a58Z&CORRELATIONID=6a0a92ea79ac3&ACK=Success&VERSION=69%2e0&BUILD=1824201&EMAIL=buyer_1297999636_per%40cerego%2ecom&PAYERID=9RWDTMRKKHQ8S&PAYERSTATUS=verified&FIRSTNAME=Test&LASTNAME=User&COUNTRYCODE=US&CURRENCYCODE=USD&AMT=1000&ITEMAMT=1000&SHIPPINGAMT=0&HANDLINGAMT=0&TAXAMT=0&DESC=Instant%20Payment%20Request&NOTIFYURL=http%3a%2f%2fmerchant%2eexample%2ecom%2fnotify&INSURANCEAMT=0&SHIPDISCAMT=0&L_ITEMHEIGHTVALUE0=%20%20%200%2e00000&L_ITEMHEIGHTVALUE1=%20%20%200%2e00000&L_ITEMHEIGHTVALUE2=%20%20%200%2e00000&L_ITEMHEIGHTVALUE3=%20%20%200%2e00000&L_ITEMHEIGHTVALUE4=%20%20%200%2e00000&L_ITEMHEIGHTVALUE5=%20%20%200%2e00000&L_ITEMHEIGHTVALUE6=%20%20%200%2e00000&L_ITEMHEIGHTVALUE7=%20%20%200%2e00000&L_ITEMHEIGHTVALUE8=%20%20%200%2e00000&L_ITEMHEIGHTVALUE9=%20%20%200%2e00000&L_ITEMHEIGHTVALUE10=%20%20%200%2e00000&L_ITEMHEIGHTVALUE11=%20%20%200%2e00000&L_ITEMHEIGHTVALUE12=%20%20%200%2e00000&L_ITEMHEIGHTVALUE13=%20%20%200%2e00000&L_ITEMHEIGHTVALUE14=%20%20%200%2e00000&L_ITEMHEIGHTVALUE15=%20%20%200%2e00000&L_ITEMHEIGHTVALUE16=%20%20%200%2e00000&L_ITEMHEIGHTVALUE17=%20%20%200%2e00000&L_ITEMHEIGHTVALUE18=%20%20%200%2e00000&L_ITEMHEIGHTVALUE19=%20%20%200%2e00000&L_ITEMWIDTHVALUE0=%20%20%200%2e00000&L_ITEMWIDTHVALUE1=%20%20%200%2e00000&L_ITEMWIDTHVALUE2=%20%20%200%2e00000&L_ITEMWIDTHVALUE3=%20%20%200%2e00000&L_ITEMWIDTHVALUE4=%20%20%200%2e00000&L_ITEMWIDTHVALUE5=%20%20%200%2e00000&L_ITEMWIDTHVALUE6=%20%20%200%2e00000&L_ITEMWIDTHVALUE7=%20%20%200%2e00000&L_ITEMWIDTHVALUE8=%20%20%200%2e00000&L_ITEMWIDTHVALUE9=%20%20%200%2e00000&L_ITEMWIDTHVALUE10=%20%20%200%2e00000&L_ITEMWIDTHVALUE11=%20%20%200%2e00000&L_ITEMWIDTHVALUE12=%20%20%200%2e00000&L_ITEMWIDTHVALUE13=%20%20%200%2e00000&L_ITEMWIDTHVALUE14=%20%20%200%2e00000&L_ITEMWIDTHVALUE15=%20%20%200%2e00000&L_ITEMWIDTHVALUE16=%20%20%200%2e00000&L_ITEMWIDTHVALUE17=%20%20%200%2e00000&L_ITEMWIDTHVALUE18=%20%20%200%2e00000&L_ITEMWIDTHVALUE19=%20%20%200%2e00000&L_ITEMLENGTHVALUE0=%20%20%200%2e00000&L_ITEMLENGTHVALUE1=%20%20%200%2e00000&L_ITEMLENGTHVALUE2=%20%20%200%2e00000&L_ITEMLENGTHVALUE3=%20%20%200%2e00000&L_ITEMLENGTHVALUE4=%20%20%200%2e00000&L_ITEMLENGTHVALUE5=%20%20%200%2e00000&L_ITEMLENGTHVALUE6=%20%20%200%2e00000&L_ITEMLENGTHVALUE7=%20%20%200%2e00000&L_ITEMLENGTHVALUE8=%20%20%200%2e00000&L_ITEMLENGTHVALUE9=%20%20%200%2e00000&L_ITEMLENGTHVALUE10=%20%20%200%2e00000&L_ITEMLENGTHVALUE11=%20%20%200%2e00000&L_ITEMLENGTHVALUE12=%20%20%200%2e00000&L_ITEMLENGTHVALUE13=%20%20%200%2e00000&L_ITEMLENGTHVALUE14=%20%20%200%2e00000&L_ITEMLENGTHVALUE15=%20%20%200%2e00000&L_ITEMLENGTHVALUE16=%20%20%200%2e00000&L_ITEMLENGTHVALUE17=%20%20%200%2e00000&L_ITEMLENGTHVALUE18=%20%20%200%2e00000&L_ITEMLENGTHVALUE19=%20%20%200%2e00000&L_NAME0=Item0&L_NAME1=Item1&L_NAME2=Item2&L_NAME3=Item3&L_NAME4=Item4&L_NAME5=Item5&L_NAME6=Item6&L_NAME7=Item7&L_NAME8=Item8&L_NAME9=Item9&L_NAME10=Item10&L_NAME11=Item11&L_NAME12=Item12&L_NAME13=Item13&L_NAME14=Item14&L_NAME15=Item15&L_NAME16=Item16&L_NAME17=Item17&L_NAME18=Item18&L_NAME19=Item19&L_ITEMWEIGHTVALUE0=%20%20%200%2e00000&L_ITEMWEIGHTVALUE1=%20%20%200%2e00000&L_ITEMWEIGHTVALUE2=%20%20%200%2e00000&L_ITEMWEIGHTVALUE3=%20%20%200%2e00000&L_ITEMWEIGHTVALUE4=%20%20%200%2e00000&L_ITEMWEIGHTVALUE5=%20%20%200%2e00000&L_ITEMWEIGHTVALUE6=%20%20%200%2e00000&L_ITEMWEIGHTVALUE7=%20%20%200%2e00000&L_ITEMWEIGHTVALUE8=%20%20%200%2e00000&L_ITEMWEIGHTVALUE9=%20%20%200%2e00000&L_ITEMWEIGHTVALUE10=%20%20%200%2e00000&L_ITEMWEIGHTVALUE11=%20%20%200%2e00000&L_ITEMWEIGHTVALUE12=%20%20%200%2e00000&L_ITEMWEIGHTVALUE13=%20%20%200%2e00000&L_ITEMWEIGHTVALUE14=%20%20%200%2e00000&L_ITEMWEIGHTVALUE15=%20%20%200%2e00000&L_ITEMWEIGHTVALUE16=%20%20%200%2e00000&L_ITEMWEIGHTVALUE17=%20%20%200%2e00000&L_ITEMWEIGHTVALUE18=%20%20%200%2e00000&L_ITEMWEIGHTVALUE19=%20%20%200%2e00000&L_TAXAMT0=%20%20%200%2e00000&L_TAXAMT1=%20%20%200%2e00000&L_TAXAMT2=%20%20%200%2e00000&L_TAXAMT3=%20%20%200%2e00000&L_TAXAMT4=%20%20%200%2e00000&L_TAXAMT5=%20%20%200%2e00000&L_TAXAMT6=%20%20%200%2e00000&L_TAXAMT7=%20%20%200%2e00000&L_TAXAMT8=%20%20%200%2e00000&L_TAXAMT9=%20%20%200%2e00000&L_TAXAMT10=%20%20%200%2e00000&L_TAXAMT11=%20%20%200%2e00000&L_TAXAMT12=%20%20%200%2e00000&L_TAXAMT13=%20%20%200%2e00000&L_TAXAMT14=%20%20%200%2e00000&L_TAXAMT15=%20%20%200%2e00000&L_TAXAMT16=%20%20%200%2e00000&L_TAXAMT17=%20%20%200%2e00000&L_TAXAMT18=%20%20%200%2e00000&L_TAXAMT19=%20%20%200%2e00000&L_DESC0=A%20new%20Item%200&L_DESC1=A%20new%20Item%201&L_DESC2=A%20new%20Item%202&L_DESC3=A%20new%20Item%203&L_DESC4=A%20new%20Item%204&L_DESC5=A%20new%20Item%205&L_DESC6=A%20new%20Item%206&L_DESC7=A%20new%20Item%207&L_DESC8=A%20new%20Item%208&L_DESC9=A%20new%20Item%209&L_DESC10=A%20new%20Item%2010&L_DESC11=A%20new%20Item%2011&L_DESC12=A%20new%20Item%2012&L_DESC13=A%20new%20Item%2013&L_DESC14=A%20new%20Item%2014&L_DESC15=A%20new%20Item%2015&L_DESC16=A%20new%20Item%2016&L_DESC17=A%20new%20Item%2017&L_DESC18=A%20new%20Item%2018&L_DESC19=A%20new%20Item%2019&L_AMT0=50&L_AMT1=50&L_AMT2=50&L_AMT3=50&L_AMT4=50&L_AMT5=50&L_AMT6=50&L_AMT7=50&L_AMT8=50&L_AMT9=50&L_AMT10=50&L_AMT11=50&L_AMT12=50&L_AMT13=50&L_AMT14=50&L_AMT15=50&L_AMT16=50&L_AMT17=50&L_AMT18=50&L_AMT19=50&L_QTY0=1&L_QTY1=1&L_QTY2=1&L_QTY3=1&L_QTY4=1&L_QTY5=1&L_QTY6=1&L_QTY7=1&L_QTY8=1&L_QTY9=1&L_QTY10=1&L_QTY11=1&L_QTY12=1&L_QTY13=1&L_QTY14=1&L_QTY15=1&L_QTY16=1&L_QTY17=1&L_QTY18=1&L_QTY19=1&PAYMENTREQUEST_0_CURRENCYCODE=JPY&PAYMENTREQUEST_0_AMT=10&PAYMENTREQUEST_0_ITEMAMT=10&PAYMENTREQUEST_0_SHIPPINGAMT=0&PAYMENTREQUEST_0_HANDLINGAMT=0&PAYMENTREQUEST_0_TAXAMT=0&PAYMENTREQUEST_0_DESC=Instant%20Payment%20Request&PAYMENTREQUEST_0_NOTIFYURL=http%3a%2f%2fmerchant%2eexample%2ecom%2fnotify&PAYMENTREQUEST_0_INSURANCEAMT=0&PAYMENTREQUEST_0_SHIPDISCAMT=0&PAYMENTREQUEST_0_INSURANCEOPTIONOFFERED=false&L_PAYMENTREQUEST_0_ITEMHEIGHTVALUE0=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMHEIGHTVALUE1=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMHEIGHTVALUE2=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMHEIGHTVALUE3=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMHEIGHTVALUE4=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMHEIGHTVALUE5=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMHEIGHTVALUE6=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMHEIGHTVALUE7=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMHEIGHTVALUE8=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMHEIGHTVALUE9=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMHEIGHTVALUE10=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMHEIGHTVALUE11=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMHEIGHTVALUE12=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMHEIGHTVALUE13=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMHEIGHTVALUE14=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMHEIGHTVALUE15=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMHEIGHTVALUE16=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMHEIGHTVALUE17=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMHEIGHTVALUE18=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMHEIGHTVALUE19=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWIDTHVALUE0=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWIDTHVALUE1=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWIDTHVALUE2=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWIDTHVALUE3=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWIDTHVALUE4=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWIDTHVALUE5=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWIDTHVALUE6=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWIDTHVALUE7=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWIDTHVALUE8=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWIDTHVALUE9=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWIDTHVALUE10=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWIDTHVALUE11=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWIDTHVALUE12=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWIDTHVALUE13=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWIDTHVALUE14=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWIDTHVALUE15=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWIDTHVALUE16=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWIDTHVALUE17=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWIDTHVALUE18=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWIDTHVALUE19=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMLENGTHVALUE0=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMLENGTHVALUE1=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMLENGTHVALUE2=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMLENGTHVALUE3=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMLENGTHVALUE4=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMLENGTHVALUE5=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMLENGTHVALUE6=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMLENGTHVALUE7=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMLENGTHVALUE8=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMLENGTHVALUE9=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMLENGTHVALUE10=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMLENGTHVALUE11=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMLENGTHVALUE12=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMLENGTHVALUE13=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMLENGTHVALUE14=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMLENGTHVALUE15=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMLENGTHVALUE16=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMLENGTHVALUE17=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMLENGTHVALUE18=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMLENGTHVALUE19=%20%20%200%2e00000&L_PAYMENTREQUEST_0_NAME0=Item0&L_PAYMENTREQUEST_0_NAME1=Item1&L_PAYMENTREQUEST_0_NAME2=Item2&L_PAYMENTREQUEST_0_NAME3=Item3&L_PAYMENTREQUEST_0_NAME4=Item4&L_PAYMENTREQUEST_0_NAME5=Item5&L_PAYMENTREQUEST_0_NAME6=Item6&L_PAYMENTREQUEST_0_NAME7=Item7&L_PAYMENTREQUEST_0_NAME8=Item8&L_PAYMENTREQUEST_0_NAME9=Item9&L_PAYMENTREQUEST_0_NAME10=Item10&L_PAYMENTREQUEST_0_NAME11=Item11&L_PAYMENTREQUEST_0_NAME12=Item12&L_PAYMENTREQUEST_0_NAME13=Item13&L_PAYMENTREQUEST_0_NAME14=Item14&L_PAYMENTREQUEST_0_NAME15=Item15&L_PAYMENTREQUEST_0_NAME16=Item16&L_PAYMENTREQUEST_0_NAME17=Item17&L_PAYMENTREQUEST_0_NAME18=Item18&L_PAYMENTREQUEST_0_NAME19=Item19&L_PAYMENTREQUEST_0_ITEMWEIGHTVALUE0=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWEIGHTVALUE1=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWEIGHTVALUE2=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWEIGHTVALUE3=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWEIGHTVALUE4=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWEIGHTVALUE5=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWEIGHTVALUE6=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWEIGHTVALUE7=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWEIGHTVALUE8=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWEIGHTVALUE9=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWEIGHTVALUE10=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWEIGHTVALUE11=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWEIGHTVALUE12=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWEIGHTVALUE13=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWEIGHTVALUE14=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWEIGHTVALUE15=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWEIGHTVALUE16=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWEIGHTVALUE17=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWEIGHTVALUE18=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWEIGHTVALUE19=%20%20%200%2e00000&L_PAYMENTREQUEST_0_TAXAMT0=%20%20%200%2e00000&L_PAYMENTREQUEST_0_TAXAMT1=%20%20%200%2e00000&L_PAYMENTREQUEST_0_TAXAMT2=%20%20%200%2e00000&L_PAYMENTREQUEST_0_TAXAMT3=%20%20%200%2e00000&L_PAYMENTREQUEST_0_TAXAMT4=%20%20%200%2e00000&L_PAYMENTREQUEST_0_TAXAMT5=%20%20%200%2e00000&L_PAYMENTREQUEST_0_TAXAMT6=%20%20%200%2e00000&L_PAYMENTREQUEST_0_TAXAMT7=%20%20%200%2e00000&L_PAYMENTREQUEST_0_TAXAMT8=%20%20%200%2e00000&L_PAYMENTREQUEST_0_TAXAMT9=%20%20%200%2e00000&L_PAYMENTREQUEST_0_TAXAMT10=%20%20%200%2e00000&L_PAYMENTREQUEST_0_TAXAMT11=%20%20%200%2e00000&L_PAYMENTREQUEST_0_TAXAMT12=%20%20%200%2e00000&L_PAYMENTREQUEST_0_TAXAMT13=%20%20%200%2e00000&L_PAYMENTREQUEST_0_TAXAMT14=%20%20%200%2e00000&L_PAYMENTREQUEST_0_TAXAMT15=%20%20%200%2e00000&L_PAYMENTREQUEST_0_TAXAMT16=%20%20%200%2e00000&L_PAYMENTREQUEST_0_TAXAMT17=%20%20%200%2e00000&L_PAYMENTREQUEST_0_TAXAMT18=%20%20%200%2e00000&L_PAYMENTREQUEST_0_TAXAMT19=%20%20%200%2e00000&L_PAYMENTREQUEST_0_DESC0=A%20new%20Item%200&L_PAYMENTREQUEST_0_DESC1=A%20new%20Item%201&L_PAYMENTREQUEST_0_DESC2=A%20new%20Item%202&L_PAYMENTREQUEST_0_DESC3=A%20new%20Item%203&L_PAYMENTREQUEST_0_DESC4=A%20new%20Item%204&L_PAYMENTREQUEST_0_DESC5=A%20new%20Item%205&L_PAYMENTREQUEST_0_DESC6=A%20new%20Item%206&L_PAYMENTREQUEST_0_DESC7=A%20new%20Item%207&L_PAYMENTREQUEST_0_DESC8=A%20new%20Item%208&L_PAYMENTREQUEST_0_DESC9=A%20new%20Item%209&L_PAYMENTREQUEST_0_DESC10=A%20new%20Item%2010&L_PAYMENTREQUEST_0_DESC11=A%20new%20Item%2011&L_PAYMENTREQUEST_0_DESC12=A%20new%20Item%2012&L_PAYMENTREQUEST_0_DESC13=A%20new%20Item%2013&L_PAYMENTREQUEST_0_DESC14=A%20new%20Item%2014&L_PAYMENTREQUEST_0_DESC15=A%20new%20Item%2015&L_PAYMENTREQUEST_0_DESC16=A%20new%20Item%2016&L_PAYMENTREQUEST_0_DESC17=A%20new%20Item%2017&L_PAYMENTREQUEST_0_DESC18=A%20new%20Item%2018&L_PAYMENTREQUEST_0_DESC19=A%20new%20Item%2019&L_PAYMENTREQUEST_0_AMT0=50&L_PAYMENTREQUEST_0_AMT1=50&L_PAYMENTREQUEST_0_AMT2=50&L_PAYMENTREQUEST_0_AMT3=50&L_PAYMENTREQUEST_0_AMT4=50&L_PAYMENTREQUEST_0_AMT5=50&L_PAYMENTREQUEST_0_AMT6=50&L_PAYMENTREQUEST_0_AMT7=50&L_PAYMENTREQUEST_0_AMT8=50&L_PAYMENTREQUEST_0_AMT9=50&L_PAYMENTREQUEST_0_AMT10=50&L_PAYMENTREQUEST_0_AMT11=50&L_PAYMENTREQUEST_0_AMT12=50&L_PAYMENTREQUEST_0_AMT13=50&L_PAYMENTREQUEST_0_AMT14=50&L_PAYMENTREQUEST_0_AMT15=50&L_PAYMENTREQUEST_0_AMT16=50&L_PAYMENTREQUEST_0_AMT17=50&L_PAYMENTREQUEST_0_AMT18=50&L_PAYMENTREQUEST_0_AMT19=50&L_PAYMENTREQUEST_0_QTY0=1&L_PAYMENTREQUEST_0_QTY1=1&L_PAYMENTREQUEST_0_QTY2=1&L_PAYMENTREQUEST_0_QTY3=1&L_PAYMENTREQUEST_0_QTY4=1&L_PAYMENTREQUEST_0_QTY5=1&L_PAYMENTREQUEST_0_QTY6=1&L_PAYMENTREQUEST_0_QTY7=1&L_PAYMENTREQUEST_0_QTY8=1&L_PAYMENTREQUEST_0_QTY9=1&L_PAYMENTREQUEST_0_QTY10=1&L_PAYMENTREQUEST_0_QTY11=1&L_PAYMENTREQUEST_0_QTY12=1&L_PAYMENTREQUEST_0_QTY13=1&L_PAYMENTREQUEST_0_QTY14=1&L_PAYMENTREQUEST_0_QTY15=1&L_PAYMENTREQUEST_0_QTY16=1&L_PAYMENTREQUEST_0_QTY17=1&L_PAYMENTREQUEST_0_QTY18=1&L_PAYMENTREQUEST_0_QTY19=1&PAYMENTREQUESTINFO_0_ERRORCODE=0
================================================
FILE: spec/fake_response/DoReferenceTransaction/failure.txt
================================================
TIMESTAMP=2011%2d07%2d19T08%3a59%3a52Z&CORRELATIONID=ed8096a3c3d7d&ACK=Failure&VERSION=72%2e0&BUILD=1982348&L_ERRORCODE0=11451&L_SHORTMESSAGE0=Billing%20Agreement%20Id%20or%20transaction%20Id%20is%20not%20valid&L_LONGMESSAGE0=Billing%20Agreement%20Id%20or%20transaction%20Id%20is%20not%20valid&L_SEVERITYCODE0=Error&TRANSACTIONTYPE=None&PAYMENTTYPE=None&ORDERTIME=1970%2d01%2d01T00%3a00%3a00Z&PAYMENTSTATUS=None&PENDINGREASON=None&REASONCODE=None
================================================
FILE: spec/fake_response/DoReferenceTransaction/success.txt
================================================
BILLINGAGREEMENTID=B%2d7HU5U5U1ULU14U49E&TIMESTAMP=2011%2d07%2d19T08%3a30%3a08Z&CORRELATIONID=12ca85fb3c9d2&ACK=Success&VERSION=72%2e0&BUILD=1982348&TRANSACTIONID=3IV51111LY1211907&TRANSACTIONTYPE=merchtpmt&PAYMENTTYPE=instant&ORDERTIME=2011%2d07%2d19T08%3a30%3a06Z&AMT=192&FEEAMT=47&TAXAMT=0&CURRENCYCODE=JPY&PAYMENTSTATUS=Completed&PENDINGREASON=None&REASONCODE=None&PROTECTIONELIGIBILITY=Ineligible&PROTECTIONELIGIBILITYTYPE=None
================================================
FILE: spec/fake_response/DoVoid/success.txt
================================================
ACK=Success&AUTHORIZATIONID=1a2b3c4d5e6f&BUILD=13055236&TIMESTAMP=2014-10-03T17%3A34%3A56Z
================================================
FILE: spec/fake_response/GetExpressCheckoutDetails/failure.txt
================================================
TOKEN=EC%2d9E2743126S4330617&CHECKOUTSTATUS=PaymentActionCompleted&TIMESTAMP=2011%2d02%2d08T07%3a10%3a26Z&CORRELATIONID=8f5fddf13ed10&ACK=Failure&VERSION=66%2e0&BUILD=1721431&L_ERRORCODE0=10411&L_SHORTMESSAGE0=This%20Express%20Checkout%20session%20has%20expired%2e&L_LONGMESSAGE0=This%20Express%20Checkout%20session%20has%20expired%2e%20%20Token%20value%20is%20no%20longer%20valid%2e&L_SEVERITYCODE0=Error&EMAIL=valid_1296805890_per%40matake%2ejp&PAYERID=PRT3TZ6MCBCNC&PAYERSTATUS=verified&FIRSTNAME=Test&LASTNAME=User&COUNTRYCODE=US&SHIPTONAME=Test%20User&SHIPTOSTREET=1%20Main%20St&SHIPTOCITY=San%20Jose&SHIPTOSTATE=CA&SHIPTOZIP=95131&SHIPTOCOUNTRYCODE=US&SHIPTOCOUNTRYNAME=United%20States&ADDRESSSTATUS=Confirmed&CURRENCYCODE=USD&AMT=14%2e00&SHIPPINGAMT=0%2e00&HANDLINGAMT=0%2e00&TAXAMT=0%2e00&INSURANCEAMT=0%2e00&SHIPDISCAMT=0%2e00&PAYMENTREQUEST_0_CURRENCYCODE=USD&PAYMENTREQUEST_0_AMT=14%2e00&PAYMENTREQUEST_0_SHIPPINGAMT=0%2e00&PAYMENTREQUEST_0_HANDLINGAMT=0%2e00&PAYMENTREQUEST_0_TAXAMT=0%2e00&PAYMENTREQUEST_0_INSURANCEAMT=0%2e00&PAYMENTREQUEST_0_SHIPDISCAMT=0%2e00&PAYMENTREQUEST_0_TRANSACTIONID=8NC65222871997739&PAYMENTREQUEST_0_INSURANCEOPTIONOFFERED=false&PAYMENTREQUEST_0_SHIPTONAME=Test%20User&PAYMENTREQUEST_0_SHIPTOSTREET=1%20Main%20St&PAYMENTREQUEST_0_SHIPTOCITY=San%20Jose&PAYMENTREQUEST_0_SHIPTOSTATE=CA&PAYMENTREQUEST_0_SHIPTOZIP=95131&PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE=US&PAYMENTREQUEST_0_SHIPTOCOUNTRYNAME=United%20States&PAYMENTREQUESTINFO_0_TRANSACTIONID=8NC65222871997739&PAYMENTREQUESTINFO_0_ERRORCODE=0
================================================
FILE: spec/fake_response/GetExpressCheckoutDetails/success.txt
================================================
TOKEN=EC%2d7HG122968U843864S&CHECKOUTSTATUS=PaymentActionNotInitiated&TIMESTAMP=2011%2d04%2d12T03%3a51%3a58Z&CORRELATIONID=6a0a92ea79ac3&ACK=Success&VERSION=69%2e0&BUILD=1824201&EMAIL=buyer_1297999636_per%40cerego%2ecom&PAYERID=9RWDTMRKKHQ8S&PAYERSTATUS=verified&FIRSTNAME=Test&LASTNAME=User&COUNTRYCODE=US&CURRENCYCODE=JPY&AMT=10&ITEMAMT=10&SHIPPINGAMT=0&HANDLINGAMT=0&TAXAMT=0&DESC=Instant%20Payment%20Request&NOTIFYURL=http%3a%2f%2fmerchant%2eexample%2ecom%2fnotify&INSURANCEAMT=0&SHIPDISCAMT=0&L_NAME0=Item1&L_QTY0=1&L_TAXAMT0=0&L_AMT0=10&L_DESC0=Item1%20Desc&L_ITEMWEIGHTVALUE0=%20%20%200%2e00000&L_ITEMLENGTHVALUE0=%20%20%200%2e00000&L_ITEMWIDTHVALUE0=%20%20%200%2e00000&L_ITEMHEIGHTVALUE0=%20%20%200%2e00000&L_ITEMCATEGORY0=Digital&PAYMENTREQUEST_0_CURRENCYCODE=JPY&PAYMENTREQUEST_0_AMT=10&PAYMENTREQUEST_0_ITEMAMT=10&PAYMENTREQUEST_0_SHIPPINGAMT=0&PAYMENTREQUEST_0_HANDLINGAMT=0&PAYMENTREQUEST_0_TAXAMT=0&PAYMENTREQUEST_0_DESC=Instant%20Payment%20Request&PAYMENTREQUEST_0_NOTIFYURL=http%3a%2f%2fmerchant%2eexample%2ecom%2fnotify&PAYMENTREQUEST_0_INSURANCEAMT=0&PAYMENTREQUEST_0_SHIPDISCAMT=0&PAYMENTREQUEST_0_INSURANCEOPTIONOFFERED=false&L_PAYMENTREQUEST_0_NAME0=Item1&L_PAYMENTREQUEST_0_QTY0=1&L_PAYMENTREQUEST_0_TAXAMT0=0&L_PAYMENTREQUEST_0_AMT0=10&L_PAYMENTREQUEST_0_DESC0=Item1%20Desc&L_PAYMENTREQUEST_0_ITEMWEIGHTVALUE0=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMLENGTHVALUE0=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWIDTHVALUE0=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMHEIGHTVALUE0=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMCATEGORY0=Digital&PAYMENTREQUESTINFO_0_ERRORCODE=0
================================================
FILE: spec/fake_response/GetExpressCheckoutDetails/with_billing_accepted_status.txt
================================================
TOKEN=EC%2d4D299105F9409730D&BILLINGAGREEMENTACCEPTEDSTATUS=1&CHECKOUTSTATUS=PaymentActionNotInitiated&TIMESTAMP=2011%2d08%2d08T01%3a56%3a13Z&CORRELATIONID=53a48e61dfca7&ACK=Success&VERSION=78%2e0&BUILD=2020243&EMAIL=client_1305381804_per%40matake%2ejp&PAYERID=CMJLWADKVFQYJ&PAYERSTATUS=verified&FIRSTNAME=Test&LASTNAME=User&COUNTRYCODE=US&CURRENCYCODE=JPY&AMT=0&SHIPPINGAMT=0&HANDLINGAMT=0&TAXAMT=0&INSURANCEAMT=0&SHIPDISCAMT=0&PAYMENTREQUEST_0_CURRENCYCODE=JPY&PAYMENTREQUEST_0_AMT=0&PAYMENTREQUEST_0_SHIPPINGAMT=0&PAYMENTREQUEST_0_HANDLINGAMT=0&PAYMENTREQUEST_0_TAXAMT=0&PAYMENTREQUEST_0_INSURANCEAMT=0&PAYMENTREQUEST_0_SHIPDISCAMT=0&PAYMENTREQUEST_0_INSURANCEOPTIONOFFERED=false&PAYMENTREQUESTINFO_0_ERRORCODE=0
================================================
FILE: spec/fake_response/GetRecurringPaymentsProfileDetails/failure.txt
================================================
PROFILEID=I%2dK1VFLRN3VVG0x&TIMESTAMP=2011%2d02%2d08T07%3a19%3a43Z&CORRELATIONID=edc954f1c34c5&ACK=Failure&VERSION=66%2e0&BUILD=1704252&L_ERRORCODE0=11552&L_SHORTMESSAGE0=Invalid%20profile%20ID&L_LONGMESSAGE0=The%20profile%20ID%20is%20invalid&L_SEVERITYCODE0=Error
================================================
FILE: spec/fake_response/GetRecurringPaymentsProfileDetails/success.txt
================================================
PROFILEID=I%2dK1VFLRN3VVG0&STATUS=Active&AUTOBILLOUTAMT=NoAutoBill&DESC=iKnow%21%20Subscription&MAXFAILEDPAYMENTS=0&SUBSCRIBERNAME=Test%20User&PROFILESTARTDATE=2011%2d02%2d03T15%3a00%3a00Z&NEXTBILLINGDATE=2011%2d03%2d04T10%3a00%3a00Z&NUMCYCLESCOMPLETED=1&NUMCYCLESREMAINING=18446744073709551615&OUTSTANDINGBALANCE=0&FAILEDPAYMENTCOUNT=0&LASTPAYMENTDATE=2011%2d02%2d04T10%3a50%3a56Z&LASTPAYMENTAMT=1000&TRIALAMTPAID=0®ULARAMTPAID=1000&AGGREGATEAMT=1000&AGGREGATEOPTIONALAMT=0&FINALPAYMENTDUEDATE=1970%2d01%2d01T00%3a00%3a00Z&TIMESTAMP=2011%2d02%2d08T07%3a19%3a25Z&CORRELATIONID=8e18dd6545045&ACK=Success&VERSION=66%2e0&BUILD=1704252&SHIPTOSTREET=1%20Main%20St&SHIPTOCITY=San%20Jose&SHIPTOSTATE=CA&SHIPTOZIP=95131&SHIPTOCOUNTRYCODE=US&SHIPTOCOUNTRY=US&SHIPTOCOUNTRYNAME=United%20States&SHIPADDRESSOWNER=PayPal&SHIPADDRESSSTATUS=Unconfirmed&BILLINGPERIOD=Month&BILLINGFREQUENCY=1&TOTALBILLINGCYCLES=0&CURRENCYCODE=JPY&AMT=1000&SHIPPINGAMT=0&TAXAMT=0®ULARBILLINGPERIOD=Month®ULARBILLINGFREQUENCY=1®ULARTOTALBILLINGCYCLES=0®ULARCURRENCYCODE=JPY®ULARAMT=1000®ULARSHIPPINGAMT=0®ULARTAXAMT=0
================================================
FILE: spec/fake_response/GetTransactionDetails/failure.txt
================================================
ADDRESSOWNER=PayPal&ADDRESSSTATUS=None&TIMESTAMP=2012%2d02%2d23T21%3a07%3a22Z&CORRELATIONID=4e18d75a23953&ACK=Failure&VERSION=78%2e0&BUILD=2571254&L_ERRORCODE0=10004&L_SHORTMESSAGE0=Transaction%20refused%20because%20of%20an%20invalid%20argument%2e%20See%20additional%20error%20messages%20for%20details%2e&L_LONGMESSAGE0=The%20transaction%20id%20is%20not%20valid&L_SEVERITYCODE0=Error&PENDINGREASON=None&REASONCODE=None
================================================
FILE: spec/fake_response/GetTransactionDetails/success.txt
================================================
RECEIVEREMAIL=test%40email%2ecom&RECEIVERID=ABCDEFG12345&EMAIL=test%40email%2ecom&PAYERID=12345ABCDEFG&PAYERSTATUS=verified&COUNTRYCODE=US&SHIPTONAME=Billy%20Bob&SHIPTOSTREET=1%20Main%20St&SHIPTOCITY=San%20Jose&SHIPTOSTATE=CA&SHIPTOCOUNTRYCODE=US&SHIPTOCOUNTRYNAME=United%20States&SHIPTOZIP=95131&ADDRESSOWNER=PayPal&ADDRESSSTATUS=Confirmed&SALESTAX=0%2e00&SUBJECT=Test%20Subject&TIMESTAMP=2012%2d02%2d23T20%3a51%3a29Z&CORRELATIONID=4fc0a06cbaec7&ACK=Success&VERSION=78%2e0&BUILD=2571254&FIRSTNAME=Billy&LASTNAME=Bob&TRANSACTIONID=123456789ABCD&TRANSACTIONTYPE=cart&PAYMENTTYPE=instant&ORDERTIME=2012%2d02%2d13T23%3a09%3a46Z&AMT=740%2e43&FEEAMT=21%2e77&TAXAMT=0%2e00&SHIPPINGAMT=0%2e00&HANDLINGAMT=0%2e00&CURRENCYCODE=USD&PAYMENTSTATUS=Completed&PENDINGREASON=None&REASONCODE=None&PROTECTIONELIGIBILITY=Eligible&PROTECTIONELIGIBILITYTYPE=ItemNotReceivedEligible%2cUnauthorizedPaymentEligible&L_NAME0=Item%201&L_NAME1=Item%202&L_QTY0=1&L_QTY1=1&L_SHIPPINGAMT0=0%2e00&L_SHIPPINGAMT1=0%2e00&L_HANDLINGAMT0=0%2e00&L_HANDLINGAMT1=0%2e00&L_CURRENCYCODE0=USD&L_CURRENCYCODE1=USD&L_AMT0=687%2e93&L_AMT1=52%2e50
================================================
FILE: spec/fake_response/IPN/invalid.txt
================================================
INVALID
================================================
FILE: spec/fake_response/IPN/valid.txt
================================================
VERIFIED
================================================
FILE: spec/fake_response/ManageRecurringPaymentsProfileStatus/failure.txt
================================================
TIMESTAMP=2011%2d02%2d08T07%3a21%3a08Z&CORRELATIONID=aa160cad77481&ACK=Failure&VERSION=66%2e0&BUILD=1704252&L_ERRORCODE0=11556&L_SHORTMESSAGE0=Invalid%20profile%20status%20for%20cancel%20action%3b%20profile%20should%20be%20active%20or%20suspended&L_LONGMESSAGE0=Invalid%20profile%20status%20for%20cancel%20action%3b%20profile%20should%20be%20active%20or%20suspended&L_SEVERITYCODE0=Error
================================================
FILE: spec/fake_response/ManageRecurringPaymentsProfileStatus/success.txt
================================================
PROFILEID=I%2dK1VFLRN3VVG0&TIMESTAMP=2011%2d02%2d08T07%3a20%3a44Z&CORRELATIONID=86bde487ccba6&ACK=Success&VERSION=66%2e0&BUILD=1704252
================================================
FILE: spec/fake_response/RefundTransaction/full.txt
================================================
REFUNDTRANSACTIONID=6D456341FS516215S&FEEREFUNDAMT=0%2e50&GROSSREFUNDAMT=10%2e00&NETREFUNDAMT=9%2e50&CURRENCYCODE=USD&TOTALREFUNDEDAMOUNT=10%2e00&TIMESTAMP=2011%2d05%2d21T14%3a13%3a32Z&CORRELATIONID=862bfc523cca2&ACK=Success&VERSION=72%2e0&BUILD=1882144
================================================
FILE: spec/fake_response/SetExpressCheckout/failure.txt
================================================
TIMESTAMP=2011%2d02%2d02T02%3a16%3a50Z&CORRELATIONID=379d1b7f97afb&ACK=Failure&L_ERRORCODE0=10001&L_SHORTMESSAGE0=Internal%20Error&L_LONGMESSAGE0=Timeout%20processing%20request
================================================
FILE: spec/fake_response/SetExpressCheckout/success.txt
================================================
ACK=Success&BUILD=1721431&CORRELATIONID=5549ea3a78af1&TIMESTAMP=2011-02-02T02%3A02%3A18Z&TOKEN=EC-5YJ90598G69065317&VERSION=66.0
================================================
FILE: spec/helpers/fake_response_helper.rb
================================================
require 'fakeweb'
module FakeResponseHelper
def fake_response(file_path, api = :NVP, options = {})
endpoint = case api
when :NVP
Paypal::NVP::Request.endpoint
when :IPN
Paypal::IPN.endpoint
else
raise "Non-supported API: #{api}"
end
FakeWeb.register_uri(
:post,
endpoint,
options.merge(
:body => File.read(File.join(File.dirname(__FILE__), '../fake_response', "#{file_path}.txt"))
)
)
end
def request_to(endpoint, method = :get)
raise_error(
FakeWeb::NetConnectNotAllowedError,
"Real HTTP connections are disabled. Unregistered request: #{method.to_s.upcase} #{endpoint}"
)
end
end
FakeWeb.allow_net_connect = false
include FakeResponseHelper
================================================
FILE: spec/paypal/exception/api_error_spec.rb
================================================
require 'spec_helper.rb'
describe Paypal::Exception::APIError do
let(:error) { Paypal::Exception::APIError.new(params) }
context 'when Hash is given' do
let :params do
{
:VERSION=>"66.0",
:TIMESTAMP=>"2011-03-03T06:33:51Z",
:CORRELATIONID=>"758ebdc546b9c",
:BUILD=>"1741654",
:ACK=>"Failure",
:L_SEVERITYCODE0=>"Error",
:L_ERRORCODE0=>"10411",
:L_LONGMESSAGE0=>"This Express Checkout session has expired. Token value is no longer valid.",
:L_SHORTMESSAGE0=>"This Express Checkout session has expired.",
:L_SEVERITYCODE1=>"Error",
:L_ERRORCODE1=>"2468",
:L_LONGMESSAGE1=>"Sample of a long message for the second item.",
:L_SHORTMESSAGE1=>"Second short message.",
}
end
describe "#message" do
it "aggregates short messages" do
error.message.should ==
"PayPal API Error: 'This Express Checkout session has expired.', 'Second short message.'"
end
end
describe '#subject' do
subject { error.response }
its(:raw) { should == params }
Paypal::Exception::APIError::Response.attribute_mapping.each do |key, attribute|
its(attribute) { should == params[key] }
end
describe '#details' do
subject { error.response.details.first }
Paypal::Exception::APIError::Response::Detail.attribute_mapping.each do |key, attribute|
its(attribute) { should == params[:"L_#{key}0"] }
end
end
end
end
context 'when unknown params given' do
let :params do
{
:UNKNOWN => 'Unknown',
:L_UNKNOWN0 => 'Unknown Detail'
}
end
it 'should warn' do
Paypal.logger.should_receive(:warn).with(
"Ignored Parameter (Paypal::Exception::APIError::Response): UNKNOWN=Unknown"
)
Paypal.logger.should_receive(:warn).with(
"Ignored Parameter (Paypal::Exception::APIError::Response::Detail): UNKNOWN=Unknown Detail"
)
error
end
describe '#response' do
subject { error.response }
its(:raw) { should == params }
end
its(:message) { should == "PayPal API Error" }
end
context 'otherwise' do
subject { error }
let(:params) { 'Failure' }
its(:response) { should == params }
its(:message) { should == "PayPal API Error" }
end
end
================================================
FILE: spec/paypal/exception/http_error_spec.rb
================================================
require 'spec_helper.rb'
describe Paypal::Exception::HttpError do
subject { Paypal::Exception::HttpError.new(400, 'BadRequest', 'You are bad man!') }
its(:code) { should == 400 }
its(:message) { should == 'BadRequest' }
its(:body) { should == 'You are bad man!' }
end
================================================
FILE: spec/paypal/express/request_spec.rb
================================================
require 'spec_helper.rb'
describe Paypal::Express::Request do
class Paypal::Express::Request
attr_accessor :_sent_params_, :_method_
def post_with_logging(method, params)
self._method_ = method
self._sent_params_ = params
post_without_logging method, params
end
alias_method_chain :post, :logging
end
let(:return_url) { 'http://example.com/success' }
let(:cancel_url) { 'http://example.com/cancel' }
let(:nvp_endpoint) { Paypal::NVP::Request::ENDPOINT[:production] }
let :attributes do
{
:username => 'nov',
:password => 'password',
:signature => 'sig'
}
end
let :instance do
Paypal::Express::Request.new attributes
end
let :instant_payment_request do
Paypal::Payment::Request.new(
:amount => 1000,
:description => 'Instant Payment Request'
)
end
let :many_items do
items = Array.new
(1..20).each do |index|
items << Paypal::Payment::Request::Item.new(
:name => "Item#{index.to_s}",
:description => "A new Item #{index.to_s}",
:amount => 50.00,
:quantity => 1
)
end
end
let :instant_payment_request_with_many_items do
Paypal::Payment::Request.new(
:amount => 1000,
:description => 'Instant Payment Request',
:items => many_items
)
end
let :recurring_payment_request do
Paypal::Payment::Request.new(
:billing_type => :RecurringPayments,
:billing_agreement_description => 'Recurring Payment Request'
)
end
let :recurring_profile do
Paypal::Payment::Recurring.new(
:start_date => Time.utc(2011, 2, 8, 9, 0, 0),
:description => 'Recurring Profile',
:billing => {
:period => :Month,
:frequency => 1,
:amount => 1000
}
)
end
let :reference_transaction_request do
Paypal::Payment::Request.new(
:billing_type => :MerchantInitiatedBilling,
:billing_agreement_description => 'Billing Agreement Request'
)
end
describe '.new' do
context 'when any required parameters are missing' do
it 'should raise AttrRequired::AttrMissing' do
attributes.keys.each do |missing_key|
insufficient_attributes = attributes.reject do |key, value|
key == missing_key
end
expect do
Paypal::Express::Request.new insufficient_attributes
end.to raise_error AttrRequired::AttrMissing
end
end
end
context 'when all required parameters are given' do
it 'should succeed' do
expect do
Paypal::Express::Request.new attributes
end.not_to raise_error AttrRequired::AttrMissing
end
end
end
describe '#setup' do
it 'should return Paypal::Express::Response' do
fake_response 'SetExpressCheckout/success'
response = instance.setup recurring_payment_request, return_url, cancel_url
response.should be_instance_of Paypal::Express::Response
end
it 'should support no_shipping option' do
expect do
instance.setup instant_payment_request, return_url, cancel_url, :no_shipping => true
end.to request_to nvp_endpoint, :post
instance._method_.should == :SetExpressCheckout
instance._sent_params_.should == {
:PAYMENTREQUEST_0_DESC => 'Instant Payment Request',
:RETURNURL => return_url,
:CANCELURL => cancel_url,
:PAYMENTREQUEST_0_AMT => '1000.00',
:PAYMENTREQUEST_0_TAXAMT => "0.00",
:PAYMENTREQUEST_0_SHIPPINGAMT => "0.00",
:REQCONFIRMSHIPPING => 0,
:NOSHIPPING => 1
}
end
it 'should support allow_note=false option' do
expect do
instance.setup instant_payment_request, return_url, cancel_url, :allow_note => false
end.to request_to nvp_endpoint, :post
instance._method_.should == :SetExpressCheckout
instance._sent_params_.should == {
:PAYMENTREQUEST_0_DESC => 'Instant Payment Request',
:RETURNURL => return_url,
:CANCELURL => cancel_url,
:PAYMENTREQUEST_0_AMT => '1000.00',
:PAYMENTREQUEST_0_TAXAMT => "0.00",
:PAYMENTREQUEST_0_SHIPPINGAMT => "0.00",
:ALLOWNOTE => 0
}
end
{
:solution_type => :SOLUTIONTYPE,
:landing_page => :LANDINGPAGE,
:email => :EMAIL,
:brand => :BRANDNAME,
:locale => :LOCALECODE,
:logo => :LOGOIMG,
:cart_border_color => :CARTBORDERCOLOR,
:payflow_color => :PAYFLOWCOLOR
}.each do |option_key, param_key|
it "should support #{option_key} option" do
expect do
instance.setup instant_payment_request, return_url, cancel_url, option_key => 'some value'
end.to request_to nvp_endpoint, :post
instance._method_.should == :SetExpressCheckout
instance._sent_params_.should include param_key
instance._sent_params_[param_key].should == 'some value'
end
end
context 'when instance payment request given' do
it 'should call SetExpressCheckout' do
expect do
instance.setup instant_payment_request, return_url, cancel_url
end.to request_to nvp_endpoint, :post
instance._method_.should == :SetExpressCheckout
instance._sent_params_.should == {
:PAYMENTREQUEST_0_DESC => 'Instant Payment Request',
:RETURNURL => return_url,
:CANCELURL => cancel_url,
:PAYMENTREQUEST_0_AMT => '1000.00',
:PAYMENTREQUEST_0_TAXAMT => "0.00",
:PAYMENTREQUEST_0_SHIPPINGAMT => "0.00"
}
end
end
context 'when recurring payment request given' do
it 'should call SetExpressCheckout' do
expect do
instance.setup recurring_payment_request, return_url, cancel_url
end.to request_to nvp_endpoint, :post
instance._method_.should == :SetExpressCheckout
instance._sent_params_.should == {
:L_BILLINGTYPE0 => :RecurringPayments,
:L_BILLINGAGREEMENTDESCRIPTION0 => 'Recurring Payment Request',
:RETURNURL => return_url,
:CANCELURL => cancel_url,
:PAYMENTREQUEST_0_AMT => '0.00',
:PAYMENTREQUEST_0_TAXAMT => "0.00",
:PAYMENTREQUEST_0_SHIPPINGAMT => "0.00"
}
end
end
context 'when reference transaction request given' do
it 'should call SetExpressCheckout' do
expect do
instance.setup reference_transaction_request, return_url, cancel_url
end.to request_to nvp_endpoint, :post
instance._method_.should == :SetExpressCheckout
instance._sent_params_.should == {
:L_BILLINGTYPE0 => :MerchantInitiatedBilling,
:L_BILLINGAGREEMENTDESCRIPTION0 => 'Billing Agreement Request',
:RETURNURL => return_url,
:CANCELURL => cancel_url,
:PAYMENTREQUEST_0_AMT => '0.00',
:PAYMENTREQUEST_0_TAXAMT => "0.00",
:PAYMENTREQUEST_0_SHIPPINGAMT => "0.00"
}
end
end
end
describe '#details' do
it 'should return Paypal::Express::Response' do
fake_response 'GetExpressCheckoutDetails/success'
response = instance.details 'token'
response.should be_instance_of Paypal::Express::Response
end
it 'should call GetExpressCheckoutDetails' do
expect do
instance.details 'token'
end.to request_to nvp_endpoint, :post
instance._method_.should == :GetExpressCheckoutDetails
instance._sent_params_.should == {
:TOKEN => 'token'
}
end
end
describe '#transaction_details' do
it 'should return Paypal::Express::Response' do
fake_response 'GetTransactionDetails/success'
response = instance.transaction_details 'transaction_id'
response.should be_instance_of Paypal::Express::Response
end
it 'should call GetTransactionDetails' do
expect do
instance.transaction_details 'transaction_id'
end.to request_to nvp_endpoint, :post
instance._method_.should == :GetTransactionDetails
instance._sent_params_.should == {
:TRANSACTIONID=> 'transaction_id'
}
end
it 'should fail with bad transaction id' do
expect do
fake_response 'GetTransactionDetails/failure'
response = instance.transaction_details 'bad_transaction_id'
end.to raise_error(Paypal::Exception::APIError)
end
it 'should handle all attributes' do
Paypal.logger.should_not_receive(:warn)
fake_response 'GetTransactionDetails/success'
response = instance.transaction_details 'transaction_id'
end
end
describe "#capture!" do
it 'should return Paypal::Express::Response' do
fake_response 'DoCapture/success'
response = instance.capture! 'authorization_id', 181.98, :BRL
response.should be_instance_of Paypal::Express::Response
end
it 'should call DoExpressCheckoutPayment' do
expect do
instance.capture! 'authorization_id', 181.98, :BRL
end.to request_to nvp_endpoint, :post
instance._method_.should == :DoCapture
instance._sent_params_.should == {
:AUTHORIZATIONID => 'authorization_id',
:COMPLETETYPE => 'Complete',
:AMT => 181.98,
:CURRENCYCODE => :BRL
}
end
it 'should call DoExpressCheckoutPayment with NotComplete capture parameter' do
expect do
instance.capture! 'authorization_id', 181.98, :BRL, 'NotComplete'
end.to request_to nvp_endpoint, :post
instance._method_.should == :DoCapture
instance._sent_params_.should == {
:AUTHORIZATIONID => 'authorization_id',
:COMPLETETYPE => 'NotComplete',
:AMT => 181.98,
:CURRENCYCODE => :BRL
}
end
end
describe "#void!" do
it 'should return Paypal::Express::Response' do
fake_response 'DoVoid/success'
response = instance.void! 'authorization_id', note: "note"
response.should be_instance_of Paypal::Express::Response
end
it 'should call DoVoid' do
expect do
instance.void! 'authorization_id', note: "note"
end.to request_to nvp_endpoint, :post
instance._method_.should == :DoVoid
instance._sent_params_.should == {
:AUTHORIZATIONID => 'authorization_id',
:NOTE => "note"
}
end
end
describe '#checkout!' do
it 'should return Paypal::Express::Response' do
fake_response 'DoExpressCheckoutPayment/success'
response = instance.checkout! 'token', 'payer_id', instant_payment_request
response.should be_instance_of Paypal::Express::Response
end
it 'should call DoExpressCheckoutPayment' do
expect do
instance.checkout! 'token', 'payer_id', instant_payment_request
end.to request_to nvp_endpoint, :post
instance._method_.should == :DoExpressCheckoutPayment
instance._sent_params_.should == {
:PAYERID => 'payer_id',
:TOKEN => 'token',
:PAYMENTREQUEST_0_DESC => 'Instant Payment Request',
:PAYMENTREQUEST_0_AMT => '1000.00',
:PAYMENTREQUEST_0_TAXAMT => "0.00",
:PAYMENTREQUEST_0_SHIPPINGAMT => "0.00"
}
end
context "with many items" do
before do
fake_response 'DoExpressCheckoutPayment/success_with_many_items'
end
it 'should handle all attributes' do
Paypal.logger.should_not_receive(:warn)
response = instance.checkout! 'token', 'payer_id', instant_payment_request_with_many_items
end
it 'should return Paypal::Express::Response' do
response = instance.checkout! 'token', 'payer_id', instant_payment_request_with_many_items
response.should be_instance_of Paypal::Express::Response
end
it 'should return twenty items' do
response = instance.checkout! 'token', 'payer_id', instant_payment_request_with_many_items
instance._method_.should == :DoExpressCheckoutPayment
response.items.count.should == 20
end
end
end
describe '#subscribe!' do
it 'should return Paypal::Express::Response' do
fake_response 'CreateRecurringPaymentsProfile/success'
response = instance.subscribe! 'token', recurring_profile
response.should be_instance_of Paypal::Express::Response
end
it 'should call CreateRecurringPaymentsProfile' do
expect do
instance.subscribe! 'token', recurring_profile
end.to request_to nvp_endpoint, :post
instance._method_.should == :CreateRecurringPaymentsProfile
instance._sent_params_.should == {
:DESC => 'Recurring Profile',
:TOKEN => 'token',
:SHIPPINGAMT => '0.00',
:AMT => '1000.00',
:BILLINGFREQUENCY => 1,
:MAXFAILEDPAYMENTS => 0,
:BILLINGPERIOD => :Month,
:TAXAMT => '0.00',
:PROFILESTARTDATE => '2011-02-08 09:00:00',
:TOTALBILLINGCYCLES => 0
}
end
end
describe '#subscription' do
it 'should return Paypal::Express::Response' do
fake_response 'GetRecurringPaymentsProfileDetails/success'
response = instance.subscription 'profile_id'
response.should be_instance_of(Paypal::Express::Response)
end
it 'should call GetRecurringPaymentsProfileDetails' do
expect do
instance.subscription 'profile_id'
end.to request_to nvp_endpoint, :post
instance._method_.should == :GetRecurringPaymentsProfileDetails
instance._sent_params_.should == {
:PROFILEID => 'profile_id'
}
end
end
describe '#renew!' do
it 'should return Paypal::Express::Response' do
fake_response 'ManageRecurringPaymentsProfileStatus/success'
response = instance.renew! 'profile_id', :Cancel
response.should be_instance_of Paypal::Express::Response
end
it 'should call ManageRecurringPaymentsProfileStatus' do
expect do
instance.renew! 'profile_id', :Cancel
end.to request_to nvp_endpoint, :post
instance._method_.should == :ManageRecurringPaymentsProfileStatus
instance._sent_params_.should == {
:ACTION => :Cancel,
:PROFILEID => 'profile_id'
}
end
end
describe '#cancel!' do
it 'should return Paypal::Express::Response' do
fake_response 'ManageRecurringPaymentsProfileStatus/success'
response = instance.cancel! 'profile_id'
response.should be_instance_of(Paypal::Express::Response)
end
it 'should call ManageRecurringPaymentsProfileStatus' do
expect do
instance.cancel! 'profile_id'
end.to request_to nvp_endpoint, :post
instance._method_.should == :ManageRecurringPaymentsProfileStatus
instance._sent_params_.should == {
:ACTION => :Cancel,
:PROFILEID => 'profile_id'
}
end
end
describe '#suspend!' do
it 'should return Paypal::Express::Response' do
fake_response 'ManageRecurringPaymentsProfileStatus/success'
response = instance.cancel! 'profile_id'
response.should be_instance_of Paypal::Express::Response
end
it 'should call ManageRecurringPaymentsProfileStatus' do
expect do
instance.suspend! 'profile_id'
end.to request_to nvp_endpoint, :post
instance._method_.should == :ManageRecurringPaymentsProfileStatus
instance._sent_params_.should == {
:ACTION => :Suspend,
:PROFILEID => 'profile_id'
}
end
end
describe '#reactivate!' do
it 'should return Paypal::Express::Response' do
fake_response 'ManageRecurringPaymentsProfileStatus/success'
response = instance.cancel! 'profile_id'
response.should be_instance_of Paypal::Express::Response
end
it 'should call ManageRecurringPaymentsProfileStatus' do
expect do
instance.reactivate! 'profile_id'
end.to request_to nvp_endpoint, :post
instance._method_.should == :ManageRecurringPaymentsProfileStatus
instance._sent_params_.should == {
:ACTION => :Reactivate,
:PROFILEID => 'profile_id'
}
end
end
describe '#agree!' do
it 'should return Paypal::Express::Response' do
fake_response 'CreateBillingAgreement/success'
response = instance.agree! 'token'
response.should be_instance_of Paypal::Express::Response
end
it 'should call CreateBillingAgreement' do
expect do
instance.agree! 'token'
end.to request_to nvp_endpoint, :post
instance._method_.should == :CreateBillingAgreement
instance._sent_params_.should == {
:TOKEN => 'token'
}
end
end
describe '#agreement' do
it 'should return Paypal::Express::Response' do
fake_response 'BillAgreementUpdate/fetch'
response = instance.agreement 'reference_id'
response.should be_instance_of Paypal::Express::Response
end
it 'should call BillAgreementUpdate' do
expect do
instance.agreement 'reference_id'
end.to request_to nvp_endpoint, :post
instance._method_.should == :BillAgreementUpdate
instance._sent_params_.should == {
:REFERENCEID => 'reference_id'
}
end
end
describe '#charge!' do
it 'should return Paypal::Express::Response' do
fake_response 'DoReferenceTransaction/success'
response = instance.charge! 'billing_agreement_id', 1000
response.should be_instance_of Paypal::Express::Response
end
it 'should call DoReferenceTransaction' do
expect do
instance.charge! 'billing_agreement_id', 1000, :currency_code => :JPY
end.to request_to nvp_endpoint, :post
instance._method_.should == :DoReferenceTransaction
instance._sent_params_.should == {
:REFERENCEID => 'billing_agreement_id',
:AMT => '1000.00',
:PAYMENTACTION => :Sale,
:CURRENCYCODE => :JPY
}
end
end
describe '#revoke!' do
it 'should return Paypal::Express::Response' do
fake_response 'BillAgreementUpdate/revoke'
response = instance.revoke! 'reference_id'
response.should be_instance_of Paypal::Express::Response
end
it 'should call BillAgreementUpdate' do
expect do
instance.revoke! 'reference_id'
end.to request_to nvp_endpoint, :post
instance._method_.should == :BillAgreementUpdate
instance._sent_params_.should == {
:REFERENCEID => 'reference_id',
:BillingAgreementStatus => :Canceled
}
end
end
describe '#refund!' do
it 'should return Paypal::Express::Response' do
fake_response 'RefundTransaction/full'
response = instance.refund! 'transaction_id'
response.should be_instance_of Paypal::Express::Response
end
it 'should call RefundTransaction' do
expect do
instance.refund! 'transaction_id'
end.to request_to nvp_endpoint, :post
instance._method_.should == :RefundTransaction
instance._sent_params_.should == {
:TRANSACTIONID => 'transaction_id',
:REFUNDTYPE => :Full
}
end
end
end
================================================
FILE: spec/paypal/express/response_spec.rb
================================================
require 'spec_helper.rb'
describe Paypal::Express::Response do
before { fake_response 'SetExpressCheckout/success' }
let(:return_url) { 'http://example.com/success' }
let(:cancel_url) { 'http://example.com/cancel' }
let :request do
Paypal::Express::Request.new(
:username => 'nov',
:password => 'password',
:signature => 'sig'
)
end
let :payment_request do
Paypal::Payment::Request.new(
:billing_type => :RecurringPayments,
:billing_agreement_description => 'Recurring Payment Request'
)
end
let(:response) { request.setup payment_request, return_url, cancel_url }
describe '#redirect_uri' do
subject { response.redirect_uri }
it { should include 'https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=' }
end
describe '#popup_uri' do
subject { response.popup_uri }
it { should include 'https://www.paypal.com/incontext?token=' }
end
context 'when pay_on_paypal option is given' do
let(:response) { request.setup payment_request, return_url, cancel_url, :pay_on_paypal => true }
subject { response }
its(:pay_on_paypal) { should be_true }
its(:query) { should include(:useraction => 'commit') }
describe '#redirect_uri' do
subject { response.redirect_uri }
it { should include 'useraction=commit' }
end
describe '#popup_uri' do
subject { response.popup_uri }
it { should include 'useraction=commit' }
end
end
context 'when sandbox mode' do
before do
Paypal.sandbox!
fake_response 'SetExpressCheckout/success'
end
after { Paypal.sandbox = false }
describe '#redirect_uri' do
subject { response.redirect_uri }
it { should include 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=' }
end
describe '#popup_uri' do
subject { response.popup_uri }
it { should include 'https://www.sandbox.paypal.com/incontext?token=' }
end
end
context 'when mobile option is given' do
let(:response) { request.setup payment_request, return_url, cancel_url, :mobile => true }
subject { response }
describe '#redirect_uri' do
subject { response.redirect_uri }
it { should include 'https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout-mobile&token=' }
end
end
end
================================================
FILE: spec/paypal/ipn_spec.rb
================================================
require 'spec_helper'
describe Paypal::IPN do
describe '.verify!' do
context 'when valid' do
before { fake_response 'IPN/valid', :IPN }
subject { Paypal::IPN.verify!('raw-post-body') }
it { should be_true }
end
context 'when invalid' do
before { fake_response 'IPN/invalid', :IPN }
subject {}
it do
expect { Paypal::IPN.verify!('raw-post-body') }.to raise_error(Paypal::Exception::APIError)
end
end
end
end
================================================
FILE: spec/paypal/nvp/request_spec.rb
================================================
require 'spec_helper.rb'
describe Paypal::NVP::Request do
let :attributes do
{
:username => 'nov',
:password => 'password',
:signature => 'sig'
}
end
let :instance do
Paypal::NVP::Request.new attributes
end
describe '.new' do
context 'when any required parameters are missing' do
it 'should raise AttrRequired::AttrMissing' do
attributes.keys.each do |missing_key|
insufficient_attributes = attributes.reject do |key, value|
key == missing_key
end
expect do
Paypal::NVP::Request.new insufficient_attributes
end.to raise_error AttrRequired::AttrMissing
end
end
end
context 'when all required parameters are given' do
it 'should succeed' do
expect do
Paypal::NVP::Request.new attributes
end.not_to raise_error AttrRequired::AttrMissing
end
it 'should setup endpoint and version' do
client = Paypal::NVP::Request.new attributes
client.class.endpoint.should == Paypal::NVP::Request::ENDPOINT[:production]
end
it 'should support sandbox mode' do
sandbox_mode do
client = Paypal::NVP::Request.new attributes
client.class.endpoint.should == Paypal::NVP::Request::ENDPOINT[:sandbox]
end
end
end
context 'when optional parameters are given' do
let(:optional_attributes) do
{ :subject => 'user@example.com' }
end
it 'should setup subject' do
client = Paypal::NVP::Request.new attributes.merge(optional_attributes)
client.subject.should == 'user@example.com'
end
end
end
describe '#common_params' do
{
:username => :USER,
:password => :PWD,
:signature => :SIGNATURE,
:subject => :SUBJECT,
:version => :VERSION
}.each do |option_key, param_key|
it "should include :#{param_key}" do
instance.common_params.should include(param_key)
end
it "should set :#{param_key} as #{option_key}" do
instance.common_params[param_key].should == instance.send(option_key)
end
end
end
describe '#request' do
it 'should POST to NPV endpoint' do
expect do
instance.request :RPCMethod
end.to request_to Paypal::NVP::Request::ENDPOINT[:production], :post
end
context 'when got API error response' do
before do
fake_response 'SetExpressCheckout/failure'
end
it 'should raise Paypal::Exception::APIError' do
expect do
instance.request :SetExpressCheckout
end.to raise_error(Paypal::Exception::APIError)
end
end
context 'when got HTTP error response' do
before do
FakeWeb.register_uri(
:post,
Paypal::NVP::Request::ENDPOINT[:production],
:body => "Invalid Request",
:status => ["400", "Bad Request"]
)
end
it 'should raise Paypal::Exception::HttpError' do
expect do
instance.request :SetExpressCheckout
end.to raise_error(Paypal::Exception::HttpError)
end
end
end
end
================================================
FILE: spec/paypal/nvp/response_spec.rb
================================================
require 'spec_helper.rb'
describe Paypal::NVP::Response do
let(:return_url) { 'http://example.com/success' }
let(:cancel_url) { 'http://example.com/cancel' }
let :request do
Paypal::Express::Request.new(
:username => 'nov',
:password => 'password',
:signature => 'sig'
)
end
let :payment_request do
Paypal::Payment::Request.new(
:amount => 1000,
:description => 'Instant Payment Request'
)
end
let :recurring_profile do
Paypal::Payment::Recurring.new(
:start_date => Time.utc(2011, 2, 8, 9, 0, 0),
:description => 'Recurring Profile',
:billing => {
:period => :Month,
:frequency => 1,
:amount => 1000
}
)
end
describe '.new' do
context 'when non-supported attributes are given' do
it 'should ignore them and warn' do
Paypal.logger.should_receive(:warn).with(
"Ignored Parameter (Paypal::NVP::Response): ignored=Ignore me!"
)
Paypal::NVP::Response.new(
:ignored => 'Ignore me!'
)
end
end
context 'when SetExpressCheckout response given' do
before do
fake_response 'SetExpressCheckout/success'
end
it 'should handle all attributes' do
Paypal.logger.should_not_receive(:warn)
response = request.setup payment_request, return_url, cancel_url
response.token.should == 'EC-5YJ90598G69065317'
end
end
context 'when GetExpressCheckoutDetails response given' do
before do
fake_response 'GetExpressCheckoutDetails/success'
end
it 'should handle all attributes' do
Paypal.logger.should_not_receive(:warn)
response = request.details 'token'
response.payer.identifier.should == '9RWDTMRKKHQ8S'
response.payment_responses.size.should == 1
response.payment_info.size.should == 0
response.payment_responses.first.should be_instance_of(Paypal::Payment::Response)
end
context 'when BILLINGAGREEMENTACCEPTEDSTATUS included' do
before do
fake_response 'GetExpressCheckoutDetails/with_billing_accepted_status'
end
it 'should handle all attributes' do
Paypal.logger.should_not_receive(:warn)
response = request.details 'token'
end
end
end
context 'when DoExpressCheckoutPayment response given' do
before do
fake_response 'DoExpressCheckoutPayment/success'
end
it 'should handle all attributes' do
Paypal.logger.should_not_receive(:warn)
response = request.checkout! 'token', 'payer_id', payment_request
response.payment_responses.size.should == 0
response.payment_info.size.should == 1
response.payment_info.first.should be_instance_of(Paypal::Payment::Response::Info)
end
context 'when billing_agreement is included' do
before do
fake_response 'DoExpressCheckoutPayment/success_with_billing_agreement'
end
it 'should have billing_agreement' do
Paypal.logger.should_not_receive(:warn)
response = request.checkout! 'token', 'payer_id', payment_request
response.billing_agreement.identifier.should == 'B-1XR87946TC504770W'
end
end
end
context 'when CreateRecurringPaymentsProfile response given' do
before do
fake_response 'CreateRecurringPaymentsProfile/success'
end
it 'should handle all attributes' do
Paypal.logger.should_not_receive(:warn)
response = request.subscribe! 'token', recurring_profile
response.recurring.identifier.should == 'I-L8N58XFUCET3'
end
end
context 'when GetRecurringPaymentsProfileDetails response given' do
before do
fake_response 'GetRecurringPaymentsProfileDetails/success'
end
it 'should handle all attributes' do
Paypal.logger.should_not_receive(:warn)
response = request.subscription 'profile_id'
response.recurring.billing.amount.total.should == 1000
response.recurring.regular_billing.paid.should == 1000
response.recurring.summary.next_billing_date.should == '2011-03-04T10:00:00Z'
end
end
context 'when ManageRecurringPaymentsProfileStatus response given' do
before do
fake_response 'ManageRecurringPaymentsProfileStatus/success'
end
it 'should handle all attributes' do
Paypal.logger.should_not_receive(:warn)
request.renew! 'profile_id', :Cancel
end
end
end
end
================================================
FILE: spec/paypal/payment/common/amount_spec.rb
================================================
require 'spec_helper.rb'
describe Paypal::Payment::Common::Amount do
let :keys do
Paypal::Payment::Common::Amount.optional_attributes
end
describe '.new' do
it 'should not allow nil for attributes' do
amount = Paypal::Payment::Common::Amount.new
keys.each do |key|
amount.send(key).should == 0
end
end
it 'should treat all attributes as Numeric' do
# Integer
attributes = keys.inject({}) do |attributes, key|
attributes.merge!(key => "100")
end
amount = Paypal::Payment::Common::Amount.new attributes
keys.each do |key|
amount.send(key).should == 100
end
# Float
attributes = keys.inject({}) do |attributes, key|
attributes.merge!(key => "10.25")
end
amount = Paypal::Payment::Common::Amount.new attributes
keys.each do |key|
amount.send(key).should == 10.25
end
end
end
end
================================================
FILE: spec/paypal/payment/recurring/activation_spec.rb
================================================
require 'spec_helper'
describe Paypal::Payment::Recurring::Activation do
let :instance do
Paypal::Payment::Recurring::Activation.new(
:initial_amount => 100,
:failed_action => 'ContinueOnFailure'
)
end
describe '#to_params' do
it 'should handle Recurring Profile activation parameters' do
instance.to_params.should == {
:INITAMT => '100.00',
:FAILEDINITAMTACTION => 'ContinueOnFailure'
}
end
end
end
================================================
FILE: spec/paypal/payment/recurring_spec.rb
================================================
require 'spec_helper.rb'
describe Paypal::Payment::Recurring do
let :keys do
Paypal::Payment::Recurring.optional_attributes
end
let :trial_attributes do
{}
end
let :attributes do
{
:identifier => '12345',
:description => 'Subscription Payment Profile',
:status => 'Active',
:start_date => '2011-02-03T15:00:00Z',
:name => 'Nov Matake',
:auto_bill => 'NoAutoBill',
:max_fails => '0',
:aggregate_amount => '1000',
:aggregate_optional_amount => '0',
:final_payment_date => '1970-01-01T00:00:00Z',
:billing => {
:amount => Paypal::Payment::Common::Amount.new(
:total => '1000',
:shipping => '0',
:tax => '0'
),
:currency_code => 'JPY',
:period => 'Month',
:frequency => '1',
:total_cycles => '0',
:trial => trial_attributes
},
:regular_billing => {
:amount => '1000',
:shipping_amount => '0',
:tax_amount => '0',
:currency_code => 'JPY',
:period => 'Month',
:frequency => '1',
:total_cycles => '0',
:paid => '1000'
},
:summary => {
:next_billing_date => '2011-03-04T10:00:00Z',
:cycles_completed => '1',
:cycles_remaining => '18446744073709551615',
:outstanding_balance => '0',
:failed_count => '0',
:last_payment_date => '2011-02-04T10:50:56Z',
:last_payment_amount => '1000'
}
}
end
let :instance do
Paypal::Payment::Recurring.new attributes
end
describe '.new' do
it 'should accept all supported attributes' do
instance.identifier.should == '12345'
instance.description.should == 'Subscription Payment Profile'
instance.status.should == 'Active'
instance.start_date.should == '2011-02-03T15:00:00Z'
instance.billing.trial.should be_nil
end
context 'when optional trial info given' do
let :trial_attributes do
{
:period => 'Month',
:frequency => '1',
:total_cycles => '0',
:currency_code => 'JPY',
:amount => '1000',
:shipping_amount => '0',
:tax_amount => '0'
}
end
it 'should setup trial billing info' do
instance.billing.trial.should == Paypal::Payment::Recurring::Billing.new(trial_attributes)
end
end
end
describe '#to_params' do
it 'should handle Recurring Profile parameters' do
instance.to_params.should == {
:AUTOBILLOUTAMT => 'NoAutoBill',
:BILLINGFREQUENCY => 1,
:SHIPPINGAMT => '0.00',
:DESC => 'Subscription Payment Profile',
:SUBSCRIBERNAME => 'Nov Matake',
:BILLINGPERIOD => 'Month',
:AMT => '1000.00',
:MAXFAILEDPAYMENTS => 0,
:TOTALBILLINGCYCLES => 0,
:TAXAMT => '0.00',
:PROFILESTARTDATE => '2011-02-03T15:00:00Z',
:CURRENCYCODE => 'JPY'
}
end
context 'when start_date is Time' do
it 'should be stringfy' do
instance = Paypal::Payment::Recurring.new attributes.merge(
:start_date => Time.utc(2011, 2, 8, 15, 0, 0)
)
instance.start_date.should be_instance_of(Time)
instance.to_params[:PROFILESTARTDATE].should == '2011-02-08 15:00:00'
end
end
context 'when optional trial setting given' do
let :trial_attributes do
{
:period => 'Month',
:frequency => '1',
:total_cycles => '0',
:currency_code => 'JPY',
:amount => '1000',
:shipping_amount => '0',
:tax_amount => '0'
}
end
it 'should setup trial billing info' do
instance.to_params.should == {
:TRIALBILLINGPERIOD => "Month",
:TRIALBILLINGFREQUENCY => 1,
:TRIALTOTALBILLINGCYCLES => 0,
:TRIALAMT => "1000.00",
:TRIALCURRENCYCODE => "JPY",
:TRIALSHIPPINGAMT => "0.00",
:TRIALTAXAMT => "0.00",
:BILLINGPERIOD => "Month",
:BILLINGFREQUENCY => 1,
:TOTALBILLINGCYCLES => 0,
:AMT => "1000.00",
:CURRENCYCODE => "JPY",
:SHIPPINGAMT => "0.00",
:TAXAMT => "0.00",
:DESC => "Subscription Payment Profile",
:MAXFAILEDPAYMENTS => 0,
:AUTOBILLOUTAMT => "NoAutoBill",
:PROFILESTARTDATE => "2011-02-03T15:00:00Z",
:SUBSCRIBERNAME => "Nov Matake"
}
end
end
end
describe '#numeric_attribute?' do
let :numeric_attributes do
[:aggregate_amount, :aggregate_optional_amount, :max_fails, :failed_count]
end
it 'should detect numeric attributes' do
numeric_attributes.each do |key|
instance.numeric_attribute?(key).should be_true
end
non_numeric_keys = keys - numeric_attributes
non_numeric_keys.each do |key|
instance.numeric_attribute?(key).should be_false
end
end
end
end
================================================
FILE: spec/paypal/payment/request/item_spec.rb
================================================
require 'spec_helper.rb'
describe Paypal::Payment::Request::Item do
let :instance do
Paypal::Payment::Request::Item.new(
:name => 'Name',
:description => 'Description',
:amount => 10,
:quantity => 5,
:category => :Digital,
:number => '1'
)
end
describe '#to_params' do
it 'should handle Recurring Profile activation parameters' do
instance.to_params(1).should == {
:L_PAYMENTREQUEST_1_NAME0 => 'Name',
:L_PAYMENTREQUEST_1_DESC0 => 'Description',
:L_PAYMENTREQUEST_1_AMT0 => '10.00',
:L_PAYMENTREQUEST_1_QTY0 => 5,
:L_PAYMENTREQUEST_1_ITEMCATEGORY0 => :Digital,
:L_PAYMENTREQUEST_1_NUMBER0 => '1'
}
end
end
end
================================================
FILE: spec/paypal/payment/request_spec.rb
================================================
require 'spec_helper.rb'
describe Paypal::Payment::Request do
let :instant_request do
Paypal::Payment::Request.new(
:amount => 25.7,
:tax_amount => 0.4,
:shipping_amount => 1.5,
:currency_code => :JPY,
:description => 'Instant Payment Request',
:notify_url => 'http://merchant.example.com/notify',
:invoice_number => 'ABC123',
:custom => 'Custom',
:items => [{
:quantity => 2,
:name => 'Item1',
:description => 'Awesome Item 1!',
:amount => 10.25
}, {
:quantity => 3,
:name => 'Item2',
:description => 'Awesome Item 2!',
:amount => 1.1
}],
:custom_fields => {
"l_surveychoice{n}" => 'abcd' # The '{n}' will be replaced with the index
}
)
end
let :recurring_request do
Paypal::Payment::Request.new(
:currency_code => :JPY,
:billing_type => :RecurringPayments,
:billing_agreement_description => 'Recurring Payment Request'
)
end
let :reference_transaction_request do
Paypal::Payment::Request.new(
:currency_code => :JPY,
:billing_type => :MerchantInitiatedBillingSingleAgreement,
:billing_agreement_description => 'Reference Transaction Request'
)
end
describe '.new' do
it 'should handle Instant Payment parameters' do
instant_request.amount.total.should == 25.7
instant_request.amount.tax.should == 0.4
instant_request.amount.shipping.should == 1.5
instant_request.currency_code.should == :JPY
instant_request.description.should == 'Instant Payment Request'
instant_request.notify_url.should == 'http://merchant.example.com/notify'
end
it 'should handle Recurring Payment parameters' do
recurring_request.currency_code.should == :JPY
recurring_request.billing_type.should == :RecurringPayments
recurring_request.billing_agreement_description.should == 'Recurring Payment Request'
end
it 'should handle Recurring Payment parameters' do
reference_transaction_request.currency_code.should == :JPY
reference_transaction_request.billing_type.should == :MerchantInitiatedBillingSingleAgreement
reference_transaction_request.billing_agreement_description.should == 'Reference Transaction Request'
end
end
describe '#to_params' do
it 'should handle Instant Payment parameters' do
instant_request.to_params.should == {
:PAYMENTREQUEST_0_AMT => "25.70",
:PAYMENTREQUEST_0_TAXAMT => "0.40",
:PAYMENTREQUEST_0_SHIPPINGAMT => "1.50",
:PAYMENTREQUEST_0_CURRENCYCODE => :JPY,
:PAYMENTREQUEST_0_DESC => "Instant Payment Request",
:PAYMENTREQUEST_0_NOTIFYURL => "http://merchant.example.com/notify",
:PAYMENTREQUEST_0_ITEMAMT => "23.80",
:PAYMENTREQUEST_0_INVNUM => "ABC123",
:PAYMENTREQUEST_0_CUSTOM => "Custom",
:L_PAYMENTREQUEST_0_NAME0 => "Item1",
:L_PAYMENTREQUEST_0_DESC0 => "Awesome Item 1!",
:L_PAYMENTREQUEST_0_AMT0 => "10.25",
:L_PAYMENTREQUEST_0_QTY0 => 2,
:L_PAYMENTREQUEST_0_NAME1 => "Item2",
:L_PAYMENTREQUEST_0_DESC1 => "Awesome Item 2!",
:L_PAYMENTREQUEST_0_AMT1 => "1.10",
:L_PAYMENTREQUEST_0_QTY1 => 3,
:L_SURVEYCHOICE0 => 'abcd' # Note the 'n' was replaced by the index
}
end
it 'should handle Recurring Payment parameters' do
recurring_request.to_params.should == {
:PAYMENTREQUEST_0_AMT => "0.00",
:PAYMENTREQUEST_0_TAXAMT => "0.00",
:PAYMENTREQUEST_0_SHIPPINGAMT => "0.00",
:PAYMENTREQUEST_0_CURRENCYCODE => :JPY,
:L_BILLINGTYPE0 => :RecurringPayments,
:L_BILLINGAGREEMENTDESCRIPTION0 => "Recurring Payment Request"
}
end
it 'should handle Reference Transactions parameters' do
reference_transaction_request.to_params.should == {
:PAYMENTREQUEST_0_AMT => "0.00",
:PAYMENTREQUEST_0_TAXAMT => "0.00",
:PAYMENTREQUEST_0_SHIPPINGAMT => "0.00",
:PAYMENTREQUEST_0_CURRENCYCODE => :JPY,
:L_BILLINGTYPE0 => :MerchantInitiatedBillingSingleAgreement,
:L_BILLINGAGREEMENTDESCRIPTION0 => "Reference Transaction Request"
}
end
end
describe '#items_amount' do
context 'when BigDecimal'
let(:instance) do
Paypal::Payment::Request.new(
:items => [{
:quantity => 3,
:name => 'Item1',
:description => 'Awesome Item 1!',
:amount => 130.45
}]
)
end
# NOTE:
# 130.45 * 3 => 391.34999999999997 (in ruby 1.9)
it 'should calculate total amount correctly' do
instance.items_amount.should == 391.35
end
end
end
================================================
FILE: spec/paypal/payment/response/address_spec.rb
================================================
require 'spec_helper.rb'
describe Paypal::Payment::Response::Address do
let :keys do
Paypal::Payment::Response::Address.optional_attributes
end
describe '.new' do
it 'should allow nil for attributes' do
payer = Paypal::Payment::Response::Address.new
keys.each do |key|
payer.send(key).should be_nil
end
end
it 'should treat all attributes as String' do
attributes = keys.inject({}) do |attributes, key|
attributes.merge!(key => "xyz")
end
payer = Paypal::Payment::Response::Address.new attributes
keys.each do |key|
payer.send(key).should == "xyz"
end
end
end
end
================================================
FILE: spec/paypal/payment/response/info_spec.rb
================================================
require 'spec_helper.rb'
describe Paypal::Payment::Response::Info do
let :attribute_mapping do
Paypal::Payment::Response::Info.attribute_mapping
end
let :attributes do
{
:ACK => 'Success',
:CURRENCYCODE => 'JPY',
:ERRORCODE => 0,
:ORDERTIME => '2011-02-08T03:23:54Z',
:PAYMENTSTATUS => 'Completed',
:PAYMENTTYPE => 'instant',
:PENDINGREASON => 'None',
:PROTECTIONELIGIBILITY => 'Ineligible',
:PROTECTIONELIGIBILITYTYPE => 'None',
:REASONCODE => 'None',
:TRANSACTIONID => '8NC65222871997739',
:TRANSACTIONTYPE => 'expresscheckout',
:AMT => '14.00',
:FEEAMT => '0.85',
:TAXAMT => '0.00',
:RECEIPTID => '12345',
:SECUREMERCHANTACCOUNTID => '123456789',
:PAYMENTREQUESTID => '12345',
:SELLERPAYPALACCOUNTID => 'seller@shop.example.com',
:EXCHANGERATE => '0.811965'
}
end
describe '.new' do
context 'when attribute keys are uppercase Symbol' do
it 'should accept all without any warning' do
Paypal.logger.should_not_receive(:warn)
from_symbol_uppercase = Paypal::Payment::Response::Info.new attributes
attribute_mapping.values.each do |key|
from_symbol_uppercase.send(key).should_not be_nil
end
from_symbol_uppercase.amount.should == Paypal::Payment::Common::Amount.new(
:total => 14,
:fee => 0.85
)
end
end
context 'when attribute keys are lowercase Symbol' do
it 'should ignore them and warn' do
_attrs_ = attributes.inject({}) do |_attrs_, (k, v)|
_attrs_.merge!(k.to_s.downcase.to_sym => v)
end
_attrs_.each do |key, value|
Paypal.logger.should_receive(:warn).with(
"Ignored Parameter (Paypal::Payment::Response::Info): #{key}=#{value}"
)
end
from_symbol_lowercase = Paypal::Payment::Response::Info.new _attrs_
attribute_mapping.values.each do |key|
from_symbol_lowercase.send(key).should be_nil
end
from_symbol_lowercase.amount.should == Paypal::Payment::Common::Amount.new
end
end
context 'when attribute keys are String' do
it 'should ignore them and warn' do
attributes.stringify_keys.each do |key, value|
Paypal.logger.should_receive(:warn).with(
"Ignored Parameter (Paypal::Payment::Response::Info): #{key}=#{value}"
)
end
from_string = Paypal::Payment::Response::Info.new attributes.stringify_keys
attribute_mapping.values.each do |key|
from_string.send(key).should be_nil
end
from_string.amount.should == Paypal::Payment::Common::Amount.new
end
end
context 'when non-supported attributes are given' do
it 'should ignore them and warn' do
_attr_ = attributes.merge(
:ignored => 'Ignore me!'
)
Paypal.logger.should_receive(:warn).with(
"Ignored Parameter (Paypal::Payment::Response::Info): ignored=Ignore me!"
)
Paypal::Payment::Response::Info.new _attr_
end
end
end
end
================================================
FILE: spec/paypal/payment/response/item_spec.rb
================================================
require 'spec_helper.rb'
describe Paypal::Payment::Response::Info do
let :attributes do
{
:NAME => 'Item Name',
:DESC => 'Item Description',
:QTY => '1',
:NUMBER => '1',
:ITEMCATEGORY => 'Digital',
:ITEMWIDTHVALUE => '1.0',
:ITEMHEIGHTVALUE => '2.0',
:ITEMLENGTHVALUE => '3.0',
:ITEMWEIGHTVALUE => '4.0'
}
end
describe '.new' do
subject { Paypal::Payment::Response::Item.new(attributes) }
its(:name) { should == 'Item Name' }
its(:description) { should == 'Item Description' }
its(:quantity) { should == 1 }
its(:category) { should == 'Digital' }
its(:width) { should == '1.0' }
its(:height) { should == '2.0' }
its(:length) { should == '3.0' }
its(:weight) { should == '4.0' }
its(:number) { should == '1' }
context 'when non-supported attributes are given' do
it 'should ignore them and warn' do
_attr_ = attributes.merge(
:ignored => 'Ignore me!'
)
Paypal.logger.should_receive(:warn).with(
"Ignored Parameter (Paypal::Payment::Response::Item): ignored=Ignore me!"
)
Paypal::Payment::Response::Item.new _attr_
end
end
end
end
================================================
FILE: spec/paypal/payment/response/payer_spec.rb
================================================
require 'spec_helper.rb'
describe Paypal::Payment::Response::Payer do
let :keys do
Paypal::Payment::Response::Payer.optional_attributes
end
describe '.new' do
it 'should allow nil for attributes' do
payer = Paypal::Payment::Response::Payer.new
keys.each do |key|
payer.send(key).should be_nil
end
end
it 'should treat all attributes as String' do
attributes = keys.inject({}) do |attributes, key|
attributes.merge!(key => "xyz")
end
payer = Paypal::Payment::Response::Payer.new attributes
keys.each do |key|
payer.send(key).should == "xyz"
end
end
end
end
================================================
FILE: spec/paypal/payment/response_spec.rb
================================================
require 'spec_helper.rb'
describe Paypal::Payment::Response do
describe '.new' do
context 'when non-supported attributes are given' do
it 'should ignore them and warn' do
Paypal.logger.should_receive(:warn).with(
"Ignored Parameter (Paypal::Payment::Response): ignored=Ignore me!"
)
response = Paypal::Payment::Response.new(
:ignored => 'Ignore me!'
)
end
end
end
end
================================================
FILE: spec/paypal/util_spec.rb
================================================
require 'spec_helper.rb'
describe Paypal::Util do
describe '.formatted_amount' do
it 'should return String in "xx.yy" format' do
Paypal::Util.formatted_amount(nil).should == '0.00'
Paypal::Util.formatted_amount(10).should == '10.00'
Paypal::Util.formatted_amount(10.02).should == '10.02'
Paypal::Util.formatted_amount(10.2).should == '10.20'
Paypal::Util.formatted_amount(10.24).should == '10.24'
Paypal::Util.formatted_amount(10.255).should == '10.25'
end
end
describe '.to_numeric' do
it 'should return Numeric' do
Paypal::Util.to_numeric('10').should be_kind_of(Integer)
Paypal::Util.to_numeric('10.5').should be_kind_of(Float)
Paypal::Util.to_numeric('-1.5').should == -1.5
Paypal::Util.to_numeric('-1').should == -1
Paypal::Util.to_numeric('0').should == 0
Paypal::Util.to_numeric('0.00').should == 0
Paypal::Util.to_numeric('10').should == 10
Paypal::Util.to_numeric('10.00').should == 10
Paypal::Util.to_numeric('10.02').should == 10.02
Paypal::Util.to_numeric('10.2').should == 10.2
Paypal::Util.to_numeric('10.20').should == 10.2
Paypal::Util.to_numeric('10.24').should == 10.24
Paypal::Util.to_numeric('10.25').should == 10.25
end
end
end
================================================
FILE: spec/spec_helper.rb
================================================
require 'simplecov'
SimpleCov.start do
add_filter 'spec'
end
require 'paypal'
require 'rspec'
require 'helpers/fake_response_helper'
RSpec.configure do |config|
config.before do
Paypal.logger = double("logger")
end
config.after do
FakeWeb.clean_registry
end
end
def sandbox_mode(&block)
Paypal.sandbox!
yield
ensure
Paypal.sandbox = false
end
gitextract_wg6sknv5/
├── .document
├── .github/
│ └── FUNDING.yml
├── .gitignore
├── .rspec
├── .travis.yml
├── Gemfile
├── LICENSE
├── README.rdoc
├── Rakefile
├── VERSION
├── lib/
│ ├── paypal/
│ │ ├── base.rb
│ │ ├── exception/
│ │ │ ├── api_error.rb
│ │ │ └── http_error.rb
│ │ ├── exception.rb
│ │ ├── express/
│ │ │ ├── request.rb
│ │ │ └── response.rb
│ │ ├── express.rb
│ │ ├── ipn.rb
│ │ ├── nvp/
│ │ │ ├── request.rb
│ │ │ └── response.rb
│ │ ├── payment/
│ │ │ ├── common/
│ │ │ │ └── amount.rb
│ │ │ ├── recurring/
│ │ │ │ ├── activation.rb
│ │ │ │ ├── billing.rb
│ │ │ │ └── summary.rb
│ │ │ ├── recurring.rb
│ │ │ ├── request/
│ │ │ │ └── item.rb
│ │ │ ├── request.rb
│ │ │ ├── response/
│ │ │ │ ├── address.rb
│ │ │ │ ├── info.rb
│ │ │ │ ├── item.rb
│ │ │ │ ├── payer.rb
│ │ │ │ ├── reference.rb
│ │ │ │ └── refund.rb
│ │ │ └── response.rb
│ │ └── util.rb
│ └── paypal.rb
├── paypal-express.gemspec
└── spec/
├── fake_response/
│ ├── BillAgreementUpdate/
│ │ ├── fetch.txt
│ │ └── revoke.txt
│ ├── CreateBillingAgreement/
│ │ └── success.txt
│ ├── CreateRecurringPaymentsProfile/
│ │ ├── failure.txt
│ │ └── success.txt
│ ├── DoCapture/
│ │ ├── failure.txt
│ │ └── success.txt
│ ├── DoExpressCheckoutPayment/
│ │ ├── failure.txt
│ │ ├── success.txt
│ │ ├── success_with_billing_agreement.txt
│ │ └── success_with_many_items.txt
│ ├── DoReferenceTransaction/
│ │ ├── failure.txt
│ │ └── success.txt
│ ├── DoVoid/
│ │ └── success.txt
│ ├── GetExpressCheckoutDetails/
│ │ ├── failure.txt
│ │ ├── success.txt
│ │ └── with_billing_accepted_status.txt
│ ├── GetRecurringPaymentsProfileDetails/
│ │ ├── failure.txt
│ │ └── success.txt
│ ├── GetTransactionDetails/
│ │ ├── failure.txt
│ │ └── success.txt
│ ├── IPN/
│ │ ├── invalid.txt
│ │ └── valid.txt
│ ├── ManageRecurringPaymentsProfileStatus/
│ │ ├── failure.txt
│ │ └── success.txt
│ ├── RefundTransaction/
│ │ └── full.txt
│ └── SetExpressCheckout/
│ ├── failure.txt
│ └── success.txt
├── helpers/
│ └── fake_response_helper.rb
├── paypal/
│ ├── exception/
│ │ ├── api_error_spec.rb
│ │ └── http_error_spec.rb
│ ├── express/
│ │ ├── request_spec.rb
│ │ └── response_spec.rb
│ ├── ipn_spec.rb
│ ├── nvp/
│ │ ├── request_spec.rb
│ │ └── response_spec.rb
│ ├── payment/
│ │ ├── common/
│ │ │ └── amount_spec.rb
│ │ ├── recurring/
│ │ │ └── activation_spec.rb
│ │ ├── recurring_spec.rb
│ │ ├── request/
│ │ │ └── item_spec.rb
│ │ ├── request_spec.rb
│ │ ├── response/
│ │ │ ├── address_spec.rb
│ │ │ ├── info_spec.rb
│ │ │ ├── item_spec.rb
│ │ │ └── payer_spec.rb
│ │ └── response_spec.rb
│ └── util_spec.rb
└── spec_helper.rb
SYMBOL INDEX (144 symbols across 28 files)
FILE: lib/paypal.rb
type Paypal (line 8) | module Paypal
function endpoint (line 21) | def self.endpoint
function popup_endpoint (line 28) | def self.popup_endpoint
function log (line 36) | def self.log(message, mode = :info)
function logger (line 39) | def self.logger
function logger= (line 42) | def self.logger=(logger)
function sandbox? (line 48) | def self.sandbox?
function sandbox! (line 51) | def self.sandbox!
function sandbox= (line 54) | def self.sandbox=(boolean)
FILE: lib/paypal/base.rb
type Paypal (line 1) | module Paypal
class Base (line 2) | class Base
method initialize (line 5) | def initialize(attributes = {})
FILE: lib/paypal/exception.rb
type Paypal (line 1) | module Paypal
class Exception (line 2) | class Exception < StandardError
FILE: lib/paypal/exception/api_error.rb
type Paypal (line 1) | module Paypal
class Exception (line 2) | class Exception
class APIError (line 3) | class APIError < Exception
method initialize (line 5) | def initialize(response = {})
method message (line 13) | def message
class Response (line 22) | class Response
class Detail (line 41) | class Detail
method initialize (line 51) | def initialize(attributes = {})
method initialize (line 65) | def initialize(attributes = {})
method short_messages (line 88) | def short_messages
FILE: lib/paypal/exception/http_error.rb
type Paypal (line 1) | module Paypal
class Exception (line 2) | class Exception
class HttpError (line 3) | class HttpError < Exception
method initialize (line 5) | def initialize(code, message, body = '')
FILE: lib/paypal/express/request.rb
type Paypal (line 1) | module Paypal
type Express (line 2) | module Express
class Request (line 3) | class Request < NVP::Request
method setup (line 7) | def setup(payment_requests, return_url, cancel_url, options = {})
method details (line 38) | def details(token)
method transaction_details (line 43) | def transaction_details(transaction_id)
method checkout! (line 48) | def checkout!(token, payer_id, payment_requests)
method capture! (line 60) | def capture!(authorization_id, amount, currency_code, complete_typ...
method void! (line 72) | def void!(authorization_id, params={})
method subscribe! (line 84) | def subscribe!(token, recurring_profile)
method subscription (line 93) | def subscription(profile_id)
method renew! (line 101) | def renew!(profile_id, action, options = {})
method suspend! (line 113) | def suspend!(profile_id, options = {})
method cancel! (line 117) | def cancel!(profile_id, options = {})
method reactivate! (line 121) | def reactivate!(profile_id, options = {})
method agree! (line 128) | def agree!(token, options = {})
method agreement (line 139) | def agreement(reference_id)
method charge! (line 147) | def charge!(reference_id, amount, options = {})
method revoke! (line 160) | def revoke!(reference_id)
method refund! (line 172) | def refund!(transaction_id, options = {})
FILE: lib/paypal/express/response.rb
type Paypal (line 1) | module Paypal
type Express (line 2) | module Express
class Response (line 3) | class Response < NVP::Response
method initialize (line 6) | def initialize(response, options = {})
method redirect_uri (line 12) | def redirect_uri
method popup_uri (line 18) | def popup_uri
method query (line 26) | def query(with_cmd = false)
FILE: lib/paypal/ipn.rb
type Paypal (line 1) | module Paypal
type IPN (line 2) | module IPN
function endpoint (line 3) | def self.endpoint
function verify! (line 11) | def self.verify!(raw_post)
FILE: lib/paypal/nvp/request.rb
type Paypal (line 1) | module Paypal
type NVP (line 2) | module NVP
class Request (line 3) | class Request < Base
method endpoint (line 13) | def self.endpoint
method initialize (line 21) | def initialize(attributes = {})
method common_params (line 26) | def common_params
method request (line 36) | def request(method, params = {})
method post (line 44) | def post(method, params)
method handle_response (line 48) | def handle_response
FILE: lib/paypal/nvp/response.rb
type Paypal (line 1) | module Paypal
type NVP (line 2) | module NVP
class Response (line 3) | class Response < Base
method initialize (line 45) | def initialize(attributes = {})
FILE: lib/paypal/payment/common/amount.rb
type Paypal (line 1) | module Paypal
type Payment (line 2) | module Payment
type Common (line 3) | module Common
class Amount (line 4) | class Amount < Base
method numeric_attribute? (line 7) | def numeric_attribute?(key)
FILE: lib/paypal/payment/recurring.rb
type Paypal (line 1) | module Paypal
type Payment (line 2) | module Payment
class Recurring (line 3) | class Recurring < Base
method initialize (line 7) | def initialize(attributes = {})
method to_params (line 15) | def to_params
method numeric_attribute? (line 38) | def numeric_attribute?(key)
FILE: lib/paypal/payment/recurring/activation.rb
type Paypal (line 1) | module Paypal
type Payment (line 2) | module Payment
class Recurring::Activation (line 3) | class Recurring::Activation < Base
method to_params (line 6) | def to_params
FILE: lib/paypal/payment/recurring/billing.rb
type Paypal (line 1) | module Paypal
type Payment (line 2) | module Payment
class Recurring::Billing (line 3) | class Recurring::Billing < Base
method initialize (line 7) | def initialize(attributes = {})
method to_params (line 21) | def to_params
FILE: lib/paypal/payment/recurring/summary.rb
type Paypal (line 1) | module Paypal
type Payment (line 2) | module Payment
class Recurring::Summary (line 3) | class Recurring::Summary < Base
method numeric_attribute? (line 6) | def numeric_attribute?(key)
FILE: lib/paypal/payment/request.rb
type Paypal (line 1) | module Paypal
type Payment (line 2) | module Payment
class Request (line 3) | class Request < Base
method initialize (line 7) | def initialize(attributes = {})
method to_params (line 25) | def to_params(index = 0)
method items_amount (line 60) | def items_amount
FILE: lib/paypal/payment/request/item.rb
type Paypal (line 1) | module Paypal
type Payment (line 2) | module Payment
class Request::Item (line 3) | class Request::Item < Base
method initialize (line 6) | def initialize(attributes = {})
method to_params (line 11) | def to_params(parent_index, index = 0)
FILE: lib/paypal/payment/response.rb
type Paypal (line 1) | module Paypal
type Payment (line 2) | module Payment
class Response (line 3) | class Response < Base
method initialize (line 6) | def initialize(attributes = {})
FILE: lib/paypal/payment/response/address.rb
type Paypal (line 1) | module Paypal
type Payment (line 2) | module Payment
class Response::Address (line 3) | class Response::Address < Base
FILE: lib/paypal/payment/response/info.rb
type Paypal (line 1) | module Paypal
type Payment (line 2) | module Payment
class Response::Info (line 3) | class Response::Info < Base
method initialize (line 27) | def initialize(attributes = {})
FILE: lib/paypal/payment/response/item.rb
type Paypal (line 1) | module Paypal
type Payment (line 2) | module Payment
class Response::Item (line 3) | class Response::Item < Base
method initialize (line 23) | def initialize(attributes = {})
FILE: lib/paypal/payment/response/payer.rb
type Paypal (line 1) | module Paypal
type Payment (line 2) | module Payment
class Response::Payer (line 3) | class Response::Payer < Base
FILE: lib/paypal/payment/response/reference.rb
type Paypal (line 1) | module Paypal
type Payment (line 2) | module Payment
class Response::Reference (line 3) | class Response::Reference < Base
FILE: lib/paypal/payment/response/refund.rb
type Paypal (line 1) | module Paypal
type Payment (line 2) | module Payment
class Response::Refund (line 3) | class Response::Refund < Base
method initialize (line 7) | def initialize(attributes = {})
FILE: lib/paypal/util.rb
type Paypal (line 1) | module Paypal
type Util (line 2) | module Util
function formatted_amount (line 4) | def self.formatted_amount(x)
function to_numeric (line 9) | def self.to_numeric(x)
function numeric_attribute? (line 17) | def numeric_attribute?(key)
function == (line 21) | def ==(other)
FILE: spec/helpers/fake_response_helper.rb
type FakeResponseHelper (line 3) | module FakeResponseHelper
function fake_response (line 5) | def fake_response(file_path, api = :NVP, options = {})
function request_to (line 23) | def request_to(endpoint, method = :get)
FILE: spec/paypal/express/request_spec.rb
class Paypal::Express::Request (line 4) | class Paypal::Express::Request
method post_with_logging (line 6) | def post_with_logging(method, params)
FILE: spec/spec_helper.rb
function sandbox_mode (line 20) | def sandbox_mode(&block)
Condensed preview — 85 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (131K chars).
[
{
"path": ".document",
"chars": 60,
"preview": "README.rdoc\nlib/**/*.rb\nbin/*\nfeatures/**/*.feature\nLICENSE\n"
},
{
"path": ".github/FUNDING.yml",
"chars": 59,
"preview": "# These are supported funding model platforms\n\ngithub: nov\n"
},
{
"path": ".gitignore",
"chars": 160,
"preview": "## MAC OS\n.DS_Store\n\n## TEXTMATE\n*.tmproj\ntmtags\n\n## EMACS\n*~\n\\#*\n.\\#*\n\n## VIM\n*.swp\n\n## PROJECT::GENERAL\ncoverage*\nrdoc"
},
{
"path": ".rspec",
"chars": 31,
"preview": "--color\n--format=documentation\n"
},
{
"path": ".travis.yml",
"chars": 65,
"preview": "before_install:\n - gem install bundler\n\nrvm:\n - 2.0.0\n - 2.1.2"
},
{
"path": "Gemfile",
"chars": 93,
"preview": "source 'http://rubygems.org'\n\nplatform :jruby do\n gem 'jruby-openssl', '>= 0.7'\nend\n\ngemspec"
},
{
"path": "LICENSE",
"chars": 1054,
"preview": "Copyright (c) 2011 nov matake\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this soft"
},
{
"path": "README.rdoc",
"chars": 1006,
"preview": "= paypal-express\n\nHandle PayPal Express Checkout.\nBoth Instance Payment and Recurring Payment are supported.\nExpress Che"
},
{
"path": "Rakefile",
"chars": 402,
"preview": "require 'bundler'\nBundler::GemHelper.install_tasks\n\nrequire 'rspec/core/rake_task'\nRSpec::Core::RakeTask.new(:spec)\n\nnam"
},
{
"path": "VERSION",
"chars": 5,
"preview": "0.8.1"
},
{
"path": "lib/paypal/base.rb",
"chars": 450,
"preview": "module Paypal\n class Base\n include AttrRequired, AttrOptional, Util\n\n def initialize(attributes = {})\n if at"
},
{
"path": "lib/paypal/exception/api_error.rb",
"chars": 2893,
"preview": "module Paypal\n class Exception\n class APIError < Exception\n attr_accessor :response\n def initialize(respon"
},
{
"path": "lib/paypal/exception/http_error.rb",
"chars": 250,
"preview": "module Paypal\n class Exception\n class HttpError < Exception\n attr_accessor :code, :message, :body\n def ini"
},
{
"path": "lib/paypal/exception.rb",
"chars": 57,
"preview": "module Paypal\n class Exception < StandardError\n end\nend"
},
{
"path": "lib/paypal/express/request.rb",
"chars": 5568,
"preview": "module Paypal\n module Express\n class Request < NVP::Request\n\n # Common\n\n def setup(payment_requests, retur"
},
{
"path": "lib/paypal/express/response.rb",
"chars": 926,
"preview": "module Paypal\n module Express\n class Response < NVP::Response\n attr_accessor :pay_on_paypal, :mobile\n\n def"
},
{
"path": "lib/paypal/express.rb",
"chars": 16,
"preview": "require 'paypal'"
},
{
"path": "lib/paypal/ipn.rb",
"chars": 455,
"preview": "module Paypal\n module IPN\n def self.endpoint\n _endpoint_ = URI.parse Paypal.endpoint\n _endpoint_.query = {"
},
{
"path": "lib/paypal/nvp/request.rb",
"chars": 1548,
"preview": "module Paypal\n module NVP\n class Request < Base\n attr_required :username, :password, :signature\n attr_opti"
},
{
"path": "lib/paypal/nvp/response.rb",
"chars": 10165,
"preview": "module Paypal\n module NVP\n class Response < Base\n cattr_reader :attribute_mapping\n @@attribute_mapping = {"
},
{
"path": "lib/paypal/payment/common/amount.rb",
"chars": 274,
"preview": "module Paypal\n module Payment\n module Common\n class Amount < Base\n attr_optional :total, :item, :fee, :h"
},
{
"path": "lib/paypal/payment/recurring/activation.rb",
"chars": 309,
"preview": "module Paypal\n module Payment\n class Recurring::Activation < Base\n attr_optional :initial_amount, :failed_actio"
},
{
"path": "lib/paypal/payment/recurring/billing.rb",
"chars": 1287,
"preview": "module Paypal\n module Payment\n class Recurring::Billing < Base\n attr_optional :period, :frequency, :paid, :curr"
},
{
"path": "lib/paypal/payment/recurring/summary.rb",
"chars": 354,
"preview": "module Paypal\n module Payment\n class Recurring::Summary < Base\n attr_optional :next_billing_date, :cycles_compl"
},
{
"path": "lib/paypal/payment/recurring.rb",
"chars": 1508,
"preview": "module Paypal\n module Payment\n class Recurring < Base\n attr_optional :start_date, :description, :identifier, :s"
},
{
"path": "lib/paypal/payment/request/item.rb",
"chars": 942,
"preview": "module Paypal\n module Payment\n class Request::Item < Base\n attr_optional :name, :description, :amount, :number,"
},
{
"path": "lib/paypal/payment/request.rb",
"chars": 2730,
"preview": "module Paypal\n module Payment\n class Request < Base\n attr_optional :action, :currency_code, :description, :noti"
},
{
"path": "lib/paypal/payment/response/address.rb",
"chars": 196,
"preview": "module Paypal\n module Payment\n class Response::Address < Base\n attr_optional :owner, :status, :name, :zip, :str"
},
{
"path": "lib/paypal/payment/response/info.rb",
"chars": 1493,
"preview": "module Paypal\n module Payment\n class Response::Info < Base\n cattr_reader :attribute_mapping\n @@attribute_m"
},
{
"path": "lib/paypal/payment/response/item.rb",
"chars": 1153,
"preview": "module Paypal\n module Payment\n class Response::Item < Base\n cattr_reader :attribute_mapping\n @@attribute_m"
},
{
"path": "lib/paypal/payment/response/payer.rb",
"chars": 165,
"preview": "module Paypal\n module Payment\n class Response::Payer < Base\n attr_optional :identifier, :status, :first_name, :"
},
{
"path": "lib/paypal/payment/response/reference.rb",
"chars": 185,
"preview": "module Paypal\n module Payment\n class Response::Reference < Base\n attr_required :identifier\n attr_optional "
},
{
"path": "lib/paypal/payment/response/refund.rb",
"chars": 267,
"preview": "module Paypal\n module Payment\n class Response::Refund < Base\n attr_optional :transaction_id\n attr_accessor"
},
{
"path": "lib/paypal/payment/response.rb",
"chars": 3002,
"preview": "module Paypal\n module Payment\n class Response < Base\n attr_accessor :amount, :ship_to, :bill_to, :description, "
},
{
"path": "lib/paypal/util.rb",
"chars": 518,
"preview": "module Paypal\n module Util\n\n def self.formatted_amount(x)\n # Thanks @nahi ;)\n sprintf \"%0.2f\", BigDecimal."
},
{
"path": "lib/paypal.rb",
"chars": 2049,
"preview": "require 'logger'\nrequire 'active_support'\nrequire 'active_support/core_ext'\nrequire 'attr_required'\nrequire 'attr_option"
},
{
"path": "paypal-express.gemspec",
"chars": 1191,
"preview": "Gem::Specification.new do |s|\n s.name = \"paypal-express\"\n s.version = File.read(File.join(File.dirname(__FILE__), \"VER"
},
{
"path": "spec/fake_response/BillAgreementUpdate/fetch.txt",
"chars": 369,
"preview": "BILLINGAGREEMENTID=B%2d8XW15926RT2253736&BILLINGAGREEMENTDESCRIPTION=Reference%20Payment%20Agreement&BILLINGAGREEMENTSTA"
},
{
"path": "spec/fake_response/BillAgreementUpdate/revoke.txt",
"chars": 369,
"preview": "BILLINGAGREEMENTID=B%2d8XW15926RT2253736&BILLINGAGREEMENTDESCRIPTION=Reference%20Payment%20Agreement&BILLINGAGREEMENTSTA"
},
{
"path": "spec/fake_response/CreateBillingAgreement/success.txt",
"chars": 148,
"preview": "BILLINGAGREEMENTID=B%2d45776062X95244343&TIMESTAMP=2011%2d08%2d06T07%3a53%3a50Z&CORRELATIONID=9a16fde4456e1&ACK=Success&"
},
{
"path": "spec/fake_response/CreateRecurringPaymentsProfile/failure.txt",
"chars": 222,
"preview": "TIMESTAMP=2011%2d02%2d08T07%3a18%3a29Z&CORRELATIONID=fde1527b25b4f&ACK=Failure&VERSION=66%2e0&BUILD=1704252&L_ERRORCODE0"
},
{
"path": "spec/fake_response/CreateRecurringPaymentsProfile/success.txt",
"chars": 162,
"preview": "PROFILEID=I%2dL8N58XFUCET3&PROFILESTATUS=ActiveProfile&TIMESTAMP=2011%2d02%2d08T07%3a17%3a51Z&CORRELATIONID=7d2e125f5ca6"
},
{
"path": "spec/fake_response/DoCapture/failure.txt",
"chars": 224,
"preview": "ACK=Failure&BUILD=8334781&CORRELATIONID=dd9e16358819b&L_ERRORCODE0=10609&L_LONGMESSAGE0=Transaction+id+is+invalid.&L_SEV"
},
{
"path": "spec/fake_response/DoCapture/success.txt",
"chars": 508,
"preview": "ACK=Success&AMT=440.00&AUTHORIZATIONID=2RG78938NK8989844&BUILD=8334781&CORRELATIONID=311611c111b48&CURRENCYCODE=BRL&EXCH"
},
{
"path": "spec/fake_response/DoExpressCheckoutPayment/failure.txt",
"chars": 214,
"preview": "TIMESTAMP=2011%2d02%2d08T07%3a15%3a19Z&CORRELATIONID=5dd0308345382&ACK=Failure&VERSION=66%2e0&BUILD=1721431&L_ERRORCODE0"
},
{
"path": "spec/fake_response/DoExpressCheckoutPayment/success.txt",
"chars": 742,
"preview": "TOKEN=EC-9E2743126S4330617&SUCCESSPAGEREDIRECTREQUESTED=false&TIMESTAMP=2011-02-08T03:23:55Z&CORRELATIONID=15b93874c358c"
},
{
"path": "spec/fake_response/DoExpressCheckoutPayment/success_with_billing_agreement.txt",
"chars": 781,
"preview": "TOKEN=EC-9E2743126S4330617&SUCCESSPAGEREDIRECTREQUESTED=false&TIMESTAMP=2011-02-08T03:23:55Z&CORRELATIONID=15b93874c358c"
},
{
"path": "spec/fake_response/DoExpressCheckoutPayment/success_with_many_items.txt",
"chars": 13821,
"preview": "TOKEN=EC%2d7HG122968U843864S&CHECKOUTSTATUS=PaymentActionNotInitiated&TIMESTAMP=2011%2d04%2d12T03%3a51%3a58Z&CORRELATION"
},
{
"path": "spec/fake_response/DoReferenceTransaction/failure.txt",
"chars": 447,
"preview": "TIMESTAMP=2011%2d07%2d19T08%3a59%3a52Z&CORRELATIONID=ed8096a3c3d7d&ACK=Failure&VERSION=72%2e0&BUILD=1982348&L_ERRORCODE0"
},
{
"path": "spec/fake_response/DoReferenceTransaction/success.txt",
"chars": 433,
"preview": "BILLINGAGREEMENTID=B%2d7HU5U5U1ULU14U49E&TIMESTAMP=2011%2d07%2d19T08%3a30%3a08Z&CORRELATIONID=12ca85fb3c9d2&ACK=Success&"
},
{
"path": "spec/fake_response/DoVoid/success.txt",
"chars": 90,
"preview": "ACK=Success&AUTHORIZATIONID=1a2b3c4d5e6f&BUILD=13055236&TIMESTAMP=2014-10-03T17%3A34%3A56Z"
},
{
"path": "spec/fake_response/GetExpressCheckoutDetails/failure.txt",
"chars": 1532,
"preview": "TOKEN=EC%2d9E2743126S4330617&CHECKOUTSTATUS=PaymentActionCompleted&TIMESTAMP=2011%2d02%2d08T07%3a10%3a26Z&CORRELATIONID="
},
{
"path": "spec/fake_response/GetExpressCheckoutDetails/success.txt",
"chars": 1589,
"preview": "TOKEN=EC%2d7HG122968U843864S&CHECKOUTSTATUS=PaymentActionNotInitiated&TIMESTAMP=2011%2d04%2d12T03%3a51%3a58Z&CORRELATION"
},
{
"path": "spec/fake_response/GetExpressCheckoutDetails/with_billing_accepted_status.txt",
"chars": 715,
"preview": "TOKEN=EC%2d4D299105F9409730D&BILLINGAGREEMENTACCEPTEDSTATUS=1&CHECKOUTSTATUS=PaymentActionNotInitiated&TIMESTAMP=2011%2d"
},
{
"path": "spec/fake_response/GetRecurringPaymentsProfileDetails/failure.txt",
"chars": 264,
"preview": "PROFILEID=I%2dK1VFLRN3VVG0x&TIMESTAMP=2011%2d02%2d08T07%3a19%3a43Z&CORRELATIONID=edc954f1c34c5&ACK=Failure&VERSION=66%2e"
},
{
"path": "spec/fake_response/GetRecurringPaymentsProfileDetails/success.txt",
"chars": 1107,
"preview": "PROFILEID=I%2dK1VFLRN3VVG0&STATUS=Active&AUTOBILLOUTAMT=NoAutoBill&DESC=iKnow%21%20Subscription&MAXFAILEDPAYMENTS=0&SUBS"
},
{
"path": "spec/fake_response/GetTransactionDetails/failure.txt",
"chars": 418,
"preview": "ADDRESSOWNER=PayPal&ADDRESSSTATUS=None&TIMESTAMP=2012%2d02%2d23T21%3a07%3a22Z&CORRELATIONID=4e18d75a23953&ACK=Failure&VE"
},
{
"path": "spec/fake_response/GetTransactionDetails/success.txt",
"chars": 1102,
"preview": "RECEIVEREMAIL=test%40email%2ecom&RECEIVERID=ABCDEFG12345&EMAIL=test%40email%2ecom&PAYERID=12345ABCDEFG&PAYERSTATUS=verif"
},
{
"path": "spec/fake_response/IPN/invalid.txt",
"chars": 7,
"preview": "INVALID"
},
{
"path": "spec/fake_response/IPN/valid.txt",
"chars": 8,
"preview": "VERIFIED"
},
{
"path": "spec/fake_response/ManageRecurringPaymentsProfileStatus/failure.txt",
"chars": 387,
"preview": "TIMESTAMP=2011%2d02%2d08T07%3a21%3a08Z&CORRELATIONID=aa160cad77481&ACK=Failure&VERSION=66%2e0&BUILD=1704252&L_ERRORCODE0"
},
{
"path": "spec/fake_response/ManageRecurringPaymentsProfileStatus/success.txt",
"chars": 134,
"preview": "PROFILEID=I%2dK1VFLRN3VVG0&TIMESTAMP=2011%2d02%2d08T07%3a20%3a44Z&CORRELATIONID=86bde487ccba6&ACK=Success&VERSION=66%2e0"
},
{
"path": "spec/fake_response/RefundTransaction/full.txt",
"chars": 253,
"preview": "REFUNDTRANSACTIONID=6D456341FS516215S&FEEREFUNDAMT=0%2e50&GROSSREFUNDAMT=10%2e00&NETREFUNDAMT=9%2e50&CURRENCYCODE=USD&TO"
},
{
"path": "spec/fake_response/SetExpressCheckout/failure.txt",
"chars": 176,
"preview": "TIMESTAMP=2011%2d02%2d02T02%3a16%3a50Z&CORRELATIONID=379d1b7f97afb&ACK=Failure&L_ERRORCODE0=10001&L_SHORTMESSAGE0=Intern"
},
{
"path": "spec/fake_response/SetExpressCheckout/success.txt",
"chars": 128,
"preview": "ACK=Success&BUILD=1721431&CORRELATIONID=5549ea3a78af1&TIMESTAMP=2011-02-02T02%3A02%3A18Z&TOKEN=EC-5YJ90598G69065317&VERS"
},
{
"path": "spec/helpers/fake_response_helper.rb",
"chars": 753,
"preview": "require 'fakeweb'\n\nmodule FakeResponseHelper\n\n def fake_response(file_path, api = :NVP, options = {})\n endpoint = ca"
},
{
"path": "spec/paypal/exception/api_error_spec.rb",
"chars": 2373,
"preview": "require 'spec_helper.rb'\n\ndescribe Paypal::Exception::APIError do\n let(:error) { Paypal::Exception::APIError.new(params"
},
{
"path": "spec/paypal/exception/http_error_spec.rb",
"chars": 282,
"preview": "require 'spec_helper.rb'\n\ndescribe Paypal::Exception::HttpError do\n subject { Paypal::Exception::HttpError.new(400, 'Ba"
},
{
"path": "spec/paypal/express/request_spec.rb",
"chars": 19007,
"preview": "require 'spec_helper.rb'\n\ndescribe Paypal::Express::Request do\n class Paypal::Express::Request\n attr_accessor :_sent"
},
{
"path": "spec/paypal/express/response_spec.rb",
"chars": 2344,
"preview": "require 'spec_helper.rb'\n\ndescribe Paypal::Express::Response do\n before { fake_response 'SetExpressCheckout/success' }\n"
},
{
"path": "spec/paypal/ipn_spec.rb",
"chars": 478,
"preview": "require 'spec_helper'\n\ndescribe Paypal::IPN do\n describe '.verify!' do\n context 'when valid' do\n before { fake_"
},
{
"path": "spec/paypal/nvp/request_spec.rb",
"chars": 3163,
"preview": "require 'spec_helper.rb'\n\ndescribe Paypal::NVP::Request do\n let :attributes do\n {\n :username => 'nov',\n :p"
},
{
"path": "spec/paypal/nvp/response_spec.rb",
"chars": 4580,
"preview": "require 'spec_helper.rb'\n\ndescribe Paypal::NVP::Response do\n let(:return_url) { 'http://example.com/success' }\n let(:c"
},
{
"path": "spec/paypal/payment/common/amount_spec.rb",
"chars": 936,
"preview": "require 'spec_helper.rb'\n\ndescribe Paypal::Payment::Common::Amount do\n let :keys do\n Paypal::Payment::Common::Amount"
},
{
"path": "spec/paypal/payment/recurring/activation_spec.rb",
"chars": 465,
"preview": "require 'spec_helper'\n\ndescribe Paypal::Payment::Recurring::Activation do\n let :instance do\n Paypal::Payment::Recurr"
},
{
"path": "spec/paypal/payment/recurring_spec.rb",
"chars": 5010,
"preview": "require 'spec_helper.rb'\n\ndescribe Paypal::Payment::Recurring do\n let :keys do\n Paypal::Payment::Recurring.optional_"
},
{
"path": "spec/paypal/payment/request/item_spec.rb",
"chars": 731,
"preview": "require 'spec_helper.rb'\n\ndescribe Paypal::Payment::Request::Item do\n let :instance do\n Paypal::Payment::Request::It"
},
{
"path": "spec/paypal/payment/request_spec.rb",
"chars": 4733,
"preview": "require 'spec_helper.rb'\n\ndescribe Paypal::Payment::Request do\n let :instant_request do\n Paypal::Payment::Request.ne"
},
{
"path": "spec/paypal/payment/response/address_spec.rb",
"chars": 666,
"preview": "require 'spec_helper.rb'\n\ndescribe Paypal::Payment::Response::Address do\n let :keys do\n Paypal::Payment::Response::A"
},
{
"path": "spec/paypal/payment/response/info_spec.rb",
"chars": 3150,
"preview": "require 'spec_helper.rb'\n\ndescribe Paypal::Payment::Response::Info do\n let :attribute_mapping do\n Paypal::Payment::R"
},
{
"path": "spec/paypal/payment/response/item_spec.rb",
"chars": 1221,
"preview": "require 'spec_helper.rb'\n\ndescribe Paypal::Payment::Response::Info do\n let :attributes do\n {\n :NAME => 'Item Na"
},
{
"path": "spec/paypal/payment/response/payer_spec.rb",
"chars": 658,
"preview": "require 'spec_helper.rb'\n\ndescribe Paypal::Payment::Response::Payer do\n let :keys do\n Paypal::Payment::Response::Pay"
},
{
"path": "spec/paypal/payment/response_spec.rb",
"chars": 444,
"preview": "require 'spec_helper.rb'\n\ndescribe Paypal::Payment::Response do\n describe '.new' do\n context 'when non-supported att"
},
{
"path": "spec/paypal/util_spec.rb",
"chars": 1288,
"preview": "require 'spec_helper.rb'\n\ndescribe Paypal::Util do\n describe '.formatted_amount' do\n it 'should return String in \"xx"
},
{
"path": "spec/spec_helper.rb",
"chars": 370,
"preview": "require 'simplecov'\n\nSimpleCov.start do\n add_filter 'spec'\nend\n\nrequire 'paypal'\nrequire 'rspec'\nrequire 'helpers/fake_"
}
]
About this extraction
This page contains the full source code of the nov/paypal-express GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 85 files (119.0 KB), approximately 37.4k tokens, and a symbol index with 144 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.